Macro if property = "X"

Hello

I have a macro that assigns random colors to parts of an assembly.

I would like this macro to only apply to the component with a custom property "component family" = "1"

Below is my code:

Dim vMatProp As Variant

Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
vMatProp = swModel.MaterialPropertyValues

'Get all elements
If swModel.GetType = swDocPART Then
   vElementArr = swModel.GetBodies2(swAllBodies, False)

       For Each vElement In vElementArr
           Set swElement = vElement
           Randomize
           vMatProp(0) = Rnd 'Red
           vMatProp(1) = Rnd - 255 'Green
           vMatProp(2) = Rnd 'Blue
           vMatProp(3) = Rnd / 2 + 0.5 'Ambient
           vMatProp(4) = Rnd / 2 + 0.5 'Diffuse
           vMatProp(5) = Rnd 'Specular
           vMatProp(6) = Rnd * 0.9 + 0.1 'Shininess
           swElement.MaterialPropertyValues2 = vMatProp
       Next

ElseIf swModel.GetType = swDocASSEMBLY Then
   vElementArr = swModel.GetComponents(True)

       For Each vElement In vElementArr
           Set swElement = vElement
           Randomize
           vMatProp(0) = Rnd * 0.05 + 0.95 'Red
           vMatProp(1) = 0.77 * Rnd + 0.05  'Green
           vMatProp(2) = (1 - 2 * Abs(0.45 - vMatProp(1))) * Rnd + 2 * Abs(0.45 - vMatProp(1))   'Blue
           vMatProp(3) = Rnd / 2 + 0.5 'Ambient
           vMatProp(4) = Rnd / 2 + 0.5 'Diffuse
           vMatProp(5) = Rnd 'Specular
           vMatProp(6) = Rnd * 0.9 + 0.1 'Shininess
           swElement.MaterialPropertyValues = vMatProp
       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

 

Look at this link:

http://help.solidworks.com/2020/English/api/sldworksapi/Get_Custom_Properties_of_Referenced_Part_Example_VB.htm

You should be able to retrieve the info you want and add an additional condition with your property

Thank you sbadenis

First of all, I used the whole first section "If swModel.GetType = swDocPART Then" which I don't use (I'm working at the assembly level)

then, in the list of "Dim", the line

Dim swCustProp As CustomPropertyManager


then, instead of "Get all elements", I paste

' Get the custom property data
Set swCustProp = swModelDocExt.CustomPropertyManager("")
bool = swCustProp.Get4("Property_Name", False, val, valout)

I replace "Property_Name" with "Component family"

But where do I specify the value "1" I am looking for for this property?

 

Hello

In a second type of treatment:

If Valout = "1" then
 xxx
End if

 

Hello

Try with this code:

Dim swApp As Object

Sub main()

Dim swModel As ModelDoc2
Dim swModel2 As ModelDoc2
Dim vMatProp As Variant
Dim swCustProp As CustomPropertyManager
Dim val As String
Dim valout As String
Dim bool As Boolean

Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
vMatProp = swModel.MaterialPropertyValues

If swModel.GetType = swDocPART Then
    MsgBox ("Cette macro n'est à utiliser que sur les assemblages.")
    Exit Sub

ElseIf swModel.GetType = swDocASSEMBLY Then
    vElementArr = swModel.GetComponents(True)
    For Each vElement In vElementArr
        Set swElement = vElement
        Set swModel2 = swElement.GetModelDoc2
        Set swCustProp = swModel2.Extension.CustomPropertyManager("")
        bool = swCustProp.Get4("famille de composant", False, val, valout)
        If valout = "1" Then
            Randomize
            vMatProp(0) = Rnd * 0.05 + 0.95 'Red
            vMatProp(1) = 0.77 * Rnd + 0.05  'Green
            vMatProp(2) = (1 - 2 * Abs(0.45 - vMatProp(1))) * Rnd + 2 * Abs(0.45 - vMatProp(1))   'Blue
            vMatProp(3) = Rnd / 2 + 0.5 'Ambient
            vMatProp(4) = Rnd / 2 + 0.5 'Diffuse
            vMatProp(5) = Rnd 'Specular
            vMatProp(6) = Rnd * 0.9 + 0.1 'Shininess
            swElement.MaterialPropertyValues = vMatProp
        End If
    Next

