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

CATIA VBA宏改造需求:获取电缆保护件长度并在列表框展示

解决CATIA VBA宏无法访问零件层级参数的问题

首先,你的核心问题是在产品层级代码中没有正确切换到对应的零件文档,导致无法访问零件内部的Parameters和HybridBodies。下面是修正后的完整代码,同时我会拆解关键修复点:

修正后的完整代码

Sub GetProtectionLengths()
    Dim selection1 As Selection
    Set selection1 = CATIA.ActiveDocument.Selection
    
    ' 搜索所有电缆保护件
    selection1.Search "CATElectricalSearch.Protection,all"
    
    Dim i As Integer
    Dim oInstProd As Product
    Dim strpartno As String
    Dim partDoc As Document
    Dim part1 As Part
    Dim parameters1 As Parameters
    Dim length1 As Dimension
    Dim hybridBodies1 As HybridBodies
    Dim hybridBody1 As HybridBody
    Dim hybridShapes1 As HybridShapes
    Dim reference1 As Reference, reference2 As Reference, reference3 As Reference
    Dim relations1 As Relations
    Dim formula1 As Formula
    Dim ParamV As Parameter
    
    ' 初始化用户表单列表框
    UserFormTapeCheck.ListBox1.Clear
    UserFormTapeCheck.ListBox1.ColumnCount = 3
    UserFormTapeCheck.ListBox1.ColumnWidths = "150;150;100" ' 可根据需求调整
    
    For i = 1 To selection1.Count
        Set oInstProd = selection1.Item(i).LeafProduct
        strpartno = oInstProd.ReferenceProduct.PartNumber
        
        ' 关键修复1:获取当前保护件对应的零件文档
        Set partDoc = oInstProd.ReferenceProduct.Document
        If partDoc.Type <> "Part" Then
            ' 如果不是零件文档,跳过(理论上保护件应该是零件)
            With UserFormTapeCheck.ListBox1
                .AddItem
                .List(i - 1, 0) = oInstProd.Name
                .List(i - 1, 1) = strpartno
                .List(i - 1, 2) = "非零件文档"
            End With
            GoTo NextIteration
        End If
        
        ' 切换到零件文档并获取Part对象
        partDoc.Activate
        Set part1 = partDoc.Part
        Set parameters1 = part1.Parameters
        Set relations1 = part1.Relations
        
        On Error Resume Next
        Err.Clear
        Set ParamV = parameters1.Item("Lungime")
        
        If Err.Number = 0 Then
            ' 参数已存在,直接获取值
            With UserFormTapeCheck.ListBox1
                .AddItem
                .List(i - 1, 0) = oInstProd.Name
                .List(i - 1, 1) = strpartno
                .List(i - 1, 2) = ParamV.ValueAsString
            End With
            ' 可选:如果不需要保留参数,删除它
            parameters1.Remove "Lungime"
            ' 检查是否有对应的公式并删除
            On Error Resume Next
            relations1.Remove "Formula_Lungime"
            Err.Clear
        Else
            ' 参数不存在,创建参数并添加公式计算长度
            Set length1 = parameters1.CreateDimension("", "LENGTH", 0)
            length1.Rename "Lungime"
            
            ' 获取外部参考混合体(确保该混合体存在)
            On Error Resume Next
            Set hybridBody1 = part1.HybridBodies.Item("External References")
            If Err.Number <> 0 Then
                With UserFormTapeCheck.ListBox1
                    .AddItem
                    .List(i - 1, 0) = oInstProd.Name
                    .List(i - 1, 1) = strpartno
                    .List(i - 1, 2) = "无外部参考混合体"
                End With
                GoTo CleanupAndNext
            End If
            Err.Clear
            
            Set hybridShapes1 = hybridBody1.HybridShapes
            ' 确保曲线和点存在(这里假设顺序是曲线、MyEndPt1、MyEndPt2)
            On Error Resume Next
            Set reference1 = hybridShapes1.Item("MyCurve") ' 替换为你的曲线名称
            Set reference2 = hybridShapes1.Item("MyEndPt1")
            Set reference3 = hybridShapes1.Item("MyEndPt2")
            If Err.Number <> 0 Then
                With UserFormTapeCheck.ListBox1
                    .AddItem
                    .List(i - 1, 0) = oInstProd.Name
                    .List(i - 1, 1) = strpartno
                    .List(i - 1, 2) = "曲线/点缺失"
                End With
                GoTo CleanupAndNext
            End If
            Err.Clear
            
            ' 创建公式计算曲线上两点间的长度
            Set formula1 = relations1.CreateFormula("Formula_Lungime", "", length1, _
                "length( `External References\" & reference1.Name & "` ,`External References\" & reference2.Name & "` , `External References\" & reference3.Name & "` ) ")
            
            ' 更新零件以计算公式值
            part1.Update
            
            ' 将值添加到列表框
            With UserFormTapeCheck.ListBox1
                .AddItem
                .List(i - 1, 0) = oInstProd.Name
                .List(i - 1, 1) = strpartno
                .List(i - 1, 2) = length1.ValueAsString
            End With
        End If
        
CleanupAndNext:
        ' 清理当前零件的临时参数和公式(如果需要保留参数可删除这部分)
        On Error Resume Next
        parameters1.Remove "Lungime"
        relations1.Remove "Formula_Lungime"
        Err.Clear
        
NextIteration:
    Next i
    
    selection1.Clear
    ' 显示用户表单
    UserFormTapeCheck.Show
End Sub

关键修复点说明

1. 正确切换到零件文档

原来的代码错误地激活了selection1.Item(1)的文档,导致所有循环都操作同一个零件。修正后通过oInstProd.ReferenceProduct.Document获取当前保护件对应的零件文档,确保每个循环处理的是当前选中的保护件。

2. 增加文档类型和存在性检查

添加了对文档类型的判断,以及混合体、曲线、点的存在性检查,避免因缺失元素导致宏崩溃,同时给出明确的错误提示。

3. 变量作用域调整

将零件相关的变量(如part1、parameters1)放在循环内或确保每次循环重新赋值,避免变量残留导致的错误。

4. 强制更新零件

在创建公式后调用part1.Update(),确保参数值被正确计算,避免获取到初始的0值。

5. 规范公式命名

将公式命名为Formula_Lungime,方便后续查找和删除,避免使用默认的Formula.47这种动态命名的公式,防止删除错误。

额外注意事项

  • 确保保护件零件中的外部参考混合体名称为"External References",如果你的混合体名称不同,需要替换代码中对应的字符串。
  • 曲线和点的名称要与代码中的MyCurve、MyEndPt1、MyEndPt2一致,或者根据实际名称修改代码。
  • 如果希望保留创建的Lungime参数,可以删除循环末尾的清理代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 13:52:38