Recognizing Parts in any level of Sub-Assembly, within an Assembly

Recognizing Parts in any level of Sub-Assembly, within an Assembly

Anonymous
Not applicable
309 Views
2 Replies
Message 1 of 3

Recognizing Parts in any level of Sub-Assembly, within an Assembly

Anonymous
Not applicable

Hello to every one!

I have been expirimenting with pieces of code taken from a post of two esteemed Autodesk emploees (https://modthemachine.typepad.com/my_weblog/2009/03/accessing-assembly-components.html ), and tons of help from...you guessed it...VB and VBA help!

 

The intent:

I am trying to create a versatile and flexible piece of code, which will be able to locate and count every part there is within a master assembly, which may or may not not contain a sub - assembly with countless sub assemblies. Once I was able to do (with a lot of restrictions like no weldments must be included), I wanted to add to the code extra capabilities such as reading the volume of each part. 

 

The problem:

While the code is able to read the parts of an assembly in any level of included sub assemblies, and is also able to retact the volume for each one, depending on the test assembly I am using to test the code, the code "crashes" for  unknown reason/s to me.

 

I would really use some help, so I am thankful in advance, to anyone that would try to help 

 

The code:

 

It is comprised of the main routine and three sub routins

 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~Main Routine Starts~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Public Sub Test_Routine()

 

  Dim oInvApp As Application
  Set oInvApp = ThisApplication

  Dim oMasterAsDoc As Inventor.AssemblyDocument
  Set oMasterAsDoc = oInvApp.ActiveDocument

  Dim oMasterAsComDef As Inventor.ComponentDefinition
  Set oMasterAsComDef = oMasterAsDoc.ComponentDefinition

  Dim iLeafNodes As Long
  Dim iSubAssemblies As Long

  Debug.Print oMasterAsDoc.DisplayName

  Dim oCompOcc As ComponentOccurrence

  Dim Level As Long
  Level = 1

  Dim oPrtsRabo As New Collection
  Dim oPrtRaboMtrx(1 To 6) As Long

  Dim oPartSVol As New Collection
  Dim oPartVol As Double

  For Each oCompOcc In oMasterAsComDef.Occurrences

      If oCompOcc.SubOccurrences.Count = 0 Then
        Debug.Print oCompOcc.Name
        iLeafNodes = iLeafNodes + 1
        Call PartVolumeLocator(oMasterAsComDef, iLeafNodes, oPartSVol, oPartVol)
     Else
        Debug.Print Space(Level * 2) & oCompOcc.Name
        iSubAssemblies = iSubAssemblies + 1
        Call processAllSubOcc(oCompOcc, iLeafNodes, iSubAssemblies, Level, _
        oMasterAsComDef, _
        oPartSVol, oPartVol)
     End If
  Next

 

  Debug.Print "No of sub assemblies: " + CStr(iSubAssemblies)
  Debug.Print "No of total parts (a.k.a. leaf nodes): " + CStr(iLeafNodes)

  MsgBox "No of total parts (a.k.a. leaf nodes):" & CStr(iLeafNodes), vbOKOnly

 

  Dim FirstLevelOnly As Boolean
      If MsgBox("Does the Assembly contain any Sub-Assembly?", vbYesNo) = vbYes Then
           FirstLevelOnly = False
      Else
          FirstLevelOnly = True
      End If

  Dim oBOM As BOM
  Set oBOM = ThisApplication.ActiveDocument.ComponentDefinition.BOM

  If FirstLevelOnly Then
    oBOM.StructuredViewFirstLevelOnly = True
  Else
    oBOM.StructuredViewFirstLevelOnly = False
  End If

    oBOM.StructuredViewEnabled = True

  Dim oBOMView As BOMView
  Set oBOMView = oBOM.BOMViews.Item("Structured")

  Debug.Print "Item"; Tab(15); "Quantity"; Tab(30); "Part Number"; Tab(70); "Description"
  Debug.Print "----------------------------------------------------------------------------------"


  Dim ItemTab As Long
  ItemTab = -3
      Call QueringBOMRowProps(oBOMView.BOMRows, ItemTab)

End Sub

~~~~~~~~~~~~~~~~~~~~~~~~~~~~Main Routine Ends~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~Sub Routine #1 Starts~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Private Sub processAllSubOcc(ByVal oCompOcc As ComponentOccurrence, ByRef iLeafNodes As Long, ByRef iSubAssemblies As Long, SpLevel, _
oMasterAsComDef, _
oPartSVol, oPartVol)

