Checking for component in assembly

Checking for component in assembly

Thomas.Long
Advocate Advocate
2,229 Views
5 Replies
Message 1 of 6

Checking for component in assembly

Thomas.Long
Advocate
Advocate

I have a macro to place a part into the assembly. The problem is that while it works, it seems to skip past it and not wait for user input. So I am attempting to write a code into my program to check for the existence of the part and simply loop the code until the part is actually placed. Unfortunately I'm not great at coding in inventor and I'm getting some of the nomenclature wrong it seems.

 

This is the code for my check function

 

SyntaxEditor Code Snippet

Function CompExist(sName) As Boolean
    
    'Declaring Parameters
    
    Dim blTag As Boolean
    blTag = False
    
    Dim oOcc As ComponentOccurrence 
     
    Dim oDoc As AssemblyDocument
    oDoc = ThisDoc.Document

    Dim oCompDef As AssemblyComponentDefinition
    oCompDef = oDoc.ComponentDefinition

    Dim Occurrences As ComponentOccurrences
    
    ' Iterate through all of the occurrence in this collection.  This 
    ' represents the occurrences at the top level of an assembly.

    Dim i As Integer

   
    For i = 1 To oCompDef.ComponentDefinition.ComponentOccurrences(i).Name
    
        If oCompDef.ComponentDefinition.ComponentOccurrences(i).Name = sName Then
        blTag = True
        
        End If
        
    Next
    
    CompExist = blTag
    
End Function

 My error seems to come from the for loop, where I can't quite get the naming correct for iterating through all of the components. I keep getting the error "Public member 'ComponentDefinition' on type 'AssemblyComponentDefinition' not found."

 


In case you had any suggestions for implementing a wait code directly into the component placement macro, here is the code for it.

Public Sub Place_Part()

' Get the command manager.
Dim oCommandMgr As CommandManager
Set oCommandMgr = ThisApplication.CommandManager

 

 

' Post the filename.
Call oCommandMgr.PostPrivateEvent(kFileNameEvent, _
"N:\Mechpart\TLONG\Reference Materials\C15.ipt")

 

 

' Get control definition for the place component command.
Dim oControlDef As ControlDefinition
Set oControlDef = oCommandMgr.ControlDefinitions.Item( _
"AssemblyPlaceComponentCmd")

 

 

' Execute the command.
Call oControlDef.Execute

End Sub

 

Thank you in advance for your help.

0 Likes
Accepted solutions (1)
2,230 Views
5 Replies
Replies (5)
Message 2 of 6

Anonymous
Not applicable

Thomas,

 

I am a bit confused by what you mean when you say, "check for the existence of the part and simply loop the code until the part is actually placed."

 

My assumption is that you are trying to place a part into an assembly and have the code check whether or not the part already exists inside of the assembly before placing the part? Do you want some sort of pop-up message allowing the user to select Yes/No indicating whether to place the part or exit the script?

0 Likes
Message 3 of 6

Thomas.Long
Advocate
Advocate

Apologies, I was unclear at the time. I call a visual basic command to input the part into the assembly. However, it doesn't specify location so you have to click yourself to place the part.

 

The problem with this is that my program then continues without waiting for user input and errors out upon trying to feed information to a part that does not exist in the assembly, since the computer runs through it faster than the user can actually click to insert the part.

 

So what I'm trying to find a way to do is to force the computer to wait for input from the user or to loop in that area until the part exists inside of the assembly so that it doesn't error out because its trying to alter parameters in a part that isn't in the assembly.

0 Likes
Message 4 of 6

Thomas.Long
Advocate
Advocate

I did get the check for the component working, but the overall code didn't function as I hoped so its worthless anyways. Any kind of wait command I use ends up eating all the processing power allocated so I can't enter the component or else uses the Thread.Sleep visual basic command, which pretty much does the same thing. 

So I'm back to square one, telling the computer to wait until the component is found.

0 Likes
Message 5 of 6

Anonymous
Not applicable
Accepted solution

Thomas,

 

Instead of using the CommandManager, you could use the Occurrences.Add method in which you would specify the file path and a matrix to locate the component.

 

Some things I noticed in your code:

 

  • VBA requires the use of "Set" when assigning objects to variables. Since the active document is an object you would have to use "Set". Same would apply when getting a reference to the Component Definition.

 

  • There is no ThisDoc in the Inventor API, so getting the reference to the active document would look like this:

 

