Change User Parameters only in first occurrence from the Top assembly.

Change User Parameters only in first occurrence from the Top assembly.

valentin_azamfirei
Participant Participant
337 Views
5 Replies
Message 1 of 6

Change User Parameters only in first occurrence from the Top assembly.

valentin_azamfirei
Participant
Participant

I have a rule that changes user parameters from the TOP assy inside component parts.

The problem is that the assembly has a lot of repetitve parts. and the rule checks for parameters inside each of the parts... 

Do you know how can i check only in the first occurence of a part?

 

Here is the code:

Sub Main()
    Dim oDoc As AssemblyDocument = ThisApplication.ActiveDocument
    Dim oCompDef As AssemblyComponentDefinition = oDoc.ComponentDefinition
    Dim oOcc_s As ComponentOccurrences = oCompDef.Occurrences
    Dim oUserParams As UserParameters = oCompDef.Parameters.UserParameters
    'look at each occurrence in the assembly
    For Each oOcc As ComponentOccurrence In oOcc_s
        'update params for each occurrence
        UpdateParam(oOcc,oUserParams)
    Next
'    iLogicVb.UpdateWhenDone = True
End Sub
Sub UpdateParam(occ As ComponentOccurrence, params As Inventor.UserParameters)

 If Component.IsActive(occ.Name) = True

    Dim oParams As Parameters = occ.Definition.Parameters
    For Each param As UserParameter In params
        Try 
        oParams(param.Name).Value = param.Value
        Catch
        End Try
    Next
    
    For Each subOcc As ComponentOccurrence In occ.SubOccurrences
        UpdateParam(subOcc, params)
    Next
 End If
 iLogicVb.UpdateWhenDone = True
End Sub
0 Likes
338 Views
5 Replies
Replies (5)
Message 2 of 6

WCrihfield
Mentor
Mentor

Hi @valentin_azamfirei.  The easiest way to do that is by iterating through either the assembly's 'ReferencedDocuments' collection (first level stuff only), or iterating through the assembly's 'AllReferencedDocuments' collection, instead of its components.  There may be 20 components referencing the same document, but only one referenced document for all of those 20 components.  Looping through the referenced documents ensures that you only interact with each one once, instead of 20 times.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 6

valentin_azamfirei
Participant
Participant

Can you help me a little(more) on this? 😄

0 Likes
Message 4 of 6

WCrihfield
Mentor
Mentor

Hi @valentin_azamfirei.  Sure.  The following is an example iLogic rule that could be ran from an assembly, that will attempt to copy only the values of the assembly's user parameters down to all of the documents being referenced by that assembly, to parameters within them with the same parameter names.  It will not attempt to create any new user parameters within any of those referenced documents.  Also keep in mind that when using AllReferencedDocuments, that will reach down through all levels through the assembly, not just the documents being referenced by top level components.  If this example were changed to using the regular ReferencedDocuments of the assembly, that would only reach the documents being referenced by the top level components, not the ones being referenced within sub assembly components below those top level components.  I am using the AllReferencedDocuments route here because your original code was using a recursive routine to step down  to lower level components , and this will have a similar effect, but be more efficient.  Each referenced document may have one or many components within one or more levels of the assembly referencing it, but that document will only be 'processed' once using this technique.

Sub Main
	If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then
		MsgBox("An Assembly Document must be active for this rule to work. Exiting.", vbCritical, "")
		Exit Sub
	End If
	Dim oADoc As AssemblyDocument = ThisDoc.Document
	Dim oAllRefDocs As DocumentsEnumerator = oADoc.AllReferencedDocuments
	If oAllRefDocs.Count = 0 Then Exit Sub
	Dim oAsmUParams As UserParameters = oADoc.ComponentDefinition.Parameters.UserParameters
	If oAsmUParams.Count = 0 Then Exit Sub
	Dim oTrans As Inventor.Transaction
	oTrans = ThisApplication.TransactionManager.StartTransaction(oADoc, "Copy UserParameters")
	For Each oRefDoc As Document In oAllRefDocs
		If oRefDoc.IsModifiable = False Then Continue For
		Dim oRefParams As UserParameters = Nothing
		Try : oRefParams = oRefDoc.ComponentDefinition.Parameters : Catch : End Try
		If oRefParams Is Nothing OrElse oRefParams.Count = 0 Then Continue For
		For Each oAsmUParam As UserParameter In oAsmUParams
			Dim oRefParam As UserParameter = Nothing
			Try
				oRefParam = oRefParams.Item(oAsmUParam.Name)
			Catch
				'Logger.Error("Parameter named '" & oAsmUParam.Name & "' not found in " & oRefDoc.FullDocumentName)
			End Try
			If oRefParam Is Nothing Then Continue For
			If oRefParam.Value <> oAsmUParam.Value Then
				Try
					oRefParam.Value = oAsmUParam.Value
				Catch
					'Logger.Error("Error updating Value of Parameter named '" & oAsmUParam.Name & "' in " & oRefDoc.FullDocumentName)
				End Try
			End If
		Next 'oAsmUParam
	Next 'oRefDoc
	oTrans.End
	If oADoc.RequiresUpdate Then oADoc.Update2(True)
	'If oADoc.Dirty Then oADoc.Save2(True)
End Sub

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
Message 5 of 6

valentin_azamfirei
Participant
Participant

Hello, 

Sorry for late reply

It's working only for the parts with parameters in the top assembly and not for the ones in subassemblies.

Tried to change the rule but with no results

0 Likes
Message 6 of 6

WCrihfield
Mentor
Mentor

Hi @valentin_azamfirei.  I am not sure why that may be happening.  The following line of code within the main loop of referenced documents in the code above could be turned into 3 lines of code, and used to monitor this situation to get a better idea of what is going on.

If oRefDoc.IsModifiable = False Then Continue For

That is the first line of code within the loop of all referenced documents.  If that document is not modifiable, then it will skip directly to the next referenced document in the loop, without trying to do anything else with the current referenced document.

 

There are multiple reasons why a referenced document might not be modifiable.  As you may know, Content Center parts and files stored in directories that are designated as a library are ReadOnly, so they will not be modifiable.  Also sometimes when you have multiple components in the same assembly that reference the same model file, but are referencing different ModelState versions of that same model file, they will be understood as a ModelState 'member', which tend to be ReadOnly.  In files with more than just the one original ModelState, there is a 'factory' and 'members', and only the 'factory' document can be edited, while the 'member' documents are ReadOnly.  If you are using Inventor 2022 or later, and your assembly contains multiple components that reference the same model file on disk, but different ModelState versions of it, then we will need to include several more lines of code in an attempt to deal with that added complication.

 

To see which documents are currently not modifiable, you could transform that single line of code mentioned above into multiple lines of code, with an added line of code in the middle for reporting which documents were not modifiable, such as a Logger.Info() line, which would write something to the iLogic Log window, like the following.

If oRefDoc.IsModifiable = False Then
	Logger.Info("The following Document was not modifiable:" & vbCrLf & oRefDoc.FullDocumentName)
	Continue For
End If

I am suggesting that you use FullDocumentName there, because it will include not only the FullFileName (path, file name, & file extension), but it will also include the name of the iPart member, iAssembly member, or ModelState member associated with that file within "<" & ">" brackets at the end, if appropriate, which is more useful/informational in this situation.

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes