Ilogic to update or add Instance property to all items in structured BOM

Ilogic to update or add Instance property to all items in structured BOM

logan.klenner_MKT
Explorer Explorer
1,959 Views
7 Replies
Message 1 of 8

Ilogic to update or add Instance property to all items in structured BOM

logan.klenner_MKT
Explorer
Explorer

Hi All,

I would like some help creating an iLogic code to iterate through the structured BOM of an assembly and update/add an instance property.

 

I had a code that would do this to the assembly component occurrences (see snip below), but there was 2 issues with this.

  1. It would not apply to the children of of phantom assemblies so caused issues with parts lists
  2. I recently discovered that if you 'replace' a component then the instance property no longer updates or creates (This must be a glitch surely?)

So i'm thinking if it is possible to do this through the structured BOM might be a better way? (It can be done manually, so hopefully there is an automation for it)

 

The basic rundown is we need to create a 'Pack Qty' for our parts lists. The pack qty = the Item qty from this assembly * the number of these assemblies to be made (Custom Iprop "TOTAL_QUANTITY)

The code needs to give each occurrence and Instance property = to the parent assy total quantity and the Partslist sums these with a substitution column to give the final Pack Qty.

If the Instance property does not get through to the promoted components from phantom sub-assemblies then this causes 'Varies' issues.

 

Also it needs to be an instance property as the items are used in multiple assemblies and so have a 'Total_Quantity' of their own that is the sum of all it's pack quantities.

 

Sorry if this is worded confusingly, and thanks in advance.

 

'This is the original method that did not get children & also had an issue with replaced components
Dim activeDocName As String = ThisApplication.ActiveDocument.FullFileName
Dim thisDocName As String = ThisDoc.Document.FullFileName
  
 If (activeDocName <> thisDocName) Then
     ' the script was not triggered by the active document
     Return
 End If 

 'Check active document is an assembly
If ThisApplication.ActiveDocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then
	MessageBox.Show("This rule " & iLogicVb.RuleName & " only works for Assembly Documents.", "WRONG DOCUMENT TYPE", MessageBoxButtons.OK, MessageBoxIcon.Error)
	Return
End If

'set a reference to the assembly component definintion.
Dim oAsmCompDef As AssemblyComponentDefinition
oAsmCompDef = ThisApplication.ActiveDocument.ComponentDefinition

'Get the value from the parent assembly TOTAL_QUANTITY
Dim oPQ As String
    oPQ = (iProperties.Value("Custom", "TOTAL_QUANTITY"))

'Iterate through all of the occurrences
Dim oOccurrence As ComponentOccurrence
For Each oOccurrence In oAsmCompDef.Occurrences

'Set instance property value
    	iProperties.InstanceValue(oOccurrence.Name, "PACK_QTY") = oPQ
'Message box for debugging
   	'MessageBox.Show(oPQ, "iLogic")
Next

 

0 Likes
Accepted solutions (1)
1,960 Views
7 Replies
Replies (7)
Message 2 of 8

dalton98
Collaborator
Collaborator
Sub Main
Dim oAss as AssemblyDocument
oAss= ThisApplication.ActiveDocument Dim oBOM As BOM oBOM = oAss.ComponentDefinition.BOM oBOM.StructuredViewEnabled = True oBOM.StructuredViewFirstLevelOnly = False

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

Dim oRow as BOMRow
For Each oRow in oBOMView.BOMRows
'do stuff
qty = oRow.ItemQuantity
Call RecurseBOMRow(oRow)
Next
End Sub

Sub RecurseBOMRow(oRow as BOMRow)
For Each oRow In oRow.ChildRows
'do stuff
qty = oRow.ItemQuantity
If Not oRow.ChildRows Is Nothing
Call RecurseBOMRow(oRow)
End If
Next
End Sub

I didn't quite understand what you were wanting but this is a simple version that goes through each row in the structured BOM, checks if it has child rows and goes through them, and gets the item quantity.

0 Likes
Message 3 of 8

dalton98
Collaborator
Collaborator

Ok I had some coffee. To set the instance property you would add this under the qty = oRow.ItemQuantity line

Dim oDoc As Document
oDoc = oRow.ComponentDefinitions.Item(1).Document
iProperties.InstanceValue(oDoc.DisplayName, "PACK_QTY") = qty * 5	

 

 

0 Likes
Message 4 of 8

logan.klenner_MKT
Explorer
Explorer

Thanks Dalton,

I think this is almost there.
It is however coming up with an error
"iProperties: The component named "Assembly1.iam" was not found."
That assembly certainly does exist in this test model.

 

I am thinking using the oDoc.Displayname may not be getting the correct definition name to apply the instance properties too?

The other thing is I am hoping I can run this in 'Firstlevelonly' so that it only applies to components in a 'phantom' sub assembly but not to components of a 'Normal' sub assembly.

2022-04-07 07_12_04-Bill of Materials [TEMP PROPS.iam].png

0 Likes
Message 5 of 8

dalton98
Collaborator
Collaborator

This is how you would make custom properties but these aren't instance they are permanent(if you save)

Dim oDoc As Document
oDoc = oRow.ComponentDefinitions.Item(1).Document
oDoc.PropertySets.Item("Inventor User Defined Properties").Add(qty * 5, "PACK_QTY")

 

And for instance properties the only way I could think to do it would be..

Dim oDoc As Document
oDoc = oRow.ComponentDefinitions.Item(1).Document
For i As Integer = 1 To oRow.ItemQuantity
iProperties.InstanceValue(oDoc.DisplayName & ":" & i, "PACK_QTY") = 5
Next

 

0 Likes
Message 6 of 8

dalton98
Collaborator
Collaborator

And for this to work all the components would have to be "filename". you can do this by going to the ribbon

Assemble>Productivity>Rename Browser Nodes

0 Likes
Message 7 of 8

logan.klenner_MKT
Explorer
Explorer

Thanks Again Dalton, really appreciate the help.

I've bene playing around a bit more and think I am very close. I have managed to get it reading the occurrence name.
The only problem here is there is duplicates of the occurrence names due to promoted components from the phantom sub assemblies.

So anything with an occurrence name in a sub assembly that matches an occurrence name from the main assembly does not get update. Anything with a unique occurrence name does.
i.e if there is 4 occurrences of 'part1' in the main assembly, and 7 in a sub. Then 5,6 & 7 will have the instance property applied but 1-4 will not.

Any suggestions on how to dig down to rectify this?

Current code snip:

Sub Main

Dim oAdoc As AssemblyDocument 
oAdoc = ThisApplication.ActiveDocument

'Check it is the active document that triggered this script
Dim activeDocName As String = oAdoc.FullFileName
Dim thisDocName As String = ThisDoc.Document.FullFileName
If (activeDocName <> thisDocName) Then
     'the script was not triggered by the active document
     Return
 End If 

'Check active document is an assembly
If ThisApplication.ActiveDocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then
	MessageBox.Show("This rule " & iLogicVb.RuleName & " only works for Assembly Documents.", "WRONG DOCUMENT TYPE", MessageBoxButtons.OK, MessageBoxIcon.Error)
	Return
End If

'Get current Assembly TOTAL_QUANTITY value as Pack Quantity multiplier
Dim oPQ As String
    oPQ = (iProperties.Value("Custom", "TOTAL_QUANTITY"))

Dim oCompDef As AssemblyComponentDefinition
oCompDef = oAdoc.ComponentDefinition
Dim asmOccurrences = oCompDef.Occurrences

'Get BOM Definition
Dim oBOM As BOM
oBOM = oCompDef.BOM

'Set BOM to structured view & first level only
oBOM.StructuredViewEnabled = True
oBOM.StructuredViewFirstLevelOnly = True

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

Dim oRow As BOMRow
For Each oRow In oBOMView.BOMRows
'do stuff
	'Message box for debugging
   			MessageBox.Show(oRow.ItemNumber, "Debug1")
For Each CompDef As ComponentDefinition In oRow.ComponentDefinitions
        Dim occurrences = asmOccurrences.AllLeafOccurrences(CompDef)
        For Each occ As ComponentOccurrence In occurrences
				'Message box for debugging
   				MessageBox.Show(occ.Name, "Debug2")
				iProperties.InstanceValue(occ.Name, "PACK_QTY") = oPQ
Next
Next
Next
End Sub

 

In the snip below I have turned off merging to demonstrate what has been updated and what has not. (Previous value manually set to 20, ilogic trying to update to 50)

2022-04-07 10_35_15-Bill of Materials [TEMP PROPS.iam].png

 

0 Likes
Message 8 of 8

logan.klenner_MKT
Explorer
Explorer
Accepted solution

OK, Pending more testing I think I have found a solution.
Essentially I needed to rename all occurrences available from that BOM level to have a unique name (Sequentially numbered occurrence suffix)

Here is the currently working Code.

 

 

Sub Main

Dim oAdoc As AssemblyDocument 
oAdoc = ThisApplication.ActiveDocument

'Check it is the active document that triggered this script
Dim activeDocName As String = oAdoc.FullFileName
Dim thisDocName As String = ThisDoc.Document.FullFileName
If (activeDocName <> thisDocName) Then
     'the script was not triggered by the active document
     Return
 End If 

'Check active document is an assembly
If ThisApplication.ActiveDocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then
	MessageBox.Show("This rule " & iLogicVb.RuleName & " only works for Assembly Documents.", "WRONG DOCUMENT TYPE", MessageBoxButtons.OK, MessageBoxIcon.Error)
	Return
End If

'Get current Assembly TOTAL_QUANTITY value as Pack Quantity multiplier
Dim oPQ As String
    oPQ = (iProperties.Value("Custom", "TOTAL_QUANTITY"))

Dim oCompDef As AssemblyComponentDefinition
oCompDef = oAdoc.ComponentDefinition
Dim asmOccurrences = oCompDef.Occurrences

'Get BOM Definition
Dim oBOM As BOM
oBOM = oCompDef.BOM

'Set BOM to structured view
oBOM.StructuredViewEnabled = True
oBOM.StructuredViewFirstLevelOnly = True

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

Dim oRow As BOMRow

'Lets rename all our occurrences to make them unique
OccCounter = 0
For Each oRow In oBOMView.BOMRows
	'Message box for debugging
   			'MessageBox.Show(oRow.ItemNumber, "Debug-row")
	For Each CompDef As ComponentDefinition In oRow.ComponentDefinitions
        Dim occurrences = asmOccurrences.AllLeafOccurrences(CompDef)
        For Each occ As ComponentOccurrence In occurrences
			OccCounter = OccCounter + 1
			'Removes the :x portion of name
			NewName = (occ.Name.Split(":")(0)) 
			'Trace.WriteLine(occ.Name & " - Original name - " & NewName)
			'Append the new :x portion of name
			NewName = NewName & ":" & OccCounter
			If occ.Name = NewName Then
				'Do nothing it's already that anyway
			Else
				Try
					'Write new name
					occ.Name = NewName
					'Message box for debugging
	   				'MessageBox.Show(occ.Name, "Debug-Name")
				Catch
				Try
					'Write new name with an A suffix. - Assumes fail was due to existing name in assembly already
					occ.Name = NewName & "A"
					'Message box for debugging
	   				'MessageBox.Show(occ.Name, "Debug-Name Retry")
					Catch
					MessageBox.Show(occ.Name & ": Count=" & OccCounter & ", Rename didn't work." & vbNewLine & "Please run again", "Debug - rename try")
					Exit Sub
				End Try
				End Try
			End If
		Next
	Next
Next
'Now lets write our instance Variable
For Each oRow In oBOMView.BOMRows
	For Each CompDef As ComponentDefinition In oRow.ComponentDefinitions
        Dim occurrences = asmOccurrences.AllLeafOccurrences(CompDef)
        For Each occ As ComponentOccurrence In occurrences
			Try
				'Message box for debugging
	   			'MessageBox.Show(occ.Name & " - " & oPQ, "Debug-Name")
				'Write the new instance Property
				iProperties.InstanceValue(occ.Name, "PACK_QTY") = oPQ
			Catch 				
				MessageBox.Show(occ.Name & ", Instance property write failed" & vbNewLine & "Please run again", "Debug - Instance property - Write")
				Exit Sub
			End Try
		Next
	Next
Next
End Sub

 

 

 

 

0 Likes