Send parameters to specific assemblies

Send parameters to specific assemblies

SharkDesign
Mentor Mentor
1,695 Views
15 Replies
Message 1 of 16

Send parameters to specific assemblies

SharkDesign
Mentor
Mentor

I'm using the following code which sends certain parameters down to every part. 

My main assembly is made up of 4 separate assemblies and I don't need to send all parameters to each assembly. 

For instance, some will go to all parts in asm 1, and different ones need to go to all parts in asm 2 etc.

Is there a way to specify which assemblies to send it to rather than sending it to absolutely everything. 

This just takes ages and thought it would streamline the process.

 

Sub Main()
Dim oAsmDoc As AssemblyDocument 
oAsmDoc = ThisApplication.ActiveDocument  
Call Iterate(oAsmDoc.ComponentDefinition.Occurrences, 1)
End Sub 

Private Sub Iterate(Occurrences As ComponentOccurrences, Level As Integer) 
'Iterate through Assembly

Dim oOcc As ComponentOccurrence 
For Each oOcc In Occurrences 

'Find Parts in Assembly
Dim Part As String
Part = oOcc.Name

On Error Resume Next
Parameter(Part, "XXX") = XXX 
Parameter(Part, "yyy") = yyy etc etc etc 'Run through the sub assemblies If oOcc.DefinitionDocumentType = kAssemblyDocumentObject Then Call Iterate(oOcc.SubOccurrences, Level + 1) End If Next InventorVb.DocumentUpdate() End Sub
  Inventor Certified Professional
0 Likes
Accepted solutions (1)
1,696 Views
15 Replies
Replies (15)
Message 2 of 16

omartin
Advocate
Advocate

If you loop through, "allReferencedDocument" instead of all the occurences it would speed up your time alot, and then you may get a way with sending all the parameters but:

 

How do you know which parts/assemblies will get what parameters?

You can set an iProperty on those assemblies that will determine if parameters are sent.

and then instead of looping through all occurrences, you can have two loops:

 

one that checks the assembly for the iproperty indicating to set the parameters.

and then you loop through this assembly to set the parameters.

 

Sub Main()
Dim oasmDoc As AssemblyDocument
oasmDoc = ThisAssembly.Document

For Each tempDoc As Document In oasmDoc.AllReferencedDocuments
	If tempDoc.DocumentType = Inventor.DocumentTypeEnum.kAssemblyDocumentObject Then	
	Dim strFlag As String = ""
	
	Try		
		strFlag= iProperties.Value(tempDoc.DisplayName, "Custom", "propertyFlag")
	Catch
		strFlag = ""
	End Try		
	
	If strFlag <> "" Then
		Call Iterate(tempDoc, strFlag)
	End If		
End If	
Next
End Sub

	
Private Sub Iterate(Occurrences As AssemblyDocument, flag As String) 
	
	For Each td As Document In Occurrences.AllReferencedDocuments
									
		Select Case flag
			Case "x"		
				'On Error Resume Next 'or 
				'create the parameter? ...	
				Parameter(tempDoc.DisplayName, "XXX") = XXX
				'.
				'.						
			Case "y"				
				Parameter(tempDoc.DisplayName, "yyy") = yyy
				'.					
				'.
			End Select	
	Next
	
End Sub

 

Was my reply Helpful ? send a Kudos or accept as solution
0 Likes
Message 3 of 16

SharkDesign
Mentor
Mentor
I have 4 assemblies, bay 1 2 3 4
Parameters that start with bay 2 would go to bay 3 parameters starting with
bay 4 would go to that assembly.
Basically.you have the option to set the width of each bay and so the
parameters drive the length of parts in each bay.
  Inventor Certified Professional
0 Likes
Message 4 of 16

SharkDesign
Mentor
Mentor

I meant marked Bay 2 would go to bay2, but it won't let me edit the post.

  Inventor Certified Professional
0 Likes
Message 5 of 16

