Search Assembly from Drawing for iProperties to create custom table from list

Search Assembly from Drawing for iProperties to create custom table from list

KWarrenCA
Advocate Advocate
2,060 Views
23 Replies
Message 1 of 24

Search Assembly from Drawing for iProperties to create custom table from list

KWarrenCA
Advocate
Advocate

I'm looking for some help on iLogic to create a custom table on a drawing after looking through the assembly of parts and sub assembly iProperties to find any that have the value ACC in the cost center. Then it will put the stock number of those files in the custom table to show that those are the accessories required for the full assembly. I was able to find this code from Clint Brown that can take an assembly and put it in a text file but I'd like to try and stream line it and possibly put the quantity of accessories needed in the table as well.

 

Sub Main()
Dim oAsmDoc As AssemblyDocument 
oAsmDoc = ThisApplication.ActiveDocument  

Dim oAppend As System.IO.StreamWriter
oAppend = IO.File.AppendText("C:\Temp\iProperties.txt")
oAppend.WriteLine("ACCESSORY LIST: " & ThisDoc.PathAndFileName(True))
oAppend.Flush()
oAppend.Close()

Call Iterate(oAsmDoc.ComponentDefinition.Occurrences, 1)
End Sub 

Private Sub Iterate(Occurrences As ComponentOccurrences, Level As Integer) 
'Iterate through Assembly
Dim oOcc As ComponentOccurrence 
For Each oOcc In Occurrences 

'Find Parts in Assembly
Dim oPart As String
oPart = oOcc.Name
Try 

'Write iProps to Parts
If iProperties.Value(oPart,"Design Tracking Properties", "Cost Center") = "ACC" Then
	oInfo = iProperties.Value(oPart, "Design Tracking Properties", "Stock Number") & " - " & iProperties.Value(oPart,"Design Tracking Properties", "Cost Center") 

	'____Open and append to an existing text file_______
Dim oAppend As System.IO.StreamWriter
oAppend = IO.File.AppendText("C:\Temp\iProperties.txt")
oAppend.WriteLine(oInfo)
oAppend.Flush()
oAppend.Close()
End If

Catch
MessageBox.Show("Something went wrong", "Check your assembly")
End Try

'Run through the sub assemblies 
If oOcc.DefinitionDocumentType = kAssemblyDocumentObject Then
Call Iterate(oOcc.SubOccurrences, Level + 2) 
End If 
Next

End Sub

 

0 Likes
Accepted solutions (4)
2,061 Views
23 Replies
Replies (23)
Message 2 of 24

A.Acheson
Mentor
Mentor

Hi @KWarrenCA 

Another approach if your open too it is to filter a partlist for the specific items. You can set up a style just for this purpose with the correct  columns etc. Creating a custom table is a little trickier and really a partslist is a table allready where you can just leverage the built in tools. 

The only down side I can see to this method is changes to the partlist might affect your filtered partslist untill the rule is ran again. 

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

Andrii_Humeniuk
Advisor
Advisor

Hello. I wrote the code according to your wishes, please check whether this solution suits you.

 

Sub main
	Dim oDoc As Document = ThisApplication.ActiveDocument
	If TypeOf oDoc Is DrawingDocument Then
		Dim oDrawDoc As DrawingDocument = oDoc		
		Dim oRefDoc As DocumentsEnumerator = oDrawDoc.ReferencedDocuments
		If oRefDoc.Count > 0 Then
			If TypeOf oRefDoc.Item(1) Is AssemblyDocument Then
				If oRefDoc.Item(1).AllReferencedDocuments.Count > 0 Then
					Call CreatTable(oDrawDoc, oRefDoc.Item(1))
				End If
			Else
				MessageBox.Show("A table can only be created for AssemblyDocument.", "Error!",MessageBoxButtons.OK,MessageBoxIcon.Error)
			End If
		Else
			MessageBox.Show("This drawing not have any document.", "Error!",MessageBoxButtons.OK,MessageBoxIcon.Error)
		End If
	Else
		MessageBox.Show("Active document is not DrawingDocument.", "Error!",MessageBoxButtons.OK,MessageBoxIcon.Error)
	End If
End Sub

