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: 

Open part with iLogic

17 REPLIES 17
SOLVED
Reply
Message 1 of 18
JorisSteurs1246
4246 Views, 17 Replies

Open part with iLogic

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.

 

Tags (2)
17 REPLIES 17
Message 2 of 18
Owner2229
in reply to: JorisSteurs1246

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
Consider using "Accept as Solution" / "Kudos" if you find this helpful.
- - - - - - - - - - - - - - -
Regards,
Mike

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." - John F. Woods
Message 3 of 18
JorisSteurs1246
in reply to: Owner2229

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.

 

Message 4 of 18
Owner2229
in reply to: JorisSteurs1246

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

 

Consider using "Accept as Solution" / "Kudos" if you find this helpful.
- - - - - - - - - - - - - - -
Regards,
Mike

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." - John F. Woods
Message 5 of 18
JorisSteurs1246
in reply to: Owner2229

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

  

Message 6 of 18
Owner2229
in reply to: JorisSteurs1246

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

 

Consider using "Accept as Solution" / "Kudos" if you find this helpful.
- - - - - - - - - - - - - - -
Regards,
Mike

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." - John F. Woods
Message 7 of 18
JorisSteurs1246
in reply to: Owner2229

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'.

Message 8 of 18
Owner2229
in reply to: JorisSteurs1246

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
Consider using "Accept as Solution" / "Kudos" if you find this helpful.
- - - - - - - - - - - - - - -
Regards,
Mike

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." - John F. Woods
Message 9 of 18
JorisSteurs1246
in reply to: Owner2229

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.

Message 10 of 18
Owner2229
in reply to: JorisSteurs1246

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
Consider using "Accept as Solution" / "Kudos" if you find this helpful.
- - - - - - - - - - - - - - -
Regards,
Mike

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." - John F. Woods
Message 11 of 18
JorisSteurs1246
in reply to: Owner2229

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

Message 12 of 18
Owner2229
in reply to: JorisSteurs1246

I'm not realy sure how you have done your selection in the first place...

Consider using "Accept as Solution" / "Kudos" if you find this helpful.
- - - - - - - - - - - - - - -
Regards,
Mike

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." - John F. Woods
Message 13 of 18
JorisSteurs1246
in reply to: Owner2229

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.

 

Message 14 of 18
Owner2229
in reply to: JorisSteurs1246

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
Consider using "Accept as Solution" / "Kudos" if you find this helpful.
- - - - - - - - - - - - - - -
Regards,
Mike

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." - John F. Woods
Message 15 of 18
JorisSteurs1246
in reply to: Owner2229

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
Message 16 of 18

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 

Message 17 of 18
Owner2229
in reply to: JorisSteurs1246

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") = ""

 

Consider using "Accept as Solution" / "Kudos" if you find this helpful.
- - - - - - - - - - - - - - -
Regards,
Mike

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." - John F. Woods
Message 18 of 18
JorisSteurs1246
in reply to: Owner2229

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.

Post to forums  

Technology Administrators


Autodesk Design & Make Report