Rule to generate 'Custom Property' from Parameter

Rule to generate 'Custom Property' from Parameter

John4MJN3
Enthusiast Enthusiast
582 Views
4 Replies
Message 1 of 5

Rule to generate 'Custom Property' from Parameter

John4MJN3
Enthusiast
Enthusiast

Hi a couple of weeks back I got a bit of help with some code because I'm rubbish at it mainly.

 

Basically I was going to generate a custom parameter called 'bought out type'.

John4MJN3_0-1695638488591.png

I now want to add something that will take that result in this case 'Automation Tools' and create a custom property of the same name. 

 

 

 This was it:

Dim oUParams As UserParameters = ThisApplication.ActiveDocument.ComponentDefinition.Parameters.UserParameters
Dim oUParam As UserParameter
Dim sName As String = "Bought_Out_Type"
Dim oValues As New List(Of String)
oValues.Add("Motion & Drives")
oValues.Add("Pneumatics & Hydraulics")
oValues.Add("Automation Tools")
oValues.Add("Electrical Control & Motion")
oValues.Add("Electrical Components")
oValues.Add("Fixings")
oValues.Add("Pipe & Fittings")
oValues.Add("Mechanical Components")
oValues.Add("Raw Material")

Try
	oUParam = oUParams.Item(sName)
	MultiValue.SetList(sName, oValues.ToArray)
Catch
	oUParam = oUParams.AddByValue(sName, "", UnitsTypeEnum.kTextUnits)
	MultiValue.SetList(sName, oValues.ToArray)
End Try

 The only other thing I'm struggling with, I wanted to generate a secondary 'Bought Out Code' which is a shorthand version of the first things we created. The only issue is I cannot get it to populate the parameter properly, it seems to get them mixed up!!

'Access User parameters of the active document
Dim oMyParameters As UserParameters = ThisApplication.ActiveDocument.ComponentDefinition.Parameters.UserParameters 
'Create list of Parameter names of type: number
Dim textParams As New List(Of String) 
textParams.AddRange({"Bought_Out_Code"})
'Testing and Creation of User Parameters of type: text
For Each item In textParams
	Try 'Check if User Parameter exists
		Param = oMyParameters.Item(item)
	Catch 'Parameter doesn't exist as a User Parameter
		Try 'attempt to create new parameter
			oMyParameters.AddByValue(item, "filler", UnitsTypeEnum.kTextUnits) '(Name, Value, Unit Type)
		Catch 'Parameter exists but not as a User Parameter
			MessageBox.Show("The Parameter: " & item & " exists as a parameter, but is not a user parameter.", "Creation Failure")
		End Try
	End Try
Next

If Parameter("Bought_Out_Type") = "Motion & drives" Then Parameter("Bought_Out_Code") = "MOTO"
If Parameter("Bought_Out_Type") = "Pneumatics & Hydraulics" Then Parameter("Bought_Out_Code") = "PNHY"
If Parameter("Bought_Out_Type") = "Automation Tools" Then Parameter("Bought_Out_Code") = "AUTO"
If Parameter("Bought_Out_Type") = "Electrical Control & Motion" Then Parameter("Bought_Out_Code") = "ECON"
If Parameter("Bought_Out_Type") = "Electrical Components" Then Parameter("Bought_Out_Code") = "EGEN"
If Parameter("Bought_Out_Type") = "Fixings" Then Parameter("Bought_Out_Code") = "FIXS"
If Parameter("Bought_Out_Type") = "Pipe & Fittings" Then Parameter("Bought_Out_Code") = "PIPE"
If Parameter("Bought_Out_Type") = "Mechanical Components" Then Parameter("Bought_Out_Code") = "COMP"
If Parameter("Bought_Out_Type") = "Raw Material" Then Parameter("Bought_Out_Code") = "MATE"

iLogicForm.ShowGlobal("Bought Out Types")





0 Likes
583 Views
4 Replies
Replies (4)
Message 2 of 5

WCrihfield
Mentor
Mentor