SharkDesign
Mentor
Mentor

Can't get this to work. 

I replaced TD with tempdoc which seemed to fix it, but it doesn't write any parameters at all. 

 

I'm assuming propertyFlag is the name of my custom property

strFlag= iProperties.Value(tempDoc.DisplayName, "Custom", "propertyFlag")

and  "x" is the property text inserted in the property flag iproperty. 

Case "x"

Also, does propertyFlag have to be in the iproperties of every part or just the ones I want to send the parameter to?

  Inventor Certified Professional
0 Likes
Message 6 of 16

SharkDesign
Mentor
Mentor

I'm also interested in how to modify the original code to cycle through referenced documents instead of every single part as I have used similar code elsewhere and this could speed it up. 

 

Thanks

  Inventor Certified Professional
0 Likes
Message 7 of 16

omartin
Advocate
Advocate

Yes your right the 'propertyFlag' was just an iProperty I came up with, you would need to add this iProeprty to just the assembly, you want to push paramaters down from and the x would indicate which paramter set your are dealing with, you could change this to 'bay 1, 2 etc".  so for the 'bay 2' sub assembly you would add the 'propertyFlag' iproperty and it should send the parameters to everything under this sub assembly.

 

But that was before I knew how you were deciding to send the parameters:

 

you can try with:

Class rule
Public oasmDoc As AssemblyDocument

Sub Main()
'Dim oasmDoc As AssemblyDocument
oasmDoc = ThisAssembly.Document

For Each tempDoc As Document In oasmDoc.AllReferencedDocuments		
	If tempDoc.DocumentType = Inventor.DocumentTypeEnum.kAssemblyDocumentObject Then	
		'you can add some more logic here to refine your search
		Call Iterate(tempDoc)	
	End If	
Next
End Sub


Private Sub Iterate(Occurrences As AssemblyDocument) 
	
	For Each tempDoc As Document In Occurrences.AllReferencedDocuments						
	
	On Error Resume Next 'or creta parameter?
		Select Case True			
			Case Occurrences.FullDocumentName.Contains("bay 1")		
				
				'create the parameter? ...	
				
				Parameter(tempDoc.DisplayName, "xxx") = Parameter(oasmDoc, "xxx")				
				'.
				'.						
			Case Occurrences.FullDocumentName.Contains("bay 2")						
				'Parameter(tempDoc.DisplayName, "yyy") = 45
				Parameter(tempDoc.DisplayName, "yyy") = Parameter(oasmDoc, "yyy")
				'.					
				'.
			End Select	
	Next
	
End Sub
End Class
 

The prob with the original code I don't see any checks to know which parameter sets need to be passed.

 

instead of passing all the occurrences you would pass allReferncedDocuments.

and then in your sub routine. you would need to check the parts parent assembly to see what bay it is (if you have multiple subs you would have to loop up the tree).

 

then you wouldn't need the last bit where you had loop though sub assemblies because you already checked each individual file/part

 

Was my reply Helpful ? send a Kudos or accept as solution
0 Likes
Message 8 of 16

SharkDesign
Mentor
Mentor

I get loads of errors

 

 

Public oasmDoc As AssemblyDocument

Type AssemblyDocument is not defined

 

For Each tempDoc As Document In oasmDoc.AllReferencedDocuments

 

'ThisAssembly' is not accessible in this context because it is a 'Friend' (no idea what that means but I thought it was amusing)

 

 

oasmDoc = ThisAssembly.Document

 

Type 'Documnet' is not defined.

 

Private Sub Iterate(Occurrences As AssemblyDocument) 

Type AssemblyDocument is not defined

 

For Each tempDoc As Document In Occurrences.AllReferencedDocuments

Type 'Document' is not defined

  Inventor Certified Professional
0 Likes
Message 9 of 16

omartin
Advocate
Advocate

I made oasmDoc a global variable so you have to wrap the whole thing in a class see the first few lines:

Class rule
Public oasmDoc As AssemblyDocument

 

Sub Main()
'Dim oasmDoc As AssemblyDocument
oasmDoc = ThisAssembly.Document

 

Also I found using the display name for setting the parameter is not that consistent you can change:

Parameter(tempDoc.DisplayName, "XXX") ...

to:

Dim filename As String = IO.Path.GetFileName(oOcc.FullDocumentName)
Parameter(filename, "xxx")...

 

Also I was thinking about it, you could still use you original code, if you simply want to send all the parameters, without checking what bay it is in:

Sub Main()
Dim oAsmDoc As AssemblyDocument 
oAsmDoc = ThisApplication.ActiveDocument  
Call Iterate(oAsmDoc)
End Sub 

Private Sub Iterate(Occurrences As AssemblyDocument)', Level As Integer) 
'Iterate through Assembly

Dim oOcc As Document 
For Each oOcc In Occurrences.allReferencedDocuments 
If oOcc.DocumentType = Inventor.DocumentTypeEnum.kPartDocumentObject Then
'Find Parts in Assembly
'Dim Part As String
'Part = oOcc.Name

	On Error Resume Next

	Dim filename As String = IO.Path.GetFileName(oOcc.FullDocumentName)	
	
	'Parameter(Occurrences,"xxx") these are the parameters from your top assembly
	Parameter(filename,"xxx") = Parameter(Occurrences,"xxx") 
	Parameter(filename,"yyy") = Parameter(Occurrences,"yyy") 

''Run through the sub assemblies 
'If oOcc.DefinitionDocumentType = kAssemblyDocumentObject Then
'Call Iterate(oOcc.SubOccurrences, Level + 1) 
'End If 
End If

Next 

InventorVb.DocumentUpdate()
End Sub

 

Was my reply Helpful ? send a Kudos or accept as solution
0 Likes
Message 10 of 16

SharkDesign
Mentor
Mentor
Yeh I copied the global bit.
When it didn't work I just copied your entire code in and it didn't like
it.

  Inventor Certified Professional
0 Likes
Message 11 of 16

omartin
Advocate
Advocate

hmmm you can try to declare it as inventor.assemblydocument

Was my reply Helpful ? send a Kudos or accept as solution
0 Likes
Message 12 of 16

JelteDeJong
Mentor
Mentor

hi,

maby this code helps. it creates a dictonary of all parameters in the main assembly. then it creates a list with all the unique part files. it loops over that list and opens all part documents. In those documents for each parameter is checked if that parameter is also avalible in the  dictonary (of parameters in the main assembly) if that is true then the value/expresion is copyed to the part files parameter.

conclusion:

parts will only be checked 1 time for parameters that are both in the main assembly and in the subassemblys. only thos parameters are copyed.

Sub Main()
    Dim doc As AssemblyDocument = ThisApplication.ActiveDocument

    Dim mainParameterList As Dictionary(Of String, UserParameter) = New Dictionary(Of String, UserParameter)()
    For Each Parameter As UserParameter In doc.ComponentDefinition.Parameters.UserParameters
        mainParameterList.Add(Parameter.Name, Parameter)
    Next
	
	Dim FileNameList As List(Of String) = createPartsList(doc)
    For Each fullFileName As String In FileNameList

        Dim pDoc As PartDocument = ThisApplication.Documents.Open(fullFileName, False)
        For Each Parameter As UserParameter In pDoc.ComponentDefinition.Parameters.UserParameters
            If (mainParameterList.ContainsKey(Parameter.Name)) Then
                Parameter.Expression = mainParameterList(Parameter.Name).Expression
                MsgBox(String.Format("Parameter '{0}' is updated to '{1}' in document: {2}",
                                     Parameter.Name,
                                     Parameter.Expression,
                                     pDoc.DisplayName))
            End If
        Next
        pDoc.Close(True)
    Next
End Sub

