How to read item number as per structured view

abilabib
Advocate
Advocate

How to read item number as per structured view

abilabib
Advocate
Advocate

I'm try for read item number like a picture below and wanna get the data structure as per Structured View.

But I can't. Because the program read the ItemNumber as per Model data or Hierarchy in object history. 

I wanna the data like this:

1
1.1
1.2
1.3
1.4
1.5
2
2.1
2.2
2.3
3
3.1
3.2
4
5
6

 

But I get actual data like this :

1
1.1
1.2
1.3
1.4
1.5
4
2
2.1
2.2
2.3
5
6
3
3.1
3.2

Here's the code :

 

Sub ListBomItems()
        Dim asm As AssemblyDocument
        asm = invApp.ActiveDocument

        Dim b As BOM
        b = asm.ComponentDefinition.BOM

        b.StructuredViewEnabled = True

        Dim bv As BOMView
        bv = b.BOMViews("Structured")

        Call ListItems(bv.BOMRows, 0)
    End Sub

    Sub ListItems(rows As BOMRowsEnumerator, indent As Integer)
        Dim row As BOMRow
        For Each row In rows
            Debug.Print(row.ItemNumber.ToString)
            If Not row.ChildRows Is Nothing Then
                Call ListItems(row.ChildRows, indent + 2)
            End If
        Next
    End Sub

Is there way for rearrange data structure in Model Data / Hierarchy model ?

 

 

 

BOM Structured.jpg

0 Likes
Reply
Accepted solutions (2)
2,162 Views
21 Replies
Replies (21)

martin.jacko
Autodesk
Autodesk

Hi,

 

Output looks very interesting.

 

Could you please provide dataset for investigation?

 

Thanks,

Martin

0 Likes

abilabib
Advocate
Advocate

@martin.jacko
Here's the file. 

0 Likes

MechMachineMan
Advisor
Advisor

It has been like this forever.

 

Inventor doesn't internally resort the data based on the item numbering scheme you have set.

 

The internal order is based on the order in which the documents were added to the assembly (I think).

 

If you want to get a list by the bom structure, you should just be able to re-sort it by item number afterwords using a custom comparison. Or you could evaluate if you really need the program to do the sorting, and can just get by with some other sort method (ie; excel) afterwards.


--------------------------------------
Did you find this reply helpful ? If so please use the 'Accept as Solution' or 'Like' button below.

Justin K
Inventor 2018.2.3, Build 227 | Excel 2013+ VBA
ERP/CAD Communication | Custom Scripting
Machine Design | Process Optimization


iLogic/Inventor API: Autodesk Online Help | API Shortcut In Google Chrome | iLogic API Documentation
Vb.Net/VBA Programming: MSDN | Stackoverflow | Excel Object Model
Inventor API/VBA/Vb.Net Learning Resources: Forum Thread

Sample Solutions:Debugging in iLogic ( and Batch PDF Export Sample ) | API HasSaveCopyAs Issues |
BOM Export & Column Reorder | Reorient Skewed Part | Add Internal Profile Dogbones |
Run iLogic From VBA | Batch File Renaming| Continuous Pick/Rename Objects

Local Help: %PUBLIC%\Documents\Autodesk\Inventor 2018\Local Help

Ideas: Dockable/Customizable Property Browser | Section Line API/Thread Feature in Assembly/PartsList API Static Cells | Fourth BOM Type
0 Likes

abilabib
Advocate
Advocate

@MechMachineMan : Thanks for your reply. Because it's impossible for Numbering component direct from Inventor. So I decide using Excel Spreadsheet in this case. 

 

 

Regards,

 

Afri 

0 Likes

chandra.shekar.g
Autodesk Support
Autodesk Support

@abilabib,

 

I tested provided sample and source code in Inventor 2019 and Visual studio 2017. The results are sorted as shown below. Can you please specify Inventor version that is currently using?

 

Sorted_BOM_Items.PNG

Thanks and regards,

 


CHANDRA SHEKAR G
Developer Advocate
Autodesk Developer Network



0 Likes

dgreatice
Collaborator
Collaborator

Hi, this my version. and work for me.

 

use strcomp argument to find item no. and sort it.

 

Public Sub OlahDataExport()
    Dim oAPp As Application
    Dim oAD As AssemblyDocument
   
    Dim oACD As AssemblyComponentDefinition
    Dim oBOM As BOM
    Dim oBOMStructure As BOMView
    Dim oBomRow As BOMRow
    Dim oGetBomRow As BOMRow
   
    Set oAPp = ThisApplication
    Set oAD = oAPp.ActiveDocument
    Set oACD = oAD.ComponentDefinition
    Set oBOM = oACD.BOM
    On Error Resume Next
    Set oBOMStructure = oBOM.BOMViews.Item("Structured")
   
    If Err.Number <> 0 Then
        oBOM.StructuredViewEnabled = True
        oBOM.StructuredViewFirstLevelOnly = False
        Set oBOMStructure = oBOM.BOMViews.Item("Structured")
    End If


    oBOMStructure.Sort ("Item")
   
    For i = 1 To oBOMStructure.BOMRows.Count
        For Each oBomRow In oBOMStructure.BOMRows
            If StrComp(oBomRow.ItemNumber, i, vbTextCompare) = 0 Then
                Set oGetBomRow = oBomRow
                Debug.Print oGetBomRow.ItemNumber
                Call EachChildRowCall(oGetBomRow)
            End If
        Next
    Next
