原文地址: http://modthemachine.typepad.com/my_weblog/2009/03/accessing-assembly-components.html
对装配操作很多时候需要访问组成装配的部件(也可称作组件),英文叫做component。 本文对访问部件进行介绍。为简单起见,只讨论装配,零件,子装配。不讨论约束,装配特征等。
什么是装配?
再来回顾一下什么是装配。简单讲,装配可视作零件或子装的容器。每个部件引用定义了该部件在装配中的空间位置,显示样式等。该引用并不含有几何信息,只是对原信息的引用。总之,可以理解为,装配里只是记录引用了哪些文件,位置,样式等信息。而当装配需要显示时,几何信息从原部件中得到。 例如有这样一个装配:
下图是装配浏览。可以看见装配有14个部件,两个是子装,12个是零件。其实只有一个子装文档,5个零件文档。几何信息只存在于这些零件中。而总装配引用了几何信息,规定了在装配中的位置而已。
常用API:
ComponentOccurrence – 表示部件。也可称作引用。可代表子装或零件。例如上面这个总装有14个引用.
File Reference – 表示装配引用的文档。如上面的总装,有1个子装文档和5个零件文档。比如上面的Pillar零件,被引用了4次,但实际上对应当然文档就一个。
Leaf Occurrences – 每个部件的子部件。相当于遍历整个装配结构。所有零件These are occurrences that define the end of each branch as you traverse an assembly. In Inventor all parts are considered leaf occurrences.
访问部件有几种方法。各有特点。以下做介绍。
装配结构
第一种方法是访问整个装配结构。即如你在浏览窗口看到的装配树。这提供了装配的全部结构信息
通过这种方式访问有个问题是,装配中部件可以任意数量。而一个部件的子部件也可以任意数量。所以你不得不遍历每个部件,每个分支以获得完整的信息。而一般我们通过递归调用。
' 获取当前激活装配
Dim oAsmDoc As AssemblyDocument
Set oAsmDoc = ThisApplication.ActiveDocument
Debug.Print oAsmDoc.DisplayName
' 递归.
Call TraverseAssembly(oAsmDoc.ComponentDefinition.Occurrences, 1)
End Sub
Private Sub TraverseAssembly(Occurrences As ComponentOccurrences, _
Level As Integer)
' 遍历部件中所有子部件
Dim oOcc As ComponentOccurrence
For Each oOcc In Occurrences
' 打印出部件名
Debug.Print Space(Level * 3) & oOcc.Name
' 如果是子装,则需要递归
If oOcc.DefinitionDocumentType = kAssemblyDocumentObject Then
Call TraverseAssembly(oOcc.SubOccurrences, Level + 1)
End If
Next
End Sub
我想这个代码不难理解。首先从总装获得部件集合Occurrences。而部件的SubOccurrences只返回部件直接下一级的部件(即不是所有分支)。代码每遇到一个部件,则遍历其下一级部件,依次打印出名字。如果是子装,则意味着该部件有子部件。则递归调用遍历函数直到完全解释出装配结构。
从VBA的输出窗口可看到执行结果。与我们在产品浏览窗口看到的一样。
Floor:1
Arch:1
CurvedSupport:1
CurvedSupport:2
ArchTop:1
Arch:2
CurvedSupport:1
CurvedSupport:2
ArchTop:1
Pillar:1
Pillar:2
Pillar:3
Pillar:4
Inventor:1
代码中还有一个参数 “Level” 。它是用来标记当前遍历的装配结构中的层级。例如总装下直接的一级部件是1,如果是子装,直接的下一级部件就是2. 以上代码只是打印出部件名。你可以在那个位置做你需要的工作,例如访问BOM,访问iProperty等。
零件列表
一般情况下,通过遍历得到结构。如果你不需要层级结构,而是获知有那些零件。则可通过某些属性
所有零件
下面第一段代码用AllLeafOccurrences属性得到零件的集合。 该方法还有个缺省参数,可指定获取哪个子装的所有零件。默认是总装。
' 获取当前激活装配
Dim oAsmDoc As AssemblyDocument
Set oAsmDoc = ThisApplication.ActiveDocument
' 获取装配定义
Dim oAsmDef As AssemblyComponentDefinition
Set oAsmDef = oAsmDoc.ComponentDefinition
' 获取装配所有零件
Dim oLeafOccs As ComponentOccurrencesEnumerator
Set oLeafOccs = oAsmDef.Occurrences.AllLeafOccurrences
' 遍历并打印零件名
Dim oOcc As ComponentOccurrence
For Each oOcc In oLeafOccs
Debug.Print oOcc.Name
Next
End Sub
从VBA输出窗口可看到结果.
CurvedSupport:1
CurvedSupport:2
ArchTop:1
CurvedSupport:1
CurvedSupport:2
ArchTop:1
Pillar:1
Pillar:2
Pillar:3
Pillar:4
Inventor:1
引用了特定零件的所有部件
可能你需要哪些部件引用了某个紧固件零件,然后想用另外的紧固件来替换。则可以通过文档的 AllReferencedOccurrences获取。参数就是特定零件对应的文档. 例如:
' 获取激活装配
Dim oAsmDoc As AssemblyDocument
Set oAsmDoc = ThisApplication.ActiveDocument
' 获取装配定义
Dim oAsmDef As AssemblyComponentDefinition
Set oAsmDef = oAsmDoc.ComponentDefinition
' 假定我们想考察哪些部件引用了Pillar零件
Dim oDoc As Document
Set oDoc = ThisApplication.Documents.ItemByName( _
"C:\AssemblySample\Pillar.ipt")
' 调用 AllReferencedOccurrences
Dim oOccs As ComponentOccurrencesEnumerator
Set oOccs = oAsmDef.Occurrences.AllReferencedOccurrences(oDoc)
' 打印出部件名
Dim oOcc As ComponentOccurrence
For Each oOcc In oOccs
Debug.Print oOcc.Name
Next
End Sub
VBA输出窗口结果:
Pillar:2
Pillar:3
Pillar:4
从上可见,获取特定的部件列表比遍历结构树要容易些。其实API还有好几个属性,可灵活访问各种信息,不需要遍历结构树。例如ComponentOccurrence的ContainingOccurrence, OccurrencePath, 和ParentOccurrence. 请参见帮助文档。
所有引用文档
还有个常用的就是考察引用的文档,因为有时你并不需要访问每个部件。例如,假定你想把所有零件的材料变成另外一个材料。当然,可以用上面的遍历方法,得到每个部件,从而得到每个文档,然后修改材料。但因为一个零件可以被引用多次,所以遍历会造成很多重复劳动。效率低。我们只需要得到哪个零件即可。
因此AssemblyDocument 的AllReferencedDocuments 属性就排上用场了。它只返回该装配引用过的文档,而不关心其被引用了多少次。
' 获取激活文档
Dim oAsmDoc As AssemblyDocument
Set oAsmDoc = ThisApplication.ActiveDocument
' 获取所有引用文档
Dim oRefDocs As DocumentsEnumerator
Set oRefDocs = oAsmDoc.AllReferencedDocuments
' 遍历这些文档
Dim oRefDoc As Document
For Each oRefDoc In oRefDocs
Debug.Print oRefDoc.DisplayName
Next
End Sub
输出结果:
Inventor.ipt
ArchTop.ipt
CurvedSupport.ipt
Arch.iam
Floor.ipt
来个更复杂点的代码,实现我们刚才讨论的:把所有零件材料修改为Gold
'获取当前激活文档
Dim oAsmDoc As AssemblyDocument
Set oAsmDoc = ThisApplication.ActiveDocument
' 需要设置的材料名
Dim strMaterialName As String
strMaterialName = "Gold"
Dim oMaterial As Material
On Error Resume Next
' 获取材料对象
Set oMaterial = oAsmDoc.Materials.Item(strMaterialName)
If Err Then
MsgBox "The material """ & strMaterialName & _
""" was not found in the library."
Exit Sub
End If
On Error GoTo 0
' 获取装配所有引用文档
Dim oDoc As Document
For Each oDoc In oAsmDoc.AllReferencedDocuments
' 是不是零件
If oDoc.DocumentType = kPartDocumentObject Then
Dim oPartDoc As PartDocument
Set oPartDoc = oDoc
' 设置材料
oPartDoc.ComponentDefinition.Material = oMaterial
End If
Next
End Sub