Help with SDK's Using the BOM APIs API Sample - ordering

Help with SDK's Using the BOM APIs API Sample - ordering

mslosar
Advisor Advisor
1,760 Views
9 Replies
Message 1 of 10

Help with SDK's Using the BOM APIs API Sample - ordering

mslosar
Advisor
Advisor

I've written code based on this. It's pretty much verbatim.

 

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) 
    '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
    Dim Tag As String
    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")
                If Err.Number <> 0 Then
                    Tag = ""
                    Else
                    Tag = oTagProperty.Value
                End If
                                                  
            PartInfo = "Part Number:     " & oPartNumProperty.Value & vbCrLf
            PartInfo = PartInfo & "       Mark No:     " & Tag & 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
                Else
                AddBox = False
            End If
           
            If AddBox = True Then
               'If Len(oTagProperty.Value) > 0 Then
                
                   'Debug.Print Tab(0); Tag; Tab(20); oDescripProperty.Value; Tab(90); oPartNumProperty.Value; Tab(110); oRow.ItemQuantity; Tab(120); MyCount;
                    SL_Text = SL_Text & Tag & "|" & 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
            Set oTagProperty = oCompDef.Document.PropertySets _
                .Item("User Defined Properties").Item("TAG_NO")
                If Err.Number <> 0 Then
                    Tag = ""
                    Else
                    Tag = oTagProperty.Value
                End If
            
            PartInfo = "Part Number:     " & oPartNumProperty.Value & vbCrLf
            PartInfo = PartInfo & "       Mark No:     " & Tag & 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
                Else
                AddBox = False
                Exit Sub
                
            End If
           
            If AddBox Then
                    'Debug.Print Tab(0); Tag; Tab(20); oDescripProperty.Value; Tab(90); oPartNumProperty.Value; Tab(110); oRow.ItemQuantity; Tab(120); MyCount;
                    SL_Text = SL_Text & Tag & "|" & oDescripProperty.Value & "|" & oPartNumProperty.Value & "|" & oRow.ItemQuantity & vbCrLf
                    'MsgBox SL_Text
                
                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

Anyhow, it seems that when it's run, it's pulling it's order from the Model Data tab and not the Structured tab as the sample code implies that it does.

 

Is there anything that can be done to make it get the order based on the structured tab instead?

 

Thanks

Mike

0 Likes
1,761 Views
9 Replies
Replies (9)
Message 2 of 10

adam.nagy
Autodesk Support
Autodesk Support

Hi Mike,

 

It seems to work fine for me. Could you pinpoint an inaccuracy in what you are getting?

 

Also, you can easily change your code to list the Model BOM view data, and compare the text from the two.

In my case they were different - mainly because of the Phantom assemblies that were listed in case of the Model BOM view.

 

Cheers,

 

 



Adam Nagy
Autodesk Platform Services
0 Likes
Message 3 of 10

mslosar
Advisor
Advisor
I haven't had a chance to dig into yet - we're slammed at the moment, but I had a user who wasn't getting the same thing as the Structured tab.

I'm not sure what all is taken into account, but I do know for a fact he had phantom assemblies, virtual parts, and had manually rearranged it. I may need to ask him if he manually renumbered it himself or did so through the BOM itself.

Do any of the above affect the order of output? I can see doing manual renumbering through the parts list causing that type of issue since it should be based off the BOM order.

He did show me his BOM and it matched the parts list, but it wasn't what we were getting with the output on that file.
0 Likes
Message 4 of 10

mslosar
Advisor
Advisor

Finally getting to look into this.

 

I'm getting the same results as the user when I step through it.

 

The first choice lets you set it to structured view. It IS setting to structured view, but it is looping through in the order of the model data tab - not the structured tab...

 

I'm trying to get this to loop through in the order shown in the structured tab in the BOM. That's what's supposed to be being exported here isn't it?

0 Likes
Message 5 of 10

mslosar
Advisor
Advisor

I'm working this now in the API sample out of the help files: Using the BOM APIs API Sample

 

BOMQuery seems to select the structured BOM.

 

At the end it passes the structured BOM  via Call QueryBomRowProperties(oBOMView.BOMRows, ItemTab)

 

Problem is, in the 2nd line of QueryBomRowProperties is the comment 'Iterate throughthe contents of the BOM rows. Seems at this point it loops through them in the order of the parts as shown in the Model Data and NOT as shown in the Structured View tab. Our Structured view tab has them in order 1-30 for example. However, the output to the immediate window is that of the model data window and lists in order 1, 14,6,13, etc.

 

I've tried sorting on the Item tab to no avail. And it shouldn't do anything as the Structured view is already sorted 1-30 .

 

