Getting and Displaying Property from Content Center Part

Getting and Displaying Property from Content Center Part

ober2558
Enthusiast Enthusiast
736 Views
12 Replies
Message 1 of 13

Getting and Displaying Property from Content Center Part

ober2558
Enthusiast
Enthusiast

I am looking for a code that will return a number (from a custom iproperty) from a content center part within an assembly. I am not well versed in iLogic so be as descriptive as possible. Thank you!

0 Likes
Accepted solutions (1)
737 Views
12 Replies
Replies (12)
Message 2 of 13

WCrihfield
Mentor
Mentor

Hi @ober2558.  Something simple like this might do what you want.  It is a simple 3 part iLogic snippet for accessing iProperties.  The first specification within the () area is for the name of the assembly component, and it must be exactly as you see it in the assembly's model browser tree (component names usually have something like ":1" at the end of its name, automatically, and that must be included).  The second part is the name of the property set that the iProperty is located within, which in this case, we can simply use "Custom".  Then the third part is the name of the iProperty.

'Step 1:  replace "CCPart1:1" with the name of the assembly component,
'exactly the way it looks in the model browser tree of your active assembly document

'Step 2:  Change "PropertyName" to the real name of the custom iProperty you want
oPropValue = iProperties.Value("CCPart1:1", "Custom", "PropertyName")
MsgBox("oPropValue = " & oPropValue.ToString,,"")

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 13

ober2558
Enthusiast
Enthusiast

That worked great! However is there a way to use this with any content center/multiple content center files within an assembly without having to manually specify which content center component?

0 Likes
Message 4 of 13

WCrihfield
Mentor
Mentor

Sure.  The code just needs to get a bit longer to accomplish that.  Here is an example iLogic rule that will first make sure that the active document is an assembly, and if not will let the user know, then exit the rule.  Then it gets to the collection of all the top level components in the assembly.  Then it starts looping/iterating through those components, one at a time, checking a few things.  If it is suppressed, skips to next component.  If it does not represent a part, skip to next component.  If it is not a Content Center member, skip to next component.  Then it uses that same iLogic snippet to access the custom iProperty of that component, using its exact name (which it gets from the actual component).  But you still have to edit the property name once in the code before running it.  Then it shows you a message which includes the name of the component, and the value of the custom iProperty, so you know which one it is referring to.  Then, at the 'Next' line, it goes back to the next component, if there are more.

Sub Main
	'check to make sure an assembly is currently active, or else it will not work
	If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then
		MsgBox("An Assembly must be active for this iLogic rule to work. Exiting.", vbCritical, "iLogic")
		Exit Sub 'this line exits the rule
	End If
	'get a reference to the currently open/active assembly document
	Dim oADoc As AssemblyDocument = ThisDoc.Document
	'get a reference to its component definition (contains all the geometry, features, & components)
	Dim oADef As AssemblyComponentDefinition = oADoc.ComponentDefinition
	'get a reference to the components collection (top level components only)
	Dim oOccs As ComponentOccurrences = oADef.Occurrences
	'if there are no components in the assembly, exit the rule
	If oOccs.Count = 0 Then Exit Sub
	'start looping/iterating through each component in the collection
	For Each oOcc As ComponentOccurrence In oOccs
		'if the component is suppressed, then skip to next component
		If oOcc.Suppressed = True Then Continue For
		'if the component does not represent a Part, then skip to next component
		If TypeOf oOcc.Definition Is PartComponentDefinition = False Then Continue For
		Dim oOccPDef As PartComponentDefinition = oOcc.Definition
		'If it is not a Content Center member, then skip to next component
		If oOccPDef.IsContentMember = False Then Continue For
		Dim oPropValue As Object = Nothing 'variable to hold the value
		' <<< !!! EDIT THE PROPERTY NAME HERE !!! >>>
		oPropValue = iProperties.Value(oOcc.Name, "Custom", "PropertyName")
		'show a message to the user with some information
		MsgBox("Component Name = " & oOcc.Name & vbCrLf & _
		"Property Value = " & oPropValue.ToString, vbInformation, "iLogic")
	Next 'oOcc 'now the code goes to the next component, if there are more
