Inventor Macro: Recursive Function and Enumerator

When automating Inventor, it often happens that we need to cross several levels of objects, especially when we want to iterate through all the components and subcomponents of an assembly.

To do this, it is common to use a Recursive, a function that recalls itself a number of times indefinitely.

As in the following example, where we collect a collection of names of all the components of an assembly:

Private Sub ComponentsNames_Recursive()
Dim cNames As Collection
Dim oAssyDoc As AssemblyDocument
Set oAssyDoc = ThisApplication.ActiveDocument
Set cNames = GetAllComponentsNames(oAssyDoc)
End Sub
Private Function GetAllComponentsNames(ByVal oAssyDoc As AssemblyDocument) As Collection
Dim cNames As New Collection
Dim oCompOcc As ComponentOccurrence
For Each oCompOcc In oAssyDoc.ComponentDefinition.Occurrences
cNames.Add oCompOcc.Name
If oCompOcc.DefinitionDocumentType = kAssemblyDocumentObject Then
Dim cSubCompOccNames As Collection
Set cSubCompOccNames = GetAllComponentsNames(oCompOcc.Definition.Document)
Dim sSubCompOccName As Variant
For Each sSubCompOccName In cSubCompOccNames
cNames.Add sSubCompOccName
Next
End If
Next
Set GetAllComponentsNames = cNames
End Function

Public Sub ComponentsNames_Recursive()
Dim assemblyDocument As AssemblyDocument = InventorApplication.ActiveDocument
Dim names As Collection = GetAllComponentsNames(assemblyDocument)
End Sub
Private Function GetAllComponentsNames(ByVal assemblyDocument As AssemblyDocument) As Collection
Dim names As New Collection
Dim occurrence As ComponentOccurrence
For Each occurrence In assemblyDocument.ComponentDefinition.Occurrences
names.Add(occurrence.Name)
If occurrence.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
Dim subOccNames As Collection = GetAllComponentsNames(occurrence.Definition.Document)
For Each subOccName as Object In subOccNames
names.Add(subOccName)
Next
End If
Next
Return names
End Function

But you can also achieve the same result in less lines of code through the Enumerators, as in the following example:

Private Sub ComponentsNames_Enumerator()
Dim cNames As New Collection
Dim oAssyDoc As AssemblyDocument
Dim oCompOccEnum As ComponentOccurrencesEnumerator
Dim oCompOcc As ComponentOccurrence
Set oAssyDoc = ThisApplication.ActiveDocument
Set oCompOccEnum = oAssyDoc.ComponentDefinition.Occurrences.AllReferencedOccurrences(oAssyDoc.ComponentDefinition)
For Each oCompOcc In oCompOccEnum
cNames.Add oCompOcc.Name
Next
End Sub

Public Sub ComponentsNames_Enumerator()
Dim names As New Collection
Dim assemblyDocument As AssemblyDocument = InventorApplication.ActiveDocument
Dim compOccEnum As ComponentOccurrencesEnumerator = assemblyDocument.ComponentDefinition.Occurrences.AllReferencedOccurrences(assemblyDocument.ComponentDefinition)
For Each compOcc As ComponentOccurrence In compOccEnum
names.Add(compOcc.Name)
Next
End Sub

I was asked about this again today, so thought I'd share it here too. Quick iLogic routine to export workpoints to txt https://clintbrown.co.uk/2019/09/07/export-points-to-csv-with-ilogic/ #cadtip #autodesk #autodesk #autodeskinventor