Private Function CreatTable(ByVal oDrawDoc As DrawingDocument, ByVal oAssDoc As AssemblyDocument)
	Dim sListInfo As New List(Of String)
	For Each oDoc As Document In oAssDoc.AllReferencedDocuments
		If oDoc.PropertySets.Item("Design Tracking Properties").Item("Cost Center").Value = "ACC" Then
			sListInfo.Add(oDoc.PropertySets.Item("Design Tracking Properties").Item("Stock Number").Value)
		End If
	Next
	If sListInfo.Count = 0 Then
		MessageBox.Show("AssemblyDocument does not have components with 'ACC' parametry.", "Error!",MessageBoxButtons.OK,MessageBoxIcon.Error)
		Exit Function
	End If
	sListInfo.Sort()
	Dim sNameTable As String = "ACCESSORY LIST: " & System.IO.Path.GetFileNameWithoutExtension(oAssDoc.FullDocumentName)
	Dim oCustomTable As CustomTable
	For Each otable As CustomTable In oDrawDoc.ActiveSheet.CustomTables
		If otable.Title = sNameTable Then
			oCustomTable = otable
		End If
	Next
	If oCustomTable Is Nothing Then
		Dim oTitles(1) As String
		oTitles(0) = "Item"
		oTitles(1) = "Stock Number"
		Dim oPlacementPoint As Point2d = ThisApplication.TransientGeometry.CreatePoint2d(15, 15)
		oCustomTable = oDrawDoc.ActiveSheet.CustomTables.Add(sNameTable, oPlacementPoint, 2, sListInfo.Count, oTitles)
		oCustomTable.Columns.Item(1).Width = 1.2
		oCustomTable.Columns.Item(2).Width = 7.8
		oCustomTable.ShowTitle = True
	Else
		If oCustomTable.Rows.Count < sListInfo.Count Then
			For i = oCustomTable.Rows.Count+1 To sListInfo.Count
				oCustomTable.Rows.Add()
			Next i
		Else If oCustomTable.Rows.Count > sListInfo.Count Then
			For i = oCustomTable.Rows.Count To sListInfo.Count+1 Step -1
				oCustomTable.Rows.Item(i).Delete()
			Next i
		End If
	End If
	For i = 1 To sListInfo.Count
		oCustomTable.Rows.Item(i).Item(1).Value = i
		oCustomTable.Rows.Item(i).Item(2).Value = sListInfo.Item(i-1)
	Next i
End Function

Andrii Humeniuk - CAD Coordinator, Autodesk Certified Instructor

LinkedIn | My free Inventor Addin | My Repositories

Did you find this reply helpful ? If so please use the Accept as Solution/Like.

EESignature

0 Likes
Message 4 of 24

A.Acheson
Mentor
Mentor

Hi @KWarrenCA 

Here is the partslist approach. Requirements are a partslist with title called  "ACCESSORIES" and a column called COST CENTER which is the iProperty of COST CENTER.

Dim drawDoc As DrawingDocument = ThisDoc.Document
Dim sht As Sheet = drawDoc.ActiveSheet
Dim pl As PartsList
Dim PLRow As PartsListRow
For Each pl In sht.PartsLists
	If  pl.Title = "ACCESSORIES" Then 
		For i As Integer = 1 To 300
			Try
				PLRow = pl.PartsListRows(i)
				'Logger.Info("PLRow: " & i)
				Try
					plRow.Expanded = True
				Catch
				End Try
				
				If plRow.Item("COST CENTER").Value = "ACC" Then
					Logger.Info("PLRow Spare Part: " & i)
					plRow.Visible = True	
				Else
					plRow.Visible = False
				End If
			Catch
				Exit For
			End Try

		Next
	End If
Next

 

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

KWarrenCA
Advocate
Advocate

@Andrii_Humeniuk This is exactly what I was looking for. Is there a way to add the total quantity of these accessories to the table as well?

 

@A.Acheson That works for the top level assemblies but the way we have our BOM structured it won't get the accessories in the sub-assemblies.

0 Likes
Message 6 of 24

Andrii_Humeniuk
Advisor
Advisor

Hi. Can your accessories be parts only or parts and assemblies?

Andrii Humeniuk - CAD Coordinator, Autodesk Certified Instructor

LinkedIn | My free Inventor Addin | My Repositories

Did you find this reply helpful ? If so please use the Accept as Solution/Like.

EESignature

0 Likes
Message 7 of 24

KWarrenCA
Advocate
Advocate

@Andrii_Humeniuk  They can be either parts or assemblies.

0 Likes
Message 8 of 24

Andrii_Humeniuk
Advisor
Advisor
Accepted solution

Added a quantity line. The design of the table should be recorded in lines 68-77.

 

