Assembly Feature Tree Traversal

So,

I’ve hit a roadblock in a VBA macro I’m writing to save parts for 3D printing. The macro works on the open document. If it’s a part, it saves it directly. If it’s an Assembly, it calls a recursive traversal routine.

I’m using a simple assembly traversal routine which look like this (this is just the traversal stuff, there is lot’s more going on that isn’t relevant to the conversation):

Option Explicit

Dim swApp As SldWorks.SldWorks
Sub main()

    Dim swAssy As ModelDoc2
    Dim swConfig As Configuration
    Dim swRootComp As Component2
    
    Set swApp = Application.SldWorks
    Set swAssy = swApp.ActiveDoc
    Set swConfig = swAssy.GetActiveConfiguration
    Set swRootComp = swConfig.GetRootComponent3(False)

    TraverseAssyComponents swRootComp

End Sub

Sub TraverseAssyComponents(swParentComp As Component2)

    Dim swChildren As Variant
    Dim swChildComp As Component2
    Dim i As Long
    Dim errors as long
    Dim warnings as long
    Dim bReturn as boolean
    Dim strFilename as string
    
    Debug.Print swParentComp.GetPathName
    swChildren = swParentComp.GetChildren

    For i = 0 To UBound(swChildren)

        Set swChildComp = swChildren(i)
        If LCase(Right(swChildComp.GetPathName, Len(".SLDXXX"))) = LCase(".sldasm") Then
            TraverseAssyComponents swChildComp
        End If
        'Some handwaving here to get the strFilename in the correct configuration.....
        breturn=swModel.SaveAs4(strFilename, swSaveAsVersion_e.swSaveAsCurrentVersion, swSaveAsOptions_e.swSaveAsOptions_Silent, errors, warnings)
    Next i

End Sub

If the items referenced by swComp is a part, it saves it out as an STL. If it’s an Assembly, it calls the routine recursively. There is a function not shown that ensures things only get saved once.

As luck would have it, my assemblies have multiple copies of the same parts, albeit with different configurations. The routine as currently crafted will only print the first instance as it’'s matching only the name, not the config.

The challenge I’ve got is that I can’t for the life of me figure out a way to get config names for the referenced parts using Component2 in the subroutine.

Any thoughts about ways to do this are appreciated.

Cheers,

chris

Ok,

Answering my own question.

Here is the answer: https://help.solidworks.com/2012/english/api/sldworksapi/Traverse_Assembly_at_Component_and_Feature_Levels_Using_Recursion_Example_VB.htm

Here is the quick and dirty version:

Option Explicit

Sub main()
    Dim swApp                       As SldWorks.SldWorks
    Dim swModel                     As SldWorks.ModelDoc2
    Dim swConfMgr                   As SldWorks.ConfigurationManager
    Dim swConf                      As SldWorks.Configuration
    Dim swRootComp                  As SldWorks.Component2

    
    Set swApp = CreateObject("SldWorks.Application")
    Set swModel = swApp.ActiveDoc
    Set swConfMgr = swModel.ConfigurationManager
    Set swConf = swConfMgr.ActiveConfiguration
    Set swRootComp = swConf.GetRootComponent3(True)

    Debug.Print "File = " & swModel.GetPathName
    If swModel.GetType = SwConst.swDocASSEMBLY Then
        TraverseComponent swRootComp
    End If

End Sub

Sub TraverseComponent(swComp As SldWorks.Component2)
    Dim vChildComp                  As Variant
    Dim swChildComp                 As SldWorks.Component2
    Dim sPadStr                     As String
    Dim i                           As Long
    
    vChildComp = swComp.GetChildren
    For i = 0 To UBound(vChildComp)
        Set swChildComp = vChildComp(i)
        
        If LCase(Right(swChildComp.GetPathName, Len(".SLDXXX"))) = LCase(".sldasm") Then
            TraverseComponent swChildComp
        ElseIf LCase(Right(swChildComp.GetPathName, Len(".SLDXXX"))) = LCase(".sldprt") Then
            Debug.Print "Part = > " & swChildComp.GetPathName & " <" & swChildComp.ReferencedConfiguration & ">"
        End If
    Next i

End Sub

As far as I have decided for myself, the most reliable way to traverse the assembly is to create a tree dictionary (if we are talking about VBA). The first-level keys are full paths to the model files (or whatever it turns out to be for Virtual). The second-level keys are the names of the configurations. In the Value we save, for example, an array with the parameters: Visible / Not Visible, Envelope / NOT Envelope, etc.
Dic_ASM(CompPatch)(Conf)(2) = True

I made a topic about it here