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: 

VBA having issues with single level assembly

2 REPLIES 2
Reply
Message 1 of 3
mslosar
6008 Views, 2 Replies

VBA having issues with single level assembly

Probably not the best title, but here goes the explanation.

 

I have a VBA macro that uses the sample code in inventor that basically cycles through an assembly and allows you to pick which items you want to add to a list that will eventually get exported to an excel file.

 

I've run this on a multi-level assembly and it works great. I have about 10 assemblies in the main file, most have sub-assemblies, and there are nuts/bolts and even virtual parts in the top level and it works just fine. no problems at all.

 

I was trying to show someone how to use it today and it failed. I couldn't figure out why. I tried running it on my machine and it worked on the main assembly i'd been using, but when i went down to a single assembly - it gave me errors. To be fair, it's given me the error on a couple assemblies with just one sub-assembly as well, but i'm at a loss to explain why.

 

The second portion (QueryBomRowProperties) doesn't seem to generate any text when you click YES on these files.

 

You run the macro and it'll ask you if you want to do just the top level of the assembly or go recursively through the whole thing. Then it prompts you part by part to see what you want to add. It's supposed to simply create a text string and then add a line to it every time you say yes. It's just that i'm getting some assemblies that generate no text. If I click yes 8 times, it's giving me 8 blank lines. Any idea why it would generate blanks likes when every piece gives it's full information in the dialog to ask you if you want to add it or not? I have no idea why it works on large assemblies with many subs, but not a basic piece. What am I missing here?

 

Dim MyCount As Integer
Dim SL_Text As String

Public Sub CreateNewShiplist()
    ' Set a reference to the assembly document.
    ' This assumes an assembly document is active.
    Dim oDoc As AssemblyDocument
    Set oDoc = ThisApplication.ActiveDocument

   ' Make sure that the structured view is enabled.
    Dim TopLevelOnly As Boolean
    
    If MsgBox("Do you want create a shipping list just the top level assembly?", vbYesNo) = vbYes Then
    TopLevelOnly = True
    Else
    TopLevelOnly = False
    End If
   
   ' Set a reference to the BOM
    Dim oBOM As BOM
    Set oBOM = oDoc.ComponentDefinition.BOM
    
    ' Set to do correct levels
    If TopLevelOnly Then
        oBOM.StructuredViewFirstLevelOnly = True
        Else
        oBOM.StructuredViewFirstLevelOnly = False
    End If
    
    oBOM.StructuredViewEnabled = True
              
    
    'Set a reference to the "Structured" BOMView
    Dim oBOMView As BOMView
    Set oBOMView = oBOM.BOMViews.Item("Structured")
        
    'Initialize the tab for ItemNumber
    Dim ItemTab As Long
    ItemTab = -3
    MyCount = 0
    SL_Text = ""
    Call QueryBOMRowProperties(oBOMView.BOMRows, ItemTab) ' for future reference - once the called function completes itself completely it comes back and continues with the next line from here
    Debug.Print SL_Text
    CreateShiplist (SL_Text)

End Sub