I could be wrong, but it seems the first function passes off the structured bom and the second function isn't using its order.  Seems like the oBOMRows as BOMRowsEnumerator is essentially pulling the structured list based on a uniqueID type of order. Rearranging the BOM via Item for example, rearranges the view some it comes out nice and neat listing items 1-XX in perfect order, however the uniqueID numbers aren't visible and are now out of order. When QueryBomRowProperties defines OBOMRows as BOMRowsEnumerator it's telling the system to take the order based on those uniqueID's.

 

I'd like this to run so it pulls ITEM 1, then 2, 3, etc. Is there a method for doing that?

0 Likes
Message 6 of 10

mslosar
Advisor
Advisor
0 Likes
Message 7 of 10

adam.nagy
Autodesk Support
Autodesk Support

Unfortunately, that seems to be correct.

I've added a note to the change-request that you would also like to see it fixed.

 

Cheers,



Adam Nagy
Autodesk Platform Services
0 Likes
Message 8 of 10

mslosar
Advisor
Advisor

thank you 🙂

0 Likes
Message 9 of 10

Anonymous
Not applicable

Hi Adam, 

 

I'm running into this issue as well. And to put some extra pressure on it, I believe my PDM system cannot render the right bill of material because of this issue. 
I have always blamed the PDM manufacturers for not fixing it, but I think they cannot do anything about it. 

 

Is this still in Inventor 2014?? Can you come up with a workaround? 

 

Thanks, 

 

Klaas

0 Likes
Message 10 of 10

Anonymous
Not applicable

I have been experimenting, and came to the following code, which I think gives the right results: 

 

 

Inventor.ApprenticeServerDocument invDoc = apprentice.Open(**INSERT FILENAME HERE**);

Inventor.AssemblyComponentDefinition oAssemblyCompDef = (Inventor.AssemblyComponentDefinition)invDoc.ComponentDefinition;

Inventor.BOMView view_model = null;
Inventor.BOMView view_structured = null;
Inventor.BOMView view_parts_only = null;

foreach (BOMView view in oAssemblyCompDef.BOM.BOMViews)
{
if (view.ViewType.Equals(Inventor.BOMViewTypeEnum.kModelDataBOMViewType))
{
view_model = view;
}
if (view.ViewType.Equals(Inventor.BOMViewTypeEnum.kStructuredBOMViewType))
{
view_structured = view;
}
if (view.ViewType.Equals(Inventor.BOMViewTypeEnum.kPartsOnlyBOMViewType))
{
view_parts_only = view;
}
}
string sPartsonlyBOM = "";
string sStructuredBOM = "";
string sModelBOM = "";

if (view_model!=null)
{
foreach (Inventor.BOMRow oBOMRow in view_model.BOMRows)
{
Inventor.ComponentDefinition oCompDef = oBOMRow.ComponentDefinitions[1];
Inventor.ApprenticeServerDocument oDoc = oCompDef.Document;
Inventor.PropertySets oSets = oDoc.PropertySets;
Inventor.PropertySet oSet = oSets["Design Tracking Properties"];
Inventor.Property oPartNumber = oSet["Part Number"];
string sPartnumberValue = oPartNumber.Value;
sModelBOM = sModelBOM + " " + "\n" + sPartnumberValue;
}
MessageBox.Show(sModelBOM, listViewItem.Text);
}
if (view_parts_only != null)
{
foreach (Inventor.BOMRow oBOMRow in view_parts_only.BOMRows)
{
Inventor.ComponentDefinition oCompDef = oBOMRow.ComponentDefinitions[1];
Inventor.ApprenticeServerDocument oDoc = oCompDef.Document;
Inventor.PropertySets oSets = oDoc.PropertySets;
Inventor.PropertySet oSet = oSets["Design Tracking Properties"];
Inventor.Property oPartNumber = oSet["Part Number"];
string sPartnumberValue = oPartNumber.Value;
sPartsonlyBOM = sPartsonlyBOM + " " + "\n" + sPartnumberValue;
}
MessageBox.Show(sPartsonlyBOM, listViewItem.Text);
}
if (view_structured != null)
{
foreach (Inventor.BOMRow oBOMRow in view_structured.BOMRows)
{
Inventor.ComponentDefinition oCompDef = oBOMRow.ComponentDefinitions[1];
Inventor.ApprenticeServerDocument oDoc = oCompDef.Document;
Inventor.PropertySets oSets = oDoc.PropertySets;
Inventor.PropertySet oSet = oSets["Design Tracking Properties"];
Inventor.Property oPartNumber = oSet["Part Number"];
string sPartnumberValue = oPartNumber.Value;
sStructuredBOM = sStructuredBOM + " " + "\n" + sPartnumberValue;
}
MessageBox.Show(sStructuredBOM, listViewItem.Text);
}

 

 

 

 

I believe this reads out the available BOM views and places the part numbers in a messagebox. Somehow, I seem to be getting correct results with this setup. 

 

/Klaas