Good day,
I got this code from a Forum that @BrianEkins answered to copy all user parameter from assembly to parts in that assembly.
I added an event trigger on asm to any user parameter changes so everytime I change something everyting in the parts update as well.
Now with 2022 Model states, as soon as I add a model state to a part it gives an error: Unspecified error (Exception from HRESULT: 0x80004005 (E_FAIL))
Im starting with iLogic as I have seen it really can do wonders.
Can anyone advise me how to change code?
Thank you
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 End Sub
Solved! Go to Solution.
Solved by JelteDeJong. Go to Solution.
try this:
If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then MsgBox("The active document must be an assembly.") Return End If Dim asmDoc As AssemblyDocument = ThisDoc.Document Dim asmParams As UserParameters = asmDoc.ComponentDefinition.Parameters.UserParameters For Each refDoc As Document In asmDoc.AllReferencedDocuments If refDoc.DocumentType = Inventor.DocumentTypeEnum.kPartDocumentObject Then Dim partDoc As PartDocument = refDoc If (partDoc.ComponentDefinition.ModelStates.Count = 1) Then Dim refDocUserParams As UserParameters = partDoc.ComponentDefinition.Parameters.UserParameters For Each asmUserParam As UserParameter In asmDoc.ComponentDefinition.Parameters.UserParameters Dim checkParam As UserParameter = Nothing Try checkParam = refDocUserParams.Item(asmUserParam.Name) Catch ex As Exception checkParam = Nothing End Try If checkParam Is Nothing Then refDocUserParams.AddByExpression(asmUserParam.Name, asmUserParam.Expression, asmUserParam.Units) Else checkParam.Expression = asmUserParam.Expression End If Next Else Dim facDoc As PartDocument = partDoc.ComponentDefinition.FactoryDocument Dim modelStates As ModelStates = facDoc.ComponentDefinition.ModelStates For Each modelState As ModelState In modelStates ModelState.Activate() Dim memberDoc As PartDocument = ModelState.Document Dim memeberParams As UserParameters = facDoc.ComponentDefinition.Parameters.UserParameters For Each asmUserParam As UserParameter In asmParams Dim checkParam As UserParameter = Nothing Try checkParam = memeberParams.Item(asmUserParam.Name) Catch ex As Exception checkParam = Nothing End Try If checkParam Is Nothing Then memeberParams.AddByExpression(asmUserParam.Name, asmUserParam.Expression, asmUserParam.Units) Else checkParam.Expression = asmUserParam.Expression End If Next Next End If End If Next
I need to go now. But I can explain a bit more later if needed. Anyway, this post gave me the correct idea.
Jelte de Jong
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
Blog: hjalte.nl - github.com
Thank you for the reply I ended up using a part in assembly to control parameters from main assembly using following code and a form. (Control being the name of the part were all other parts are linked to)
Parameter("Control:1", "Length") = Length Parameter("Control:1", "Width") = Width Parameter("Control:1", "QTY") = QTY Parameter("Control:1", "Dist") = Dist Parameter("Control:1", "Hole_Size") = Hole_Size Parameter("Control:1", "Hole_Dist1") = Hole_Dist1
Dim asmDoc As AssemblyDocument = ThisApplication.ActiveDocument asmDoc.Update()
I am Starting new Assembly now and going to try your code. Thank you will let you know.
That post is Exactly where I got above code from
I found a much cleaner solution. You can find all details and explanations on my blog.
Public Sub Main() Dim asmDoc As AssemblyDocument = ThisDoc.Document Dim asmParams As UserParameters = asmDoc.ComponentDefinition.Parameters.UserParameters For Each refDoc As Document In asmDoc.AllReferencedDocuments If refDoc.DocumentType <> Inventor.DocumentTypeEnum.kPartDocumentObject Then Continue For Dim facDoc As PartDocument = GetFactoryDocument(refDoc) Dim modelStates As ModelStates = facDoc.ComponentDefinition.ModelStates For Each ModelState As ModelState In modelStates ModelState.Activate() Dim partParams As UserParameters = facDoc.ComponentDefinition.Parameters.UserParameters For Each asmUserParam As UserParameter In asmParams Try Dim checkParam As UserParameter = partParams.Item(asmUserParam.Name) checkParam.Expression = asmUserParam.Expression Catch ex As Exception partParams.AddByExpression(asmUserParam.Name, asmUserParam.Expression, asmUserParam.Units) End Try Next Next Next End Sub Public Function GetFactoryDocument(doc As Document) If (doc Is Nothing) Then Return Nothing Dim documentType As DocumentTypeEnum = doc.DocumentType If (documentType = DocumentTypeEnum.kPartDocumentObject Or documentType = DocumentTypeEnum.kAssemblyDocumentObject) Then Dim componentDefinition = doc.ComponentDefinition If (componentDefinition.IsModelStateMember) Then Return componentDefinition.FactoryDocument End If Return doc End If Return Nothing End Function
Jelte de Jong
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
Blog: hjalte.nl - github.com
Just wanted to say thank you and I know this research and post on your blog is going to help a lot of people.
People like you who makes life much easier.
hi @JelteDeJong, @helouise
let me add a thing that could help to understand model states better.
In this specific case, and in general for legacy code written in a world without model states, it's useless to loop through the model states, you're setting the same value for all model states.
Let's suppose the part doesn't have the assembly parameter you want to propagate; the first time you run the code above for the active model state (the active in the factory, not the active in the occurrence) you'll add the parameter, for the next model states you'll just set the parameter value which already is what you want!
Let's delete the model states loop then!
yes but no! because if you do that, the second time you run the code, supposing the part already has the parameter and the assembly parameter has changed, you'll set the assembly value just for the active model state (again, the active model state in the factory) and you've basically started to leveraging the model states concept: you'll get the active model state with current assembly's parameter value but the other model states with the previous value.
That was exactly the purpose of the loop you've just told me to delete!
Here's your brand new API perfectly fitting your needs: ModelStates.MemberEditScope
Instead of looping model states, set the scope to work with all members
modelStates.MemberEditScope = MemberEditScopeEnum.kEditAllMembers
Any edit done to the factory is now applied to all model states no matter what is the active one, so set or add the parameter and then switch back to the edit scope to its original value.
it works fine, unless you have a Text or yes/NO Parameter or an Unitless Param.
is there any way to Include / exclude these two Parameter Type?
thanks in Advance
I am using something similar. however mine controls the 3D sketch overall dimensions via a form. it works great without any frame generated parts. However, when you use the form with frame generated parts it has error codes.
manually, if i suppress all the parts except the 3D sketch part. change the dimensions on the form and unsuppress the other parts the update takes place for the 3D sketch. then i have to rebuild all in the manage tab for the changes to affect the frame generated parts.
Public Sub Main() ThisApplication.SilentOperation = True 'Suppress screen updates CopyUserParams() ThisApplication.SilentOperation = False 'Unsuppress screen updates ' Get a reference to the active assembly document. Dim asmDoc As Inventor.AssemblyDocument = ThisApplication.ActiveDocument ' Update the assembly document. asmDoc.Update() ' Rebuild the assembly document. asmDoc.Rebuild() End Sub Private Sub CopyUserParams() ' Check if the active document is an assembly. 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
is there a way i can achieve the rebuild all at the instance i click set parameters in the form?
i'm new to iLogic and Forms.
Kind Regards,
Ben