Sub main
	Dim oDoc As Document = ThisApplication.ActiveDocument
	If TypeOf oDoc Is DrawingDocument Then
		Dim oDrawDoc As DrawingDocument = oDoc		
		Dim oRefDoc As DocumentsEnumerator = oDrawDoc.ReferencedDocuments
		If oRefDoc.Count > 0 Then
			If TypeOf oRefDoc.Item(1) Is AssemblyDocument Then
				Dim oAssDoc As AssemblyDocument = oRefDoc.Item(1)
				Dim oBOM As BOM = oAssDoc.ComponentDefinition.BOM
				Dim oBOMView As BOMView = GetBOMstructure(oBOM)
				If oBOMView Is Nothing Then Exit Sub
				Dim oListComp As Object = CreateObject("Scripting.Dictionary")
				Call GetListComponents(oBOMView.BOMRows, oListComp)
				Dim sNameTable As String = "ACCESSORY LIST: " & System.IO.Path.GetFileNameWithoutExtension(oAssDoc.FullDocumentName)
				Call CreatTable(oDrawDoc, oListComp, sNameTable)
			Else
				MessageBox.Show("A table can only be created for AssemblyDocument.", "Error!",MessageBoxButtons.OK,MessageBoxIcon.Error)
			End If
		Else
			MessageBox.Show("This drawing not have any document.", "Error!",MessageBoxButtons.OK,MessageBoxIcon.Error)
		End If
	Else
		MessageBox.Show("Active document is not DrawingDocument.", "Error!",MessageBoxButtons.OK,MessageBoxIcon.Error)
	End If
End Sub

Private Function GetBOMstructure(ByVal oBOM As BOM) As BOMView
	Dim sLanguageBOM, sSortItem As String
	
	Select Case ThisApplication.LanguageCode
	Case "en-US"
		sLanguageBOM = "Structure"
	Case "ru-RU"
		sLanguageBOM = "Структурированный"
	Case Else
		Return Nothing
	End Select
	
	If oBOM.StructuredViewEnabled = False Then oBOM.StructuredViewEnabled = True
	If oBOM.StructuredViewFirstLevelOnly = True Then oBOM.StructuredViewFirstLevelOnly = False
	
	Return oBOM.BOMViews.Item(sLanguageBOM)
End Function

Private Function GetListComponents(ByVal oBOMRows As BOMRowsEnumerator, ByRef oListComp As Object)
	Dim oCompDef As ComponentDefinition
	For Each oRow As BOMRow In oBOMRows
		oCompDef = oRow.ComponentDefinitions.Item(1)
		Dim oDoc As Document = oCompDef.Document
		If oDoc.PropertySets.Item("Design Tracking Properties").Item("Cost Center").Value = "ACC" Then
			Dim sStokNumb As String = oDoc.PropertySets.Item("Design Tracking Properties").Item("Stock Number").Value
			oListComp(sStokNumb) = oListComp(sStokNumb) + oRow.ItemQuantity
		End If
		If TypeOf oDoc Is AssemblyDocument Then
			GetListComponents(oRow.ChildRows, oListComp)
		End If
	Next
End Function

Private Function CreatTable(ByVal oDrawDoc As DrawingDocument, oListComp As Object, ByVal sNameTable As String)
	Dim oCustomTable As CustomTable
	For Each otable As CustomTable In oDrawDoc.ActiveSheet.CustomTables
		If otable.Title = sNameTable Then
			oCustomTable = otable
		End If
	Next
	If oCustomTable Is Nothing Then
		Dim oTitles(2) As String
		oTitles(0) = "Item"
		oTitles(1) = "Stock Number"
		oTitles(2) = "Quantity"
		Dim oPlacementPoint As Point2d = ThisApplication.TransientGeometry.CreatePoint2d(15, 15)
		oCustomTable = oDrawDoc.ActiveSheet.CustomTables.Add(sNameTable, oPlacementPoint, 3, oListComp.Count, oTitles)
		oCustomTable.Columns.Item(1).Width = 1.2
		oCustomTable.Columns.Item(2).Width = 7.8
		oCustomTable.Columns.Item(3).Width = 2
		oCustomTable.ShowTitle = True
	Else
		If oCustomTable.Rows.Count < oListComp.Count Then
			For i = oCustomTable.Rows.Count+1 To oListComp.Count
				oCustomTable.Rows.Add()
			Next i
		Else If oCustomTable.Rows.Count > oListComp.Count Then
			For i = oCustomTable.Rows.Count To oListComp.Count+1 Step -1
				oCustomTable.Rows.Item(i).Delete()
			Next i
		End If
	End If
	Dim iList As Long = 1
	For Each Item In oListComp
		oCustomTable.Rows.Item(iList).Item(1).Value = iList
		oCustomTable.Rows.Item(iList).Item(2).Value = Item
		oCustomTable.Rows.Item(iList).Item(3).Value = oListComp(Item)
		iList += 1
	Next
End Function

 

Andrii Humeniuk - CAD Coordinator, Autodesk Certified Instructor

