SolidWorks随机着色宏:如何获取随机生成颜色的参数值以用于其他子程序
Great question! The core issue here is that your current code generates color values locally within the ColorMacro1 sub—they get overwritten each loop iteration and aren't stored for access elsewhere. Let's fix this with a couple of practical approaches that let you reuse those color values in other subs.
Approach 1: Use a Public Collection to Store All Generated Colors
A Collection is perfect here because it can hold multiple color value arrays (one for each part body or assembly component) and is accessible across all subs in your module.
Step 1: Define a Public Collection at the Top of Your Module
Add this line outside of any sub (at the module level) so it's globally accessible:
Dim swApp As Object Dim Part As Object Dim boolstatus As Boolean Dim longstatus As Long, longwarnings As Long ' Public collection to store every generated color set Public GeneratedColors As Collection ' <-- Add this line
Step 2: Modify ColorMacro1 to Save Colors to the Collection
Update your loop logic to save each unique color array to the collection. We'll make a copy of the vMatProp array each time to avoid overwriting existing values:
Public Sub ColorMacro1() Dim swApp As SldWorks.SldWorks Dim swModel As SldWorks.ModelDoc2 Dim swElement As Object Dim vElementArr As Variant Dim vElement As Variant Dim vMatProp As Variant Dim newMatProp As Variant ' <-- Add this to store unique color sets Set swApp = Application.SldWorks Set swModel = swApp.ActiveDoc vMatProp = swModel.MaterialPropertyValues ' Initialize the collection (clear any existing values first) Set GeneratedColors = New Collection 'Get all elements If swModel.GetType = swDocPART Then vElementArr = swModel.GetBodies2(swAllBodies, False) For Each vElement In vElementArr Set swElement = vElement Randomize ' Create a copy of the base material properties to modify newMatProp = vMatProp newMatProp(0) = Rnd 'Red newMatProp(1) = Rnd 'Green newMatProp(2) = Rnd 'Blue newMatProp(3) = Rnd / 2 + 0.5 'Ambient newMatProp(4) = Rnd / 2 + 0.5 'Diffuse newMatProp(5) = Rnd 'Specular newMatProp(6) = Rnd * 0.9 + 0.1 'Shininess swElement.MaterialPropertyValues2 = newMatProp GeneratedColors.Add newMatProp ' Save the color to our public collection Next ElseIf swModel.GetType = swDocASSEMBLY Then vElementArr = swModel.GetComponents(False) For Each vElement In vElementArr Set swElement = vElement Randomize newMatProp = vMatProp newMatProp(0) = Rnd 'Red newMatProp(1) = Rnd 'Green newMatProp(2) = Rnd 'Blue newMatProp(3) = Rnd / 2 + 0.5 'Ambient newMatProp(4) = Rnd / 2 + 0.5 'Diffuse newMatProp(5) = Rnd 'Specular newMatProp(6) = Rnd * 0.9 + 0.1 'Shininess swElement.MaterialPropertyValues = newMatProp GeneratedColors.Add newMatProp ' Save the color to our public collection Next ElseIf swModel.GetType = swDocDRAWING Then MsgBox ("You can only apply random colors to part bodies or assembly components.") Exit Sub End If 'Redraw to see new color swModel.GraphicsRedraw2 End Sub
Step 3: Access the Colors in Another Sub
Now you can create a new sub that uses the saved color values. For example:
Public Sub ReuseGeneratedColors() ' Check if colors have been generated yet If GeneratedColors Is Nothing Then MsgBox "No colors available! Run ColorMacro1 first." Exit Sub End If ' Loop through all saved colors and use them (example: print to debug window) Dim colorSet As Variant Dim index As Integer index = 1 For Each colorSet In GeneratedColors Debug.Print "Color Set " & index & ":" Debug.Print " Red: " & Round(colorSet(0), 4) Debug.Print " Green: " & Round(colorSet(1), 4) Debug.Print " Blue: " & Round(colorSet(2), 4) Debug.Print " Ambient: " & Round(colorSet(3), 4) Debug.Print " Diffuse: " & Round(colorSet(4), 4) Debug.Print " Specular: " & Round(colorSet(5), 4) Debug.Print " Shininess: " & Round(colorSet(6), 4) Debug.Print "-------------------------" index = index + 1 Next End Sub
Approach 2: Create a Reusable Color Generation Function
If you want to generate random colors and access them in any sub (not just after running ColorMacro1), create a standalone function that returns a random color array:
' Returns a randomly generated MaterialPropertyValues array Private Function GetRandomColor() As Variant ' Start with default base values (you could also pull from the active model) Dim colorVals As Variant colorVals = Array(0, 0, 0, 0.5, 0.5, 0.5, 0.5) Randomize colorVals(0) = Rnd ' Red colorVals(1) = Rnd ' Green colorVals(2) = Rnd ' Blue colorVals(3) = Rnd / 2 + 0.5 ' Ambient colorVals(4) = Rnd / 2 + 0.5 ' Diffuse colorVals(5) = Rnd ' Specular colorVals(6) = Rnd * 0.9 + 0.1 ' Shininess GetRandomColor = colorVals End Function
Use This Function in Any Sub
You can call this function in ColorMacro1 and other subs to get random colors:
' Example usage in ColorMacro1 (replace the color generation code) newMatProp = GetRandomColor() swElement.MaterialPropertyValues2 = newMatProp ' Example usage in another sub Public Sub UseRandomColorElsewhere() Dim myColor As Variant myColor = GetRandomColor() ' Use the color values here (e.g., apply to a different element, log them, etc.) MsgBox "Random Red Value: " & Round(myColor(0), 4) End Sub
Key Notes
- Avoid Overwriting Values: Always make a copy of the
vMatProparray (like we did withnewMatProp) instead of modifying the original directly—this prevents overwriting values you want to save. - Collection vs. Array: A
Collectionis easier to work with for variable numbers of elements (like assembly components that can change count), but you could also use a public array if you prefer.
内容的提问来源于stack exchange,提问作者Mark donne

