- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi all,
I want to write an iLogic code that will do the following actions:
1. I will give a list of part names as input
2. The code will parse through a big assembly file (that contains sub-assemblies) to find the parts, and color all of them to a certain color
I have a working version for a code that works for a simple assembly where there's no sub-assembly:
' iLogic rule To color parts In an assembly Using Partial part names
' List of part names (or partial names) to color
Dim partsToColor As String() = {"SAG3YZM5" } ' Add other part names as needed
Dim partsToColorCount As Integer = partsToColor.Length ' Count the number of elements in list so we can set the loop size
Dim colorStyleName As String = "Magenta" ' Replace with desired color style name
' Loop through each component in the assembly
Dim oAssyDoc As AssemblyDocument
oAssyDoc = ThisApplication.ActiveDocument
Dim oCompOccs As ComponentOccurrences
oCompOccs = oAssyDoc.ComponentDefinition.Occurrences
For Each oOcc As ComponentOccurrence In oCompOccs
' Check if the component name contains any of the specified part names
For Index = 1 To partsToColorCount
If oOcc.Name.Contains(partsToColor(Index - 1)) Then 'Subtract 1 since the index of the first element in the array is 0
' Try to set the color of the component
Try
Component.Color(oOcc.Name) = colorStyleName
MessageBox.Show("Colored component: " & oOcc.Name)
Catch
MessageBox.Show("Error setting color for component: " & oOcc.Name)
End Try
End If
Next
NextHowever, when I try to expand this to bigger assemblies, I couldn't get the code to work:
' iLogic rule To color parts In an assembly Using Partial part names
Sub Main
' List of part names (or partial names) to color
Dim partsToColor As String() = {"SAG3YZM5" } ' Add other part names as needed
Dim partsToColorCount As Integer = partsToColor.Length ' Count the number of elements in list so we can set the loop size
Dim colorStyleName As String = "Magenta" ' Replace with desired color style name
' Loop through each component in the assembly
Dim oAssyDoc As AssemblyDocument
oAssyDoc = ThisApplication.ActiveDocument
oAssyDocType = oAssyDoc.DocumentType
If oAssyDocType <> DocumentTypeEnum.kAssemblyDocumentObject Then
MessageBox.Show("This process only runs on assemblies.")
Exit Sub
Else
Call ColorAssembly
End If
Dim oCompOccs As ComponentOccurrences
oCompOccs = oAssyDoc.ComponentDefinition.Occurrences
End Sub
Sub ColorAssembly(AssyDocument As AssemblyDocument, FileList())
For Each oOcc As ComponentOccurrence In oCompOccs
If oOcc Is On FileList() Then
Call ColorPart
ElseIf oOcc = Assembly
Call ColorAssembly()
End If
Next
End Sub
Sub ColorPart(OccurenceInAssy As Occurrence)
' Loop through each component in the assembly
Dim oAssyDoc As AssemblyDocument
oAssyDoc = ThisApplication.ActiveDocument
Dim oCompOccs As ComponentOccurrences
oCompOccs = oAssyDoc.ComponentDefinition.Occurrences
For Each oOcc As ComponentOccurrence In oCompOccs
' Check if the component name contains any of the specified part names
For Index = 1 To partsToColorCount
If oOcc.Name.Contains(partsToColor(Index - 1)) Then 'Subtract 1 since the index of the first element in the array is 0
' Try to set the color of the component
Try
Component.Color(oOcc.Name) = colorStyleName
MessageBox.Show("Colored component: " & oOcc.Name)
Catch
MessageBox.Show("Error setting color for component: " & oOcc.Name)
End Try
End If
Next
Next
End SubHere, the code will:
1. Check if an occurrence is a part or assembly
2. If it's a part, then execute the ColorPart subroutine; if it's an assembly, call ColorAssembly subroutine, where it goes into the assembly and look for the parts.
I couldn't get the code to work, and I'm fairly new to VBA. Could anyone help me with my issue?
Thank you so much!
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
@jeyuan, here is an ilogic example that changes the color of all the parts in all sub assemblies, but only applies the colors at the top level assembly.
meaning if you open the parts their color are not changed at that level, and if you open the subassemblies the part colors are not changed at that level... but they all get the color override in the top level assembly.
( p.s. thanks to @Stakin who supplied the color picker example recently)
Imports System.ComponentModel
AddReference "System.drawing"
Imports System.Windows.Forms
Imports System.Drawing
Sub Main
Dim oADoc As AssemblyDocument = ThisApplication.ActiveDocument
Dim oOccs As ComponentOccurrences = oADoc.ComponentDefinition.Occurrences
Dim oColor As Asset = GetColor
Call TraverseAssembly(oOccs, oColor)
End Sub
Sub TraverseAssembly(oOccs As ComponentOccurrences, oColor As Asset)
Dim oOcc As ComponentOccurrence
For Each oOcc In oOccs
If oOcc.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
Call TraverseAssembly(oOcc.SubOccurrences, oColor)
ElseIf oOcc.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject Then
oOcc.Appearance = oColor
End If
Next
End Sub
Function GetColor() As Asset
Dim oClDlg As New System.Windows.Forms.ColorDialog
Dim oColor As System.drawing.Color
If oClDlg.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
oColor = oClDlg.Color
End If
oName = "Paint Color"
Dim oAppearance As Asset
Try 'create new appearance
oAppearance = ThisDoc.Document.Assets.Add(AssetTypeEnum.kAssetTypeAppearance, "Generic", "Appearances", oName)
Catch
oAppearance = ThisDoc.Document.Assets.item(oName)
End Try
'set colors
Dim oNewColor As ColorAssetValue
oNewColor = oAppearance.Item("generic_diffuse")
oNewColor.Value = ThisApplication.TransientObjects.CreateColor(oColor.R, oColor.G, oColor.B)
Return oAppearance
End Function
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
A quick update to the previous example, this one only colors components named in a list
Imports System.ComponentModel
AddReference "System.drawing"
Imports System.Windows.Forms
Imports System.Drawing
Sub Main
Dim myList As New List(Of String)(New String() {"Foo", "Foo Too" }) 'list with part names
Dim oADoc As AssemblyDocument = ThisApplication.ActiveDocument
Dim oOccs As ComponentOccurrences = oADoc.ComponentDefinition.Occurrences
Dim oColor As Asset = GetColor
Call TraverseAssembly(oOccs, oColor, myList)
End Sub
Sub TraverseAssembly(oOccs As ComponentOccurrences, oColor As Asset, myList As List(Of String))
Dim oOcc As ComponentOccurrence
For Each oOcc In oOccs
If oOcc.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
Call TraverseAssembly(oOcc.SubOccurrences, oColor, myList)
ElseIf oOcc.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject Then
If myList.Contains(oOcc.Name) Then oOcc.Appearance = oColor
End If
Next
End Sub
Function GetColor() As Asset
Dim oClDlg As New System.Windows.Forms.ColorDialog
Dim oColor As System.drawing.Color
If oClDlg.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
oColor = oClDlg.Color
End If
oName = "Paint Color"
Dim oAppearance As Asset
Try 'create new appearance
oAppearance = ThisDoc.Document.Assets.Add(AssetTypeEnum.kAssetTypeAppearance,
"Generic", "Appearances", oName)
Catch
oAppearance = ThisDoc.Document.Assets.item(oName)
End Try
'set colors
Dim oNewColor As ColorAssetValue
oNewColor = oAppearance.Item("generic_diffuse")
oNewColor.Value = ThisApplication.TransientObjects.CreateColor(oColor.R, oColor.G, oColor.B)
Return oAppearance
End Function
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi Curtis,
Thank you so much! The code works very well. Now I'm trying to improve the code where the user does not need to supply a list of part names as strings separated by comma, because usually an assembly has too many parts that needs to be colored.
I'm adding the functionality where instead of MyList, the code will parse through the assembly, read the iProperty information, and color the part where "CompliantWithMachine" = No.
The "Compliant with Machine" is a custom iProperty, the type is Yes or No. I'm trying to make the code do three things:
1. If Compliant with Machine = No, color the part
2. If Compliant with Machine = Yes, don't color the part
3. If Compliant with Machine doesn't exist for a part, don't color the part.
My current code is below:
Imports System.ComponentModel
AddReference "System.drawing"
Imports System.Windows.Forms
Imports System.Drawing
Sub Main
Dim oADoc As AssemblyDocument = ThisApplication.ActiveDocument
Dim oOccs As ComponentOccurrences = oADoc.ComponentDefinition.Occurrences
Dim oColor As Asset = GetColor()
' Ensure that a color has been selected
If oColor Is Nothing Then
MessageBox.Show("No color selected. Exiting the script.")
Exit Sub
End If
' Traverse the assembly and color parts where CompliantWithMachine is False
Call TraverseAssembly(oOccs, oColor)
' Show completion message
MessageBox.Show("Coloring successfully completed.")
End Sub
Sub TraverseAssembly(oOccs As ComponentOccurrences, oColor As Asset)
Dim oOcc As ComponentOccurrence
For Each oOcc In oOccs
If oOcc.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
Call TraverseAssembly(oOcc.SubOccurrences, oColor)
ElseIf oOcc.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject Then
Try
' Get the "CompliantWithMachine" property value as a Boolean
Dim CompliantWithMachine As Boolean = False ' Default to False in case of any issues
CompliantWithMachine = oOcc.Definition.PropertySets("Inventor User Defined Properties")("CompliantWithMachine").Value
' Check the property value
If Not CompliantWithMachine Then
' If property = False (equivalent to "No"), color the part
oOcc.Appearance = oColor
Else
End If
Catch
' If the property is missing or an error occurs, do not color the part
End Try
End If
Next
End Sub
Function GetColor() As Asset
Dim oClDlg As New System.Windows.Forms.ColorDialog
Dim oColor As System.Drawing.Color
If oClDlg.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
oColor = oClDlg.Color
Else
Return Nothing
End If
Dim oName As String = "Paint Color"
Dim oAppearance As Asset
Try 'create new appearance
oAppearance = ThisDoc.Document.Assets.Add(AssetTypeEnum.kAssetTypeAppearance,
"Generic", "Appearances", oName)
Catch
oAppearance = ThisDoc.Document.Assets.Item(oName)
End Try
'set colors
Dim oNewColor As ColorAssetValue
oNewColor = oAppearance.Item("generic_diffuse")
oNewColor.Value = ThisApplication.TransientObjects.CreateColor(oColor.R, oColor.G, oColor.B)
Return oAppearance
End FunctionWhen I run the code, no parts are colored.
When I add debugging messages, it shows that all parts are identified as the property doesn't exist, which is not true.
Could you help me with this issue? Thank you so much!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
HI @jeyuan , give this version a try
Imports System.ComponentModel
AddReference "System.drawing"
Imports System.Windows.Forms
Imports System.Drawing
Sub Main
Dim oADoc As AssemblyDocument = ThisApplication.ActiveDocument
Dim oOccs As ComponentOccurrences = oADoc.ComponentDefinition.Occurrences
Dim oColor As Asset = GetColor()
' Ensure that a color has been selected
If oColor Is Nothing Then
MessageBox.Show("No color selected. Exiting the script.")
Exit Sub
End If
' Traverse the assembly and color parts where CompliantWithMachine is False
Call TraverseAssembly(oOccs, oColor)
' Show completion message
MessageBox.Show("Coloring successfully completed.")
End Sub
Sub TraverseAssembly(oOccs As ComponentOccurrences, oColor As Asset)
Dim oOcc As ComponentOccurrence
For Each oOcc In oOccs
If oOcc.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
Call TraverseAssembly(oOcc.SubOccurrences, oColor)
ElseIf oOcc.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject Then
'set default
isCompliant = True
Try
isCompliant = iProperties.Value(oOcc.Name, "Custom", "CompliantWithMachine")
Catch
' If the property is missing or an error occurs, do not color the part
End Try
If isCompliant = False Then oOcc.Appearance = oColor
End If
Next
End Sub
Function GetColor() As Asset
Dim oClDlg As New System.Windows.Forms.ColorDialog
Dim oColor As System.Drawing.Color
If oClDlg.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
oColor = oClDlg.Color
Else
Return Nothing
End If
Dim oName As String = "Paint Color"
Dim oAppearance As Asset
Try 'create new appearance
oAppearance = ThisDoc.Document.Assets.Add(AssetTypeEnum.kAssetTypeAppearance,
"Generic", "Appearances", oName)
Catch
oAppearance = ThisDoc.Document.Assets.Item(oName)
End Try
'set colors
Dim oNewColor As ColorAssetValue
oNewColor = oAppearance.Item("generic_diffuse")
oNewColor.Value = ThisApplication.TransientObjects.CreateColor(oColor.R, oColor.G, oColor.B)
Return oAppearance
End Function
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Also, here is a version that uses a preset/hardcoded color, in case that is preferred over the color picker.
Just change the hardcoded R, G, B values in bold to change the color
You can look up RGB values for colors here:
https://www.rapidtables.com/web/color/RGB_Color.html
Sub Main Dim oADoc As AssemblyDocument = ThisApplication.ActiveDocument Dim oOccs As ComponentOccurrences = oADoc.ComponentDefinition.Occurrences Dim oColor As Asset = GetColor() ' Ensure that a color has been selected If oColor Is Nothing Then MessageBox.Show("No color selected. Exiting the script.") Exit Sub End If ' Traverse the assembly and color parts where CompliantWithMachine is False Call TraverseAssembly(oOccs, oColor) ' Show completion message MessageBox.Show("Coloring successfully completed.") End Sub Sub TraverseAssembly(oOccs As ComponentOccurrences, oColor As Asset) Dim oOcc As ComponentOccurrence For Each oOcc In oOccs If oOcc.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then Call TraverseAssembly(oOcc.SubOccurrences, oColor) ElseIf oOcc.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject Then 'set default isCompliant = True Try isCompliant = iProperties.Value(oOcc.Name, "Custom", "CompliantWithMachine") Catch ' If the property is missing or an error occurs, do not color the part End Try If isCompliant = False Then oOcc.Appearance = oColor End If Next End Sub Function GetColor() As Asset 'hard coded color values 'https://www.rapidtables.com/web/color/RGB_Color.html oRed = 255 oGreen = 0 oBlue = 0 Dim oName As String = "Paint Color" Dim oAppearance As Asset Try 'create new appearance oAppearance = ThisDoc.Document.Assets.Add(AssetTypeEnum.kAssetTypeAppearance, "Generic", "Appearances", oName) Catch oAppearance = ThisDoc.Document.Assets.Item(oName) End Try 'set colors Dim oNewColor As ColorAssetValue oNewColor = oAppearance.Item("generic_diffuse") oNewColor.Value = ThisApplication.TransientObjects.CreateColor(oRed, oGreen, oBlue) Return oAppearance End Function
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report