Combining 2 codes for weight calculation

Combining 2 codes for weight calculation

ober2558
Enthusiast Enthusiast
442 Views
5 Replies
Message 1 of 6

Combining 2 codes for weight calculation

ober2558
Enthusiast
Enthusiast

I have 2 different codes that I wish to combine but I am having quite a bit of trouble. Each code works perfectly fine on their own but I need to combine them in order to do what I want. The first code adds up the "weights" of each component (ipart, iassembly, and CC component) within the assembly based off a custom iproperty, if a component does not have this iproperty it prompts the user to input one. This total is then presented to the user. 

Class ThisRule
	Sub Main
		If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then
			MsgBox("An Assembly Document Must Be Active For This Rule to Work. Exiting.", vbCritical, "")
			Exit Sub
		End If
		Dim oADoc As AssemblyDocument = ThisDoc.Document
		Dim oOccs As ComponentOccurrences = oADoc.ComponentDefinition.Occurrences
		oWeightList = New List(Of Double)
		RecursivelyProcessComponents(oOccs)
		Dim oTotaliPartsWeight As Double = oWeightList.Sum
		MsgBox("Total Tool Weight = " & oTotaliPartsWeight & " kg", vbInformation, "Total Tool Weight")
	End Sub
	
	Dim oWeightList As List(Of Double)
	
	Sub RecursivelyProcessComponents(oComps As ComponentOccurrences)
		If oComps Is Nothing OrElse oComps.Count = 0 Then Exit Sub
		For Each oComp As ComponentOccurrence In oComps
			If oComp.Suppressed Then Continue For
			If TypeOf oComp.Definition Is VirtualComponentDefinition Then Continue For
			If TypeOf oComp.Definition Is WeldsComponentDefinition Then Continue For
			Dim oCompDoc As Document = Nothing
			Try : oCompDoc = oComp.Definition.Document : Catch : End Try
			If oComp.IsiAssemblyMember Then
				Dim oMember As iAssemblyMember = oComp.Definition.iAssemblyMember
				oWeightList.Add(CDbl(oMember.Row.Item("Weight [Custom]").Value))
			ElseIf oComp.IsiPartMember Then
				Dim oMember As iPartMember = oComp.Definition.iPartMember
				oWeightList.Add(CDbl(oMember.Row.Item("Weight [Custom]").Value))
			Else 'it is not iAssemblyMember or iPartMember
				Dim bCCMember As Boolean = False
				Try : bCCMember = oComp.Definition.IsContentMember : Catch : End Try
				If bCCMember = True Then
					Dim oPropValue As Object = Nothing
					Try : oPropValue = oCompDoc.PropertySets.Item(4).Item("Weight").Value : Catch : End Try
					Try : oWeightList.Add(CDbl(oPropValue)) : Catch : End Try
				Else 'it is not an iAssemblyMember, not an iPartMember, and not Content Center member
					Dim Result As Integer
					Result = MessageBox.Show("Would You Like To Input a Temporary Weight For This Part?", _
					"No Part Weight Detected for '" & oComp.Name & "'", MessageBoxButtons.YesNoCancel, _
					MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1)
					If Result = 6 Then
						Dim Returnmyparam As String = InputBox("Input Weight in kg ", "Weight Input Prompt for '" & _
						oComp.Name & "'", "")
						'If Returnmyparam = "" Then Continue For
						Dim oWeightCProp As Inventor.Property = Nothing
						Try
							oWeightCProp = oCompDoc.PropertySets.Item(4).Item("Weight")
						Catch
							oWeightCProp = oCompDoc.PropertySets.Item(4).Add(CDbl(Returnmyparam), "Weight")
						End Try
						oWeightList.Add(CDbl(Returnmyparam))
					ElseIf Result = 7 Then
					ElseIf Result = 2 Then
						Return
					End If
				End If
			End If
		Next
	End Sub
End Class

 

The second code is separate due to specific Content Center Components being structural shapes with a user inputted length and therefore cannot work the same way using the "weight" custom iproperty. Instead this code simply takes the components masses and adds them up.