Hi @John4MJN3.  As you may have figured out, we can not simply check a checkbox for a text type user parameter, to have it automatically create a matching custom iProperty, like we can with numerical parameters.  We can in Inventor 2024 though.  So, until you get upgraded, you simply need to create a custom iProperty with the same name as the parameter, then set the parameter's value as that custom iProperty's value.  In simple scenarios, you can do that with a simple line of code like the following two examples.

In this line, the unquoted parameter name would be blue, and recognized as a local parameter.  This would only work within an internal rule (a rule that was saved within that document).

iProperties.Value("Custom", "Bought_Out_Type") = Bought_Out_Type

If using an external rule, then this next line would be the next simplest code solution.

iProperties.Value("Custom", "Bought_Out_Type") = Parameter("Bought_Out_Type")

However, keep in mind that neither of those two iLogic snippets in that last line are specifying which document they are targeting.  That can cause problems in more complex scenarios, such as when this code gets triggered to run while something like a higher level assembly or drawing are the active documents at that time, because it may try to target them instead.  If you are expecting that this code may get ran remotely like that, then you may want to go with a longer, and more specific version of code, such as using the Inventor API route of accessing those properties and parameters.

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 5

WCrihfield
Mentor
Mentor

Also, if you want to create that "Bought_Out_Code" text type multi-value user parameter using abbreviated versions of the "Bough_Out_Type" parameter's values, then you will need to access that other parameters list, not its value.  There are multiple ways to access the list of available values of a multi-value parameter.  One way is through the UserParameter.ExpressionList, then ExpressionList.GetExpressionList method.  The ExpressionList object also has a couple other properties that you might find useful, such as ExpressionList.AllowCustomValues (available in  2021 or later versions), and ExpressionList.CustomOrder (available in 2023 version or later).  Or you can use the iLogic rule Interface object 'MultiValue', and its associated properties & methods.  I see that you are using MultiValue.SetList method in your example above.  But if you just want to 'get' the list, instead of 'setting' the list, you can use the MultiValue.List property.  You may not be able to just use a simple find & replace routine on the those list values directly though.  Instead you will want to 'remove' the values that you do not want from the list, then 'add' the values that you do want into the list.  Just keep in mind that there are some differences in what Type of object you will get from these three different routes.  The ExpressionList.GetExpressionList method returns an Array of String.  And the ExpressionList.SetExpressionList method is expecting an Array of String as its first input.  The MultiValue.SetList method is expecting an Array of Object as its input.  The MultiValue.List property (which is Read/Write) has an 'IList' type value.  These are all expecting you to either 'get' or 'set' a whole list of values at once, not just get or set individual values within the list.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 4 of 5

John4MJN3
Enthusiast
Enthusiast

Thanks for your replies, there is a lot of detail there!

 

What I've got in mind is that we will need to retrospectively apply this to files that we download from partserver/other sources. This is why I'm trying to capture this in the code. We may need to upgrade to 2024 if I can't get this done in 2023 but that's not a massive problem. 

 

With that in mind what do you think would be the best approach to enable the short hand list? I think we may need to 'set' the list from the code rather than 'get' because I don't author the files in most cases as they are downloads.

 

With the code I have, it kind of works but I'm getting the wrong value expressed. For example the 'Motion & drives' gives me 'ECON' rather than 'MOTO' which it should have. So clearly I've done something wrong here.  The approach you are suggesting sounds quite different, but I'm a bit clueless how to articulate that into reality, so any suggestions would be of great help!!  

 

If Parameter("Bought_Out_Type") = "Motion & drives" Then Parameter("Bought_Out_Code") = "MOTO"
If Parameter("Bought_Out_Type") = "Pneumatics & Hydraulics" Then Parameter("Bought_Out_Code") = "PNHY"
If Parameter("Bought_Out_Type") = "Automation Tools" Then Parameter("Bought_Out_Code") = "AUTO"
If Parameter("Bought_Out_Type") = "Electrical Control & Motion" Then Parameter("Bought_Out_Code") = "ECON"
If Parameter("Bought_Out_Type") = "Electrical Components" Then Parameter("Bought_Out_Code") = "EGEN"
If Parameter("Bought_Out_Type") = "Fixings" Then Parameter("Bought_Out_Code") = "FIXS"
If Parameter("Bought_Out_Type") = "Pipe & Fittings" Then Parameter("Bought_Out_Code") = "PIPE"
If Parameter("Bought_Out_Type") = "Mechanical Components" Then Parameter("Bought_Out_Code") = "COMP"
If Parameter("Bought_Out_Type") = "Raw Material" Then Parameter("Bought_Out_Code") = "MATE"

