VBA Edit BOM

VBA Edit BOM

Anonymous
Not applicable
5,670 Views
15 Replies
Message 1 of 16

VBA Edit BOM

Anonymous
Not applicable

I'm trying to write a VBA maacro, which when launched in an assembly will go  through the BOM and modify the part number of each component.

 

Some components have "." in the part number, I need to remove "." and everything after it.

 

I can't figure out where the "part number" property resides

 

 

Public Sub CleanWireBOM()
    Dim asmDoc As AssemblyDocument
    Set asmDoc = ThisApplication.ActiveDocument
    Dim oBOM As BOM
    Set oBOM = asmDoc.ComponentDefinition.BOM
    oBOM.StructuredViewFirstLevelOnly = False
    oBOM.StructuredViewEnabled = True
    Dim oStructuredBOMView As BOMView
    Set oStructuredBOMView = oBOM.BOMViews.Item("Structured")
    Dim oBOMRow As BOMRow
    
    For Each oBOMRow In oStructuredBOMView.BOMRows
        Dim oCompDef As ComponentDefinition
        Dim PartNum As String
        PartNum =  ?????
        
    Next
End Sub
0 Likes
Accepted solutions (1)
5,671 Views
15 Replies
Replies (15)
Message 2 of 16

bradeneuropeArthur
Mentor
Mentor

this should do:

 

Public Sub CleanWireBOM()
    Dim asmDoc As AssemblyDocument
    Set asmDoc = ThisApplication.ActiveDocument
    Dim oBOM As BOM
    Set oBOM = asmDoc.ComponentDefinition.BOM
    oBOM.StructuredViewFirstLevelOnly = False
    oBOM.StructuredViewEnabled = True
    Dim oStructuredBOMView As BOMView
    Set oStructuredBOMView = oBOM.BOMViews.Item("Structured")
    Dim oBOMRow As BOMRow
    
    For Each oBOMRow In oStructuredBOMView.BOMRows
    Dim a As Document
    Set a = oBOMRow.ComponentDefinitions.Item(1).Document
    MsgBox a.FullDocumentName
    
    Dim p As PropertySet
    Set p = a.PropertySets.Item(3)
    
    Dim pr As Property
    Set pr = p.Item("Part Number")
    Dim arr() As String
    On Error Resume Next
    arr = Split(pr.Value, ".", -1)
    Err.Clear
    pr.Value = arr(0)
    a.Save

    Next
End Sub

 

Because you asked the BOM iteration.

This can be different the all ref documents!! 

Regards,

Arthur Knoors

Autodesk Affiliations & Links:
blue LinkedIn LogoSquare Youtube Logo Isolated on White Background


Autodesk Software:Inventor Professional 2025 | Vault Professional 2024 | Autocad Mechanical 2024
Programming Skills:Vba | Vb.net (Add ins Vault / Inventor, Applications) | I-logic
Programming Examples:
Drawing List!|
Toggle Drawing Sheet!|
Workplane Resize!|
Drawing View Locker!|
Multi Sheet to Mono Sheet!|
Drawing Weld Symbols!|
Drawing View Label Align!|
Open From Balloon!|
Model State Lock!
Posts and Ideas:
My Ideas|
Dimension Component!|
Partlist Export!|
Derive I-properties!|
Vault Prompts Via API!|
Vault Handbook/Manual!|
Drawing Toggle Sheets!|
Vault Defer Update!

! For administrative reasons, please mark a "Solution as solved" when the issue is solved !


 


EESignature

0 Likes
Message 3 of 16

MechMachineMan
Advisor
Advisor

Easier to just iterate through the refdocs...

 

Sub Main()
    Dim oDoc As Document
    Set oDoc = ThisApplication.ActiveDocument

    Dim oRefDoc As Document

    For each oRefDoc in oDoc.AllReferencedDocuments
If oRefDoc.isModifiable = True Then oPN = oRefDoc.PropertySets("Design Tracking Properties")("Part Number").Value

Dim arr() As String
On Error Resume Next arr = Split(oPN, ".", -1)
oPN = arr(0) Err.Clear

