Community
Inventor Programming - iLogic, Macros, AddIns & Apprentice
Inventor iLogic, Macros, AddIns & Apprentice Forum. Share your knowledge, ask questions, and explore popular Inventor topics related to programming, creating add-ins, macros, working with the API or creating iLogic tools.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

BOM Item total quantity by sub-assemby

22 REPLIES 22
Reply
Message 1 of 23
VRosselet
2151 Views, 22 Replies

BOM Item total quantity by sub-assemby

Hi,

I would like to obtain, in a structured parts list, the total number of ITEM in the sub-assembly.

See the picture attached for the example.

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 ? Because I'm not a expert in programming ...

 

Thanks for your solutions !

 

Best regards.

 

 

 

22 REPLIES 22
Message 2 of 23
xiaodong_liang
in reply to: VRosselet

Message 3 of 23
Jefkee
in reply to: xiaodong_liang

Hi,

 

I tried to use the rule u have on the blog, but when i run it i get a empty blank window? and then nothing?

 

And in what property is the qty stored?

Inventor 2013
Message 4 of 23
VRosselet
in reply to: VRosselet

Hi,

Thanks for the answer, but it is not exactely what I want.

I try to export a structured BOM with the total quantity for the parts in each sub-assembly, and the same component can be in several sub-assembly.

Thanks for your help. Regards,

Vincent

Message 5 of 23
xiaodong_liang
in reply to: Jefkee

Hi Jefkee,

I am not clear on what you meant by "blank window". This iLogic code just counts the parts within sub-assembly and finally pops out a dialog to show the statistic. To work with the code, a top assembly with some sub-assemblies must be opened.
Message 6 of 23
xiaodong_liang
in reply to: VRosselet

Hi,

 

do you actually mean the BOM view of "Parts Only"? If yes, you just need to check the relevant objects of BOM. Here is a simple VBA code.  Of course, the quantity includes the number if the part is also insterted to top assembly directly. You could just count the number in top assembly and decrease the number from total quantity .

 

Sub test()
    Dim oBOM As BOM
    Set oBOM = ThisApplication.ActiveDocument.ComponentDefinition.BOM
    
    'enable part only view
    oBOM.PartsOnlyViewEnabled = True
 
    Dim oPartOnlyView As BOMView
    Set oPartOnlyView = oBOM.BOMViews("Parts Only")
    
    Dim oBomRow As BOMRow
    For Each oBomRow In oPartOnlyView.BOMRows
        Dim oPartName As String
        oPartName = oBomRow.ComponentDefinitions(1).Document.DisplayName
        
        Dim oPartTotalQuantity As Integer
        oPartTotalQuantity = oBomRow.TotalQuantity
        
        Debug.Print "Part: "; oPartName & "  Total Quantity: " & oPartTotalQuantity
        
    Next


End Sub

 

 

 

 

Capture.JPG

Message 7 of 23
danvang
in reply to: VRosselet

Check out this thread and see if this is what you are looking for.

 

http://forums.autodesk.com/t5/Inventor-Customization/Qty-in-bom/m-p/4618825#M47203

 

Dan

** If my reply resolves this issue, please choose "Accept as Solution" **
Dan Vang
Message 8 of 23
VRosselet
in reply to: VRosselet

Hi,

Thanks for your reply.

I Copy-Cut the iLogic rule in my assembly, but I have this error:

 

System.ArgumentException: Paramètre incorrect. (Exception de HRESULT : 0x80070057 (E_INVALIDARG))

à System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)

à Inventor.BOMViews.get_Item(Object Index)

à LmiRuleScript.Main()

à Autodesk.iLogic.Exec.AppDomExec.ExecRuleInAssembly(Assembly assem)

à iLogic.RuleEvalContainer.ExecRuleEval(String execRule)

 

What am I doing wrong ?

 

Thanks for your answer.

Regards,

Vincent

Message 9 of 23
xiaodong_liang
in reply to: VRosselet

Hi Vicent,

I also tested with that code. It can run without problem. Did you copy paste it to a new rule, or merge it to your existing rule?
Message 10 of 23
VRosselet
in reply to: VRosselet

Hi,

I copy this text in a new rule ...

Regards,

Vincent

Message 11 of 23
xiaodong_liang
in reply to: VRosselet

Does the failure occur with any assembly or a specific assembly? What I tested with is a simple assembly, and also a sample from Inventor sample folder.
Message 12 of 23
VRosselet
in reply to: xiaodong_liang

I test on two differents assemblies, and it is the same result.
Is it possible to send me your rule in a text file ?
Thanks and regards,
Vincent
Message 13 of 23
xiaodong_liang
in reply to: VRosselet