iLogicForm.ShowGlobal("Bought Out Types")

 

0 Likes
Message 5 of 5

WCrihfield
Mentor
Mentor

Hi @John4MJN3.  Here is an alternative version of your code that you can try out.  Maybe this version will help eliminate the odd value mismatches.  Since parts, assemblies, and drawings can all have UserParameters, but drawings do not have a ComponentDefinition, I included a document type filter at the start.  Then I check to make sure the document is actually modifiable.  Then it either gets or creates the UserParameter.  Now, we already have a variable representing the UserParameter we just found or created, so we will use that going forward. Then I get the value of the other parameter to a String type variable (one time).  Then I use just one extended If...ElseIf...End If statement to handle all the checking / setting after that.  Within that block of code I am using a technique for comparing two Strings, which lets it ignore Case (uppercase and lowercase letter differences).  Spelling will still be important though.  Then after that block of code, since multiple changes have potentially been made to the document, I included a line of code to update the document, before showing the global iLogic form.

 

Dim oDoc As Document = ThisDoc.Document
If (Not TypeOf oDoc Is PartDocument) And (Not TypeOf oDoc Is AssemblyDocument) Then
	MessageBox.Show("This code only works for a Part or Assembly.", "Wrong Document Type", MessageBoxButtons.OK, MessageBoxIcon.Stop)
	Exit Sub
End If
If oDoc.IsModifiable = False Then Exit Sub
Dim oUParams As UserParameters = oDoc.ComponentDefinition.Parameters.UserParameters 
Dim sParamName As String = "Bought_Out_Code"
Dim oBOC As UserParameter = Nothing
Try 'Check if User Parameter exists
	oUParam = oUParams.Item(sParamName)
Catch 'Parameter doesn't exist as a User Parameter
	oUParam = oUParams.AddByValue(sParamName, "", UnitsTypeEnum.kTextUnits) '(Name, Value, Unit Type)
Catch 'UserParameter not found, and could not be created
	MessageBox.Show("Could not find or create a UserParameter named: " & sParamName & ".", "Creation Failure")
End Try
If oBOC Is Nothing Then Exit Sub
Dim sBOT As String = Parameter("Bought_Out_Type")
If String.Compare(sBOT, "Motion & drives", True) = 0 Then
	oBOC.Value = "MOTO"
ElseIf String.Compare(sBOT, "Pneumatics & Hydraulics", True) = 0 Then
	oBOC.Value = "PNHY"
ElseIf String.Compare(sBOT, "Automation Tools", True) = 0 Then
	oBOC.Value = "AUTO"
ElseIf String.Compare(sBOT, "Electrical Control & Motion", True) = 0 Then
	oBOC.Value = "ECON"
ElseIf String.Compare(sBOT, "Electrical Components", True) = 0 Then
	oBOC.Value = "EGEN"
ElseIf String.Compare(sBOT, "Fixings", True) = 0 Then
	oBOC.Value = "FIXS"
ElseIf String.Compare(sBOT, "Pipe & Fittings", True) = 0 Then
	oBOC.Value = "PIPE"
ElseIf String.Compare(sBOT, "Mechanical Components", True) = 0 Then
	oBOC.Value = "COMP"
ElseIf String.Compare(sBOT, "Raw Material", True) = 0 Then
	oBOC.Value = "MATE"
End If
If oDoc.RequiresUpdate Then oDoc.Update2(True)
iLogicForm.ShowGlobal("Bought Out Types")

 

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