Export BOM to Excel with a VBA Macro

Hello

This topic follows 2 other posts on the same topic:

  • - https://www.lynkoa.com/forum/solidworks/export-nomenclature-vers-excel-avec-une-macro-vba
  • - https://www.lynkoa.com/forum/import-de-donn%C3%A9es-num%C3%A9ris%C3%A9es/export-nomenclature-vers-excel

This macro works well and I thank you for that. However, I have two small remarks:

  1.  it does not take into account whether or not parts are defined as "Excluded from the BOM". All the documents stand out in the Excel table.
  2.  For mechanically welded parts, the macro exports each welded body as a part in its own right when these bodies should be excluded from the nomenclature (well, in my case).

Is it possible to solve these 2 small problems by an additional piece of code?

If it is not possible to hide them, perhaps it is possible to add a column to the Excel file with a property "Excluded from BOM" and as a value on each YES or NO row.

Thank you for your help

Have a nice day

Hello

I don't know which macro you started from precisely and what modifications you made but it's still weird that parts excluded from the nomenclature appear in this said nomenclature (unless they are excluded from the nomenclature in a configuration but not in the one from which you get the nomenclature).

For mechanically welded parts, this is probably due to the swBomType chosen for the creation of the BOM:

- "Indented": all levels including the profiles of the mechanically welded.

- "TopLevelOnly": only the first level so not the profiles of the mechanically welded.

On this link there seems to me all the useful information.

Kind regards

1 Like

Hello

Thank you for your answer. Yes, I had seen the topic of discussion you mention.
If I change the swBomType to "TopLevelOnly", I actually only have the 1st level, so I'm missing all the sublevels.
If I put the swBomType in "Indented", it goes down to the body of the mechanically welded parts, which is too low a floor.

Option Explicit

Sub main()

Dim xlApp As Excel.Application
Set xlApp = New Excel.Application
Dim wbk As Excel.Workbook
Dim sht As Excel.Worksheet

With xlApp
'    .Visible = True
    Set wbk = .Workbooks.Add
    Set sht = wbk.ActiveSheet
End With

Dim swApp                   As SldWorks.SldWorks
Dim swModel                 As SldWorks.ModelDoc2
Dim swModelDocExt           As SldWorks.ModelDocExtension
Dim swBOMAnnotation         As SldWorks.BomTableAnnotation
Dim swBOMFeature            As SldWorks.BomFeature
Dim boolstatus              As Boolean
Dim BomType                 As Long
Dim Configuration           As String
Dim TemplateName            As String

Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
Set swModelDocExt = swModel.Extension

TemplateName = "C:\Users\vousm\Documents travail\Config_Sw\Table nomenclature\table_nomenclature.sldbomtbt"
'BomType = swBomType_Indented
BomType = swBomType_TopLevelOnly
Configuration = swApp.GetActiveConfigurationName(swModel.GetPathName)
MsgBox Configuration
Set swBOMAnnotation = swModelDocExt.InsertBomTable3(TemplateName, 0, 0, BomType, Configuration, False, swNumberingType_Detailed, True)
Set swBOMFeature = swBOMAnnotation.BomFeature

swModel.ForceRebuild3 True

Dim NumCol As Long
Dim NumRow As Long
Dim I As Long
Dim J As Long

NumCol = swBOMAnnotation.ColumnCount
NumRow = swBOMAnnotation.RowCount

'mise en forme
For I = 1 To NumRow - 1
    xlApp.Worksheets(xlApp.ActiveSheet.Name).Rows(I + 1).RowHeight = 15
Next I
For J = 0 To NumCol - 1
    xlApp.ActiveSheet.Cells(1, J + 1).Interior.ColorIndex = 15
Next J
xlApp.Worksheets(xlApp.ActiveSheet.Name).Columns(1).ColumnWidth = 6
xlApp.Worksheets(xlApp.ActiveSheet.Name).Columns(2).ColumnWidth = 17
xlApp.Worksheets(xlApp.ActiveSheet.Name).Columns(3).ColumnWidth = 4
xlApp.Worksheets(xlApp.ActiveSheet.Name).Columns(4).ColumnWidth = 34
xlApp.Worksheets(xlApp.ActiveSheet.Name).Columns(5).ColumnWidth = 34
xlApp.Worksheets(xlApp.ActiveSheet.Name).Columns(6).ColumnWidth = 4

