We have a macro that someone did that goes thru the assembly & counts all of the components and adds a property to the parts with the quantity that we use in our part callouts. The one thing that this does not do is to take into account those parts that are marked “EXCLUDE FROM BOM”. Does anyone have a macro or can someone look at the macro we have & modify it so that it doesn’t include those parts marked exclude. I’ve included the macro that we have. If you’re able thank you many times over & if you’re not able thank you as well.
QtyMacroFeature.swp.zip (18.2 KB)
I’d try replacing the lines:
If tCmp.ReferencedConfiguration = Cfg Then
cCnt = cCnt + 1
End If
With these:
If tCmp.ReferencedConfiguration = Cfg Then
Dim configOpt as Integer
Dim configNames as Object
If Not tComp.GetExcludeFromBOM2(configOpt, configNames) Then
cCnt = cCnt + 1
End If
End If
Austin,
I tried that and it failed. The debugger came up & it did not have a variable created for the tCOMP so I changed that to just tCmp like the other lines above it had but it still failed. When I changed that & ran it, the debugger came up & errored in this area telling me that theres no if with the Next & then no if with the Else. I ran the debugger on the original & it didn’t fail in those two areas.
Next j
CmpDoc.AddCustomInfo3 Cfg, “AutoQty”, 30, “”
CmpDoc.AddCustomInfo3 Cfg, “QtyIn”, 30, “”
CmpDoc.CustomInfo2(Cfg, “AutoQty”) = cCnt
CmpDoc.CustomInfo2(Cfg, “QtyIn”) = Assembly.GetTitle & " Cfg " & Assembly.ConfigurationManager.ActiveConfiguration.Name
End If
Else
Yes, I also downloaded “QtyMacroFeature.swp.zip”
and replaced
'If tCmp.ReferencedConfiguration = Cfg Then
'cCnt = cCnt + 1
'End If
with this
If tCmp.ReferencedConfiguration = Cfg Then
Dim configOpt As Integer
Dim configNames As Object
If Not tComp.GetExcludeFromBOM2(configOpt, configNames) Then
cCnt = cCnt + 1
End If
End If
and When I changed the
Component Properties.jpg
status of one of the items it still wanted to ignore that I did not want to include it when I ran the macro
It counted the excluded item anyway.
Sorry, John. Try this?
If tCmp.ReferencedConfiguration = Cfg Then
If Not tCmp.GetExcludeFromBOM2(swInConfigurationOpts_e.swThisConfiguration, tCmp.ReferencedConfiguration) Then
cCnt = cCnt + 1
End If
End If
I tried also BUT
Using this code:
If tCmp.ReferencedConfiguration = Cfg Then
If Not tCmp.GetExcludeFromBOM2(swInConfigurationOpts_e.swThisConfiguration, tCmp.ReferencedConfiguration) Then
cCnt = cCnt + 1
End If
End If
When I run it I get this:
---- test — type mismatch 01.jpg
Then the debug This:
---- test — type mismatch 02.jpg
Finally got an assembly made to test it…
If Not tCmp.GetExcludeFromBOM2(swInConfigurationOpts_e.swThisConfiguration, tCmp.ReferencedConfiguration)(0) Then
cCnt = cCnt + 1
Need to add (0) after the function, and it does work for myself (up to that point)
I replaced the lines
“If tCmp.ReferencedConfiguration = Cfg Then
cCnt = cCnt + 1
End If”
with the code you have and it will run. However the quantity I am getting is now 118 for everything including those marked as exclude from BOM.
Do you try.
I am using it and maybe it will answer your question.
MontajaAdetEkleme.swp
I’ve been trying to follow along with what you’re looking to do with this macro so maybe this will help.
This is only the code from your rebuild function, the rest is unmodified.
Public Function swmRebuild(swAppIn As Variant, partIn As Variant, featureIn As Variant) As Variant
Dim Assembly As ModelDoc2
Dim myAsy As AssemblyDoc
Dim myCmps
Dim Cfg As String
Dim CmpDoc As ModelDoc2
Dim i As Long
Dim j As Long
Dim cCnt As Long
Dim NoUp As Long
Dim myCmp As Component2
Dim tCmp As Component2
Dim tm As Double
tm = Timer
Set swApp = swAppIn
Set Assembly = swApp.ActiveDoc
Set myAsy = Assembly
' If Assembly.ConfigurationManager.ActiveConfiguration.Name <> Assembly.CustomInfo2("", "Cfg4Qty") Then
' Assembly.Extension.ShowSmartMessage "Qtys not updated due to config", 1000, True, True
' Exit Function
' End If
NoUp = 0
myCmps = myAsy.GetComponents(False)
For i = 0 To UBound(myCmps)
Set myCmp = myCmps(i)
Debug.Print myCmp.Name & vbTab & "Excl: " & myCmp.ExcludeFromBOM
If (myCmp.GetSuppression = 3) Or (myCmp.GetSuppression = 2) Then
cCnt = 0
Set CmpDoc = myCmp.GetModelDoc
If Not CmpDoc Is Nothing Then
Cfg = myCmp.ReferencedConfiguration
For j = 0 To UBound(myCmps)
Set tCmp = myCmps(j)
Debug.Print vbTab & tCmp.Name & vbTab & "Excl: " & tCmp.ExcludeFromBOM
If tCmp.GetSuppression <> 0 And tCmp.ExcludeFromBOM = False And myCmp.ExcludeFromBOM = False Then
If tCmp.GetModelDoc2 Is CmpDoc Then
If tCmp.ReferencedConfiguration = Cfg Then
cCnt = cCnt + 1
End If
End If
End If
Next j
CmpDoc.AddCustomInfo3 Cfg, "AutoQty", 30, ""
CmpDoc.AddCustomInfo3 Cfg, "QtyIn", 30, ""
CmpDoc.CustomInfo2(Cfg, "AutoQty") = cCnt
CmpDoc.CustomInfo2(Cfg, "QtyIn") = Assembly.GetTitle & " Cfg " & Assembly.ConfigurationManager.ActiveConfiguration.Name
End If
Else
NoUp = NoUp + 1
End If
Next i
Assembly.Extension.ShowSmartMessage NoUp & " Parts not updated due to lightweight (" & Timer - tm & "s)", 10000, True, True
swmRebuild = True
End Function
This will place a 0 quantity for any component that is marked as “Exclude from BOM”. Good luck!
AlexB » Tue Aug 10, 2021 11:24 am
I’ve been trying to follow along with what you’re looking to do with this macro so maybe this will help.
This is only the code from your rebuild function, the rest is unmodified.
That works on my assembly just fine.
Thanks
Just a question?
note question.jpg
The macro you are running creates a macro feature. It’s a feature that contains macro code that runs every time you rebuild. This particular macro feature is set up to always be at the end of the feature tree (to make sure it runs last during rebuild and counts everything). The code contained in the macro feature is what counts parts and writes custom properties. You should not run the macro more than once on any given assembly, unless you delete the macro feature from the tree first. Otherwise you’ll just be counting twice. It will not make your quantities wrong/double/etc, it will just waste time.
A macro feature gets inserted into the feature tree so its “Rebuild” function gets called every time the model/assy rebuilds. In this case, it updates the quantities in child components when the assembly rebuilds to keep them accurate.
Thanks for the explanation Josh & AlexB
I do not want to co-opt this thread at all, but, I just wanted to see what the macro did or did not do
Turns out it did/does more than I expected.
With AlexB’s correction it did seem to add up correctly on my small assembly
But
I wanted to test it a bit more and ran it on a larger assembly with 5 or so deep sub assemblies and it
and it did not add things up right
(One of the major subassemblies that had subassys under it was excluded but the macro still counted the parts in it
in the total, where as the SW BOM did not count the excluded sub assy parts)
I did dissect the macro a bit more to see how… VB SW macro code works… I probably could read a book…
Or well nowadays watch a you tube to learn… but I like to take things apart to see how they work.
Thanks again for the explanation.
I added a bit of code to help check for the top level component’s “Exclude from BOM” value. This should work for the rebuild function now. I tested it on an assembly that was a couple levels.
Public Function swmRebuild(swAppIn As Variant, partIn As Variant, featureIn As Variant) As Variant
Dim Assembly As ModelDoc2
Dim myAsy As AssemblyDoc
Dim myCmps
Dim Cfg As String
Dim CmpDoc As ModelDoc2
Dim i As Long
Dim j As Long
Dim cCnt As Long
Dim NoUp As Long
Dim myCmp As Component2
Dim tCmp As Component2
Dim parentCmp As Component2
Dim tm As Double
tm = Timer
Set swApp = swAppIn
Set Assembly = swApp.ActiveDoc
Set myAsy = Assembly
' If Assembly.ConfigurationManager.ActiveConfiguration.Name <> Assembly.CustomInfo2("", "Cfg4Qty") Then
' Assembly.Extension.ShowSmartMessage "Qtys not updated due to config", 1000, True, True
' Exit Function
' End If
NoUp = 0
myCmps = myAsy.GetComponents(False)
For i = 0 To UBound(myCmps)
Set myCmp = myCmps(i)
'Debug.Print myCmp.Name & vbTab & "Excl: " & myCmp.ExcludeFromBOM
Set parentCmp = myCmp
While Not parentCmp.GetParent Is Nothing
Set parentCmp = parentCmp.GetParent ' Get the top level parent to so we can check for BOM exclusion
Wend
If (myCmp.GetSuppression = 3) Or (myCmp.GetSuppression = 2) Then
cCnt = 0
Set CmpDoc = myCmp.GetModelDoc
If Not CmpDoc Is Nothing Then
Cfg = myCmp.ReferencedConfiguration
For j = 0 To UBound(myCmps)
Set tCmp = myCmps(j)
'Debug.Print vbTab & tCmp.Name & vbTab & "Excl: " & tCmp.ExcludeFromBOM
If tCmp.GetSuppression <> 0 And tCmp.ExcludeFromBOM = False And parentCmp.ExcludeFromBOM = False Then
If tCmp.GetModelDoc2 Is CmpDoc Then
If tCmp.ReferencedConfiguration = Cfg Then
cCnt = cCnt + 1
End If
End If
End If
Next j
CmpDoc.AddCustomInfo3 Cfg, "AutoQty", 30, ""
CmpDoc.AddCustomInfo3 Cfg, "QtyIn", 30, ""
CmpDoc.CustomInfo2(Cfg, "AutoQty") = cCnt
CmpDoc.CustomInfo2(Cfg, "QtyIn") = Assembly.GetTitle & " Cfg " & Assembly.ConfigurationManager.ActiveConfiguration.Name
End If
Else
NoUp = NoUp + 1
End If
Next i
Assembly.Extension.ShowSmartMessage NoUp & " Parts not updated due to lightweight (" & Timer - tm & "s)", 10000, True, True
swmRebuild = True
End Function
I replaced this area
image.png
with the text you included here plus the others up the way & tried to run it. It didnt appear to work correct as there was no macro feature created at the bottom of the tree. With all of the changes that are up thru the posts can you attach your complete macro so I can make sure I didn’t miss anything along the way. Thanks.
The full macro code is below. It creates the macro feature at the bottom of the feature tree as in the image below.
Option Explicit
Dim swApp As SldWorks.SldWorks
Dim Part As ModelDoc2
Dim fso As New Scripting.FileSystemObject
Sub main()
Dim myPath As String
Dim myFolder As String
Dim myFeat As Feature
Dim myMethods(8) As String
Dim vMethods As Variant
Set swApp = Application.SldWorks
Set Part = swApp.ActiveDoc
Dim Names As Variant
Dim Types As Variant
Dim Values As Variant
Dim vEditBodies As Variant
Dim dimTypes As Variant
Dim dimValue As Variant
Dim icons(2) As String
Dim vIcons As Variant
Names = Empty
Types = Empty
Values = Empty
vEditBodies = Empty
myPath = swApp.GetCurrentMacroPathName
myFolder = swApp.GetCurrentMacroPathFolder & "\"
myMethods(0) = myPath
myMethods(1) = "MacroFeatureModule"
myMethods(2) = "swmRebuild"
myMethods(3) = myPath
myMethods(4) = "MacroFeatureModule"
myMethods(5) = "swmEdit"
myMethods(6) = ""
myMethods(7) = ""
myMethods(8) = ""
vMethods = myMethods
icons(0) = myFolder + "QtyMacroFeature.bmp"
icons(1) = myFolder + "QtyMacroFeature.bmp"
icons(2) = myFolder + "QtyMacroFeature.bmp"
vIcons = icons
Set myFeat = Part.FeatureManager.InsertMacroFeature3("QtyMacro", "", vMethods, Names, Types, Values, dimTypes, dimValue, vEditBodies, vIcons, swMacroFeatureByDefault + swMacroFeatureAlwaysAtEnd + swMacroFeatureEmbedMacroFile)
End Sub
Public Function swmRebuild(swAppIn As Variant, partIn As Variant, featureIn As Variant) As Variant
Dim Assembly As ModelDoc2
Dim myAsy As AssemblyDoc
Dim myCmps
Dim Cfg As String
Dim CmpDoc As ModelDoc2
Dim i As Long
Dim j As Long
Dim cCnt As Long
Dim NoUp As Long
Dim myCmp As Component2
Dim tCmp As Component2
Dim parentCmp As Component2
Dim tm As Double
tm = Timer
Set swApp = swAppIn
Set Assembly = swApp.ActiveDoc
Set myAsy = Assembly
' If Assembly.ConfigurationManager.ActiveConfiguration.Name <> Assembly.CustomInfo2("", "Cfg4Qty") Then
' Assembly.Extension.ShowSmartMessage "Qtys not updated due to config", 1000, True, True
' Exit Function
' End If
NoUp = 0
myCmps = myAsy.GetComponents(False)
For i = 0 To UBound(myCmps)
Set myCmp = myCmps(i)
'Debug.Print myCmp.Name & vbTab & "Excl: " & myCmp.ExcludeFromBOM
Set parentCmp = myCmp
While Not parentCmp.GetParent Is Nothing
Set parentCmp = parentCmp.GetParent ' Get the top level parent to so we can check for BOM exclusion
Wend
If (myCmp.GetSuppression = 3) Or (myCmp.GetSuppression = 2) Then
cCnt = 0
Set CmpDoc = myCmp.GetModelDoc
If Not CmpDoc Is Nothing Then
Cfg = myCmp.ReferencedConfiguration
For j = 0 To UBound(myCmps)
Set tCmp = myCmps(j)
'Debug.Print vbTab & tCmp.Name & vbTab & "Excl: " & tCmp.ExcludeFromBOM
If tCmp.GetSuppression <> 0 And tCmp.ExcludeFromBOM = False And parentCmp.ExcludeFromBOM = False Then
If tCmp.GetModelDoc2 Is CmpDoc Then
If tCmp.ReferencedConfiguration = Cfg Then
cCnt = cCnt + 1
End If
End If
End If
Next j
CmpDoc.AddCustomInfo3 Cfg, "AutoQty", 30, ""
CmpDoc.AddCustomInfo3 Cfg, "QtyIn", 30, ""
CmpDoc.CustomInfo2(Cfg, "AutoQty") = cCnt
CmpDoc.CustomInfo2(Cfg, "QtyIn") = Assembly.GetTitle & " Cfg " & Assembly.ConfigurationManager.ActiveConfiguration.Name
End If
Else
NoUp = NoUp + 1
End If
Next i
Assembly.Extension.ShowSmartMessage NoUp & " Parts not updated due to lightweight (" & Timer - tm & "s)", 10000, True, True
swmRebuild = True
End Function
Public Function swmEdit(swAppIn As Variant, partIn As Variant, featureIn As Variant) As Variant
swmEdit = True
End Function
Hi,
Not for nothing, But I did try the latest, above code, on my “Top level” multi level assy
And it did not count correctly, My “Main” top level, level 1" assy calls out a sub assy, “clamp slide assy”, as a level 2 that it in turn calls out/has in it several of the same sub assemblies, “Clamp assy” a level 3 assy
the level 2 assy “clamp slide” calls to suppress “one” of the “clamp assy” level 3 sub-assemblies in it. Yet the above code still counts the parts in the suppressed level 3 “clamp assy”
Where as the SW BOM does not count the parts in the suppressed sub assy.
I just wanted to try the code to see how it worked, but at least for me it did not.
I am just trying to learn by looking at code.
I’ve tried to reproduce the scenario you’re describing and am getting correct values in my top-level assembly of several hundred parts. I’m not sure what the potential issue is.
image.png