End Sub

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 5 of 13

ober2558
Enthusiast
Enthusiast

After some minor tweaking it seems to work well but I am having trouble adding this code to my other code. In essence I am trying to total up all components "Weights" (As a custom property) within an assembly. Each of these 2 codes work fine on their own but I end up having a variety of issues when combining them. Please give any guidance you can provide, Thank you!

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, vbInformation, "Total Tool Weight")
	End Sub
	
	Dim oWeightList As List(Of Double)
	
	Sub RecursivelyProcessComponents(oComps As ComponentOccurrences)
		If IsNothing(oComps) 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 oComp.IsiAssemblyMember Then
				Dim oMember As iAssemblyMember = oComp.Definition.iAssemblyMember
				oWeightList.Add(CDbl(oMember.Row.Item("Weight [Custom]").Value))
			Else If oComp.IsiPartMember Then
				Dim oMember As iPartMember = oComp.Definition.iPartMember
				oWeightList.Add(CDbl(oMember.Row.Item("Weight [Custom]").Value))
			Else
				MessageBox.Show("No Part Weight Detected", "Warning")
			End If
		Next
	End Sub
End Class

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 iParts Weight = " & oTotaliPartsWeight, vbInformation, "Total iParts Weight")
	End Sub
	
	Dim oWeightList As List(Of Double)
	
	Sub RecursivelyProcessComponents(oComps As ComponentOccurrences)
		If IsNothing(oComps) 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 PartComponentDefinition = False Then Continue For
		Dim oCompPDef As PartComponentDefinition = oComp.Definition
		If oCompPDef.IsContentMember = False Then Continue For
		Dim oPropValue As Object = Nothing 'variable to hold the value
		oPropValue = iProperties.Value(oComp.Name, "Custom", "Weight")
		oWeightList.Add(CDbl(oPropValue))
End Sub
End Class
0 Likes
Message 6 of 13

WCrihfield
Mentor
Mentor

Hi @ober2558.  Here is my attempt at combining those two codes into one.  See if this works better for you.

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 iParts Weight = " & oTotaliPartsWeight, vbInformation, "Total iParts 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
			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))	
			ElseIf TypeOf oComp.Definition Is PartComponentDefinition Then
				Dim oCompPDef As PartComponentDefinition = oComp.Definition
				If oCompPDef.IsContentMember = True Then
					Dim oPropValue As Object = Nothing 'variable to hold the value
					oPropValue = iProperties.Value(oComp.Name, "Custom", "Weight")
					oWeightList.Add(CDbl(oPropValue))
				End If
			End If
		Next 'oComp
	End Sub
End Class

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 7 of 13

ober2558
Enthusiast
Enthusiast

Thank you for your continued help! This code works great! However I have added a bit of extra code (Line 35 on) that does seems to get skipped after adding your code, any further guidance you can give would be great! 

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 IsNothing(oComps) 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 oComp.IsiAssemblyMember Then
				Dim oMember As iAssemblyMember = oComp.Definition.iAssemblyMember
				oWeightList.Add(CDbl(oMember.Row.Item("Weight [Custom]").Value))
			Else If oComp.IsiPartMember Then
				Dim oMember As iPartMember = oComp.Definition.iPartMember
				oWeightList.Add(CDbl(oMember.Row.Item("Weight [Custom]").Value))
			Else If TypeOf oComp.Definition Is PartComponentDefinition Then
				Dim oCompPDef As PartComponentDefinition = oComp.Definition
				If oCompPDef.IsContentMember = True Then
					Dim oPropValue As Object = Nothing
					oPropValue = iProperties.Value(oComp.Name, "Custom", "Weight")
					oWeightList.Add(CDbl(oPropValue))
				End If
			Else
				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
					Returnmyparam = InputBox("Input Weight in kg ", "Weight Input Prompt for '" & _
					oComp.Name & "'", "")
					oWeightList.Add(CDbl(Returnmyparam))
				Else If Result = 7 Then
				Else If Result = 2 Then
					Return
				End If
			End If
		Next
	End Sub
