We work thanks to the mechanically welded environment (SW 2017). When creating our general BOMs, if we want to have the list of each body, without having the display of the corresponding parts, we have to break down each part (as well as each assembly) by hand, which can sometimes be tedious, especially when SW decides to recompose our assemblies from time to time.
Is there a way to have a BOM that only lists the bodies of an assembly? Or a way to "break it all down" into a nomenclature? (macro?)
A big thank you in advance, you save us a lot of time.
In order for our colleagues to be able to help you, we should specify what you want when you say "without having the display of the corresponding documents,"
Can you make some screenshot of what you get with the tedious method you say: we have to break down each part (as well as each assembly) by hand, )
We have strong colleagues on these subjects, they will know what to say in view of your current work.
To break down each assembly, you have to go to the configuration properties (even if there is only one) and choose "show":
To automatically break down a piece into a body, I only see a macro.
@Zozo_mp: with SW we can display, in a nomenclature, the list of bodies composing a part instead of the part itself (according to the same logic as with a "complacency" subset).
For example, if I have an assembly containing 20 parts, each mechanically welded and composed of several bodies each. If I want my nomenclature to appear only the bodies, I have to break down my twenty pieces each time (and sometimes we have many more).
Here my piece is A, and is composed of A1 to A10.
Moreover, my subassemblies are systematically in "Show", and it does not break down the assembly. Wouldn't it just be an option to display or not the parts making up the assembly in the bill of materials?
For a macro, do you have any leads to give me? I am not comfortable with this language.
I was able to make a first macro that breaks down the table well, line by line starting from the end, so already good news! :) To gain speed, I would like to break down only the necessary lines (so those corresponding to subassembly or weldment), is there a way to recover the cell type? I can't find what I need in the doc.
I don't think it's possible to retrieve the type of article from a line because it's usually an array of text that we retrieve when we analyze a nomenclature by APIs. It's up to you to see if you can add a column that can be used as a selection criterion like "SW-File Name" for example.
Yes I thought about it, the problem is that a non-mechanically welded part will be made of .sldprt (for example all the screws), but still doesn't need to be broken down. That said, it's a first improvement indeed!
I tried to add a column with the file name, but I can't do it, in fact I get stuck at the step of defining the column type. I manage to add the column, but it is empty. The goal is to identify the file extension, to break down only the .sldprt and .sldasm After this step, I think I know how to do it.
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Sub main()
Dim swFeat As SldWorks.Feature
Dim swBomFeat As SldWorks.BomFeature
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
Set selmgr = swModel.SelectionManager
Set vTable = selmgr.GetSelectedObject6(1, -1)
DisolveBomSelect vTable
MsgBox "Nomenclature décomposée"
End Sub
Sub DisolveBomSelect(vTable As Variant)
Dim swTable As SldWorks.TableAnnotation
Dim swAnn As SldWorks.Annotation
Dim nNombreLignes As Long
Dim sRowStr As String
Dim i As Long
Set swTable = vTable
Set swAnn = swTable.GetAnnotation
nNombreLignes = swTable.RowCount
nNombreColonnes = swTable.ColumnCount
etape = swTable.InsertColumn2(swTableItemInsertPosition_Last, 0, "New Column", swInsertColumn_DefaultWidth)
swAnn.Visible = swAnnotationHidden
For i = nNombreLignes - 1 To 0 Step -1
swTable.Dissolve (i)
Next i
swAnn.Visible = swAnnotationVisible
End Sub
Rereading the thread of the discussion, I admit that I can't follow too much anymore:
- Step 1: The question is to break it all down.
- Step 2: Break down only certain lines to save time.
- Step 3: Do not decompose according to the file type because (for example) SDLPRTs can be screws and should not be decomposed.
- Step 4: Insert a column because the goal is to identify the file extension, to break down only the SLDPRT and SLDASM.
I think that before continuing the code it is necessary to define the need (decompose everything: yes or no?) and, if not, to define the criteria for selecting the lines to be decomposed. The "GetComponents2" function can indeed be another line of thought depending on what you want to break down.
And for inserting a new column, it may be easier to simply do it in the BOM template rather than trying to do it through code...
The goal remains the same: to have a completely broken down nomenclature quickly, but depending on the difficulties of implementation there are indeed intermediate steps. I do have a macro that breaks down all the components, the problem being the heaviness of this macro, which also breaks down the mechanically welded bodies and the non-welded .sldprt , which don't need to be, wasting time (the dissolve function is not a lightning bolt).
My ideal would therefore be to break down only the assemblies and the mechanically welded parts, but since I couldn't do that, I fell back on differentiation by file name.
Sorry for the vagueness of my requests, I hope this message will help us see a little more clearly:)
Here is an example that relies on the BOM coordinate system to know whether or not to decompose, the BOM must be in the form of a tabulated list (The checkmark for the detailed list of welded parts is not mandatory):
It's an example, it's up to you to adapt according to your needs...
Kind regards
Option Explicit
Sub main()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Dim swFeat As SldWorks.Feature
Dim swBomFeat As SldWorks.BomFeature
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
Set swDraw = swModel
Set swFeat = swModel.FirstFeature
Do While Not swFeat Is Nothing
If "BomFeat" = swFeat.GetTypeName Then
Set swBomFeat = swFeat.GetSpecificFeature2
ProcessBomFeature swApp, swModel, swBomFeat
End If
Set swFeat = swFeat.GetNextFeature
Loop
End Sub
Sub ProcessTableAnn(swApp As SldWorks.SldWorks, swModel As SldWorks.ModelDoc2, swTableAnn As SldWorks.TableAnnotation, ConfigName As String)
On Error Resume Next
Dim nNumRow As Long
Dim nNumColumn As Long
Dim j As Long
Dim i As Long
Dim NumberComposant As String
Dim ItemNumber As String
Dim ItemNumberPrec As String
Dim PartNumber As String
Dim MomTableau() As String
Dim n As Integer
Dim nb As Integer
n = 0
nb = 0
nNumRow = swTableAnn.RowCount
Dim swBOMTableAnn As BomTableAnnotation
Set swBOMTableAnn = swTableAnn
For j = 0 To nNumRow - 1
NumberComposant = swBOMTableAnn.GetComponentsCount2(j, ConfigName, ItemNumber, PartNumber)
If ItemNumber = ItemNumberPrec & ".1" Then
ReDim Preserve MomTableau(n)
MomTableau(n) = j - 1
n = n + 1
End If
ItemNumberPrec = ItemNumber
Next j
nb = UBound(MomTableau)
While nb >= 0
swBOMTableAnn.Dissolve (MomTableau(nb))
nb = nb - 1
Wend
End Sub
Sub ProcessBomFeature(swApp As SldWorks.SldWorks, swModel As SldWorks.ModelDoc2, swBomFeat As SldWorks.BomFeature)
Dim swFeat As SldWorks.Feature
Dim vTableArr As Variant
Dim vTable As Variant
Dim vConfigArray As Variant
Dim vConfig As Variant
Dim ConfigName As String
Dim swTable As SldWorks.TableAnnotation
Set swFeat = swBomFeat.GetFeature
vTableArr = swBomFeat.GetTableAnnotations
For Each vTable In vTableArr
Set swTable = vTable
vConfigArray = swBomFeat.GetConfigurations(True, True)
For Each vConfig In vConfigArray
ConfigName = vConfig
ProcessTableAnn swApp, swModel, swTable, ConfigName
Next vConfig
Next vTable
End Sub
First of all, thank you very much for your answer, it's really great! Your solution by numbering is very clever!
I try, I try to adapt it exactly to my use, but, inevitably, the problem hurts.
My ideal use would be to break down only the active BOM. So I use the GetSelectedObject6(1, -1).
But, it returns a table, and I can't manage to retrieve the corresponding BOM, to be able to retrieve the configuration, obviously essential for the GetComponentsCount.
If I understand your code correctly, you look at all the BOMs, for each of them you look at all the corresponding tables, and you break them down each one.
My code, quite simple considering my level, was as follows:
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Sub main()
Dim swFeat As SldWorks.Feature
Dim swBomFeat As SldWorks.BomFeature
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
Set selmgr = swModel.SelectionManager
Set vTable = selmgr.GetSelectedObject6(1, -1)
DisolveBomSelect vTable
MsgBox "Nomenclature décomposée"
End Sub
Sub DisolveBomSelect(vTable As Variant)
Dim swTable As SldWorks.TableAnnotation
Dim nNombreLignes As Long
Dim sRowStr As String
Dim i As Long
Set swTable = vTable
Set swAnn = swTable.GetAnnotation
nNombreLignes = swTable.RowCount
nNombreColonnes = swTable.ColumnCount
For i = nNombreLignes - 1 To 0 Step -1
swTable.Dissolve (i)
Next i
End Sub
Try with the code below, be careful, the selection of the nomenclature must be done in the creation tree and not on the plan.
Kind regards
Option Explicit
Sub main()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Dim swFeat As SldWorks.Feature
Dim swBomFeat As SldWorks.BomFeature
Dim selmgr As SelectionMgr
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
Set swDraw = swModel
Set selmgr = swModel.SelectionManager
Set swBomFeat = selmgr.GetSelectedObject6(1, 0)
ProcessBomFeature swApp, swModel, swBomFeat
End Sub
Sub ProcessTableAnn(swApp As SldWorks.SldWorks, swModel As SldWorks.ModelDoc2, swTableAnn As SldWorks.TableAnnotation, ConfigName As String)
On Error Resume Next
Dim nNumRow As Long
Dim nNumColumn As Long
Dim j As Long
Dim i As Long
Dim NumberComposant As String
Dim ItemNumber As String
Dim ItemNumberPrec As String
Dim PartNumber As String
'Dim RowLocked As Boolean
'Dim RowHeight As Double
Dim MomTableau() As String
Dim n As Integer
Dim nb As Integer
n = 0
nb = 0
nNumRow = swTableAnn.RowCount
Dim swBOMTableAnn As BomTableAnnotation
Set swBOMTableAnn = swTableAnn
For j = 0 To nNumRow - 1
NumberComposant = swBOMTableAnn.GetComponentsCount2(j, ConfigName, ItemNumber, PartNumber)
If ItemNumber = ItemNumberPrec & ".1" Then
'Debug.Print "Ligne à décomposer : " & j - 1
ReDim Preserve MomTableau(n)
MomTableau(n) = j - 1
n = n + 1
End If
ItemNumberPrec = ItemNumber
Next j
nb = UBound(MomTableau)
While nb >= 0
swBOMTableAnn.Dissolve (MomTableau(nb))
nb = nb - 1
Wend
End Sub
Sub ProcessBomFeature(swApp As SldWorks.SldWorks, swModel As SldWorks.ModelDoc2, swBomFeat As SldWorks.BomFeature)
Dim swFeat As SldWorks.Feature
Dim vTableArr As Variant
Dim vTable As Variant
Dim vConfigArray As Variant
Dim vConfig As Variant
Dim ConfigName As String
Dim swTable As SldWorks.TableAnnotation
Set swFeat = swBomFeat.GetFeature
vTableArr = swBomFeat.GetTableAnnotations
ConfigName = swBomFeat.Configuration
For Each vTable In vTableArr
Set swTable = vTable
ProcessTableAnn swApp, swModel, swTable, ConfigName
Next vTable
End Sub
If possible, see the version below with selection of the BOM on the plan.
Kind regards
Option Explicit
Sub main()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Dim selmgr As SelectionMgr
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
Set swDraw = swModel
Dim vTable As SldWorks.TableAnnotation
Set selmgr = swModel.SelectionManager
Set vTable = selmgr.GetSelectedObject6(1, -1)
ProcessTableAnn swApp, swModel, vTable
End Sub
Sub ProcessTableAnn(swApp As SldWorks.SldWorks, swModel As SldWorks.ModelDoc2, swTableAnn As SldWorks.TableAnnotation)
On Error Resume Next
Dim nNumRow As Long
Dim nNumColumn As Long
Dim j As Long
Dim i As Long
Dim NumberComposant As String
Dim ItemNumber As String
Dim ItemNumberPrec As String
Dim PartNumber As String
Dim MomTableau() As String
Dim n As Integer
Dim nb As Integer
n = 0
nb = 0
nNumRow = swTableAnn.RowCount
Dim swBOMTableAnn As BomTableAnnotation
Set swBOMTableAnn = swTableAnn
Dim ConfigName As String
ConfigName = swBOMTableAnn.Configuration
For j = 0 To nNumRow - 1
NumberComposant = swBOMTableAnn.GetComponentsCount2(j, ConfigName, ItemNumber, PartNumber)
If ItemNumber = ItemNumberPrec & ".1" Then
ReDim Preserve MomTableau(n)
MomTableau(n) = j - 1
n = n + 1
End If
ItemNumberPrec = ItemNumber
Next j
nb = UBound(MomTableau)
While nb >= 0
swBOMTableAnn.Dissolve (MomTableau(nb))
nb = nb - 1
Wend
End Sub