LinkedIn | My free Inventor Addin | My Repositories

Did you find this reply helpful ? If so please use the Accept as Solution/Like.

EESignature

0 Likes
Message 9 of 24

KWarrenCA
Advocate
Advocate

@Andrii_Humeniuk  I keep running into the error on line 42.

 

kwarrenH4ZT3_0-1682344595976.png

 

0 Likes
Message 10 of 24

Andrii_Humeniuk
Advisor
Advisor

What language do you have Inventor in?

Andrii Humeniuk - CAD Coordinator, Autodesk Certified Instructor

LinkedIn | My free Inventor Addin | My Repositories

Did you find this reply helpful ? If so please use the Accept as Solution/Like.

EESignature

0 Likes
Message 11 of 24

KWarrenCA
Advocate
Advocate

@Andrii_Humeniuk Just English.

0 Likes
Message 12 of 24

A.Acheson
Mentor
Mentor

Hi @KWarrenCA 

If your parts are visible in the partslist the rule will find them as the first portion of the rule is to expand all sub assemblies. Is it leaving some sub assemblies closed? If so and the number of total lines is over 300 then just make the counter look over a higher number of lines e.g 1000. 

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

KWarrenCA
Advocate
Advocate

@Andrii_Humeniuk It seems to not matter on how many parts/assemblies are in the assembly it won't get past line 42 that item is a readonly property.

kwarrenH4ZT3_0-1682348718753.png

 

0 Likes
Message 14 of 24

Andrii_Humeniuk
Advisor
Advisor
Accepted solution

OMG! This is my mistake. There is an error in the word "structured":))

 

sLanguageBOM = "Structured"

 

Andrii Humeniuk - CAD Coordinator, Autodesk Certified Instructor

LinkedIn | My free Inventor Addin | My Repositories

Did you find this reply helpful ? If so please use the Accept as Solution/Like.

EESignature

0 Likes
Message 15 of 24

KWarrenCA
Advocate
Advocate

@Andrii_Humeniuk That's what it was. Thank you for the help!!

0 Likes
Message 16 of 24

KWarrenCA
Advocate
Advocate

@Andrii_Humeniuk I've been doing some testing on different assemblies to make sure everything is working correctly but keep running into this error. It seems to be when ran on larger assemblies. How do I change the counter quantity?

kwarrenH4ZT3_0-1682356657775.png

kwarrenH4ZT3_1-1682356682377.png

 

0 Likes
Message 17 of 24

Andrii_Humeniuk
Advisor
Advisor

Try replacing this in the "GetListComponents" function. Lines 45-58

Private Function GetListComponents(ByVal oBOMRows As BOMRowsEnumerator, ByRef oListComp As Object)
	Dim oCompDef As ComponentDefinition
	For Each oRow As BOMRow In oBOMRows
		oCompDef = oRow.ComponentDefinitions.Item(1)
		Dim oDoc As Document = oCompDef.Document
		If oDoc.PropertySets.Item("Design Tracking Properties").Item("Cost Center").Value = "ACC" Then
			Dim sStokNumb As String = oDoc.PropertySets.Item("Design Tracking Properties").Item("Stock Number").Value
			oListComp(sStokNumb) = oListComp(sStokNumb) + oRow.ItemQuantity
		End If
		If oRow.ChildRows IsNot Nothing Then
			GetListComponents(oRow.ChildRows, oListComp)
		End If
	Next
End Function

 

Andrii Humeniuk - CAD Coordinator, Autodesk Certified Instructor

LinkedIn | My free Inventor Addin | My Repositories

Did you find this reply helpful ? If so please use the Accept as Solution/Like.

EESignature

0 Likes
Message 18 of 24

KWarrenCA
Advocate
Advocate

@Andrii_Humeniuk Changing that now makes the rule not run on all assemblies.

0 Likes
Message 19 of 24

Andrii_Humeniuk
Advisor
Advisor
Accepted solution

This is how it should look correctly. Copy it completely and replace it.

 

