VBA Macro - Traverse Assembly - Get Part "Description", "Material" & "iProperties"

VBA Macro - Traverse Assembly - Get Part "Description", "Material" & "iProperties"

isocam
Collaborator Collaborator
425 Views
3 Replies
Message 1 of 4

VBA Macro - Traverse Assembly - Get Part "Description", "Material" & "iProperties"

isocam
Collaborator
Collaborator

Can anybody help?

 

I have asked this question before but I do not know how to solve it.

 

I have the following VBA macro....

 

Public Sub TraverseAssembly()

    Dim oAsmDoc As AssemblyDocument

    Set oAsmDoc = ThisApplication.ActiveDocument

    msgbox(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

        Msgbox(oOcc.Name)

 

        If oOcc.DefinitionDocumentType = kAssemblyDocumentObject Then Call TraverseAssembly(oOcc.SubOccurrences, Level + 1)

    Next

End Sub

 

Is it possible to get the "DESCRIPTION", "MATERIAL" & "CUSTOM PROPERTIES" using oOcc?

 

For Example,

 

Msgbox(oOcc.Description)

 

Msgbox(oOcc.Material)

 

Msgbox(oOcc.  iProperties File Sub-Type)

 

Etc.

 

Many thanks in advance!

 

Darren

0 Likes
Accepted solutions (1)
426 Views
3 Replies
Replies (3)
Message 2 of 4

Michael.Navara
Advisor
Advisor

I recommend you to focus on iLogic or VB.NET instead of VBA. But the code can look similar.

 

iLogic sample

Sub Main()
    Dim asm As AssemblyDocument = ThisDoc.Document

    'Container for result string
    result = New StringBuilder()
    result.AppendLine(asm.DisplayName)

    Dim occurrences As ComponentOccurrences = asm.ComponentDefinition.Occurrences
    TraverseAssembly(occurrences, 0)

    Logger.Debug(result.ToString())
End Sub

Dim result As New StringBuilder

Private Sub TraverseAssembly(occurrences As ComponentOccurrences, level As Integer)

    For Each occurrence As ComponentOccurrence In occurrences
        Dim occDef As ComponentDefinition = occurrence.Definition

        Dim displayName As String
        Dim description As String
        Dim material As String

        'Occurrence is part
        Dim part As PartDocument = TryCast(occDef.Document, PartDocument)
        If part IsNot Nothing Then
            displayName = part.DisplayName
            description = part.PropertySets("{32853F0F-3444-11D1-9E93-0060B03C1CA6}")("Description").Value.ToString()
            material = part.ActiveMaterial.DisplayName

            'TODO: Do anything you want with variable 'part'
        End If

        'Occurrence is assembly
        Dim asm As AssemblyDocument = TryCast(occDef.Document, AssemblyDocument)
        If asm IsNot Nothing Then
            displayName = asm.DisplayName
            description = asm.PropertySets("{32853F0F-3444-11D1-9E93-0060B03C1CA6}")("Description").Value.ToString()
            material = "" ' Assembly hasn't material

            'TODO: Do anything you want with variable 'asm'
        End If

        'Append result
        result.AppendLine(String.Join(";",
                          New String(" ", level),
                          displayName,
                          description,
                          material
                          ))

        'Recursive call if necessary
        Dim subOccurrences  = occurrence.SubOccurrences
        If (subOccurrences IsNot Nothing And subOccurrences.Count > 0) Then
            TraverseAssembly(subOccurrences, level + 1)
        End If
    Next
End Sub

 

VBA sample

Sub Main()
    Dim asm As AssemblyDocument
    Set asm = ThisApplication.ActiveDocument

    'Container for result string
    Dim result As New Collection
    Call result.Add(asm.displayName)

    Dim occurrences As ComponentOccurrences
    Set occurrences = asm.ComponentDefinition.occurrences
    Call TraverseAssembly(occurrences, 0, result)

    For Each line In result
    Debug.Print line
    Next
    
End Sub


Private Sub TraverseAssembly(occurrences As ComponentOccurrences, level As Integer, result As Collection)
    Dim occurrence As ComponentOccurrence
    For Each occurrence In occurrences
        Dim occDef As ComponentDefinition
        Set occDef = occurrence.Definition

        Dim displayName As String
        Dim description As String
        Dim material As String

        'Occurrence is part
        If occDef.Document.DocumentType = DocumentTypeEnum.kPartDocumentObject Then
        
            Dim part As PartDocument
            Set part = occDef.Document
            
            displayName = part.displayName
            description = part.PropertySets("{32853F0F-3444-11D1-9E93-0060B03C1CA6}")("Description").value
            material = part.ActiveMaterial.displayName

            'TODO: Do anything you want with variable 'part'
        End If

        'Occurrence is assembly
        If occDef.Document.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then

            Dim asm As AssemblyDocument
            Set asm = occDef.Document

            displayName = asm.displayName
            description = asm.PropertySets("{32853F0F-3444-11D1-9E93-0060B03C1CA6}")("Description").value
            material = "" ' Assembly hasn't material

            'TODO: Do anything you want with variable 'asm'
        End If

        'Append result
    
        
        result.Add (String(level, " ") & ";" & _
                    displayName & ";" & _
                    description & ";" & _
                    material)
      
        'Recursive call if necessary
        Dim subOccurrences As ComponentOccurrences
        Set subOccurrences = occurrence.subOccurrences
        
         If (Not subOccurrences Is Nothing And subOccurrences.Count > 0) Then
            Call TraverseAssembly(subOccurrences, level + 1, result)
        End If
    Next
End Sub
Message 3 of 4

AndrewHumiston
Advocate
Advocate

Good morning,

 

here is a quick vba to get you started, if you want it to display 'part' or 'assemlby' you can use ".documenttype" instead of ".displayname" but you'll need to run a 'case' statement to sort out the enum's as they display as numerical value. Keep in mind when you are looking for document properties they can get mixed around when you are diving into where they are in an assembly, you have to access the specific component, then find the 'reference' file that is the parent of that component, this allows you to get the actual value of the specific property incase some 'funny business' has happened with the instance.

 

Sub GetOcciProps()

Dim oActiveDoc As AssemblyDocument
Set oActiveDoc = ThisApplication.ActiveDocument

Dim oOcc As ComponentOccurrence
For Each oOcc In oActiveDoc.ComponentDefinition.Occurrences
MsgBox (oOcc.ReferencedDocumentDescriptor.ReferencedDocument.PropertySets.Item("Design Tracking Properties").Item("Description").Value)
MsgBox (oOcc.ReferencedDocumentDescriptor.ReferencedDocument.PropertySets.Item("Design Tracking Properties").Item("Material").Value)
MsgBox (oOcc.ReferencedDocumentDescriptor.ReferencedDocument.DisplayName)
Next

End Sub

 

i hope this helps, let me know if you have any further questions or ideas!

 

please accept this as a solution if it has solved your issue!

0 Likes
Message 4 of 4

WCrihfield
Mentor
Mentor
Accepted solution

Hi @isocamIn iLogic, the simplest way to get/set material directly using 'oOcc' (representing a ComponentOccurrence object) is with a line of code like the following.

get example:

Dim sMaterial As String = iProperties.Material(oOcc.Name)

 set example:

iProperties.Material(oOcc.Name) = "Steel"

As for the others, which are iProperties, you can use the following in iLogic (not in VBA):

iProperties.Value(oOcc.Name, "Project", "Description") = "My Description"

However, we can not use any of those iLogic 'shortcuts' in VBA.

And no, there is no 'direct' way to access iProperties from 'oOcc', because iProperties are stored in Document objects, not in ComponentOccurrence objects.  You would need to dig into the 'oOcc' object's properties to find the Document object it is referencing, then dig into that Document to access its iProperties.  There are two routes to do that:

oOcc.Definition.Document.PropertySets.Item().Item().Value

or...

oOcc.ReferencedDocumentDescriptor.ReferencedDocument.PropertySets.Item().Item().Value

Tip:  If the component is suppressed, then accessing the oOcc.Definition property will throw an error.

Tip:  If the component is Virtual (for BOM purposes only), then it will not have a Document, and you would have to access its iProperties in a different way.

For example:

oOcc.Definition.PropertySets...and so on (no Document in there).

Tip:  The oOcc.Definition.Document property gives you a generic Object type value, instead of a generic Document value type, so you may want to create a Document type variable, then set its value with oOcc.Definition.Document first, then use that to access its iProperties.

Tip:  Same for oOcc.ReferencedDocumentDescriptor.ReferencedDocument property...it gives you an Object, not Document type, so use same strategy there.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes