I have a very simple assembly with three parts. I have a form set up that can drive the depth, height and length. I then have a rule (that I copied from another user, shown below) that will push those numbers to the other parts and drive their sizes. I also have a number that drives the location of a hole from the left side of the part. This all works awesome and I can enter the numbers and everything updates properly (picture).
There is a pipe coupling beneath the hole. When I add a new rule that drives the model state to turn off the hole and the coupling and then add a multi-value parameter to add the "Yes/No" button to the form, the original rule to push the parameters to the parts has an error (specifically line 55). From my (very limited) understanding/testing, I believe the multi-value parameter is confusing it, as the ilogic doesn't know how to push that to the other parts. I am not sure if there is a way to exclude that parameter or if there is another way of doing what I want. I am quite a novice when it comes to the ilogic stuff... so I am doing a lot of staring and head scratching.
Public Sub Main()
CopyUserParams()
End Sub
Private Sub CopyUserParams()
If ThisDoc.Document.DocumentType <> Inventor.DocumentTypeEnum.kAssemblyDocumentObject Then
MsgBox("The active document must be an assembly.")
Return
End If
Dim asmDoc As Inventor.AssemblyDocument = ThisDoc.Document
For Each refDoc As Inventor.Document In asmDoc.AllReferencedDocuments
' Look for part documents.
If refDoc.DocumentType = Inventor.DocumentTypeEnum.kPartDocumentObject Then
Dim partDoc As Inventor.PartDocument = refDoc
Dim refDocUserParams As UserParameters = partDoc.ComponentDefinition.Parameters.UserParameters
' Add the assembly parameters to the part.
For Each asmUserParam As UserParameter In asmDoc.ComponentDefinition.Parameters.UserParameters
' Check to see if the parameter already exists.
Dim checkParam As UserParameter = Nothing
Try
checkParam = refDocUserParams.Item(asmUserParam.Name)
Catch ex As Exception
checkParam = Nothing
End Try
If checkParam Is Nothing Then
' Create the missing parameter.
refDocUserParams.AddByExpression(asmUserParam.Name, asmUserParam.Expression, asmUserParam.Units)
Else
' Update the value of the existing parameter.
checkParam.Expression = asmUserParam.Expression
End If
Next
End If
Next
iLogicVb.UpdateWhenDone = True
End Sub
Hi @tanguayZKGEL. Have you considered changing the multi-value parameter, which just contains "Yes" & "No" to a Boolean type parameter (True/False). It seems to me like that would simplify things a bit. Then instead of a drop-down list containing either the text "Yes" or "No", you could have a simple checkbox there in your form, which would be easier to use, and simpler to copy.
If you need to keep it as a text type, multi-value parameter, then you will need to add more code to your existing code for copying any multi-value parameters it encounters. The Parameter or UserParameter objects have a property called "ExpressionList", which will return an ExpressionList object, which you can check the Count property of, to see if there is more than one expression for the parameter. If there is, then you know you need to use a deeper block of code to copy its expressions over too. You can use the ExpressionList object's ExpressionList.GetExpressionList() method to get 'Array of String' from the source parameter, then access the ExpressionList of the target parameter, and use its ExpressionList.SetExpressionList() method to set that 'Array of String' you got from the source to the target.
Wesley Crihfield
(Not an Autodesk Employee)
This is not the solution, but I'm seeing different behviour between Inv2023.2 (beta version) and Inv2022.3.2. (Which is your installed update version?)
Could you please just add this snippet at line 28 and let me know if it works?
Dim prtCmpDef As PartComponentDefinition = partDoc.ComponentDefinition If prtCmpDef.IsModelStateMember Then partDoc = prtCmpDef.FactoryDocument End If
Here is a slightly modified version of your code, that I have added in both my earlier suggestion, and that of @CattabianiI , and added an extra couple lines in there for possibly using the iLogic shortcut snippet 'MultiValue' to help out, but left those two lines commented out for now. Take a look at the lines of code I added in there around that point. If creating the parameter using the AddByExpression method will not work for you, we may have to use the AddByValue method first, then try transferring its Expression later.
Public Sub Main()
CopyUserParams()
End Sub
Private Sub CopyUserParams()
If ThisDoc.Document.DocumentType <> Inventor.DocumentTypeEnum.kAssemblyDocumentObject Then
MsgBox("The active document must be an assembly.")
Return
End If
Dim asmDoc As Inventor.AssemblyDocument = ThisDoc.Document
Dim asmUserParams As UserParameters = asmDoc.ComponentDefinition.Parameters.UserParameters
For Each refDoc As Inventor.Document In asmDoc.AllReferencedDocuments
' Look for part documents.
If refDoc.DocumentType <> Inventor.DocumentTypeEnum.kPartDocumentObject Then Continue For
Dim partDoc As Inventor.PartDocument = refDoc
If partDoc.ComponentDefinition.IsModelStateMember Then
partDoc = partDoc.ComponentDefinition.FactoryDocument
End If
Dim refDocUserParams As UserParameters = partDoc.ComponentDefinition.Parameters.UserParameters
' Add the assembly parameters to the part.
For Each asmUserParam As UserParameter In asmUserParams
' Check to see if the parameter already exists.
Dim checkParam As UserParameter = Nothing
Try
checkParam = refDocUserParams.Item(asmUserParam.Name)
Catch ex As Exception
checkParam = Nothing
End Try
If checkParam Is Nothing Then
' Create the missing parameter.
checkParam = refDocUserParams.AddByExpression(asmUserParam.Name, asmUserParam.Expression, asmUserParam.Units)
If asmUserParam.ExpressionList.Count > 1 Then
Dim oSourceExpressions() As String = asmUserParam.ExpressionList.GetExpressionList
checkParam.ExpressionList.SetExpressionList(oSourceExpressions)
'or try using the following 2 lines:
'sRefFileName = System.IO.Path.GetFileName(refDoc.FullFileName)
'MultiValue.List(sRefFileName, checkParam.Name) = MultiValue.List(asmUserParam.Name)
End If
Else
' Update the value of the existing parameter.
checkParam.Expression = asmUserParam.Expression
End If
Next
Next
iLogicVb.UpdateWhenDone = True
End Sub
Wesley Crihfield
(Not an Autodesk Employee)
Ok, did I understand well that the part that is giving you error has model state? Could you double check that?
I've just had this idea: is maybe the parameter you're adding in the part already in the part just not as User Parameters?
You can do the check on all parameters (Dim refDocParams As Parameters = partDoc.ComponentDefinition.Parameters) and then do the modification on user parameters like you're already doing.
Other way get back to what @WCrihfield posted before.
Try this rule, I added the check if asm parameter is contained in all part's parameters (not just user parameters):
Public Sub Main() CopyUserParams() End Sub Private Sub CopyUserParams() If ThisDoc.Document.DocumentType <> Inventor.DocumentTypeEnum.kAssemblyDocumentObject Then MsgBox("The active document must be an assembly.") Return End If Dim asmDoc As Inventor.AssemblyDocument = ThisDoc.Document Dim asmUserParams As UserParameters = asmDoc.ComponentDefinition.Parameters.UserParameters For Each refDoc As Inventor.Document In asmDoc.AllReferencedDocuments ' Look for part documents. If refDoc.DocumentType <> Inventor.DocumentTypeEnum.kPartDocumentObject Then Continue For Dim partDoc As Inventor.PartDocument = refDoc If partDoc.ComponentDefinition.IsModelStateMember Then partDoc = partDoc.ComponentDefinition.FactoryDocument End If Dim refDocUserParams As UserParameters = partDoc.ComponentDefinition.Parameters.UserParameters Dim refDocParams As Parameters = partDoc.ComponentDefinition.Parameters ' Add the assembly parameters to the part. For Each asmUserParam As UserParameter In asmUserParams ' Check to see if the parameter already exists. Dim checkParam As UserParameter = Nothing Try checkParam = refDocParams.Item(asmUserParam.Name) Catch ex As Exception checkParam = Nothing End Try If checkParam Is Nothing Then ' Create the missing parameter. checkParam = refDocUserParams.AddByExpression(asmUserParam.Name, asmUserParam.Expression, asmUserParam.Units) If asmUserParam.ExpressionList.Count > 1 Then Dim oSourceExpressions() As String = asmUserParam.ExpressionList.GetExpressionList checkParam.ExpressionList.SetExpressionList(oSourceExpressions) 'or try using the following 2 lines: 'sRefFileName = System.IO.Path.GetFileName(refDoc.FullFileName) 'MultiValue.List(sRefFileName, checkParam.Name) = MultiValue.List(asmUserParam.Name) End If Else ' Update the value of the existing parameter. checkParam.Expression = asmUserParam.Expression End If Next Next iLogicVb.UpdateWhenDone = True End Sub
That did not work either. I packed up the files I am working with if that helps...
I just thought of something else that might be causing a problem right at that line where it is trying to create the new UserParameter by using the AddByExpression method. What if the 'expression' includes the name of another parameter that does not exist yet within the part, at the time that this UserParameter is being created within the part. It would not be able to compute a value, and would throw an error. We might be able to get around that error by using the AddByValue method for creating the parameter, instead of the AddByExpression method. However, even if we did it that way, then attempted to set its 'Expression' in a later line, it would just throw the error at that point instead. If this is the scenario that is messing the process up, we might have to somehow delay that one parameter's creation until the end of the process, that way any other parameters that it may be referencing within the part have already been created, or updated. Just putting my thoughts up on the chalk board for now.
Wesley Crihfield
(Not an Autodesk Employee)
Hi @tanguayZKGEL. If you just want the parameters within your parts to exactly match the parameters within your main assembly, there is another process you may be able to use, that would not necessarily need to include a bunch of complicated iLogic code. However, it will only work for numeric parameters, not for text, or boolean (True/False) type user parameters right now...as far as I know. You could 'link' your part's parameters to the assembly's parameters directly. This would sort of assume though, that you are not planning on trying to use this same exact part in other similar assemblies, which might complicate things.
To link the parameters you will need to do several things in preparation, after both the part and assembly exist, you have both of them visibly open.
Now, any changes you make to those specific parameters within the main assembly, will also change those linked values within the part, but you may have to update the part and/or assembly after changing the values to see the changes. Similarly, you could also create an Excel file that contains all the 'shared' numerical parameters, then link both the assembly and the parts to that same Excel file, as their source for those parameters, but if you do, you will only be able to edit their values from that Excel file.
Wesley Crihfield
(Not an Autodesk Employee)
No. Leaving those multi-value or boolean type parameters present within your assembly, and not linking them, should not mess up the linking process.
Wesley Crihfield
(Not an Autodesk Employee)
Just checking, but did you delete or rename any parameters that already existed in the part with those same names, before trying to link the assembly's parameters to the part? What I mean is, if your part already contains a parameter named "LENGTH", and you attempt to link your part to the assembly's parameter, which is also named "LENGTH", it will want to create a new parameter in your part named "LENGTH" (driven by the assembly), but it can't, because there is already a parameter within the part named "LENGTH", and it will not 'use' that existing one that was already in the part. I honestly have not used a 'link' like this between an assembly and its part(s) myself, even though I have linked parts to each other before, and linked Excel to parts before, so what you are saying might be true, even if your part does not already contain any parameters with the same names. I have not tried that exact situation before, because I never had the need for it before.
Wesley Crihfield
(Not an Autodesk Employee)
Can't find what you're looking for? Ask the community or share your knowledge.