End Class
0 Likes
Message 8 of 13

WCrihfield
Mentor
Mentor

Hi @ober2558.  Before I attempt to edit the code and post the entire code back here again, I need to know what your design intent is for the extra code you added.  The way it is laid out right now, it will only reach line 35 if the component:  (is not an iAssemblyMember), (is not an iPartMember), and (is not a part).  So only components that represent sub assemblies that are not iAssemblyMembers.  In the final 'ElseIf' section of the last code I posted above, the main 'expression' it is testing for is if the component's definition is a PartComponentDefinition, which will catch all remaining part type components that are not an iPartMember.  I have to check that before trying to check if it may be a content center member, because that 'IsContentMember' property is only found under the PartComponentDefinition object.  If I were to try checking that directly by oComp.Definition.IsContentMember it would throw errors for every sub assembly and other types it encountered.  If you only want the whole last section of your code to work on parts, and not on sub assemblies, then you could reposition it within an 'ElseIf' extension of my 'If oCompPDef.IsContentMember = True Then' block of code, then if the part is not a content center member, it would continue to run the additional code (but still not on sub assemblies).

 

Plus, there is one other ongoing issue I keep seeing in the codes you are posting that I feel I need to point out.  You keep using the keyword phrase "Else If" (with a space between the two keywords), where you need to be using "ElseIf" (one keyword, with no space between "Else" & "If").  You need to know that these two have different functionality.  The keyword "ElseIf" is the primary way to test additional expressions, other than the original expression within a single If...ElseIf...Else...End If block of code.  The keyword "If" starts a separate new 'If' block of code that generally requires another "End If".  Any statements following the "Else" keyword will always be carried out, without evaluating any other expression, as long as none of the previous expressions in that 'If' block of code evaluated to True.  Below is a link to the source documentation for this functionality from Microsoft.

https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/if-then-else-sta... 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 9 of 13

ober2558
Enthusiast
Enthusiast

Thank you for your input! The ultimate goal is that if any parts, assemblies, etc. within the top level assembly DO NOT have the "weight" custom property it will prompt the user to input a weight for each which will be added to the total. Let me know if you need any further information.

0 Likes
Message 10 of 13

WCrihfield
Mentor
Mentor

OK.  Do you want the code to attempt to add that custom iProperty to the document that the component represents, and set its value to that value you manually enter? Or do you only want to add the manually entered value to the list of weights?

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 11 of 13

ober2558
Enthusiast
Enthusiast

Preferably attempt to add that custom iproperty to the document using the user inputted number

0 Likes
Message 12 of 13

WCrihfield
Mentor
Mentor
Accepted solution

OK.  I think I may have it updated for you, but obviously can't test it myself, so here is what I've got.  I replaced using the 'iProperties.Value() snippet with regular API code, because the snippet may not work properly on components that are down within sub assemblies.  One complication (but not the only one) is that there can be multiple components within all levels of the assembly which have the same component names, so it would not know which one to work with if just a simple component name is supplied.  The API code avoids that problem, because it references the specific Document object directly.  But I also had to put some extra Try...Catch...End Try blocks in there to avoid some potential errors.  I also find it interesting that you choose to use the Integer representations of DialogResult values from the MessageBox.Show() method.  I would have usually used DialogResult.Yes, or something similar, but what you have works too.

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

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 13 of 13

ober2558
Enthusiast
Enthusiast

This works perfectly, Thank you so much for all your help!

0 Likes