End Sub

 

Public Sub EachChildRowCall(ByVal oBomRow As BOMRow)
    Dim oChildROw As BOMRow
    Dim oGetChildRow As BOMRow
   
    For i = 1 To oBomRow.ChildRows.Count
        For Each oChildROw In oBomRow.ChildRows
            If StrComp(Right(oChildROw.ItemNumber, 1), i, vbTextCompare) = 0 Then
                Set oGetChildRow = oChildROw
                Debug.Print oGetChildRow.ItemNumber
                If oGetChildRow.ChildRows Is Nothing Then
                Else
                    Call EachChildRowCall(oGetChildRow)
                End If
            End If
        Next
    Next
End Sub

Please use the ACCEPT AS SOLUTION or KUDOS button if my Idea helped you to solve the problem.

Autodesk Inventor Professional Certified 2014
0 Likes

abilabib
Advocate
Advocate

@chandra.shekar.g : I'm use Inventor 2015 and VS 2013 Express

0 Likes

chandra.shekar.g
Autodesk Support
Autodesk Support

@abilabib,

 

There was a change request (INVGEN - 6581) on this. It is fixed in Inventor 2019.

 

Thanks and regards,


CHANDRA SHEKAR G
Developer Advocate
Autodesk Developer Network



0 Likes

abilabib
Advocate
Advocate

@chandra.shekar.g

 

Many thanks for your information. But we don't have planning for upgrade to 2019. We still use 2015. Because our head quarter in Canada still use 2015.

 

Thanks.

0 Likes

YuhanZhang
Autodesk
Autodesk

dgreatice  posted a workaround for this, can you try if it solves the problem?



If this solves the problem please click ACCEPT SOLUTION so other people can find it easily.



Rocky Zhang
Inventor API PD
Manufacturing Solutions
Autodesk, Inc.

0 Likes

abilabib
Advocate
Advocate

It's not working in Inventor 2015 .

Here's the result. 

1
1.1
1.2
1.3
1.4
1.5
6

Here's the code

Public Sub OlahDataExport()
        Dim oAD As AssemblyDocument
        Dim oACD As AssemblyComponentDefinition
        Dim oBOM As BOM
        Dim oBOMStructure As BOMView
        Dim oBomRow As BOMRow
        Dim oGetBomRow As BOMRow

        oAD = invApp.ActiveDocument
        oACD = oAD.ComponentDefinition
        oBOM = oACD.BOM
        On Error Resume Next
        oBOMStructure = oBOM.BOMViews.Item("Structured")

        If Err.Number <> 0 Then
            oBOM.StructuredViewEnabled = True
            oBOM.StructuredViewFirstLevelOnly = False
            oBOMStructure = oBOM.BOMViews.Item("Structured")
        End If


        oBOMStructure.Sort("Item")

        For i = 1 To oBOMStructure.BOMRows.Count
            For Each oBomRow In oBOMStructure.BOMRows
                If StrComp(oBomRow.ItemNumber, i, vbTextCompare) = 0 Then
                    oGetBomRow = oBomRow
                    Debug.Print(oGetBomRow.ItemNumber)
                    Call EachChildRowCall(oGetBomRow)
                End If
            Next
        Next
    End Sub
    Public Sub EachChildRowCall(ByVal oBomRow As BOMRow)
        Dim oChildROw As BOMRow
        Dim oGetChildRow As BOMRow

        For i = 1 To oBomRow.ChildRows.Count
            For Each oChildROw In oBomRow.ChildRows
                If StrComp(Right(oChildROw.ItemNumber, 1), i, vbTextCompare) = 0 Then
                    oGetChildRow = oChildROw
                    Debug.Print(oGetChildRow.ItemNumber)
                    If oGetChildRow.ChildRows Is Nothing Then
                    Else
                        Call EachChildRowCall(oGetChildRow)
                    End If
                End If
            Next
        Next
    End Sub
0 Likes

YuhanZhang
Autodesk
Autodesk

I have not an Inventor 2015 build at hand, but tested with Inventor 2016 and it prints the right result. Can you debug the code to check why it ignored the ItemNumber from 2 to 5? Also please check that in your data the ItemNumber is not overridden.



If this solves the problem please click ACCEPT SOLUTION so other people can find it easily.



Rocky Zhang
Inventor API PD
Manufacturing Solutions
Autodesk, Inc.

0 Likes

chandra.shekar.g
Autodesk Support
Autodesk Support
Accepted solution

@abilabib,

 

Hoping that below sorting code would help to sort items of Structured view.

 