Set oDoc = ThisApplication.ActiveDocument

 

 

  • The component occurrence name is different than the filename. Component occurrences are appended with a colon and a number to indicate the numbered instance of that specific component. Say you have two instances of PartA.ipt in your assembly. Their corresponding component occurrence names would be "PartA:1" and "PartA:2".
    So instead of comparing the filename to the component occurrence name, you would have to get the compare the two filenames. To make the code even more robust, you could compare the two file paths in case you had two parts with the same filename but located in different directories (e.g. C:/PartA and D:PartA).

 

  • In your main subroutine, you will have to get the assembly object and in your function you are getting the object again. To optimize performance, you could pass the assembly object to the function By Ref which would eliminate having to get the reference again. You probably wouldn't notice a difference in performance on something this small, but might be useful for a more complex application.

 

 

  • Instead of using indices (i=1,2,3), you could simply the code by using a "For Each" loop to look at each component occurrence in the assembly.

 

The last two comments are necessary to implement for functionality, just my 2 cents. Here is the code I came up with. Let me know if this helps.

 

Public Sub Place_Part()

Dim oApp As Application
Set oApp = ThisApplication

' if active document isn't an assembly  then exit
If Not TypeOf oApp.ActiveDocument Is AssemblyDocument Then Exit Sub

Dim oDoc As AssemblyDocument
Set oDoc = oApp.ActiveDocument

' define filepath
Dim sFilePath As String
sFilePath = "N:\Mechpart\TLONG\Reference Materials\C15.ipt"

Dim oOccs As ComponentOccurrences
Set oOccs = oDoc.ComponentDefinition.Occurrences

' Set a reference to the transient geometry object.
Dim oTG As TransientGeometry
Set oTG = oApp.TransientGeometry

' Create a matrix.  A new matrix is initialized with an identity matrix.
Dim oMatrix As Matrix
Set oMatrix = oTG.CreateMatrix

' check if file already exists in assembly
If CompExist(oDoc, sFilePath) Then
    ans = MsgBox("Component already exists within assembly. Place component anyway?", vbYesNo)
    
    If ans = vbYes Then
        Call oOccs.Add(sFilePath, oMatrix)
    Else
        Exit Sub
    End If

Else
    Call oOccs.Add(sFilePath, oMatrix)
End If
    
End Sub
Function CompExist(ByRef oAssy As Inventor.AssemblyDocument, sFilePath As String) As Boolean
    
    Dim oOcc As ComponentOccurrence

    Dim oCompDef As AssemblyComponentDefinition
    Set oCompDef = oAssy.ComponentDefinition
    
    ' Iterate through all of the occurrence in this collection.  This
    ' represents the occurrences at the top level of an assembly.
    For Each oOcc In oCompDef.Occurrences
        ' get filepath of occurrence
        sOccFilePath = oOcc.Definition.Document.FullFileName
        If sOccFilePath = sFilePath Then
            CompExist = True
            Exit Function
        End If
    Next oOcc
    
End Function   

 

Message 6 of 6

Thomas.Long
Advocate
Advocate

Thanks! The program is actually adding the component on its own now immediately so I don't even need the CompExist function anymore, so I took that little bit out, but the program itself is adding parts flawlessly. I ran into that Occurrences.Add method myself a little while back but nothing I could do would make it work so I gave up and went to the commandmanager add function that I was using there.

 

Yours works perfectly so thank you!

Btw I ended up with this for my CompExist Function, so we were actually pretty close looks like lol

SyntaxEditor Code Snippet

Function CompExist(sName) As Boolean
    
    'Declaring Parameters
    
    'Set boolean for component existence to false
    Dim blTag As Boolean
    blTag = False
    
    'Set Active Assembly
    Dim oAsmDoc As AssemblyDocument
    oAsmDoc = ThisApplication.ActiveDocument
    
    'Assembly definition 
    Dim oAsmDef As AssemblyComponentDefinition
    oAsmDef = oAsmDoc.ComponentDefinition
    
    'Component definition
    Dim oOcc As ComponentOccurrence 

    'Get all leaf occurrences of the assembly
    'Leaf occurrences do not include components inside of subassemblies, only components in the top level assembly
    Dim oLeafOccs As ComponentOccurrencesEnumerator
    oLeafOccs = oAsmDef.Occurrences.AllLeafOccurrences
    
    
    ' Iterate through all of the occurrence in this collection.  This 
    ' represents the occurrences at the top level of an assembly.
  
    For Each oOcc In oLeafOccs
    
        If oOcc.Name = sName Then
        blTag = True
        
        End If
        
    Next
    
    CompExist = blTag
    
End Function


 

0 Likes