I have the code below to open a part that's gets his name from a multivalue text parameter.
The partnames are collected from the assembly components.
I could not get these names with .ipt extension , so I have to add this myself as you can see in the code below.
It works but is not perfect and will fail when more than 9 the same occurrences are present in the assembly.
Next problem is that to open the file I have to define also the complete path of that file.
This is also a problem , because Inventor should be able to find the parts anywhere in the workspace... to often the code will fail otherwise.
Does anyone has any suggestions to improve the code below?
Thank you in advance
PS: don't worry about the messageboxes popping up, they are just acting as a logger for the time being
'get user input oSelection = Parameter("ActiveParts") 'catch null selection If oSelection = "" Then Return 'exit rule Else 'set parameter value Parameter("ActiveParts") = oSelection End If Dim doc As Document = ThisApplication.ActiveDocument 'provide user feedback MessageBox.Show("You selected: " & oSelection, "iLogic") NewName = Left(oSelection,(Len(oSelection)-2))' NOT GOOD!!, if more then 9 occurences in the assembly this will fail MessageBox.Show("I found variable: " & NewName , "Info") oFullFileName = (NewName & ".ipt") MessageBox.Show("I found variable: " & oFullFileName , "Info") oPath = ThisDoc.WorkspacePath() MessageBox.Show("I found variable: " & oPath , "Info") ThisDoc.Launch(oPath & "\parts\S_MountingPlates\S_MountingPlates_L\" & oFullFileName) ' NoT Good!!! location can change, 'Inventor has to search everywhere in workspace not only the given location.
Solved! Go to Solution.
Solved by Owner2229. Go to Solution.
Hi, I assume the parts you're trying to open are all placed in the assembly, right?
If so, then you can use this code below. For some operations you don't even need to open the part (like reading/changing iProperties and Parameters).
Ussage:
1) Run the rule
2) Select first component
3) Select next component and continue as long as you want
4) Press Esc to stop selecting
5) The rule will run
Sub Main() Dim oDoc As Document oDoc = ThisApplication.ActiveDocument Dim comps As ObjectCollection Dim comp As ComponentOccurrence oDoc.SelectSet.Clear comps = ThisApplication.TransientObjects.CreateObjectCollection While True comp = ThisApplication.CommandManager.Pick( SelectionFilterEnum.kAssemblyLeafOccurrenceFilter, "Select Part(s)") ' If nothing gets selected then we're done If IsNothing(comp) Then Exit While comps.Add(comp) End While ' If there are selected components we can do something If comps.count = 0 Then Exit Sub Dim aDoc As DocumentsEnumerator aDoc = oDoc.AllReferencedDocuments Dim iDoc As Document Dim cName As String Dim cTS As String Dim sTS As String Dim FNP As Long Dim cFNP As Long Dim docFN As String For Each iDoc In aDoc sTS = iDoc.FullFileName FNP = InStrRev(sTS, "\", - 1) docFN = Mid(sTS, FNP + 1, Len(sTS) - FNP) For Each comp In comps cTS = comp.Name cFNP = InStrRev(cTS, ":", - 1) cName = Left(cTS, cFNP - 1) If cName = Left(docFN, Len(docFN)-4) Then MsgBox("You have selected this part:" & vbLf & sTS) 'Here is how to set iProperties in each of the selected parts in assembly 'iProperties.Value(docFN, "Custom", "Mark") = "this part is now marked" 'Here is how to open the part 'ThisApplication.Documents.Open(sTS, True) End If Next Next oDoc.SelectSet.Clear End Sub
Hi Thanks for having a look into this.
I tried your code and it works nice , but it is not exactly what I'm trying to do here.
Yes the part that I want to open is always available in the assembly that holds the rule.
Your code lets you pick objects and open them afterwards.
My selection comes from text stored in the multivalue list .
I have multivalue list ( "partA:1","partB:1","partC:1","partD:1") that collected all active occurrences in the assembly with another rule.
So What I need to do is just get "partA:1" and open it as "partA.ipt" from where ever it might be saved in the active workspace.
Better would be if the multivalue list would collect the correct file names from every leaf occurence , but I dind't find any documentation about this.
Hi, to get the full file name from Occurence you can use this:
'Let's say we have occurence "oOcc" from AllLeafOccurences Dim aDoc As Document = oOcc.Definition.Document Dim FullFileName As String = aDoc.FullFileName
To strip "partA:1" to "partA" you can use this:
Dim text As String = "partA:1" Dim FNP As Integer = InstrRev(text, ":", -1) Dim PartName As String = Left(text, FNP - 1)
We can then make these to work together eg. as this:
Dim text As String = "partA:1"
Dim FNP0 As Integer = InstRev(text, ":", -1)
Dim NewDoc As String = Left(text, FNP0 - 1) Dim sTS As String Dim FNP As Integer Dim FName As String Dim oAsmCompDef As ComponentDefinition = ThisApplication.ActiveDocument.ComponentDefinition Dim oOcc As ComponentOccurrence For Each oOcc In oAsmCompDef.Occurrences sTS = oOcc.Name FNP = InStrRev(sTS, ":", -1) FName = Microsoft.VisualBasic.Left(sTS, FNP - 1) If oOcc.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject Then FName = FName & ".ipt" ElseIf oOcc.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then FName = FName & ".iam" End If If FName = NewDoc Then oDoc = oOcc.Definition.Document
ThisApplication.Documents.Open(oDoc, True) End If Next
I tried the code that you suggessted can't get it to work, because it handles with occurences and not with my string from the multivalue.
Maybe somethign can be done here instead,
Below is the code I use to get the occurneces name into the Multivalue parameter.
I've been trying very hard to get the full file name as a string into this parameter but no succes.
If I could populate my parameter with values like "PartA.ipt" and not "PartA:1 then the other code to open the selected file would be fairly simple.
'check this file is an assembly Dim doc As Document = ThisApplication.ActiveDocument If doc.DocumentType = kPartDocumentObject Then MessageBox.Show("This rule can only be run in an assembly file!", "ERROR") Return End If ' Get the active assembly. Dim oAsmDoc As AssemblyDocument oAsmDoc = ThisApplication.ActiveDocument ' Get the assembly component definition. Dim oAsmDef As AssemblyComponentDefinition oAsmDef = oAsmDoc.ComponentDefinition ' Get all of the leaf occurrences of the assembly. Dim oLeafOccs As ComponentOccurrencesEnumerator oLeafOccs = oAsmDef.Occurrences.AllLeafOccurrences Dim NameList As New ArrayList() 'Iterate through the occurrences And collect the name. Dim oOcc As ComponentOccurrence For Each oOcc In oLeafOccs oPartName = (oOcc.Name ) If Component.IsActive(oPartName) = True Then NameList.add(oPartName) Else End If Next oMyParameter=ThisApplication.ActiveDocument.ComponentDefinition.Parameters.UserParameters 'Setting an userParameter as text parameter Try otester = oMyParameter.Item("ActiveParts") Catch oInsulationType=oMyParameter.AddByValue("ActiveParts", "", UnitsTypeEnum.kTextUnits) 'make parameter a multivalue list parameter MultiValue.SetList("ActiveParts", "NoData1", "NoData2", "NoData3") End Try 'set list parameter to use array list MultiValue.List("ActiveParts") = NameList Dim ValuesL As Integer ValuesL = Len("ActiveParts") Parameter("CountActiveParts") = ValuesL
Alright then, here is the first rule (to populate the parameter):
' Check this file is an assembly Dim doc As Document = ThisApplication.ActiveDocument If Not doc.DocumentType = kAssemblyDocumentObject Then MessageBox.Show("This rule can only be run in an assembly file!", "ERROR") Return End If ' Get the active assembly. Dim oAsmDoc As AssemblyDocument oAsmDoc = ThisApplication.ActiveDocument ' Get the assembly component definition. Dim oAsmDef As AssemblyComponentDefinition oAsmDef = oAsmDoc.ComponentDefinition ' Get all of the leaf occurrences of the assembly. Dim oLeafOccs As ComponentOccurrencesEnumerator oLeafOccs = oAsmDef.Occurrences.AllLeafOccurrences Dim NameList As New ArrayList() ' Iterate through the occurrences And collect the name. Dim oOcc As ComponentOccurrence
Dim oPartName As String For Each oOcc In oLeafOccs oPartName = (oOcc.Name) If Component.IsActive(oPartName) = True Then
Dim FNP As Integer = InstrRev(oPartName, ":", -1)
Dim FName As String = Left(oPartName, FNP - 1)
If oOcc.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject Then
FName = FName & ".ipt"
ElseIf oOcc.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
FName = FName & ".iam"
End If
NameList.add(FName) Else End If Next oMyParameter=ThisApplication.ActiveDocument.ComponentDefinition.Parameters.UserParameters ' Setting an userParameter as text parameter Try otester = oMyParameter.Item("ActiveParts") Catch oInsulationType=oMyParameter.AddByValue("ActiveParts", "", UnitsTypeEnum.kTextUnits) ' Make parameter a multivalue list parameter MultiValue.SetList("ActiveParts", "NoData1", "NoData2", "NoData3") End Try ' Set list parameter to use array list MultiValue.List("ActiveParts") = NameList Dim ValuesL As Integer ValuesL = Len("ActiveParts") Parameter("CountActiveParts") = ValuesL
And here is your second rule (to open the parts):
' Get user input oSelection As ArrayList = Parameter("ActiveParts") ' Catch null selection If oSelection.Count = 0 Then Return ' Exit rule End If ' Go throught the selection Dim oAsmCompDef As ComponentDefinition = ThisApplication.ActiveDocument.ComponentDefinition Dim oOcc As ComponentOccurrence
Dim oDoc As Document Dim sTS As String Dim FNP As Integer Dim FName As String Dim item As String For Each oOcc In oAsmCompDef.Occurrences sTS = oOcc.Name FNP = InStrRev(sTS, ":", -1) FName = Microsoft.VisualBasic.Left(sTS, FNP - 1) If oOcc.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject Then FName = FName & ".ipt" ElseIf oOcc.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then FName = FName & ".iam" End If
For Each item in oSelection If FName = item Then oDoc = oOcc.Definition.Document ThisApplication.Documents.Open(oDoc, True) End If Next Next
Hi Mike,
The first rule works beatifull 🙂
But the second rule gives an error saying " oSelection is not declared"
i try to solve it like this by putting "Dim"
Dim oSelection As ArrayList = Parameter("ActiveParts")
But then I get the following error
Error in rule: OpenPart3, in document: S_BeamAssy_L.iam
Unable to cast object of type 'System.String' to type 'System.Collections.ArrayList'.
Ah, sorry, my fault. Here is the correction:
' Get user input Dim oSelection As ArrayList = MultiValue.List("ActiveParts") ' Catch null selection If oSelection.Count = 0 Then Return ' Exit rule End If ' Go throught the selection Dim oAsmCompDef As ComponentDefinition = ThisApplication.ActiveDocument.ComponentDefinition Dim oOcc As ComponentOccurrence Dim oDoc As Document Dim sTS As String Dim FNP As Integer Dim FName As String Dim item As String For Each oOcc In oAsmCompDef.Occurrences sTS = oOcc.Name FNP = InStrRev(sTS, ":", -1) FName = Microsoft.VisualBasic.Left(sTS, FNP - 1) If oOcc.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject Then FName = FName & ".ipt" ElseIf oOcc.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then FName = FName & ".iam" End If For Each item in oSelection If FName = item Then oDoc = oOcc.Definition.Document ThisApplication.Documents.Open(oDoc, True) End If Next Next
Did you only add " Dim" in the front?
This I tried myself but didn't work .
your latest code gives the following error.
Error in rule: OpenPart3, in document: S_BeamAssy_L.iam
Unable to cast COM object of type 'System.__ComObject' to class type 'System.String'. Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.
Hi, try this one. I have tested it and it should work. I have hightlighted the corrections for you.
' Get user input Dim oSelection As ArrayList = MultiValue.List("ActiveParts") ' Catch null selection If oSelection.Count = 0 Then Return ' Exit rule End If ' Go throught the selection Dim oAsmCompDef As ComponentDefinition = ThisApplication.ActiveDocument.ComponentDefinition Dim oOcc As ComponentOccurrence Dim oDoc As Document Dim sTS As String Dim FNP As Integer Dim FName As String Dim item As String For Each oOcc In oAsmCompDef.Occurrences sTS = oOcc.Name FNP = InStrRev(sTS, ":", -1) FName = Microsoft.VisualBasic.Left(sTS, FNP - 1) If oOcc.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject Then FName = FName & ".ipt" ElseIf oOcc.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then FName = FName & ".iam" End If For Each item In oSelection If FName = item Then oDoc = oOcc.Definition.Document ThisApplication.Documents.Open(oDoc.FullFileName, True) End If Next Next
Hi Mike
No more errors, works nice 🙂
Just that it opens every part from the array, while its was my goal to open only the selected part from the array.
I assume this is a minor change?
Joris
I'm not realy sure how you have done your selection in the first place...
Hi Mike
The multivalue parameter wil be placed on an ilogic form as a dropdown box
Under this dropdown box comes a button to trigger the rule that will open the part that is selected in the dropdown box.
I've to do so because my assembly has a big amount of suppressed parts,
so it is too difficult to search a specific part from the browser itself.
Alright then, here you go:
' Get user input Dim oSelection As String = Parameter("ActiveParts") ' Catch null selection If oSelection.Count = 0 Then Return ' Exit rule End If ' Go throught the selection Dim oAsmCompDef As ComponentDefinition = ThisApplication.ActiveDocument.ComponentDefinition Dim oOcc As ComponentOccurrence Dim oDoc As Document Dim sTS As String Dim FNP As Integer Dim FName As String For Each oOcc In oAsmCompDef.Occurrences sTS = oOcc.Name FNP = InStrRev(sTS, ":", -1) FName = Microsoft.VisualBasic.Left(sTS, FNP - 1) If oOcc.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject Then FName = FName & ".ipt" ElseIf oOcc.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then FName = FName & ".iam" End If If FName = oSelection Then oDoc = oOcc.Definition.Document ThisApplication.Documents.Open(oDoc.FullFileName, True) End If Next
The count on the oSelection string gave an error , but I've managed to make a walk around this problem.
Maybe not the most elegant solution , but anyhow 😉
Here is the working code
'check number of entries in the multi value param. Dim ValuesL As Integer ValuesL = Len("ActiveParts") ' Get user input Dim oSelection As String = Parameter("ActiveParts") ' Catch null selection or empty multi value param. If ValuesL >= 1 Then If oSelection = "" Then MessageBox.Show("No FileName found to open", "ERROR") Else End If Else MessageBox.Show("No FileName found to open", "ERROR") End If ' Go throught the selection Dim oAsmCompDef As ComponentDefinition = ThisApplication.ActiveDocument.ComponentDefinition Dim oOcc As ComponentOccurrence Dim oDoc As Document Dim sTS As String Dim FNP As Integer Dim FName As String For Each oOcc In oAsmCompDef.Occurrences sTS = oOcc.Name FNP = InStrRev(sTS, ":", -1) FName = Microsoft.VisualBasic.Left(sTS, FNP - 1) If oOcc.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject Then FName = FName & ".ipt" ElseIf oOcc.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then FName = FName & ".iam" End If If FName = oSelection Then oDoc = oOcc.Definition.Document ThisApplication.Documents.Open(oDoc.FullFileName, True) End If Next
Hi Mike,
If its OK for you to re-post the working code I came up with then i can accept your post as solution.
Anyhow its 99.5 percent your code and skill, so you definitely deserve the credits for it. 🙂
Thanks for all the effort, it is really appreciated.
Joris
Hi, maybe more like this 😉
You don't need to use the "Len("ActiveParts")" as you don't care if there are any parts in the parameter.
You only need to know if something is selected. Btw. shouldn't we clear the selection after we're done? So it won't cause any trubles when the rule is runed again.
' Get user input Dim oSelection As String = Parameter("ActiveParts") ' Catch null selection If oSelection = vbNullString Then
MessageBox.Show("No FileName found to open", "ERROR")
Return ' Exit rule End If ' Go throught the selection Dim oAsmCompDef As ComponentDefinition = ThisApplication.ActiveDocument.ComponentDefinition Dim oOcc As ComponentOccurrence Dim oDoc As Document Dim sTS As String Dim FNP As Integer Dim FName As String For Each oOcc In oAsmCompDef.Occurrences sTS = oOcc.Name FNP = InStrRev(sTS, ":", -1) FName = Microsoft.VisualBasic.Left(sTS, FNP - 1) If oOcc.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject Then FName = FName & ".ipt" ElseIf oOcc.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then FName = FName & ".iam" End If If FName = oSelection Then oDoc = oOcc.Definition.Document ThisApplication.Documents.Open(oDoc.FullFileName, True) End If Next
' Clear the selection
Parameter("ActiveParts") = ""
Hi Mike,
Yes you are correct about the selection , the way you did it is much better.
About clearing the selection I would keep this for myself as an option.
If you run the command a second time with the same selection , Inventor will just show you the window that was already open.
Also in my userform I can see still the filename of the latest file that was opened, so its a little more easy if you are cycling trough opening the parts of your assembly.
Nevertheless , again great thanks for helping me out
Joris
Can't find what you're looking for? Ask the community or share your knowledge.