For I = 0 To NumRow - 1
    For J = 0 To NumCol - 1
        If J <> 5 Then  'cas de la colonne Qté
            xlApp.ActiveSheet.Cells(I + 1, J + 1).NumberFormat = "@"
        End If
        xlApp.ActiveSheet.Cells(I + 1, J + 1).VerticalAlignment = 2
        sht.Cells(I + 1, J + 1).Value = swBOMAnnotation.Text(I, J)
    Next J
Next I


boolstatus = swModelDocExt.SelectByID2(swBOMFeature.GetFeature.Description, "BOMFEATURE", 0, 0, 0, True, 0, Nothing, 0)
swModel.EditDelete

Dim chemin As String
chemin = "C:\temp\BOS4.xlsx"

With xlApp
    wbk.SaveAs chemin
    wbk.Close
    .Quit
End With

End Sub

 

How can we do it then?
Thank you for your feedback,

Kind regards

Hello

In this case it is possible to set swBomType to "Indented" and retrieve the component for each row of the BOM using the Getcomponents2 function to decide whether or not to insert it in the Excel file, you may have to hang on to the ModelDoc2 object for each component to analyze it, this can be done using the GetModelDoc2 function.

Kind regards

Wow, we're going to reach the limits of my programming skills.

I have the impression that everything comes down to the line "Set swBOMAnnotation = swModelDocExt.InsertBomTable3... " where the nomenclature is created. Already here, the bodies of the welded part appear. Attached, the document in question.
Since SW, by manually changing the parameters of the nomenclature, I can't hide these bodies. Even unchecking the "Detailed list of welded parts" box doesn't help.
What to do in this case?

Thank you for your help


test.zip

Hello

Here is a possible solution, I started from the macro I had already made so it's to be re-adapted to your case but the principle is: for each line of the nomenclature I get the ModelDoc to analyze it and see if it's a welded construction, if it's the case and that this ModelDoc2 is the same as the previous line then I don't have to worry about it. does not take this into account for the export to Excel.
I did my tests on one of my assemblies because I can't open the holder (future version).

Kind regards

Option Explicit

Sub main()

Dim xlApp As Excel.Application
Set xlApp = New Excel.Application
Dim wbk As Excel.Workbook
Dim sht As Excel.Worksheet

With xlApp
    .Visible = True
    Set wbk = .Workbooks.Add
    Set sht = wbk.ActiveSheet
End With

Dim swApp                   As SldWorks.SldWorks
Dim swModel                 As SldWorks.ModelDoc2
Dim swModelDocExt           As SldWorks.ModelDocExtension
Dim swBOMAnnotation         As SldWorks.BomTableAnnotation
Dim swBOMFeature            As SldWorks.BomFeature
Dim boolstatus              As Boolean
Dim BomType                 As Long
Dim Configuration           As String
Dim TemplateName            As String

Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
Set swModelDocExt = swModel.Extension

TemplateName = "Z:\Model_SW\Nomenclature.sldbomtbt"
BomType = swBomType_Indented
Configuration = "Défaut"
Set swBOMAnnotation = swModelDocExt.InsertBomTable3(TemplateName, 0, 0, BomType, Configuration, False, swNumberingType_Detailed, False)
Set swBOMFeature = swBOMAnnotation.BomFeature

swModel.ForceRebuild3 True

Dim NumCol As Long
Dim NumRow As Long
Dim I As Long
Dim J As Long
Dim H As Long

NumCol = swBOMAnnotation.ColumnCount
NumRow = swBOMAnnotation.RowCount

xlApp.Worksheets(xlApp.ActiveSheet.Name).Rows(1).RowHeight = 40
For I = 1 To NumRow - 1
    xlApp.Worksheets(xlApp.ActiveSheet.Name).Rows(I + 1).RowHeight = 20
Next I
For J = 0 To NumCol - 1
    xlApp.Worksheets(xlApp.ActiveSheet.Name).Columns(J + 1).ColumnWidth = 25
    xlApp.ActiveSheet.Cells(1, J + 1).Interior.ColorIndex = 15
Next J