Sub Main
	Dim doc As AssemblyDocument = ThisApplication.ActiveDocument
	Dim occs As ComponentOccurrences = doc.ComponentDefinition.Occurrences
	Dim mass As Double
	
	For Each refDoc As Document In doc.AllReferencedDocuments
		If TypeOf refDoc Is AssemblyDocument Then Continue For
		If Not refDoc.ComponentDefinition.IsContentMember Then Continue For

		Dim list As New List(Of String)
		list.Add("Profile 1")
		list.Add("Profile 2")
		list.Add("Profile 3")
		list.Add("Profile 4")
		list.Add("Profile 5")
		list.Add("Profile 6")
		list.Add("Profile 7")
		list.Add("Profile 8")
		list.Add("Profile 9")
		list.Add("Profile 10")
		list.Add("Profile 11")

		Dim check As Boolean = False
		
		For Each s As String In list
			If refDoc.DisplayName.Contains(s) Then 
				check = True
				Exit For 
				
			End If
		Next
		
		If check = False Then Continue For
						
		Dim qty As Integer = occs.AllReferencedOccurrences(refDoc).Count	
		mass += refDoc.ComponentDefinition.MassProperties.Mass * qty
		
	Next
	
	MessageBox.Show(mass & " kg")
	
End Sub

 

I am looking to combine these 2 codes in order to get a grand total. I am not a very experienced coder so in-depth help would be greatly appreciated. Please let me know if you have any further questions. Thank you!

0 Likes
Accepted solutions (1)
443 Views
5 Replies
Replies (5)
Message 2 of 6

WCrihfield
Mentor
Mentor

Hi @ober2558.  What do you plan on doing with this Mass/Weight data once you have it?  Do you need to enter this data somewhere else?  Do you need that data to be separated into categories (mass of all iAssemblies, mass of all iParts, mass of all content center parts, mass of all other, etc)?  Is the mass of the iAssemblyMembers & iPartMembers from the MassProperties.Mass different from the value in the custom iProperty "Weight"?  Do you want the total(s) to be written to a custom iProperty of the main assembly?  Did you know that you can actually overwrite the value of the MassProperties.Mass property?  It is a Read/Write Double data type property, and there is another property (MassProperties.MassOverridden) that will indicate whether it has been overridden, so that you can check it.  If it is True, since this too is a Read/Write Boolean type property, you can even set it to False, which should return the Mass value to its normal value.  But you may not be able to change either of those if the document is ReadOnly, like with content center stuff.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 6

ober2558
Enthusiast
Enthusiast

Hello again! I just want the total mass/weight displayed to the user in a message box, it will not need to be used anywhere else as of right now. They do not need to be separated in any manner. The custom "weight" property has different values than those calculated by Inventor in the "mass properties" (these parts are not entirely accurate but still need to display the correct weight). The total will not need to be added to the assembly as a custom property. I am aware you can override the mass properties however when using iparts/iassemblies, this overridden mass will be applied to all members of the ipart/iassembly which are in fact not all the same weight. 

Message 4 of 6

WCrihfield
Mentor
Mentor
Accepted solution

Hi @ober2558.  Here is my attempt at combining those two rules.  I added the list of labels out where it is 'shared', then set its values within the Sub Main area, since they do not change.  Then I used some comment lines to mark where I added/edited the other rule, so you can more easily see what I did.  I hope this works the way you intended.