Sub Main
'Get current document
doc = ThisDoc.Document
Dim oAssyDef As AssemblyComponentDefinition = doc.ComponentDefinition
'Get the BOM object
Dim oBOM As BOM = oAssyDef.BOM
'enable the Parts Only View
oBOM.PartsOnlyViewEnabled = True
'Get the Parts Only view of the BOM
Dim oBOMViewPO As BOMView = oBOM.BOMViews.Item("Parts Only")
'declare variable for each BOM row.
Dim oBOMRowPO As BOMRow

'For each row in the Parts Only BOM, do the following
For Each oBOMRowPO In oBOMViewPO.BOMRows
'Set a reference to the primary ComponentDefinition of the row
Dim oCompDef As ComponentDefinition = oBOMRowPO.ComponentDefinitions.Item(1)

'get the full filename associated to the component in the row. ex: c:\temp\part1.ipt
Dim CompFullDocumentName As String = oCompDef.Document.FullDocumentName
Dim CompFileNameOnly As String
'get the location of the last backslash
Dim index As Integer = CompFullDocumentName.lastindexof("\")
'get the filename only from the full filename
CompFileNameOnly = CompFullDocumentName.substring(index+1)

'MessageBox.Show(CompFileNameOnly)

'get the Qty value in the current row
Dim Qty As String = oBOMRowPO.TotalQuantity

'check to see if the component is a library part, cc part or read only.
Dim IsLibCCReadonly As Boolean = LibCCReadonlyChecker(CompFullDocumentName)

'if the file is NOT a library part, cc part or read only.
If IsLibCCReadonly = False Then
'set following custom iproperty to equal the QTY from the row
iProperties.Value(CompFileNameOnly, "Custom", "cQty") = Qty
End If
Next

'at this time, the qty value for all parts have been copied to the custom property.
'next, the following code will cycle through only the subassemblies.

'if the Structured BOM view is enabled then...
If oBOM.StructuredViewEnabled Then
'If show First Level is set then turn it off. This will set it to All Levels
If oBOM.StructuredViewFirstLevelOnly Then
oBOM.StructuredViewFirstLevelOnly = False
End If
Else
'enable the Structured BOM view
oBOM.StructuredViewEnabled = True
'set the FirstLevelOnly to false therefore make it All Levels
oBOM.StructuredViewFirstLevelOnly = False
End If

'Get the Structured view of the BOM
Dim oBOMViewStruc As BOMView = oBOM.BOMViews.Item("Structured")
'declare variable for each BOM row.
Dim oBOMRowStruc As BOMRow
'Create a blank array(list). This will be used to store a list of all subassemblies for comparing if the subassembly already exist.
Dim arrSubAssemblyList As New ArrayList

'call a subroutine to cycle through the structured BOM. It will need the collection of rows, the subassembly list, and 1 is the initial parentqty.
Call QueryBOMRowProperties(oBOMViewStruc.BOMRows, arrSubAssemblyList, 1)

End Sub

Private Sub QueryBOMRowProperties(oBOMRows As BOMRowsEnumerator, arrSubAssembly As ArrayList, oParentQty As Integer)

'declare a incrementer variable
Dim i As Long
'for each row in the structured BOM
For i = 1 To oBOMRows.count
'get the row based on the incrementer
Dim oBOMRowStruc As BOMRow = oBOMRows.item(i)
'get the component definition assocated with the row
Dim oCompDef As ComponentDefinition = oBOMRowStruc.ComponentDefinitions.item(1)
Dim oQty As Integer

'If the component is an assembly and it's bom structure is Normal then do the following. else do nothing
If TypeOf oCompDef Is AssemblyComponentDefinition And oCompDef.BOMStructure = BOMStructureEnum.kNormalBOMStructure Then
'get the full filename associated to the component in the row. ex: c:\temp\subassembly.iam
Dim CompFullDocumentName As String = oCompDef.Document.FullDocumentName
Dim CompFileNameOnly As String
'get the location of the last backslash
Dim index As Integer = CompFullDocumentName.lastindexof("\")
'get the filename only from the full filename
CompFileNameOnly = CompFullDocumentName.substring(index+1)
'MessageBox.Show(CompFileNameOnly)

'get the qty of the row and multiply by the parent qty.
oQty = oBOMRowStruc.ItemQuantity * oParentQty

'create a variable that will be used to get the qty of the subassembly if it was used elsewhere
Dim additionalQty As Integer = 0
'if the subassembly list is not empty then...
If arrSubAssembly.Count <> 0 Then
'create a counter. this will be used to determine which item in the subassembly array (list) when it finds a match.
'this counter will be used to edit that item with the new qty.
Dim counter As Integer = 0
'for each item in the subassembly array (list) starting at 0 (first item) to last item
For j As Integer = 0 To arrSubAssembly.Count-1
'get the location of the colon
Dim commaindex As Integer = arrSubAssembly(j).indexof(":")
'get just the file name
Dim CompName As String = arrSubAssembly(j).substring(0,commaindex)

'if the file name of the current row matches the current item in the subassembly array (list) then...
If CompName = CompFileNameOnly Then
'set the additional qty to the qty found in the subassembly array (list)
additionalQty = arrSubAssembly(j).substring(commaindex+1)
'set the counter equal to the item in the subassembly array (list)
counter = j
'since a match is found, we need to exit the for loop so that counter no longer increments.
'so Set j To the number of items in the subassembly array. this will exit out the for loop.
j = arrSubAssembly.Count
Else
'increase the counter
counter += 1
End If
Next

'if additional qty was not changed then there was no match. It will be a new item in the subassembly array (list)
If additionalQty = 0 Then
'add the subassambly to the subassembly array (list)
arrSubAssembly.add(CompFileNameOnly & ":" & oQty)
Else
'if it did find a match, then update the qty for that item in the subassembly array (list)
arrSubAssembly(counter) = CompFileNameOnly & ":" & oQty + additionalQty
End If
Else
'add the first subassembly to the list. It will add the filename and the qty separated by a colon. ex. subassembly.iam:2
arrSubAssembly.add(CompFileNameOnly & ":" & oQty)
End If

'check to see if the component is a library part, cc part or read only.
Dim IsLibCCReadonly As Boolean = LibCCReadonlyChecker(CompFullDocumentName)

'if the file is NOT a library part, cc part or read only.
If IsLibCCReadonly = False Then
'set following custom iproperty to equal the QTY from the row plus the additional qty value
iProperties.Value(CompFileNameOnly, "Custom", "cQty") = oQty + additionalQty

'Recursively iterate child rows if present.
If Not oBOMRowStruc.ChildRows Is Nothing Then
'recall the subroutine, push the childrows of the sub, sub assembly array (list), and the qty of the subassembly
Call QueryBOMRowProperties(oBOMRowStruc.ChildRows, arrSubAssembly, oQty)
End If
End If
End If
Next
End Sub

Private Function LibCCReadonlyChecker(filename As String) As Boolean
' Get the active project
Dim oProject As DesignProject = ThisApplication.DesignProjectManager.ActiveDesignProject
' Get all the library paths
Dim oLibraryPaths As ProjectPaths = oProject.LibraryPaths
Dim oLibraryPath As ProjectPath

'for each library path in the list of all library paths
For Each oLibraryPath In oLibraryPaths
'get the library path
Dim oLibs As String = oLibraryPath.Path
'if the file is in a library path then Return True
If filename.Contains(oLibs) = True Then
Return True
End If
Next

'if the file is in the CC location then Return True
If filename.Contains(oProject.ContentCenterPath) = True Then
Return True
End If

'get read only status
Dim File_Attr As Long = System.IO.File.GetAttributes(filename)
'if the file is readonly or readonly and archieve then Return True
If File_Attr = 1 Or File_Attr = 33 Then
Return True
End If

'return False if it's not a library, CC or a Readonly part.
Return False

End Function
Message 14 of 23
VRosselet
in reply to: xiaodong_liang

Hi,

Thanks for your reply.

Unfortunately, it doesn't work, always the same error !

Personnaly, I don't understand ...

Regards,

Vincent

Message 15 of 23
danvang
in reply to: VRosselet

Just curious. What is your active project set to?

** If my reply resolves this issue, please choose "Accept as Solution" **
Dan Vang
Message 16 of 23
VRosselet
in reply to: xiaodong_liang

Hi,

I'm not sure I understand your question.

I'm testing the rule on two projects, one Vault, one non-Vault, but nothing change...

I do a new assembly with two news parts, but it is the same thing.

I test on another PC, and I have always the same error ...

Regards,

Vincent

Message 17 of 23
Jefkee
in reply to: VRosselet

Should this rule work for 2013?

Inventor 2013
Message 18 of 23
danvang
in reply to: Jefkee

Jefkee,

Yes this code works in 2013 as well.

 

Vrosselet,

Do you have a sample assembly that you can upload for me to test?

** If my reply resolves this issue, please choose "Accept as Solution" **
Dan Vang
Message 19 of 23
VRosselet
in reply to: xiaodong_liang

Hi,

Thanks for all your reply.

I found the problem: it is a language problem, because I'm working on a french version. I install the english language pack and I have no error yet.

But how works this rule ? nothing change on the assembly.

Should I do something special in the assembly ?

Regards,

Vincent

Message 20 of 23
danvang
in reply to: VRosselet

Ahhh. good 'o language pack. forgot to mention that. What the rule does is create a custom iproperty called "cQTY". That custom iproperty will contain the quantity of that part for the assembly that the rule ran on. In the BOM, display the cQTY property and you should see the values. Hopefully this is what you were trying to do.

** If my reply resolves this issue, please choose "Accept as Solution" **
Dan Vang

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report