SetExpressionList wtih API not working

SetExpressionList wtih API not working

Curtis_Waguespack
Consultant Consultant
1,347 Views
15 Replies
Message 1 of 16

SetExpressionList wtih API not working

Curtis_Waguespack
Consultant
Consultant

I am trying to set a list to a parameter, using the API ( not iLogic functions)  and I'm seeing an odd result. Maybe I'm missing something obvious?

 

Can someone put "fresh eyes" on this and let me know what I'm missing?

 

Thanks! 

 

 

 

You can see the result by running this code from an iLogic rule in any part file.

 

After running the rule, the parameter does not have a list

Curtis_Waguespack_1-1719927180918.png

 

But if I return to the rule in the iLogic editor, and hover over the parameter I see the list

Curtis_Waguespack_0-1719927135670.png

 

Capture current state also pulls the list, but I can't use the iLogic Multivalue function in my case, because in the end I intend this to be in an add-in.

 

Curtis_Waguespack_2-1719927255444.png

 

 

 

Dim list As New ArrayList
list.Add("11111")
list.Add("22222")
list.Add("33333")
'list.Add("44444")

Dim InvDocument As Document = ThisDoc.Document

Dim oListParam As Inventor.Parameter
Try
	oListParam = InvDocument.ComponentDefinition.Parameters.UserParameters.Item("Test")
Catch
	oListParam = InvDocument.ComponentDefinition.Parameters.UserParameters.AddByValue("Test", "", UnitsTypeEnum.kTextUnits)
End Try

'set array list to string array
Dim ListArray As String()
For i = 0 To list.Count - 1
	ReDim Preserve ListArray(i)
	ListArray(i) = list.Item(i)
Next

MsgBox(UBound(ListArray))

'set list to parameter
oListParam.ExpressionList.SetExpressionList(ListArray)

 

EESignature

0 Likes
Accepted solutions (3)
1,348 Views
15 Replies
Replies (15)
Message 2 of 16

R.Mabery
Advocate
Advocate
Accepted solution

Hi Curtis,

 

The strings in the Array need to have "" around them.

 