Class ThisRule
	Sub Main
		If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then
			MsgBox("An Assembly Document Must Be Active For This Rule to Work. Exiting.", vbCritical, "")
			Exit Sub
		End If
		Dim oADoc As AssemblyDocument = ThisDoc.Document
		Dim oOccs As ComponentOccurrences = oADoc.ComponentDefinition.Occurrences
		oWeightList = New List(Of Double)
		oLabels = New List(Of String)
		oLabels.Add("Profile 1")
		oLabels.Add("Profile 2")
		oLabels.Add("Profile 3")
		oLabels.Add("Profile 4")
		oLabels.Add("Profile 5")
		oLabels.Add("Profile 6")
		oLabels.Add("Profile 7")
		oLabels.Add("Profile 8")
		oLabels.Add("Profile 9")
		oLabels.Add("Profile 10")
		oLabels.Add("Profile 11")
		RecursivelyProcessComponents(oOccs)
		Dim oTotaliPartsWeight As Double = oWeightList.Sum
		MsgBox("Total Tool Weight = " & oTotaliPartsWeight & " kg", vbInformation, "Total Tool Weight")
	End Sub
	
	Dim oWeightList As List(Of Double)
	Dim oLabels As List(Of String)
	
	Sub RecursivelyProcessComponents(oComps As ComponentOccurrences)
		If oComps Is Nothing OrElse oComps.Count = 0 Then Exit Sub
		For Each oComp As ComponentOccurrence In oComps
			If oComp.Suppressed Then Continue For
			If TypeOf oComp.Definition Is VirtualComponentDefinition Then Continue For
			If TypeOf oComp.Definition Is WeldsComponentDefinition Then Continue For
			Dim oCompDoc As Document = Nothing
			Try : oCompDoc = oComp.Definition.Document : Catch : End Try
			If oComp.IsiAssemblyMember Then
				Dim oMember As iAssemblyMember = oComp.Definition.iAssemblyMember
				oWeightList.Add(CDbl(oMember.Row.Item("Weight [Custom]").Value))
			ElseIf oComp.IsiPartMember Then
				Dim oMember As iPartMember = oComp.Definition.iPartMember
				oWeightList.Add(CDbl(oMember.Row.Item("Weight [Custom]").Value))
			Else 'it is not iAssemblyMember or iPartMember
				Dim bCCMember As Boolean = False
				Try : bCCMember = oComp.Definition.IsContentMember : Catch : End Try
				If bCCMember = True Then
					'<<< STARAT OF ADDED/EDITED SECTION >>>
					Dim bCheck As Boolean = False
					For Each sLabel In oLabels
						If oCompDoc.DisplayName.Contains(sLabel) Then bCheck = True
					Next
					If bCheck = True Then
						oWeightList.Add(oComp.MassProperties.Mass)
					Else 'the content member Document did not have any of those labels in its DisplayName
						Dim oPropValue As Object = Nothing
						Try : oPropValue = oCompDoc.PropertySets.Item(4).Item("Weight").Value : Catch : End Try
						Try : oWeightList.Add(CDbl(oPropValue)) : Catch : End Try
					End If
					'<<< END OF ADDED/EDITED SECTION >>>
				Else 'it is not an iAssemblyMember, not an iPartMember, and not Content Center member
					Dim Result As Integer
					Result = MessageBox.Show("Would You Like To Input a Temporary Weight For This Part?", _
					"No Part Weight Detected for '" & oComp.Name & "'", MessageBoxButtons.YesNoCancel, _
					MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1)
					If Result = 6 Then
						Dim Returnmyparam As String = InputBox("Input Weight in kg ", "Weight Input Prompt for '" & _
						oComp.Name & "'", "")
						'If Returnmyparam = "" Then Continue For
						Dim oWeightCProp As Inventor.Property = Nothing
						Try
							oWeightCProp = oCompDoc.PropertySets.Item(4).Item("Weight")
						Catch
							oWeightCProp = oCompDoc.PropertySets.Item(4).Add(CDbl(Returnmyparam), "Weight")
						End Try
						oWeightList.Add(CDbl(Returnmyparam))
					ElseIf Result = 7 Then
					ElseIf Result = 2 Then
						Return
					End If
				End If
			End If
		Next
	End Sub
End Class

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 5 of 6

ober2558
Enthusiast
Enthusiast

Absolutely perfect! You're a lifesaver! any way I could round the final total to 4 decimal places?

0 Likes
Message 6 of 6

WCrihfield
Mentor
Mentor

Maybe add this line right under your line getting the List.Sum weight in your Sub Main area.

oTotaliPartsWeight = Round(oTotaliPartsWeight, 4, MidpointRounding.AwayFromZero)

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)