oRefDoc.PropertySets("Design Tracking Properties")("Part Number").Value = oPN
End if
Next
End Sub

 


--------------------------------------
Did you find this reply helpful ? If so please use the 'Accept as Solution' or 'Like' button below.

Justin K
Inventor 2018.2.3, Build 227 | Excel 2013+ VBA
ERP/CAD Communication | Custom Scripting
Machine Design | Process Optimization


iLogic/Inventor API: Autodesk Online Help | API Shortcut In Google Chrome | iLogic API Documentation
Vb.Net/VBA Programming: MSDN | Stackoverflow | Excel Object Model
Inventor API/VBA/Vb.Net Learning Resources: Forum Thread

Sample Solutions:Debugging in iLogic ( and Batch PDF Export Sample ) | API HasSaveCopyAs Issues |
BOM Export & Column Reorder | Reorient Skewed Part | Add Internal Profile Dogbones |
Run iLogic From VBA | Batch File Renaming| Continuous Pick/Rename Objects

Local Help: %PUBLIC%\Documents\Autodesk\Inventor 2018\Local Help

Ideas: Dockable/Customizable Property Browser | Section Line API/Thread Feature in Assembly/PartsList API Static Cells | Fourth BOM Type
0 Likes
Message 4 of 16

Anonymous
Not applicable

Thank you for the quick responses. The code works well for regular parts & assemblies but not for cable/harness (which is what I was hoping to use it for).

My assembly consists of:

Connector1

Connector2

Cable1

 -> Wire1

 -> Wire2

 -> Wire3

 

Cable1 is set to "Phantom" in the BOM to promote the individual wires.

When I run the code with a debug statement

 

Debug.Print oBOMRow.ItemNumber, "-", pr.Value, vbCr

 

I get:

 

 

1             -             C1            

2             -             Cable1        

3             -             Cable1        

4             -             Cable1        

 

 

I guess the individual wires don't have their own "documents". So how can I access their part numbers?

Same thing happens if I add a "Virtual" component to the top level assembly. The code doesn't pick up it's part number.

I have tried setting the BOM to both "Structured" and "Parts Only" but the results is the same.

0 Likes
Message 5 of 16

smilinger
Advisor
Advisor
Accepted solution

Try this then:

 

Sub CleanWireBOM()
    Dim asmDoc As AssemblyDocument
    Set asmDoc = ThisApplication.ActiveDocument
    
    Dim oBom As BOM
    Set oBom = asmDoc.ComponentDefinition.BOM
    oBom.StructuredViewEnabled = True
    oBom.StructuredViewFirstLevelOnly = False
    Dim oBOMView As BOMView
    Set oBOMView = oBom.BOMViews(2)
    
    Dim compDef As ComponentDefinition
    Dim doc As Document
    Dim row As BOMRow
    Dim prop As Property
    For Each row In oBOMView.BOMRows
        Set compDef = row.ComponentDefinitions(1)
        Set doc = compDef.Document
        If compDef.Type = kVirtualComponentDefinitionObject Then
            Set prop = compDef.PropertySets("Design Tracking Properties")("Part Number")
        Else
            Set prop = doc.PropertySets("Design Tracking Properties")("Part Number")
        End If
        
        If doc.IsModifiable Then
            If prop.Value <> "" Then prop.Value = Split(prop.Value, ".")(0)
        End If
    Next
End Sub
Message 6 of 16

Anonymous
Not applicable

Hello there! 

 

So far I haven't been able to find a tutorial or instructions on how to do a BOM modification and this thread is the closest thing I have found so far 

 

Please see my picture:

 

Basically,2.PNG if we have 2 E-stops, BOM will list it as:

Main-Estop       AB          800T-FX6A5     qty            TAG1

Panel E-Stop    Blank      Blank                                  TAG2

 

And I basically want to do,  

Main-Estop       AB          800T-FX6A5     qty            TAG1,TAG2,TAG3 ETC......

 

I can do it manually but it takes a lot of time

 

Any help or link will be totally appreciated 

 

Thank you  

0 Likes
Message 7 of 16

lihouxin065
Advocate
Advocate

I need to code by Inventor iLogic rules ,Would you do me a favor?