Private Sub QueryBOMRowProperties(oBOMRows As BOMRowsEnumerator, ItemTab As Long)
    Dim PartInfo As String
    Dim AddBox As Boolean
    AddBox = False
        
    ItemTab = ItemTab + 3
    ' Iterate through the contents of the BOM Rows.
    Dim i As Long
    For i = 1 To oBOMRows.Count
        ' Get the current row.
        Dim oRow As BOMRow
        Set oRow = oBOMRows.Item(i)
        
        'Set a reference to the primary ComponentDefinition of the row
        Dim oCompDef As ComponentDefinition
        Set oCompDef = oRow.ComponentDefinitions.Item(1)

        Dim oPartNumProperty As Property
        Dim oDescripProperty As Property
        Dim oTagProperty As Property
        
        If TypeOf oCompDef Is VirtualComponentDefinition Then
            'Get the file property that contains the "Part Number"
            'The file property is obtained from the virtual component definition
            Set oPartNumProperty = oCompDef.PropertySets _
                .Item("Design Tracking Properties").Item("Part Number")

            'Get the file property that contains the "Description"
            Set oDescripProperty = oCompDef.PropertySets _
                .Item("Design Tracking Properties").Item("Description")
                            
            On Error Resume Next
            Set oTagProperty = oCompDef.PropertySets _
                .Item("User Defined Properties").Item("TAG_NO")
                
            
            PartInfo = "Part Number:     " & oPartNumProperty.Value & vbCrLf
            PartInfo = PartInfo & "       Mark No:     " & oTagProperty.Value & vbCrLf
            PartInfo = PartInfo & "  Description:     " & oDescripProperty.Value & vbCrLf
            PartInfo = PartInfo & "                Qty:     " & oRow.ItemQuantity
                                   
            If MsgBox("Do you want to add the following part to the Ship List?" & vbCrLf & vbCrLf & PartInfo, vbYesNo) = vbYes Then
                AddBox = True
                'Exit Sub
                Else
                AddBox = False
            End If
           
            If AddBox = True Then
               'If Len(oTagProperty.Value) > 0 Then
                
                   Debug.Print Tab(0); oTagProperty.Value; Tab(20); oDescripProperty.Value; Tab(90); oPartNumProperty.Value; Tab(110); oRow.ItemQuantity; Tab(120); MyCount;
                    
                    SL_Text = SL_Text & oTagProperty.Value & "|" & oDescripProperty.Value & "|" & oPartNumProperty.Value & "|" & oRow.ItemQuantity & vbCrLf
                 
                End If
            
            Else
                
            'Get the file property that contains the "Part Number"
            'The file property is obtained from the parent
            'document of the associated ComponentDefinition.
            Set oPartNumProperty = oCompDef.Document.PropertySets _
                .Item("Design Tracking Properties").Item("Part Number")

            'Get the file property that contains the "Description"
            Set oDescripProperty = oCompDef.Document.PropertySets _
                .Item("Design Tracking Properties").Item("Description")
            
            On Error Resume Next
           ' oTagProperty.Value = ""
            Set oTagProperty = oCompDef.Document.PropertySets _
                .Item("User Defined Properties").Item("TAG_NO")
                
            'PartInfo = oPartNumProperty.Value & Space(10) & oTagProperty.Value & Space(10) & oDescripProperty.Value
            PartInfo = "Part Number:     " & oPartNumProperty.Value & vbCrLf
            PartInfo = PartInfo & "       Mark No:     " & oTagProperty.Value & vbCrLf
            PartInfo = PartInfo & "  Description:     " & oDescripProperty.Value & vbCrLf
            PartInfo = PartInfo & "                Qty:     " & oRow.ItemQuantity
                        
            If MsgBox("Do you want to add the following part to the Ship List?" & vbCrLf & vbCrLf & PartInfo, vbYesNo) = vbYes Then
                AddBox = True
                'MsgBox "Add it"
                'Exit Sub
                Else
                AddBox = False
                'MsgBox "Don't add"
            End If
           
            If AddBox Then
                'If Len(oTagProperty.Value) > 0 Then
                
                    Debug.Print Tab(0); oTagProperty.Value; Tab(20); oDescripProperty.Value; Tab(90); oPartNumProperty.Value; Tab(110); oRow.ItemQuantity; Tab(120); MyCount;
                    'MsgBox "here"
                    SL_Text = SL_Text & oTagProperty.Value & "|" & oDescripProperty.Value & "|" & oPartNumProperty.Value & "|" & oRow.ItemQuantity & vbCrLf
                
                End If


            'Recursively iterate child rows if present.
            If Not oRow.ChildRows Is Nothing Then
                Dim CheckSA As Boolean
                    If MsgBox("Do you want to seach the following sub assembly for the Ship List?" & vbCrLf & vbCrLf & PartInfo, vbYesNo) = vbYes Then
                        Call QueryBOMRowProperties(oRow.ChildRows, ItemTab)
                    End If
            End If
        End If
    Next
    
    ItemTab = ItemTab - 3
    
    End Sub

 

2 REPLIES 2
Message 2 of 3
mslosar
in reply to: mslosar

I'm now thinking it has something to do with library parts.

 

I created a new assembly with a a few normal parts from a project and added a virtual part for good measure. No problem at all.

 

I made another assembly out of 2 library parts and a virtual part and it generates a blank response....why would it skip library parts if that's all that's present?

 

I can do a full assembly where library exist but are three levels deep and they get added just fine. What makes it different on a single assembly?

 

Update - I've made a new assembly in the following order:

 

Virtual part

3 normal project parts

 

it worked. I then added a library part. It worked. I then built a new assembly using the exact same parts in the following order:

 

library part

virtual part

3 normal project parts

 

The library and normal parts failed. Just generated blank results, but the virtual part worked. Seems as if there's a problem if a library part is first in the BOM listing because that seems to be when an assembly fails to generate a response.

 

There is not check for library part in the API code I based this on, the check is for virtual. If virtual, do this.....else, do this. Apparently a library part in the first slot causes a problem. Is this a bug?

 

Any ideas here? It's not really feasible to go through all existing assemblies to see if they have a library part in the first slot the BOM checks. I've tried moving them out of the first spot in the BOM, too. Doesn't work. Seems you'd have to delete it from the browser and re-add it. Not really something you can do if the whole assembly is made of library parts.

Message 3 of 3
mslosar
in reply to: mslosar

I've narrowed it all the way down to this line(s):

 

 

 On Error Resume Next
           Set oTagProperty = oCompDef.Document.PropertySets _
                .Item("User Defined Properties").Item("TAG_NO")

 

Apparently if the first object (ipt, iam, ipn) that the BOM exports is a library part - this part fails.

 

My understanding is that that phrasing is creating a property called oTagProperty and that i'm assigning the text from the objects TAG_NO value field to the oTagProperty.

 

I'd prefer to error check it with something like:

 

 On Error Resume Next
           Set oTagProperty = oCompDef.Document.PropertySets _
                .Item("User Defined Properties").Item("TAG_NO")
           if err.number <> 0 then
                 set oTagProperty=""  'leaves it blanks
           end if

 Seems OK in theory. Upon trying to run it that line apparently generates an error that's skipped and all subsequent lines involving the oTagProperty are skipped as well.

 

I've tried set otagproperty.value and even just otagproperty.value = "" but nothing seems to be able to set the property to a string value.

 

How do I go about setting the property oTagProperty to a string value? FWIW, there is a Dim oTagProperty as Property line a bit up in the function

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report