You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CATIA V5代码优化求助:selection1.Add遍历全组件致运行缓慢

CATIA V5 宏代码优化:解决批量选择组件的性能问题

问题概述

原宏功能为隔离选中组件(隐藏其余组件),但执行selection1.Add时会遍历文档内所有组件(无论可见状态),导致代码运行缓慢。需求优化为:仅筛选可见产品下的可见零件存入invertedSelection,不可见产品直接跳过内部遍历。

优化方案

核心思路是递归遍历产品结构,提前判断组件可见性:

  • 先检查当前产品/组件的可见状态,不可见则直接跳过其子组件遍历
  • 仅对可见产品,递归遍历其下所有子组件
  • 只将可见的零件对象加入目标集合,避免无效遍历

优化后的完整代码

Sub CATMain()
    Dim selection1 As Selection
    Set selection1 = CATIA.ActiveDocument.Selection

    If selection1.Count > 0 Then
        Dim activeProduct As Product
        Set activeProduct = CATIA.ActiveDocument.Product
        
        ' 收集所有需要隐藏的可见零件(即选中组件之外的可见零件)
        Dim invertedSelection As New Collection
        Call CollectVisibleNonSelectedParts(activeProduct, selection1, invertedSelection)
        
        ' 隐藏需要隔离的零件
        selection1.Clear
        Dim i As Integer
        For i = 1 To invertedSelection.Count
            selection1.Add invertedSelection.Item(i)
        Next i
        
        Dim visPropertySet1 As VisPropertySet
        Set visPropertySet1 = selection1.VisProperties
        visPropertySet1.SetShow 0
        selection1.Clear
        
        ' 显示用户窗体
        UserForm1.Show
        Do While UserForm1.Visible
            DoEvents
        Loop
        
        ' 恢复隐藏的零件
        selection1.Clear
        For i = 1 To invertedSelection.Count
            selection1.Add invertedSelection.Item(i)
        Next i
        
        Dim visPropertySet2 As VisPropertySet
        Set visPropertySet2 = selection1.VisProperties
        visPropertySet2.SetShow 1
        selection1.Clear
        
    Else
        MsgBox "未选中任何组件", vbExclamation, "隔离组件"
        Exit Sub
    End If
End Sub

' 递归收集可见且未被选中的零件
Sub CollectVisibleNonSelectedParts(parentProduct As Product, selectedItems As Selection, targetCol As Collection)
    Dim comp As Product
    For Each comp In parentProduct.Products
        ' 检查当前组件是否可见
        Dim visProp As VisPropertySet
        Set visProp = comp.VisProperties
        Dim isVisible As Boolean
        isVisible = (visProp.GetShow = 1)
        
        If isVisible Then
            ' 检查是否是零件(而非装配体)
            If comp.IsComponent Then
                Dim partDoc As Document
                On Error Resume Next
                Set partDoc = comp.ReferenceProduct.Parent
                On Error GoTo 0
                
                If Not partDoc Is Nothing And partDoc.Type = "Part" Then
                    ' 检查该零件是否未被选中
                    Dim isSelected As Boolean
                    isSelected = False
                    Dim j As Integer
                    For j = 1 To selectedItems.Count
                        If selectedItems.Item(j).Value Is comp Then
                            isSelected = True
                            Exit For
                        End If
                    Next j
                    
                    If Not isSelected Then
                        targetCol.Add comp
                    End If
                End If
            End If
            
            ' 递归遍历子产品(仅当前组件可见时才遍历)
            Call CollectVisibleNonSelectedParts(comp, selectedItems, targetCol)
        End If
    Next comp
End Sub

关键优化点说明

  1. 递归筛选逻辑:新增CollectVisibleNonSelectedParts递归函数,仅遍历可见产品的子组件,直接跳过不可见产品的内部结构,减少无效遍历
  2. 可见性判断:通过comp.VisProperties.GetShow获取组件可见状态,返回1为可见,0为隐藏
  3. 零件类型校验:仅收集Part类型的对象,避免将装配体本身加入集合
  4. 选中状态排除:跳过已被用户选中的组件,确保只收集需要隐藏的对象
  5. 移除Group依赖:原代码使用Groups.AddFromSel和FillSelWithInvert会一次性获取所有反选组件,改为主动筛选后大幅减少需要处理的对象数量

内容的提问来源于stack exchange,提问作者AMMO

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 08:36:19