0 Likes
Message 8 of 16

A.Acheson
Mentor
Mentor

Use find and replace tool to remove the word "Set".

Create a sub routine called Sub Main and set up like this. 

 

Sub Main
CleanWireBOM()
End Sub

 

 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
Message 9 of 16

lihouxin065
Advocate
Advocate

lihouxin065_0-1670894028422.png

0 Likes
Message 10 of 16

lihouxin065
Advocate
Advocate

Sub Main CleanWireBOM() End Sub Sub CleanWireBOM() Dim asmDoc As AssemblyDocument asmDoc = ThisApplication.ActiveDocument Dim oBom As BOM oBom = asmDoc.ComponentDefinition.BOM oBom.StructuredViewEnabled = True oBom.StructuredViewFirstLevelOnly = False Dim oBOMView As BOMView oBOMView = oBom.BOMViews(2) Dim compDef As ComponentDefinition Dim doc As Document Dim row As BOMRow Dim prop As Property For Each row In oBOMView.BOMRows compDef = row.ComponentDefinitions(1) doc = compDef.Document If compDef.Type = kVirtualComponentDefinitionObject Then prop = compDef.Propertys("Design Tracking Properties")("Part Number") Else prop = doc.Propertys("Design Tracking Properties")("Part Number") End If If doc.IsModifiable Then If prop.Value <> "" Then prop.Value = Split(prop.Value, ".")(0) End If Next End Sub

0 Likes
Message 11 of 16

A.Acheson
Mentor
Mentor

A few things when posting the code you can use the special editor to keep the formatting. See below. 

AAcheson_0-1670896439061.png

 

So the property object needs a reference to Inventor so write it it in one of two ways

Inventor.Property
[Property]

In the find and replace of "Set" it unfortunately took it from "PropertySets" which is required.  The below code is functioning. 

Sub Main 
	CleanWireBOM() 
End Sub 
Sub CleanWireBOM()
	
	Dim asmDoc As AssemblyDocument 
	asmDoc = ThisApplication.ActiveDocument 
	
	Dim oBom As BOM 
	oBom = asmDoc.ComponentDefinition.BOM 
	
	oBom.StructuredViewEnabled = True 
	oBom.StructuredViewFirstLevelOnly = False 
	
	Dim oBOMView As BOMView 
	oBOMView = oBom.BOMViews(2) 
	
	Dim compDef As ComponentDefinition 
	Dim doc As Document 
	Dim row As BOMRow 
	Dim prop As Inventor.Property 
	
	For Each row In oBOMView.BOMRows 
		compDef = row.ComponentDefinitions(1) 
		doc = compDef.Document 
		
		If compDef.Type = kVirtualComponentDefinitionObject Then 
			prop = compDef.PropertySets("Design Tracking Properties")("Part Number") 
		Else 
			prop = doc.PropertySets("Design Tracking Properties")("Part Number") 
		End If 
		If doc.IsModifiable Then 
			If prop.Value <> "" Then prop.Value = Split(prop.Value, ".")(0) 
		End If 
	Next 
End Sub

 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
Message 12 of 16

lihouxin065
Advocate
Advocate

Thank you very much for your reply, it looks like it only works for non-virtual parts, not for wires, cables, etc.

20221217194520.png

0 Likes
Message 13 of 16

A.Acheson
Mentor
Mentor

I think the issue is the nested sub assemblies of the structured BOM. There is no recursion on that rule so anything inside assemblies is ignored. You can use the parts only BOM and effect the parts. 

Change this line from index of 2 to 3 or use the string "Parts Only"

oBOMView = oBom.BOMViews("Parts Only") 'index 2 is "Structured",'index 3 is "Parts Only"

 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
Message 14 of 16

lihouxin065
Advocate
Advocate

Thank you for your patient guidance. After making some changes, it will also have an effect on virtual parts. The contents before the first "." from the left in the original part number are retained.

What should I do if I need to retain the content before the first "." from the right?

clear the contents enclosed by the blue curveclear the contents enclosed by the blue curve

 

Sub Main 
	CleanWireBOM() 
