Community
Inventor Programming - iLogic, Macros, AddIns & Apprentice
Inventor iLogic, Macros, AddIns & Apprentice Forum. Share your knowledge, ask questions, and explore popular Inventor topics related to programming, creating add-ins, macros, working with the API or creating iLogic tools.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Copy user parameters from assembly to parts

10 REPLIES 10
SOLVED
Reply
Message 1 of 11
helouise
1559 Views, 10 Replies

Copy user parameters from assembly to parts

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

 

10 REPLIES 10
Message 2 of 11
bhavik4244
in reply to: helouise

@helouise 

 

it's working perfect at my end, try to tick on "Straight VB code"  and run again,

 

bhavik4244_0-1627987309595.png

 


Bhavik Suthar
Message 3 of 11
JelteDeJong
in reply to: helouise

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.

EESignature


Blog: hjalte.nl - github.com

Message 4 of 11
helouise
in reply to: JelteDeJong

@JelteDeJong 

 

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

Message 5 of 11
JelteDeJong
in reply to: helouise

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.

EESignature


Blog: hjalte.nl - github.com

Message 6 of 11
helouise
in reply to: JelteDeJong

@JelteDeJong 

 

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.

Message 7 of 11
helouise
in reply to: JelteDeJong

I'm probably being an Idiot right now but what is Kudos?
Message 8 of 11
CattabianiI
in reply to: JelteDeJong

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.

Message 9 of 11

it works smoothly,
thanks

Message 10 of 11

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

Message 11 of 11
PumaBH
in reply to: helouise

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. 

 

benWBWZL_1-1680779176327.png

 

 

 

 

benWBWZL_0-1680779067615.png

 

benWBWZL_2-1680779334176.png

 

 

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 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report