You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SolidWorks随机着色宏:如何获取随机生成颜色的参数值以用于其他子程序

Solution: Accessing Randomly Generated Color Values in Your SolidWorks VBA Macro

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 vMatProp array (like we did with newMatProp) instead of modifying the original directly—this prevents overwriting values you want to save.
  • Collection vs. Array: A Collection is 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 16:14:04