Calculate total assembly cost

Calculate total assembly cost

Anonymous
Not applicable
5,388 Views
14 Replies
Message 1 of 15

Calculate total assembly cost

Anonymous
Not applicable

I've written a piece of iLogic code which calculates the material and labour costs of all my manufactured parts and writes the value to the 'Estimated Cost' iproperty. My code reads from an excel pricing sheet so that all the costs are kept up to date, I've even got it to calculate the labour costs of any assembly files  ...so far so good

 

However at the final hurdle, I've ran into some difficulty when trying to generate a total cost of all parts and assemblies through exporting my top level BOM to an XLS document.

 

I think I'd like to export a first-level only BOM, but for this to work I need each assembly to total up the costs of each of its sub-parts.

 

Can anyone suggest a piece of code I could use to do this calculation?

 

Something like:

If openDoc.DocumentType = 12291 Then
iProperties.Value("Project", "Estimated Cost") = Total cost of assembly sub-parts + assembly labour
End If

 

 

 

0 Likes
5,389 Views
14 Replies
Replies (14)
Message 2 of 15

Jef_E
Collaborator
Collaborator

Hi!

 

I whipped somthing up real quick.. This code count all occurrences in the assembly their cost and add them up. It does not check if the occurrence is suppressed or BOM-Structure is reference/phantom. It just counts every thing.

 

If you want to make exceptions I can help you with that also. Just ask 🙂

 

Sub Main TraverseAssemblySample()
    ' Get the active assembly.
    Dim oAsmDoc As AssemblyDocument
     oAsmDoc = ThisApplication.ActiveDocument
	 
	 Dim oCost As Decimal
	 oCost = 0

    ' Call the function that does the recursion.
    Call TraverseAssembly(oAsmDoc.ComponentDefinition.Occurrences, 1, oCost)
	
	MsgBox(oCost)
End Sub

Private Sub TraverseAssembly(ByVal Occurrences As ComponentOccurrences, _
							 ByVal Level As Integer, _
							 ByRef oCost As Double)
    ' Iterate through all of the occurrence in this collection.  This
    ' represents the occurrences at the top level of an assembly.
    For Each oOcc As ComponentOccurrence In Occurrences
		
		' Get the document file for this occurrence
		Dim oDoc As Document
		oDoc = oOcc.Definition.Document
				
		' Get the iPropertySet that constains the estimated cost property
		Dim oPropSet As PropertySet
		oPropSet = oDoc.PropertySets.Item("Design Tracking Properties")
		
		' Get the cost of this occurrence
		oCost += oPropSet.Item("Cost").Value
		
        ' Check to see if this occurrence represents a subassembly
        ' and recursively call this function to traverse through it.
        If oOcc.DefinitionDocumentType = kAssemblyDocumentObject Then
            Call TraverseAssembly(oOcc.SubOccurrences, Level + 1, oCount)
        End If
    Next
End Sub


Please kudo if this post was helpfull
Please accept as solution if your problem was solved

Inventor 2014 SP2
0 Likes
Message 3 of 15

Anonymous
Not applicable

Found a piece of code on another post that works a treat for summing the total of all the parts/assemblies

 

http://forums.autodesk.com/t5/inventor-customization/ilogic-how-to-sum-a-property-of-all-sub-assembl...

 

Now though I need to establish the correct event trigger and none seem to fit the bill!

 

I basically need this rule to run in my assembly when the value of one of the sub-parts change. Is this impossible?

0 Likes
Message 4 of 15

Anonymous
Not applicable

@Jef_E

 

Thanks Jef, your code works great. One issue I have with the other one is that it doesn't include the cost of parts that are in a phantom assembly.

 