ElseIf swModel.GetType = swDocDRAWING Then
    MsgBox ("Cette macro n'est à utiliser que sur les assemblages.")
    Exit Sub

End If

swModel.GraphicsRedraw2

End Sub

Kind regards

3 Likes

  @ Cyril.f:

instead of "ElseIf swModel.GetType = swDocASSEMBLY Then"

I paste "If Valout = "1" then"

Result: Compilation error on line

bool = swCustProp.Get4("Component Family", False, Val, Valout) 

Val is a "non-optional argument"

 

@ D.Roger:

No mistake, but nothing happens on my assembly...

It's a shame because for once, the code is understandable at my beginner level, and I can modify it to make the macro evolve

Another question by the way, what should I change if I want to apply the color at the part level and not at the assembly component level?

To retrieve the value of the variable on the part, it must be considered as loaded in Solidworks, so in resolved mode, is this the case in your assembly?

Kind regards

And I think I can answer instead of @Cyril.f , he never told you to replace "ElseIf swModel.GetType = swDocASSEMBLY Then" with "If Valout = "1" then" but answered your question "But where do I specify the value "1" looking for this property?". The solution he gives is exactly the same as mine but without the concrete example...

For the remark "Val is a "non-optional argument", it means that you don't "type" your variable so put a line "Dim Val as String" before ... The same goes for the variable "valout" of course.

Another point, with the lines:

Set swCustProp = swModel2.Extension.CustomPropertyManager("")

bool = swCustProp.Get4("component family", False, val, valout)

If valout = "1" Then

This means that the custom property must be called Component Family, its evaluated value must be 1 , and it must be in the Customize tab . If it is found in the custom properties specific to the configuration then it is not quite the same code that is needed because you have to specify the name of the configuration in which to look for the value, such as the configuration named Default in the following line:

Set swCustProp = swModel2.Extension.CustomPropertyManager("Default").

Kind regards

1 Like

@d.roger , you did well to answer for me. For the rest I completely agree with your analysis.          

1 Like

Thank you for the detailed and didactic answers;)

I just tried with the proposed code, without adding anything, and, oh joy, it works... I don't know where I screwed up on my first try. Sorry for questioning your expertise.

I'll try to add a line to change the parts to solved.

Finally, do you have an idea to apply color at the level of the part and not the assembly component?

 

Hello

My macro seemed to work fine on my test assembly, but on other assemblies, it gets stuck on the line        

Set swCustProp = swModel2.Extension.CustomPropertyManager("")

"Error 91: Object variable or With block variable not defined"

Hello

As already said before:

"To retrieve the value of the variable on the part, it must be considered as loaded in Solidworks, so in solved mode, is this the case in your assembly?"

Kind regards

yes yes, everything is resolved.

So possible that it comes from a part that is in a deleted state...

But anyway, it comes from the line:

"Set swModel2 = swElement.GetModelDoc2"

which crashes because the macro does not find the ModelDoc2 of a component for one reason or another (lite mode, deleted state, ...) which returns an error of this type. I see that the error handling has not been done :-) ... As a reminder, the macros given here are only for example and must be reworked to at least add error handling...

Kind regards

indeed, there are...

Add at least the line:

"On Error Resume Next"

Just below the line:

"For Each vElement In vElementArr"

This will have the effect of continuing the loop even if the macro lands on an error.

See HERE.

Kind regards

1 Like

Perfect, it works perfectly!

To improve the thing, I'm going to try to insert a line to switch everything to solved mode. I found this function: "LightweightAllResolved". I'll try to insert it, ideally with a dialog box to confirm.

And the recurring question: if I want to apply color to parts instead of components, I have a hunch that I need to replace this line
vElementArr = swModel.GetComponents

by some chode of the kind
Set swCompModel = swApp.ActivateDoc (or ActivateDoc2 or ActivateDoc3...?)
Am I on the right track?