H = 1
For I = 0 To NumRow - 1
    Dim vPtArr As Variant
    Dim swcomp As Component2
    Dim comp As ModelDoc2
    Dim Titre As String
    Dim newTitre As String
    Dim FeatName As String
    Dim printOk As Boolean
    printOk = False
    FeatName = ""
    vPtArr = swBOMAnnotation.GetComponents2(I, Configuration)
    If (Not IsEmpty(vPtArr)) Then
        Set swcomp = vPtArr(0)
        Set comp = swcomp.GetModelDoc2
        
        newTitre = comp.GetTitle
        
        Dim swfeat As Feature
        Set swfeat = comp.FirstFeature
        Do While Not swfeat Is Nothing
            If swfeat.Name = "Construction soudée" Then
                FeatName = "Construction soudée"
            End If
            Set swfeat = swfeat.GetNextFeature
        Loop
    End If
    
    If FeatName = "Construction soudée" Then
        If Not Titre = newTitre Then
            printOk = True
        End If
    Else
        printOk = True
    End If
    
    If printOk = True Then
        For J = 0 To NumCol - 1
            xlApp.ActiveSheet.Cells(H, J + 1).NumberFormat = "@"
            xlApp.ActiveSheet.Cells(H, J + 1).VerticalAlignment = 2
            sht.Cells(H, J + 1).Value = swBOMAnnotation.Text(I, J)
        Next J
        H = H + 1
    End If
    Titre = newTitre
Next I

boolstatus = swModelDocExt.SelectByID2(swBOMFeature.GetFeature.Description, "BOMFEATURE", 0, 0, 0, True, 0, Nothing, 0)
swModel.EditDelete

swModel.ForceRebuild3 True

Dim chemin As String
chemin = Left(swModel.GetPathName, Len(swModel.GetPathName) - 7) & ".xlsx"

With xlApp
    wbk.SaveAs chemin
    wbk.Close
    .Quit
End With

End Sub

 

Good morning, sir

Thank you for taking the time to look at my problem. So I modified my macro with your recommendations.
If I understand correctly, the macro goes through all the construction lines of the part and checks if it finds a "welded construction" text.
Everything happens in this loop:

Do While Not swfeat Is Nothing
    Debug.Print swfeat.Name
            If swfeat.Name = "Construction soudée" Then
                FeatName = "Construction soudée"
            End If
            Set swfeat = swfeat.GetNextFeature
Loop


Applied to my part, the loop goes over the functions but not over "List of welded parts".
I added a Debug.Print swfeat. Name to see what comes out:
 

Favoris
Historique
Ensembles de sélections
Capteurs
Classeur de conception
Annotations
Marquages
Lumières, caméras et scène
Corps volumiques
Surface Bodies
Commentaires
Equations
S235

compared to the tree structure of my room (see attachment).

Thank you again for your help
Have a nice day


arbre_piece.png

Weird, here's what I have in a debug.print:

compared to the part in SW:

You can see that I started with a welded construction in the construction of my piece... too bad I can't open the previously attached...

Kind regards

Indeed, it's strange.
Do you have the automatic update feature checked?


Could it come from there?

Thanks for trying

Yes, it's checked...

But what's surprising is that the debug.print doesn't output everything in the creation tree, the part is loaded in resolved mode?

Yes, the play is well in resolution

And what does it look like with the assembly and the attachments?


insert-bom-asm.zip

I just retested, I just saw
 

Boss.-Extru.3
Dégagement M81
Diamètre du perçage Ø12.0 (12)1
Article-liste-des-pièces-soudées1
Article-liste-des-pièces-soudées2
Article-liste-des-pièces-soudées3
Esquisse29
Esquisse2

Article-list... right in the middle of the rest of the tree in the room. That's weird.
Well, I should manage to get out of it by looking if I have the word "welded" in the swfeat. Name.
The only problem with this method is that you have to be careful not to rename the welded bodies.

Here's the modified snippet of code if anyone ever needs it
 

 Do While Not swfeat Is Nothing
            Debug.Print swfeat.Name
            If InStr(1, swfeat.Name, "soudée") <> 0 Then
            'If swfeat.Name = "soudée" Then
                FeatName = "Construction soudée"
            End If
            Set swfeat = swfeat.GetNextFeature
        Loop

 

Thank you d.roger

I don't know what your solidworks looks like but it almost has to do the design on its own by just clicking on a macro :-D

Be careful, from time to time you have to close the macro editor and re-open it (without forgetting to save your macro first), I noticed that after a while of use it has a little trouble freshening up, it can also come from there ...

In my macro I look for the "Welded construction" function which does not change even when renaming the welded bodies:

As for my SW, no it doesn't do the design by itself by clicking on a macro, although for some parts it's not very far from it :-)

you will have to think about validating the best answer if there is one that meets the request, it can help other users likely to have the same type of request ...

Kind regards

And just for fun, the video is of poor quality but it shows how SW can draw a pinion by involute of a circle almost by himself :-)


usinage_pignon.mp4