Ideally, I'd like the phantom assembly to remain at a value of 0 for it's cost (in another part of my rule it set's the value of any phantom parts to 0) and have my main assembly include the parts within my phantom assembly in it's calculation.

 

Any idea how to alter yours or the other code to achieve this?

 

This is the other code as I am using it:

'clear the custom property in the assembly 
iProperties.Value("Project", "Estimated Cost") = 0

'set a reference to the assembly component definintion.
'This assumes an assembly document is open.
Dim oAsmCompDef As AssemblyComponentDefinition
oAsmCompDef = ThisApplication.ActiveDocument.ComponentDefinition
'Iterate through all of the occurrences
Dim oOccurrence As ComponentOccurrence
For Each oOccurrence In oAsmCompDef.Occurrences
'check for and skip virtual components
'(in case a virtual component trips things up)
If Not TypeOf oOccurrence.Definition Is VirtualComponentDefinition Then
'custom property in the assembly 
xNumber = iProperties.Value("Project", "Estimated Cost")
'custom property in the parts
yNumber = iProperties.Value(oOccurrence.Name, "Project", "Estimated Cost")
sumNumber = xNumber + yNumber
'set custom property values
iProperties.Value("Project", "Estimated Cost") = sumNumber 
Else
End If
Next

 

0 Likes
Message 5 of 15

Jef_E
Collaborator
Collaborator

I modified the code marked with red. Now the phantom AND reference parts are skipped by the code.

 

Sub Main TraverseAssemblySample()
    ' Get the active assembly.
    Dim oAsmDoc As AssemblyDocument
     oAsmDoc = ThisApplication.ActiveDocument
	 
	 Dim oCost As Decimal
	 oCost = 0

    ' Call the function that does the recursion.
    Call TraverseAssembly(oAsmDoc.ComponentDefinition.Occurrences, 1, oCost)
	
	MsgBox(oCost)
End Sub

Private Sub TraverseAssembly(ByVal Occurrences As ComponentOccurrences, _
							 ByVal Level As Integer, _
							 ByRef oCost As Double)
    ' Iterate through all of the occurrence in this collection.  This
    ' represents the occurrences at the top level of an assembly.
    For Each oOcc As ComponentOccurrence In Occurrences
	
		' Skip Phantom and reference parts.
		If oOcc.BOMStructure = BOMStructureEnum.kPhantomBOMStructure _ 
		Or oOcc.BOMStructure = BOMStructureEnum.kReferenceBOMStructure Then
			Continue For
		End If
		
		' Get the document file for this occurrence
		Dim oDoc As Document
		oDoc = oOcc.Definition.Document
			
		' Get the iPropertySet that constains the estimated cost property
		Dim oPropSet As PropertySet
		oPropSet = oDoc.PropertySets.Item("Design Tracking Properties")
		
		' Get the cost of this occurrence
		oCost += oPropSet.Item("Cost").Value
		
        ' Check to see if this occurrence represents a subassembly
        ' and recursively call this function to traverse through it.
        If oOcc.DefinitionDocumentType = kAssemblyDocumentObject Then
            Call TraverseAssembly(oOcc.SubOccurrences, Level + 1, oCount)
        End If
    Next
End Sub


Please kudo if this post was helpfull
Please accept as solution if your problem was solved

Inventor 2014 SP2
0 Likes
Message 6 of 15

Anonymous
Not applicable

Any idea how I would get it to include the parts that are inside those phantom assemblies?

 

These phantom assembly files are just being used to group together some common parts in a certain arrangement, I still want the parts within them to be included in the sum.

0 Likes
Message 7 of 15

Jef_E
Collaborator
Collaborator
Sub Main TraverseAssemblySample()
    ' Get the active assembly.
    Dim oAsmDoc As AssemblyDocument
    oAsmDoc = ThisApplication.ActiveDocument
	 
Dim oCost As Decimal oCost = 0 ' Call the function that does the recursion. Call TraverseAssembly(oAsmDoc.ComponentDefinition.Occurrences, 1, oCost) MsgBox(oCost) End Sub Private Sub TraverseAssembly(ByVal Occurrences As ComponentOccurrences, _ ByVal Level As Integer, _ ByRef oCost As Double) ' Iterate through all of the occurrence in this collection. This ' represents the occurrences at the top level of an assembly. For Each oOcc As ComponentOccurrence In Occurrences ' Skip Phantom and reference parts. If oOcc.BOMStructure = BOMStructureEnum.kPhantomBOMStructure _ Or oOcc.BOMStructure = BOMStructureEnum.kReferenceBOMStructure Then
' Do Nothing Else ' The occurrence is valid count the cost. ' Get the document file for this occurrence Dim oDoc As Document oDoc = oOcc.Definition.Document ' Get the iPropertySet that constains the estimated cost property Dim oPropSet As PropertySet oPropSet = oDoc.PropertySets.Item("Design Tracking Properties") ' Get the cost of this occurrence oCost += oPropSet.Item("Cost").Value End If ' Check to see if this occurrence represents a subassembly ' and recursively call this function to traverse through it. If oOcc.DefinitionDocumentType = kAssemblyDocumentObject Then Call TraverseAssembly(oOcc.SubOccurrences, Level + 1, oCount) End If Next End Sub

It's not rocket science 🙂 here is the edit. Didn't test it.. don't have Inventor here.



Please kudo if this post was helpfull
Please accept as solution if your problem was solved

Inventor 2014 SP2
0 Likes
Message 8 of 15

Anonymous
Not applicable

@Jef_E wrote:
        ' Check to see if this occurrence represents a subassembly
        ' and recursively call this function to traverse through it.
        If oOcc.DefinitionDocumentType = kAssemblyDocumentObject Then
            Call TraverseAssembly(oOcc.SubOccurrences, Level + 1, oCount)
        End If
    Next
End Sub

It's not rocket science 🙂 here is the edit. Didn't test it.. don't have Inventor here.


Great stuff, but shouldn't oCount be oCost?

 

0 Likes
Message 9 of 15

Anonymous
Not applicable

Thank you both for your replies, I'm relatively new to iLogic so when it comes to writing my own code, sometimes I'm not sure where to start or what terminology to use to access the information I need.

 

However when I read through your code I understand it quite well. I couldn't find a solution to my problem of getting the rule to run in an assembly anytime the BOM was changed, so I used the 'After Save Document' event trigger.... I think you know where this is going 🙂

 

Because the rule uses the active document, when I save my top level-assembly and the rule runs in all my sub-assemblies, it's not accessing the correct  component occurrences of those assemblies and giving me a wrong value. Is there a simple fix to this?

0 Likes
Message 10 of 15

Anonymous
Not applicable

I should also add, although the code skips any phantom assemblies but includes their parts. It also calculates the total of all parts through every level. 

For example, the total cost of my final assembly comes in at £140.62, based on the BOM below.

 Cost Example.JPG

 

Whereas I only want it to calculate the following, giving a value of £88.47:

Cost Example 2.JPG

The cost of A01908 includes the cost of it's two sub parts + labour costs

0 Likes
Message 11 of 15

Jef_E
Collaborator
Collaborator

Why would you want the code to run evry time you save? Just let it run when you want to know to cost? Add a button in the iLogic browser "Show Cost" and voila?



Please kudo if this post was helpfull
Please accept as solution if your problem was solved

Inventor 2014 SP2
0 Likes
Message 12 of 15

Jef_E
Collaborator
Collaborator

@c.henderson2HQZG wrote:

I should also add, although the code skips any phantom assemblies but includes their parts. It also calculates the total of all parts through every level. 

For example, the total cost of my final assembly comes in at £140.62, based on the BOM below.

 Cost Example.JPG

 

Whereas I only want it to calculate the following, giving a value of £88.47:

Cost Example 2.JPG

The cost of A01908 includes the cost of it's two sub parts + labour costs


Sorry in my opinion there is no logic to this.. Your assembly cost = 80.89 but the content is around 50? I gave the solution to the problem stated. Please work out your own tweaks that come out afterwards.



Please kudo if this post was helpfull
Please accept as solution if your problem was solved

Inventor 2014 SP2
0 Likes
Message 13 of 15

Anonymous
Not applicable

This snippet of code is part of a universal rule that exists in all of our part/assembly file templates. So I need the rule in each part to run when there are changes made to it. This is easy in a part file as there are event triggers specific to changes in geometry/parameters (i.e. the length of the part). But this is a bit trickier getting the assembly to update it's total cost when you add/remove a part, the rule needs to run again after the assembly has been changed to calculate the new cost. I can achieve this by setting the 'Before save' event trigger, so that the user just has to save the top level assembly and all sub parts/assemblies with changes made to them will run the rule and update their cost. 

 

To overcome the issue I was having before I changed ThisApplication.ActiveDocument to ThisDoc.Document, and it works perfectly now 🙂

0 Likes
Message 14 of 15

Anonymous
Not applicable

@Jef_E wrote:

Sorry in my opinion there is no logic to this.. Your assembly cost = 80.89 but the content is around 50? I gave the solution to the problem stated. Please work out your own tweaks that come out afterwards.


The cost of the sub-parts combined are approx 50 yes, but what you are not seeing is another part of my rule that calculates the labour cost of that assembly (approx 30) and adds this to sub-parts cost, giving me my total cost of 80.89 for that assembly.

0 Likes
Message 15 of 15

shadowcaster111
Enthusiast
Enthusiast

I could use a copy of that finished code
that adds in the labor
sounds like just the thing to solve a problem I have

 

0 Likes