Dim oSubCompOcc As ComponentOccurrence
For Each oSubCompOcc In oCompOcc.SubOccurrences

If oSubCompOcc.SubOccurrences.Count = 0 Then

Debug.Print Space(SpLevel * 4) & oSubCompOcc.Name
iLeafNodes = iLeafNodes + 1
Call PartVolumeLocator(oMasterAsComDef, iLeafNodes, oPartSVol, oPartVol)
Else

Debug.Print Space(SpLevel * 6) & oSubCompOcc.Name
iSubAssemblies = iSubAssemblies + 1

 

Call processAllSubOcc(oSubCompOcc, iLeafNodes, iSubAssemblies, SpLevel, _
oMasterAsComDef, oPrtsRabo, oPrtRaboMtrx, _
oPartSVol, oPartVol)
End If
Next
End Sub

~~~~~~~~~~~~~~~~~~~~~~~~~~~~Sub Routine #1 Ends~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~Sub Routine #2 Starts~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Private Sub QueringBOMRowProps(oBOMRows As BOMRowsEnumerator, ItemTab As Long)

ItemTab = ItemTab + 3

Dim i As Long
For i = 1 To oBOMRows.Count

Dim oRow As BOMRow
Set oRow = oBOMRows.Item(i)


Dim oCompDef As ComponentDefinition
Set oCompDef = oRow.ComponentDefinitions.Item(1)

Dim oPartNumProperty As Property
Dim oDescripProperty As Property

If TypeOf oCompDef Is VirtualComponentDefinition Then

Set oPartNumProperty = oCompDef.PropertySets _
.Item("Design Tracking Properties").Item("Part Number")

Set oDescripProperty = oCompDef.PropertySets _
.Item("Design Tracking Properties").Item("Description")

Debug.Print Tab(ItemTab); oRow.ItemNumber; Tab(17); oRow.ItemQuantity; Tab(30); _
oPartNumProperty.Value; Tab(70); oDescripProperty.Value
Else

Set oPartNumProperty = oCompDef.Document.PropertySets _
.Item("Design Tracking Properties").Item("Part Number")

Set oDescripProperty = oCompDef.Document.PropertySets _
.Item("Design Tracking Properties").Item("Description")

Debug.Print Tab(ItemTab); oRow.ItemNumber; Tab(17); oRow.ItemQuantity; Tab(30); _
oPartNumProperty.Value; Tab(70); oDescripProperty.Value

If Not oRow.ChildRows Is Nothing Then
Call QueringBOMRowProps(oRow.ChildRows, ItemTab)
End If
End If
Next
ItemTab = ItemTab - 3

End Sub

~~~~~~~~~~~~~~~~~~~~~~~~~~~~Sub Routine #2 Ends~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~Sub Routine #3 Starts~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Public Sub PartVolumeLocator(oMasterAsComDef, iLeafNodes, oPartSVol, oPartVol)
oPartVol = oMasterAsComDef.Occurrences.Item(iLeafNodes).MassProperties.Volume
oPartSVol.Add oPartVol

Debug.Print Space(2) & oMasterAsComDef.Occurrences.Item(iLeafNodes).MassProperties.Volume
End Sub

~~~~~~~~~~~~~~~~~~~~~~~~~~~~Sub Routine #3 Ends~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

Test Assembly:

Please find the test assembly attached

0 Likes
310 Views
2 Replies
Replies (2)
Message 2 of 3

NachoShaw
Advisor
Advisor

Hi

 

i havent downloaded your part or code to test but have picked up on a couple of things-

 

you are looping every occurrence and getting the volume but it might be better to loop the assembly references instead because if your assembly has say, 1000 of the same component, you will loop 1000 times vs 1 loop for the single reference.

 

If you need to condition based on it being a part or assembly, you can check the DocumentType to determine if its a part or assembly.

 

As you looping through a BOM, you can get the qty of the reference by finding an occurrence using the display name of the reference with a FindByName function and setting BOM to Parts Only

 

if i get time, ill try and put something together tonight

 

 

Nacho
Automation & Design Engineer

Inventor automation Programmer (C#, VB.Net / iLogic)
Furniture, Sheet Metal, Structural, Metal fab, Tradeshow, Fabrication, CNC

EESignature


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.


0 Likes
Message 3 of 3

Anonymous
Not applicable

Thank you for your reply. This actually sounds wise thing to do. I guess, for a rookie, it's an easy thing to miss. Although let's say the code must remain the same. Why would it "crash"? If you find the time and run it please, let me know.  

0 Likes