Sub main
	Dim oDoc As Document = ThisApplication.ActiveDocument
	If TypeOf oDoc Is DrawingDocument Then
		Dim oDrawDoc As DrawingDocument = oDoc		
		Dim oRefDoc As DocumentsEnumerator = oDrawDoc.ReferencedDocuments
		If oRefDoc.Count > 0 Then
			If TypeOf oRefDoc.Item(1) Is AssemblyDocument Then
				Dim oAssDoc As AssemblyDocument = oRefDoc.Item(1)
				Dim oBOM As BOM = oAssDoc.ComponentDefinition.BOM
				Dim oBOMView As BOMView = GetBOMstructure(oBOM)
				If oBOMView Is Nothing Then Exit Sub
				Dim oListComp As Object = CreateObject("Scripting.Dictionary")
				Call GetListComponents(oBOMView.BOMRows, oListComp)
				Dim sNameTable As String = "ACCESSORY LIST: " & System.IO.Path.GetFileNameWithoutExtension(oAssDoc.FullDocumentName)
				Call CreatTable(oDrawDoc, oListComp, sNameTable)
			Else
				MessageBox.Show("A table can only be created for AssemblyDocument.", "Error!",MessageBoxButtons.OK,MessageBoxIcon.Error)
			End If
		Else
			MessageBox.Show("This drawing not have any document.", "Error!",MessageBoxButtons.OK,MessageBoxIcon.Error)
		End If
	Else
		MessageBox.Show("Active document is not DrawingDocument.", "Error!",MessageBoxButtons.OK,MessageBoxIcon.Error)
	End If
End Sub

Private Function GetBOMstructure(ByVal oBOM As BOM) As BOMView
	Dim sLanguageBOM, sSortItem As String	
	Select Case ThisApplication.LanguageCode
	Case "en-US"
		sLanguageBOM = "Structured"
	Case Else
		Return Nothing
	End Select	
	If oBOM.StructuredViewEnabled = False Then oBOM.StructuredViewEnabled = True
	If oBOM.StructuredViewFirstLevelOnly = True Then oBOM.StructuredViewFirstLevelOnly = False	
	Return oBOM.BOMViews.Item(sLanguageBOM)
End Function

Private Function GetListComponents(ByVal oBOMRows As BOMRowsEnumerator, ByRef oListComp As Object)
	Dim oCompDef As ComponentDefinition
	For Each oRow As BOMRow In oBOMRows
		oCompDef = oRow.ComponentDefinitions.Item(1)
		Dim oDoc As Document = oCompDef.Document
		If oDoc.PropertySets.Item("Design Tracking Properties").Item("Cost Center").Value = "ACC" Then
			Dim sStokNumb As String = oDoc.PropertySets.Item("Design Tracking Properties").Item("Stock Number").Value
			oListComp(sStokNumb) = oListComp(sStokNumb) + oRow.ItemQuantity
		End If
		If oRow.ChildRows IsNot Nothing Then
			GetListComponents(oRow.ChildRows, oListComp)
		End If		
	Next
End Function

Private Function CreatTable(ByVal oDrawDoc As DrawingDocument, ByVal oListComp As Object, ByVal sNameTable As String)
	Dim oCustomTable As CustomTable
	For Each otable As CustomTable In oDrawDoc.ActiveSheet.CustomTables
		If otable.Title = sNameTable Then
			oCustomTable = otable
		End If
	Next
	If oCustomTable Is Nothing Then
		Dim oTitles(2) As String
		oTitles(0) = "Item"
		oTitles(1) = "Stock Number"
		oTitles(2) = "Quantity"
		Dim oPlacementPoint As Point2d = ThisApplication.TransientGeometry.CreatePoint2d(15, 15)
		oCustomTable = oDrawDoc.ActiveSheet.CustomTables.Add(sNameTable, oPlacementPoint, 3, oListComp.Count, oTitles)
		oCustomTable.Columns.Item(1).Width = 1.2
		oCustomTable.Columns.Item(2).Width = 7.8
		oCustomTable.Columns.Item(3).Width = 2
		oCustomTable.ShowTitle = True
	Else
		If oCustomTable.Rows.Count < oListComp.Count Then
			For i = oCustomTable.Rows.Count+1 To oListComp.Count
				oCustomTable.Rows.Add()
			Next i
		Else If oCustomTable.Rows.Count > oListComp.Count Then
			For i = oCustomTable.Rows.Count To oListComp.Count+1 Step -1
				oCustomTable.Rows.Item(i).Delete()
			Next i
		End If
	End If
	Dim iList As Long = 1
	For Each Item In oListComp
		oCustomTable.Rows.Item(iList).Item(1).Value = iList
		oCustomTable.Rows.Item(iList).Item(2).Value = Item
		oCustomTable.Rows.Item(iList).Item(3).Value = oListComp(Item)
		iList += 1
	Next
End Function

 

Andrii Humeniuk - CAD Coordinator, Autodesk Certified Instructor

LinkedIn | My free Inventor Addin | My Repositories

Did you find this reply helpful ? If so please use the Accept as Solution/Like.

EESignature

0 Likes
Message 20 of 24

KWarrenCA
Advocate
Advocate

@Andrii_Humeniuk Your the man! That worked on all the assemblies I was having issues with even an assembly with 3121 parts.