- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Change BOMStructure to subassembly when the BOMStructure of assembly is Purchased
Hi everybody! I'm trying to write a macro in order to change BOMStructure of all subcomponents when the BOMStructure of assembly parent is "purchased"
I mean:
1 Assembly --> BOMStructure=Purchased
1.1 Component 1 --> BOMStructure=Normal (change to "purchased")
1.1.2 Component 1 --> BOMStructure=Normal (change to "purchased")
I found some macro codes which allow transverse through the subassemblies of an assembly, but I'm not able to change the BOMStructure of subassemblies. Any suggestion how could I manage it?
This is the code I've recently found in this forum:
Public Sub Main() ' Get the active assembly. Dim oAsmDoc As AssemblyDocument oAsmDoc = ThisApplication.ActiveDocument Call TraverseAssembly(oAsmDoc.ComponentDefinition.Occurrences, 1) End Sub Private Sub TraverseAssembly(Occurrences As ComponentOccurrences, _ Level As Integer) Dim oOcc As ComponentOccurrence For Each oOcc In Occurrences Try oOcc.Definition.BOMStructure = BOMStructureEnum.kPhantomBOMStructure Catch 'MsgBox(oOcc.Name & "remains unchanged") End Try ' Check to see if this occurrence represents a subassembly ' and recursively call this function to traverse through it. If oOcc.DefinitionDocumentType = kAssemblyDocumentObject Then Call TraverseAssembly(oOcc.SubOccurrences, Level + 1) End If Next End Sub
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
There were a couple of things that needed to be changed to make it work. First of all, you were trying to change the BOMStructure of the component's definition, not of the component itself. You had to remove a level from that line of code. Second, the Sub was designed to recieve a 'ComponentOccurrences' object, which comes from the ComponentDefinition.Occurrences, but you were supplying oOcc.SubOccurrences, which is a ComponentOccurrencesEnumerator, to that Sub within the TraverseAssembly Sub's code. On another note, in your post you said you were working with 'Purchased' main assembly, and wanted to set all components within to 'Purchased' BOMStructure, but your code was trying to set them all to 'Phantom' BOMStructure, so I changed that part too. I added some code to the main Sub that gets the BOMStructure of the main assembly, then uses that as the basis to set everything under it.
Here is the new code:
Public Sub Main()
Dim oAsmDoc As AssemblyDocument = ThisApplication.ActiveDocument
'get the BOMStructure status of the main assembly
oBOMSt = oAsmDoc.ComponentDefinition.BOMStructure
'now push that to all sub assemblies and components at all levels within
TraverseAssembly(oAsmDoc.ComponentDefinition.Occurrences, oBOMSt)
End Sub
Private Sub TraverseAssembly(Occurrences As ComponentOccurrences, oBOMStr As BOMStructureEnum)
For Each oOcc As ComponentOccurrence In Occurrences
Try
oOcc.BOMStructure = oBOMStr
Catch
MsgBox(oOcc.Name & "remains unchanged")
End Try
' Check to see if this occurrence represents a subassembly
' and recursively call this function to traverse through it.
If oOcc.DefinitionDocumentType = kAssemblyDocumentObject Then
TraverseAssembly(oOcc.Definition.Occurrences, oBOMStr)
End If
Next
End Sub
If this solved your problem, or answered your question, please click ACCEPT SOLUTION.
Or, if this helped you, please click (LIKE or KUDOS)
.
If you want and have time, I would appreciate your Vote(s) for My IDEAS
or you can Explore My CONTRIBUTIONS
Wesley Crihfield
(Not an Autodesk Employee)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi WCrihfield, thank you for your answer. You were right, the code I attached to my post doesn´t exactl...
If I´m not wrong, firstly your code take the "BOMStructure" of the main assembly and set this "BOMStructure" to all its parts and subassemblies, right?. That´s not exactly what I´d like to manage, but maybe I explained badly, sorry. This is what I was trying to get:
1- Traverse main assembly
2- Check "BOMStructure" of its subassemblies. In case the "BOMStructure" is "purchased" then set the "BOMStructure" of all parts and subassemblies contained in such subassembly to "purchased" too. If "BOMStructure" is different to "purchased", nothing happens.
Anyway, I´ve tried your code and I don´t know why but it gives an error of "procedure call" in this part "oOcc.BOMStructure = oBOMStr".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
You are correct about the purpose of the code I posted.
I believe I now better understand what you actually wanted, and have changed the code as I believe was needed.
This new code now doesn't bother checking the BOMStructure of the main assembly. It now only loops through the first/top level components, and processes the sub assemblies. And it will only process that sub assembly if it's BOMStructure is currently set to Purchased. It then loops through just the first/top level components within that sub assembly, and changes each component's BOMStructure to Purchased, to match the sub assembly. I hope I was correct in assuming you only wanted the first level of components within each purchased sub assembly to be set to Purchased, and not attempting to dig down any deeper.
Here is the new code:
Public Sub Main()
Dim oAsmDoc As AssemblyDocument = ThisApplication.ActiveDocument
oOccs = oAsmDoc.ComponentDefinition.Occurrences
For Each oOcc As ComponentOccurrence In oOccs
'If it's not an Assembly, don't process it
If oOcc.DefinitionDocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then Continue For
'If it's not Purchased, don't process it
If oOcc.BOMStructure <> BOMStructureEnum.kPurchasedBOMStructure Then Continue For
'loop all first level components within this Purchased sub assembly
For Each oComp As ComponentOccurrence In oOcc.Definition.Occurrences
'if not already Purchased, then set to Purchased
If oComp.BOMStructure <> kPurchasedBOMStructure Then
oComp.BOMStructure = kPurchasedBOMStructure
End If
Next
Next
End Sub
Wesley Crihfield
(Not an Autodesk Employee)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Here is a version of that same rule that will dig down through all levels under the purchased sub assemblies to set them all to Purchased, just in case that is what you really wanted.
Sub Main()
Dim oAsmDoc As AssemblyDocument = ThisApplication.ActiveDocument
oOccs = oAsmDoc.ComponentDefinition.Occurrences
For Each oOcc As ComponentOccurrence In oOccs
'If it's not an Assembly, don't process it
If oOcc.DefinitionDocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then Continue For
'If it's not Purchased, don't process it
If oOcc.BOMStructure <> BOMStructureEnum.kPurchasedBOMStructure Then Continue For
StepDown(oOcc.Definition.Occurrences)
Next
End Sub
Sub StepDown(oComps As ComponentOccurrences)
For Each oComp As ComponentOccurrence In oComps
If oComp.BOMStructure <> BOMStructureEnum.kPurchasedBOMStructure Then
oComp.BOMStructure =BOMStructureEnum.kPurchasedBOMStructure
End If
If oComp.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
StepDown(oComp.Definition.Occurrences)
End If
Next
End Sub
Wesley Crihfield
(Not an Autodesk Employee)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Thank you, your second code is exactly what I was trying to get.
However, when the macro runs an "argument not optional error" appears in this part of the code "StepDown (oOcc.Definition.Occurrences)".
Any suggestion why does it happen?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
That's an odd sounding error, so I'm not entirely sure what it means. I'm guessing there may be more properties of the ComponentOccurrence that we need to be checking for, to help avoid potential errors. For instance, we may need to check the values of these:
ComponentOccurrence.Suppressed
ComponentOccurrence.Enabled
ComponentOccurrence.DisabledActionTypes = ActionTypeEnum.kRestructureAction (not sure about this one)
ComponentOccurrence.IsAssociativelyImported (not sure if this would be a problem)
ComponentOccurrence.IsiAssemblyMember (not sure if this would be a problem)
I'm also not sure if current ModelState settings might be preventing us from changing the BOMStructure, but I don't recall this being one of the things the ModelState us supposed to be handling. I do know they record which components are suppressed, because that was one of the main purposes of the LevelOfDetail representations, which these new ModelStates are replacing.
I added those first 3 checks into the code, then also incorporated a Try...Catch block in there at the only line that is trying to do something, to catch any possible error, report them, and allow the code to continue. Give this a try.
Sub Main()
Dim oAsmDoc As AssemblyDocument = ThisApplication.ActiveDocument
oOccs = oAsmDoc.ComponentDefinition.Occurrences
For Each oOcc As ComponentOccurrence In oOccs
'If it's not an Assembly, don't process it
If oOcc.DefinitionDocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then Continue For
'If it's not Purchased, don't process it
If oOcc.BOMStructure <> BOMStructureEnum.kPurchasedBOMStructure Then Continue For
If oOcc.DisabledActionTypes = ActionTypeEnum.kRestructureAction Then Continue For
If oOcc.Suppressed Or oOcc.Enabled = False Then Continue For
StepDown(oOcc.Definition.Occurrences)
Next
End Sub
Sub StepDown(oComps As ComponentOccurrences)
For Each oComp As ComponentOccurrence In oComps
If oComp.BOMStructure <> BOMStructureEnum.kPurchasedBOMStructure Then
If oComp.DisabledActionTypes = ActionTypeEnum.kRestructureAction Then Continue For
If oComp.Suppressed Or oComp.Enabled = False Then Continue For
Try
oComp.BOMStructure = BOMStructureEnum.kPurchasedBOMStructure
Catch oEx As Exception
MsgBox("Failed to set BOMStructure to Purchased." & vbCrLf & _
oEx.Message & vbCrLf & oEx.StackTrace, vbExclamation, "iLogic")
End Try
End If
If oComp.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
StepDown(oComp.Definition.Occurrences)
End If
Next
End Sub
Wesley Crihfield
(Not an Autodesk Employee)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I've tried your code, although I modified it a bit in order to use it in VBA.
However the error still appears in the same line, so it seems that it doesn't the problem.
This is the first part of your code:
Sub Main()
Dim oAsmDoc As AssemblyDocument
Set oAsmDoc = ThisApplication.ActiveDocument
Dim oOccs As ComponentOccurrences
Set oOccs = oAsmDoc.ComponentDefinition.Occurrences
Dim oOcc As ComponentOccurrence
For Each oOcc In oOccs
'If it's not an Assembly, don't process it
If Not oOcc.DefinitionDocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then
'If it's not Purchased, don't process it
If Not oOcc.BOMStructure <> BOMStructureEnum.kPurchasedBOMStructure Then
If Not oOcc.DisabledActionTypes = ActionTypeEnum.kRestructureAction Then
If Not oOcc.Suppressed Or oOcc.Enabled = False Then
StepDown (oOcc.Definition.Occurrences)
End If
Next
End Sub
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I finally wrote a code that it works how I needed. I'm sure that there is probably a better way to do it, but this is the only solution I found.
Sub BOMStructure()
Dim oAsmDoc As AssemblyDocument
Set oAsmDoc = ThisApplication.ActiveDocument
Call TraverseAssembly(oAsmDoc.ComponentDefinition.Occurrences)
End Sub
Private Sub TraverseAssembly(Occurrences As ComponentOccurrences)
Dim oOcc As ComponentOccurrence
For Each oOcc In Occurrences
If oOcc.DefinitionDocumentType = kAssemblyDocumentObject And oOcc.BOMStructure = kPurchasedBOMStructure Then
Dim SubItem, x As Long
SubItem = oOcc.SubOccurrences.Count
For x = 1 To SubItem
oOcc.SubOccurrences.item(x).Definition.BOMStructure = BOMStructureEnum.kPurchasedBOMStructure
Next
End If
Next
End Sub