By Xiaodong Liang
Question:
I would like to obtain, in a structured parts list, the total number of ITEM in the sub-assembly.
I have found an iLogic rule to create an user ipropertie in each part, with the total nomber of this part in all the assemby (included all sub-assemblies).
I would like to know if it is possible to obtain the total of this part only in the sub-assembly. Is it possible with an iLogic rule or VBA ?
Solution:
You can recurse the referenced documents of the top assembly, filter out the sub assemblies. And iterate the occurrences of the assemblies to count each part. iLogic is based on VB.NET, so you could take advantage the Dictionary object to make the worflow more clear.
The following code is a demo to dump an assembly, get the part count of each sub assembly.
Sub Main()
'get top assembly
Dim oTopAss As AssemblyDocument
oTopAss = ThisApplication.ActiveDocument
'store part info for each sub assembly,
' including decedent Sub Assembly
Dim oTotalDict As _
New Dictionary(Of String, _
Dictionary(Of String, Integer))
Dim oEachRefDoc As Document
For Each oEachRefDoc In _
oTopAss.ReferencedDocuments
If TypeOf oEachRefDoc Is _
AssemblyDocument Then
'get full path of the assembly
Dim oSubAssFullPath As String
oSubAssFullPath = _
oEachRefDoc.FullFileName
If oTotalDict.ContainsKey(oSubAssFullPath) Then
' should have iterated, do nothing
Else
'store each unique part per its full path
Dim oSubDict = _
New Dictionary(Of String, _
Integer)
'add a dictionary for the sub assembly
oTotalDict.Add(oSubAssFullPath, _
oSubDict)
'iterate the parts within the sub assembly
recurseSubAss(oEachRefDoc, _
oTotalDict, _
oSubDict)
End If
End If
Next
'dump the count statistic of the assemblies
Dim oMsg As String
Dim iAssKey As String
Dim oEachAssDic As _
Dictionary(Of String, Integer) = Nothing
For Each iAssKey In _
oTotalDict.Keys
'each sub assembly, including the decendent assembly
oMsg += vbCr + "***" + _
iAssKey + "***"
oEachAssDic = _
oTotalDict(iAssKey)
Dim iPartKey As String
For Each iPartKey In _
oEachAssDic.Keys
Dim quantity As Integer = _
oEachAssDic(iPartKey)
oMsg += vbCr + " " + _
iPartKey + " [count: " + _
quantity .ToString() + "]"
Next
Next
'message the info
System.Windows.Forms.MessageBox.Show(oMsg)
End Sub
Sub recurseSubAss(ByVal oParentDoc As AssemblyDocument, _
ByRef oTotalDict As _
Dictionary(Of String, _
Dictionary(Of String, Integer)), _
ByRef oSubDict As _
Dictionary(Of String, _
Integer))
Dim oAssDef As AssemblyComponentDefinition
oAssDef = oParentDoc.ComponentDefinition
Dim oEachOcc As ComponentOccurrence
For Each oEachOcc In oAssDef.Occurrences
Dim oEachRefDoc As Document
oEachRefDoc = oEachOcc.Definition.Document
If TypeOf oEachRefDoc Is _
AssemblyDocument Then
'get full path of the assembly
Dim oSubAssFullPath As String
oSubAssFullPath = _
oEachRefDoc.FullFileName
If oTotalDict.ContainsKey(oSubAssFullPath) Then
' should have iterated, do nothing
Else
'store each unique part per its full path
Dim oSubSubDict = _
New Dictionary(Of String, Integer)
'add a dictionary for the sub assembly
oTotalDict.Add(oSubAssFullPath, _
oSubSubDict)
'iterate the documents within the sub assembly
recurseSubAss(oEachRefDoc, _
oTotalDict, _
oSubSubDict)
End If
Else
' it is part
'get full path of the part
Dim oPartFullPath As String
oPartFullPath = oEachRefDoc.FullFileName
'add this part to the dictionary
If oSubDict.ContainsKey(oPartFullPath) Then
' if the part has existed in the dictionary
'quantity + 1
oSubDict(oPartFullPath) = _
oSubDict(oPartFullPath) + 1
Else
' add this part, quantity =1
oSubDict.Add(oPartFullPath, 1)
End If
End If
Next
End Sub