End Sub 
Sub CleanWireBOM()
	
	Dim asmDoc As AssemblyDocument 
	asmDoc = ThisApplication.ActiveDocument 
	
	Dim oBom As BOM 
	oBom = asmDoc.ComponentDefinition.BOM 
	
	oBom.StructuredViewEnabled = True 
	oBom.StructuredViewFirstLevelOnly = False 
	oBom.PartsOnlyViewEnabled = True 
	
	Dim oBOMView As BOMView 
	oBOMView = oBom.BOMViews(3) 'index 2 is "Structured",'index 3 is "Parts Only"
	
	Dim compDef As ComponentDefinition 
	Dim doc As Document 
	Dim row As BOMRow 
	Dim prop As Inventor.Property 
	
	For Each row In oBOMView.BOMRows 
		compDef = row.ComponentDefinitions(1) 
		doc = compDef.Document 
		
		If compDef.Type = kVirtualComponentDefinitionObject Then 
			prop = compDef.PropertySets("Design Tracking Properties")("Part Number") 
		Else 
			prop = doc.PropertySets("Design Tracking Properties")("Part Number") 
		End If 
		If doc.IsModifiable Then 
			If prop.Value <> "" Then prop.Value = Split(prop.Value, ".")(0) 
		End If 
	Next 
End Sub

 

 

0 Likes
Message 15 of 16

A.Acheson
Mentor
Mentor

You can remove the Split line and find the location of the right most deliminator then count from the left. Here is a sample. InStrRev function offical documentation

Dim TestText As String = "1234.456.789"
Dim RightDelim As Integer  = InStrRev(TestText, ".")
Dim Value As String = Left(TestText, RightDelim - 1)

 And here is how it will work in the rule. The only down side, if you run the rule twice you will remove more of the string. A work around could be to count the delimitators from the left if that is consistently 2x

If doc.IsModifiable Then 
  If prop.Value <> "" Then 
     Dim ChangeText As String = prop.Value
     Dim RightDelim As Integer  = InStrRev(ChangeText, ".")
     If RightDelim > 0 Then
	     prop.Value = Left(ChangeText, RightDelim - 1)
     End If
   End If
End If

 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
Message 16 of 16

lihouxin065
Advocate
Advocate

Thank you so much!

   The code can intercept the required characters as expected, but when dealing with the whole BOM, the wires, cables, and some virtual parts by length are merged and retaken in order, some lines are not processed after running the code.

How should I fix this problem.

 

before  running the codebefore running the code

 

 

after running the codeafter running the code

 

Sub Main 
	CleanWireBOM()
	MessageBox.Show("Done", "CleanWireBOM")

End Sub 
Sub CleanWireBOM()
	
	Dim asmDoc As AssemblyDocument 
	asmDoc = ThisApplication.ActiveDocument 
	
	Dim oBom As BOM 
	oBom = asmDoc.ComponentDefinition.BOM 
	
	oBom.StructuredViewEnabled = True 
	oBom.StructuredViewFirstLevelOnly = False 
	oBom.PartsOnlyViewEnabled = True 
	
	Dim oBOMView As BOMView 
	oBOMView = oBom.BOMViews(3) 'index 2 is "Structured",'index 3 is "Parts Only"
	
	Dim compDef As ComponentDefinition 
	Dim doc As Document 
	Dim row As BOMRow 
	Dim prop As Inventor.Property 
	
	For Each row In oBOMView.BOMRows 
		compDef = row.ComponentDefinitions(1) 
		doc = compDef.Document 
		
		If compDef.Type = kVirtualComponentDefinitionObject Then 
			prop = compDef.PropertySets("Design Tracking Properties")("Part Number") 
		Else 
			prop = doc.PropertySets("Design Tracking Properties")("Part Number") 
		End If 
		If doc.IsModifiable Then 
		  If prop.Value <> "" Then 
		     Dim ChangeText As String = prop.Value
		     Dim RightDelim As Integer  = InStrRev(ChangeText, ".")
		     If RightDelim > 0 Then
			     prop.Value = Left(ChangeText, RightDelim - 1)
		     End If
		   End If
		End If
	Next 
End Sub

 

0 Likes