Change BOMStructure to subassembly when the BOMStructure of assembly is Purchased

Change BOMStructure to subassembly when the BOMStructure of assembly is Purchased

dibujocad
Enthusiast Enthusiast
837 Views
8 Replies
Message 1 of 9

Change BOMStructure to subassembly when the BOMStructure of assembly is Purchased

dibujocad
Enthusiast
Enthusiast

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

 

0 Likes
838 Views
8 Replies
Replies (8)
Message 2 of 9

WCrihfield
Mentor
Mentor

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

EESignature

(Not an Autodesk Employee)

Message 3 of 9

dibujocad
Enthusiast
Enthusiast

Hi 

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".

 

0 Likes
Message 4 of 9

WCrihfield
Mentor
Mentor

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

EESignature

(Not an Autodesk Employee)

Message 5 of 9

WCrihfield
Mentor
Mentor

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

EESignature

(Not an Autodesk Employee)

Message 6 of 9

dibujocad
Enthusiast
Enthusiast

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?

0 Likes
Message 7 of 9

WCrihfield
Mentor
Mentor

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

EESignature

(Not an Autodesk Employee)

0 Likes
Message 8 of 9

dibujocad
Enthusiast
Enthusiast

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

0 Likes
Message 9 of 9

dibujocad
Enthusiast
Enthusiast

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

0 Likes