ListArray(i) = String.Concat("""", list.Item(i), """")

Thanks,
Randy Mabery
Applications Expert
IMAGINiT Technologies
Message 3 of 16

WCrihfield
Mentor
Mentor

I have been seeing the same behavior for quite a while now myself too.  Very frustrating, since I generally tend to prefer doing things by way of Inventor API, rather than using the 'iLogic Only' tools, in several situations.  It seems like this used to work just fine, then it quit working somewhere along the way.  I do not recall exactly when though.  I am still using 2024.3 right now, but it has been a problem since long before that update, at least for me.

Another thing is that it seems to always throw an error (COMException - Unspecified error) when I specify True for the optional second input called 'ChangeCurrentValue', which is a Boolean.  No matter if the parameter already existed, and had other multi-values already in it or not.  May be part of the same issue, not sure.

ExpressionList.SetExpressionList 

 

Edit:  By the way, this is the example I had in my 'snippets' for testing this problematic Inventor API method.  Not that there is anything particularly special about it.

Dim oDoc As Document = ThisDoc.Document
Dim oParams As Inventor.Parameters = Nothing
If (TypeOf oDoc Is AssemblyDocument) OrElse (TypeOf oDoc Is PartDocument) Then
	oParams = oDoc.ComponentDefinition.Parameters
ElseIf (TypeOf oDoc Is DrawingDocument) Then
	oParams = oDoc.Parameters
End If
If oParams Is Nothing Then Return
Dim oUParams As UserParameters = oParams.UserParameters
Dim oUParam As UserParameter = Nothing
Dim sParamName As String = "TestMultiValueParam"
Dim oValues() As String = {"Val1", "Val2", "Val3", "Val4" }
Try
	oUParam = oUParams.Item(sParamName)
Catch
	oUParam = oUParams.AddByValue(sParamName, "", UnitsTypeEnum.kTextUnits)
End Try
oUParam.IsKey = True
'oUParam.ExposedAsProperty = True
oUParam.ExpressionList.SetExpressionList(oValues, True)
oDoc.Update2(True)

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 4 of 16

Curtis_Waguespack
Consultant
Consultant

@R.Mabery That's it! Thanks, that was driving me crazy!

 

Dim ListArray As String()
For i = 0 To list.Count - 1
	ReDim Preserve ListArray(i)
	ListArray(i) = String.Concat("""", list.Item(i), """")	
Next



@WCrihfield , thanks for taking a look. I think you're right about it behaving differently in the past. 

 

It's interesting that my example was not throwing an error, and was setting the list ( as shown my getting it from the iLogic editor) , but not showing in the native parameter editor.

 

@MjDeck, if you have some time, this might be something to look into.

 

Thanks again everyone!

EESignature

0 Likes
Message 5 of 16

Curtis_Waguespack
Consultant
Consultant

@WCrihfield, I think True for the ChangeCurrentValue option fails when there is no list, so the failure of the method to create the list correctly is allowing it to trip over ChangeCurrentValue  = True.

 

 ChangeCurrentValue  = True worked for me after including R.Mabery's solution. But I'm not sure how to get the extra quotes into the array values using the syntax in your example, without a lot of extra work. 

 

In any case, I think this SetExpressionList method could use some attention in general. It would be nice if it would handle the error if the list didn't get created and ChangeCurrentValue is True, and it would be nice if the string array formatting that it's needing could be handled more elegantly as well.

EESignature

Message 6 of 16

WCrihfield
Mentor
Mentor
Accepted solution

I see now what it seems to be wanting...an extra set of double quotation marks around each String.  That is very odd, and should not be required.  I can now get it to work with this extra character, and extra trouble involved, but it should not be this way.  It does not seem logical, or easy to understand.  I guess their initial response to similar issues in the past may have been to create the iLogic alternative way of doing this, instead of fixing or recoding the Inventor API code supporting its functionality.

 

Anyways, here is my updated code sample that seems to be working for me...even when specifying True in the optional second input.  I used the Chr() function to return the " character, and captured that to a Char type variable, then concatenated that in front of, and behind each entry within my List(Of String), which I then later converted into an Array of Strings, using its AsArray Function.  This way certainly takes up a lot more lines of code.  If it was a longer list, I would likely set the initial values of the List with 'From {}', similar to the Array, then later incorporate a Loop to add the extra character into each entry.

Dim oDoc As Document = ThisDoc.Document
Dim oParams As Inventor.Parameters = Nothing
If (TypeOf oDoc Is AssemblyDocument) OrElse (TypeOf oDoc Is PartDocument) Then
	oParams = oDoc.ComponentDefinition.Parameters
ElseIf (TypeOf oDoc Is DrawingDocument) Then
	oParams = oDoc.Parameters
End If
If oParams Is Nothing Then Return
Dim oUParams As UserParameters = oParams.UserParameters
Dim oUParam As UserParameter = Nothing
Dim sParamName As String = "TestMultiValueParam"
Dim sDoubleQuote As Char = Chr(34)
Dim oValuesList As New List(Of String)
oValuesList.Add(sDoubleQuote & "Val1" & sDoubleQuote)
oValuesList.Add(sDoubleQuote & "Val2" & sDoubleQuote)
oValuesList.Add(sDoubleQuote & "Val3" & sDoubleQuote)
oValuesList.Add(sDoubleQuote & "Val4" & sDoubleQuote)
Try
	oUParam = oUParams.Item(sParamName)
Catch
	oUParam = oUParams.AddByValue(sParamName, "", UnitsTypeEnum.kTextUnits)
End Try
oUParam.IsKey = True
'oUParam.ExposedAsProperty = True
oUParam.ExpressionList.SetExpressionList(oValuesList.ToArray, True)
oDoc.Update2(True)

 Thanks for the tip.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 7 of 16

Curtis_Waguespack
Consultant
Consultant

@WCrihfield , yeah list of string and chr(34) was the extra work I was thinking of. But I don't see this as discoverable by someone who encounters this for the first time,  so I think Autodesk likely needs to make a small improvement here.

 

In my real world case, I'm getting the array list from a Windows form list, so R.Mabery's suggestion works well.

 

EESignature

0 Likes
Message 8 of 16

A.Acheson
Mentor
Mentor

This would be essential to add in the API samples for SetExpressionList.. This is usually the first place to look for how to implement methods. Thanks for the forum for guiding the way.

 

If the starter is clicking get out the hammer!!

 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
Message 9 of 16

MjDeck
Autodesk
Autodesk

@WCrihfield , thanks for finding the solution.

 

We require the extra quotes because, in future, we might want to add formulas for Text parameters. Then you could do operations like string concatenation and substrings by putting equations in the Parameters dialog. You wouldn't need to write an iLogic rule or other custom code.

 

So for a Text parameter, the Expression in the API is a string literal that includes the quotes. You can see this in Text parameters by themselves, even without a multivalue list.
To demonstrate, use the Parameters dialog to create a new Text parameter named Text0 in a part. Then create and run a rule with this code:

Dim partDoc As PartDocument = ThisDoc.Document
Dim text0Param As Inventor.Parameter = partDoc.ComponentDefinition.Parameters("Text0")
Logger.Info("Text0 value = {0}", text0Param.Value)
Logger.Info("Text0 expression = {0}", text0Param.Expression)

You will see that the Value is the same string that shows up in the Parameters dialog. But the Expression has double quotes around it.
(If we supported text expressions, the Expression could be something like TextA + TextB (with no quotes). That would concatenate two other Text parameters (TextA and TextB) to produce the result.)

So in code, when working with string literals, you have to provide the extra quotes. When working directly with the parameter, this might not come up because you can just set the Value instead of the Expression. But if you did want to set the Expression, you would need the extra quotes:

Dim sDoubleQuote As Char = """"(0)
text0Param.Expression = sDoubleQuote + "Other Value" + sDoubleQuote


Unfortunately, this makes it harder to use the API. We provided a pathway to add formulas for text parameters in the future, but to do that we require the extra syntax to indicate a literal string. And for now that's the only option.

I'll make sure we have a plan to add this info to the documentation.
We should also throw an error if a string without double quotes is assigned to a value in an ExpressionList.
(If you try to assign such a string directly to a Parameter.Expression, it will throw an error.)


Mike Deck
Software Developer
Autodesk, Inc.

Message 10 of 16

eugen.gutol
Contributor
Contributor

I was dealing with this issue last couple of days and for some reason google didn't bring up this thread... would've saved a lot of time.

Anyway, while trying to solve this, I was exploring the debugger and saw that manually created multivalue parameters have an additional AttributeSets and 2 AttributeSet (see print screen attached) that would be named AllowCustomValues and AllowCustomOrder compared to API created parameters. 

I was thinking the bug could come from these, kind of, doubled options and, maybe something else I couldn't see in the debug tree.

After trying the code that @WCrihfield provided (HUGE THANKS for it 🙂 ) the created parameter is also missing them, but works fine.

Message 11 of 16

WCrihfield
Mentor
Mentor

Hi @eugen.gutol.  I noticed those attributes before also, not through the VBA editor, but through iLogic inspection rule.  Seems like I saw it mentioned elsewhere on this forum at some point also.  Anyways, I just wanted to mention that, those same attributes will also show up when you create the multi-value parameter by code, if you set those two properties values through API code.  My example code above did not include setting those properties though.  I will include links to the online help area documentation of those two properties below, for reference.

ExpressionList.AllowCustomValues 

ExpressionList.CustomOrder

We would normally include 2 extra lines in our code, right after where we use the 'SetExpressionList method, where we could set the values of those two properties.  If we include setting those properties in our code for creating the multi-value UserParameter, then those attributes will get created also, just like the manual process does.  Although, it does seem like I had to set the CustomOrder property value before setting the AllowCustomValues order, because in my testing, I set them both to True in the opposite order, and the AllowCustomValues remained False afterwards, for some reason.  But when I erased the parameter, then switched the order of setting those two properties, then both got set to True properly.  Not sure if that behavior was just a fluke (temporary mistake), or a real issue though.  It seems to me that one of those properties (custom order I think) only became available in one of the last coupe updates of Inventor, but I could be wrong.

Update:  AllowCustomValues was added in 2021, while CustomOrder was added in 2023.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 12 of 16

eugen.gutol
Contributor
Contributor

Hi All,

Back to this topic 🙂

I'm trying to create a list of Content Center parts in an ascending order and feed it to a parameter. I'm using LINQ for this. It should create an Array which later can be fed straight into a parameter using SetExpressionList, but I get "Unable to cast object of type 'System.Object[]' to type 'System.String'." on the line that sends the list into parameter. 

 

Here's the code:

Dim hexhead_fam As ContentTreeViewNode = ThisApplication.ContentCenter.TreeViewTopNode.ChildNodes.Item("Fasteners").ChildNodes.Item("Bolts").ChildNodes.Item("Hex Head")
Dim randomstr As Parameter = ThisApplication.ActiveDocument.ComponentDefinition.Parameters.UserParameters.Item("random_string")
Dim fam_names = (From fm In hexhead_fam.Families
				Order By fm.DisplayName Ascending
				Select Chr(34) & fm.DisplayName & Chr(34)).ToArray
For Each fam In fam_names
	Logger.Debug("fam: " & fam)
Next
randomstr.ExpressionList.ClearAll()
randomstr.ExpressionList.SetExpressionList(fam_names)

if I add another List of string variable and feed it data using For Each loop ...

Dim test as New List(Of String)

For each val in fam_names

      test.Add(val)

Next

randomstr.ExpressionList.SetExpressionList(test.ToArray)

Then this works without issues. Seems very strange that LINQ list is an Object not an Array.

Did you have to deal with something like this ? Can the part with new variable be omitted?

0 Likes
Message 13 of 16

WCrihfield
Mentor
Mentor

Hi @eugen.gutol.  I think you may be missing a step in your Linq line(s) of code.  The ContentTreeViewNode.Families property returns an Inventor.ContentFamiliesEnumerator object.  You may need to use the '.OfType()' method, or its '.Cast() method from that object, to convert it into an IEnumerable(Of Inventor.ContentFamily) first.  Then continue with the OrderBy() method after that step.  This is fairly common issue when dealing with native Inventor objects.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 14 of 16

MjDeck
Autodesk
Autodesk
Accepted solution

It will work if you explicitly convert the objects being selected to String. The system must know that they're strings when it does the concatenation. But then it converts them to Object. You can convert them back by changing the line:

Select Chr(34) & fm.DisplayName & Chr(34)).ToArray

to

Select Convert.ToString(Chr(34) & fm.DisplayName & Chr(34))).ToArray()

Mike Deck
Software Developer
Autodesk, Inc.

Message 15 of 16

eugen.gutol
Contributor
Contributor

@MjDeck & @WCrihfield Huge thanks, it works !!!

I still have lots to learn 🙂

0 Likes
Message 16 of 16

JBerns
Advisor
Advisor

@WCrihfield (Wesley),

 

After a couple of days of working on my external rule that uses API, I finally found your solution to updating multivalue text parameters. DoubleQuotes - who knew?

As was stated above, the SetExpressionList help page needs more info, or better yet, examples.

This solution would get my vote.

Thanks, Wesley!

 

Regards,

Jerry

-----------------------------------------------------------------------------------------
CAD Administrator
Using AutoCAD & Inventor 2025
Autodesk Certified Instructor
Autodesk Inventor 2020 Certified Professional
Autodesk AutoCAD 2017 Certified Professional
0 Likes