Function createPartsList(doc As AssemblyDocument) As List(Of String)
    Dim newList As List(Of String) = New List(Of String)()

    For Each oOcc As Document In doc.ReferencedDocuments ' .ComponentDefinition.Occurrences
        If (oOcc.DocumentType = DocumentTypeEnum.kPartDocumentObject) Then
            Dim fullFileName = oOcc.FullFileName
            If (newList.Contains(fullFileName) = False) Then
                newList.Add(fullFileName)
            End If
        ElseIf (oOcc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject) Then
            For Each fullFileName As String In createPartsList(oOcc)
                If (newList.Contains(fullFileName) = False) Then
                    newList.Add(fullFileName)
                End If
            Next
        End If
    Next
    Return newList
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 13 of 16

SharkDesign
Mentor
Mentor

@omartin wrote:

hmmm you can try to declare it as inventor.assemblydocument


I then get the error "Type 'Inventor.AssemblyDocument' is not defined."

  Inventor Certified Professional
0 Likes
Message 14 of 16

SharkDesign
Mentor
Mentor

This seems to work quite well, but it only writes to part files.

Is there a way to push this to the parameters of the sub assembly as well?

 

Thank you

  Inventor Certified Professional
0 Likes
Message 15 of 16

JelteDeJong
Mentor
Mentor
Accepted solution

hi,

i updated the code. it now also pushes parameters to sub-assemblys.

Sub Main()
        Dim doc As AssemblyDocument = ThisDoc.Document

        Dim mainParameterList As Dictionary(Of String, UserParameter) = New Dictionary(Of String, UserParameter)()
        For Each Parameter As UserParameter In doc.ComponentDefinition.Parameters.UserParameters
            mainParameterList.Add(Parameter.Name, Parameter)
        Next

        Dim fileList As List(Of String) = createPartsList(doc)
        For Each fullFileName As String In fileList
            Dim oDoc As Document = ThisApplication.Documents.Open(fullFileName, False)
            Dim docParameters As UserParameters = Nothing
            If (oDoc.DocumentType = DocumentTypeEnum.kPartDocumentObject) Then
                Dim pDoc As PartDocument = oDoc
                docParameters = pDoc.ComponentDefinition.Parameters.UserParameters
            ElseIf (oDoc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject) Then
                Dim aDoc As AssemblyDocument = oDoc
                docParameters = aDoc.ComponentDefinition.Parameters.UserParameters
            End If


            For Each Parameter As UserParameter In docParameters
                If (mainParameterList.ContainsKey(Parameter.Name)) Then
                    Parameter.Expression = mainParameterList(Parameter.Name).Expression
                    MsgBox(String.Format("Parameter '{0}' is updated to '{1}' in document: {2}",
                                         Parameter.Name,
                                         Parameter.Expression,
                                         oDoc.DisplayName))
                End If
            Next
            oDoc.Close(True)
        Next
    End Sub

    Function createPartsList(doc As AssemblyDocument) As List(Of String)
        Dim newList As List(Of String) = New List(Of String)()

        For Each oOcc As Document In doc.ReferencedDocuments ' .ComponentDefinition.Occurrences
            Dim fullFileName = oOcc.FullFileName
            If (oOcc.DocumentType = DocumentTypeEnum.kPartDocumentObject) Then
                If (newList.Contains(fullFileName) = False) Then
                    newList.Add(fullFileName)
                End If
            ElseIf (oOcc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject) Then
                For Each FileName As String In createPartsList(oOcc)
                    If (newList.Contains(fullFileName) = False) Then
                        newList.Add(fullFileName)
                    End If
                Next
                If (newList.Contains(fullFileName) = False) Then
                    newList.Add(fullFileName)
                End If
            End If
        Next
        Return newList
    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

0 Likes
Message 16 of 16

SharkDesign
Mentor
Mentor

It bloody works!!!

Thank you so much. 

Wish I knew how to do it myself like...

  Inventor Certified Professional
0 Likes