Sub ListBomItems()
        Dim asm As AssemblyDocument
        asm = invApp.ActiveDocument

        Dim b As BOM
        b = asm.ComponentDefinition.BOM

        b.StructuredViewEnabled = True

        Dim bv As BOMView
        bv = b.BOMViews("Structured")
        Dim oSort As Dictionary(Of Integer, Integer)
        oSort = BOM_Sort(bv.BOMRows)
        Call ListItems(bv.BOMRows, 0, oSort)
    End Sub
    Function BOM_Sort(rows As BOMRowsEnumerator)
        Dim oSort As Dictionary(Of Integer, Integer) = New Dictionary(Of Integer, Integer)
        Dim oRow As BOMRow
        For i As Integer = 1 To rows.Count Step 1
            oRow = rows.Item(i)
            oSort.Add(oRow.ItemNumber, i)
        Next
        BOM_Sort = oSort
    End Function
    Sub ListItems(rows As BOMRowsEnumerator, indent As Integer, oSort As Dictionary(Of Integer, Integer))
        Dim row As BOMRow
        Dim i As Integer

        For i = 1 To rows.Count Step 1

            Dim key As Integer = oSort(i)
            row = rows.Item(key)

            Debug.Print(row.ItemNumber.ToString)

            If Not row.ChildRows Is Nothing Then
                Call ListItems(row.ChildRows, indent + 2)
            End If
        Next
    End Sub
    Sub ListItems(rows As BOMRowsEnumerator, indent As Integer)
        Dim row As BOMRow
        For Each row In rows
            Debug.Print(row.ItemNumber.ToString)
            If Not row.ChildRows Is Nothing Then
                Call ListItems(row.ChildRows, indent + 2)
            End If
        Next
    End Sub

Thanks and regards,


CHANDRA SHEKAR G
Developer Advocate
Autodesk Developer Network



0 Likes

abilabib
Advocate
Advocate

@chandra.shekar.g : Many thanks for your code. I'll try. 

0 Likes

chandra.shekar.g
Autodesk Support
Autodesk Support

@abilabib,

 

If solves problem, click on "Accept as solution" / give a "Like".

 

Thanks and regards,

 


CHANDRA SHEKAR G
Developer Advocate
Autodesk Developer Network



0 Likes

abilabib
Advocate
Advocate
But there's like jumping in looping system. Because some component type can't be read.

Not Read Component Type.jpg

0 Likes

chandra.shekar.g
Autodesk Support
Autodesk Support
Accepted solution

@abilabib,

 

 

 

Below highlighted (red in color) was missing in previous code.

 

Sub ListBomItems()
        Dim asm As AssemblyDocument
        asm = invApp.ActiveDocument

        Dim b As BOM
        b = asm.ComponentDefinition.BOM

        b.StructuredViewEnabled = True

        Dim bv As BOMView
        bv = b.BOMViews("Structured")
        Dim oSort As Dictionary(Of Integer, Integer)
        oSort = BOM_Sort(bv.BOMRows)
        Call ListItems(bv.BOMRows, 0, oSort)
    End Sub
    Function BOM_Sort(rows As BOMRowsEnumerator)
        Dim oSort As Dictionary(Of Integer, Integer) = New Dictionary(Of Integer, Integer)
        Dim oRow As BOMRow
        For i As Integer = 1 To rows.Count Step 1
            oRow = rows.Item(i)
            oSort.Add(oRow.ItemNumber, i)
        Next
        BOM_Sort = oSort
    End Function
    Sub ListItems(rows As BOMRowsEnumerator, indent As Integer, oSort As Dictionary(Of Integer, Integer))
        Dim row As BOMRow
        Dim i As Integer

        For i = 1 To rows.Count Step 1

            Dim key As Integer = oSort(i)
            row = rows.Item(key)

            Dim oCompDef As ComponentDefinition
            oCompDef = row.ComponentDefinitions.Item(1)

            Debug.Print(row.ItemNumber.ToString & " " & oCompDef.Type.ToString)

            If Not row.ChildRows Is Nothing Then
                Call ListItems(row.ChildRows, indent + 2)
            End If
        Next
    End Sub
    Sub ListItems(rows As BOMRowsEnumerator, indent As Integer)
        Dim row As BOMRow
        For Each row In rows
            Dim oCompDef As ComponentDefinition
            oCompDef = row.ComponentDefinitions.Item(1)

            Debug.Print(row.ItemNumber.ToString & " " & oCompDef.Type.ToString)
            If Not row.ChildRows Is Nothing Then
                Call ListItems(row.ChildRows, indent + 2)
            End If
        Next
    End Sub

Thanks and regards,


CHANDRA SHEKAR G
Developer Advocate
Autodesk Developer Network



abilabib
Advocate
Advocate

Dear @chandra.shekar.g :

 

Many thanks for your code and effort. 

Case Closed. 

0 Likes

abilabib
Advocate
Advocate

@chandra.shekar.g. Many thanks for your code. My program is done Smiley Happy.

Final Result.JPG

0 Likes