Macro si propriété = "X"

Bonjour

J'ai une macro qui attribue des couleurs aléatoires aux pièces d'un assemblage.

Je souhaiterais que cette macro ne s'applique qu'au composant ayant une propriété personnalisé "famille de composant" = "1"

Ci dessous mon 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

 

Regarde du côté de ce lien:

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

Tu devrait pouvoir récupérer l'info que tu souhaite et ajouter une condition supplémentaire avec ta propriété

Merci sbadenis

Dans un premier temps, j'aisuprimé toute la première section "If swModel.GetType = swDocPART Then" qui ne me sert pas (je travail au niveau de l'assemblage)

ensuite, dans la liste des "Dim", l'ajoute la ligne

Dim swCustProp As CustomPropertyManager


ensuite, à la place de "Get all elements", je colle

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

je remplace "Property_Name" par "Famille de composant"

Mais ou est ce que je spécifie la valeur "1" recherchée pour cette propriété?

 

Bonjour,

Dans un second traitement de type:

If Valout = "1" then
 xxx
End if

 

Bonjour,

Essaye avec ce 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

Cordialement,

3 « J'aime »

Cyril.f :

à la place de "ElseIf swModel.GetType = swDocASSEMBLY Then"

je colle "If Valout = "1" then"

Résultat : erreur de compilation sur la ligne

bool = swCustProp.Get4("Famille de composant", False, Val, Valout) 

Val est une "argument non facultatif"

 

@ d.roger :

Pas d'erreur , mais rien ne se passe sur mon assemblage...

Dommage car pour le coup, le code est compréhensible a mon niveau de débutant, et je peux le modifier pour faire évoluer la macro

Autre question au passage, que devrais-je modifier si je veux appliquer la couleur au niveau de la pièce et non pas du composant d'assemblage?

Pour récupérer la valeur de la variable sur la pièce il faut que celle-ci soit considérée comme chargée dans Solidworks donc en mode résolu, est-ce le cas dans ton assemblage ?

Cordialement,

Et je penses que je peux répondre à la place de @Cyril.f , il ne t'as jamais dis de remplacer "ElseIf swModel.GetType = swDocASSEMBLY Then" par "If Valout = "1" then" mais a répondu à ta question "Mais ou est ce que je spécifie la valeur "1" recherchée pour cette propriété?". La solution qu'il donne est exactement la même que la mienne mais sans l'exemple concret...

Pour la remarque "Val est un "argument non facultatif", cela signifie que tu n'as pas "typer" ta variable donc mettre une ligne "Dim Val as String" avant ... idem pour la variable "valout" bien sûr.

Autre point, avec les lignes :

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

bool = swCustProp.Get4("famille de composant", False, val, valout)

If valout = "1" Then

Cela signifie que la propriété personnalisée doit s'appeler famille de composant , que sa valeur évaluée doit être 1 et quelle doit se trouver dans l'onglet Personnaliser. Si elle se trouve dans les propriétées personnalisées spécifiques à la configuration alors ce n'est plus tout à fait le même code qu'il faut car il faut préciser le nom de la configuration dans laquelle aller chercher la valeur comme par exemple la configuration nommée Défaut dans la ligne suivante :

Set swCustProp = swModel2.Extension.CustomPropertyManager("Défaut").

Cordialement,

1 « J'aime »

@d.roger , tu as bien fait de répondre à ma place. Pour le reste je suis parfaitement d'accord avec ton analyse.          

1 « J'aime »

Merci pour les réponses détaillées et didactiques ;)

je viens d'essayer avec le code proposé, sans rien ajouter, et, ho joie, ça fonctionne... je ne sais pas ou j'ai merdé lors de mon premier essai. Désolé d'avoir mis en doute votre expertise.

Je vais tenter d'ajouter une ligne pour passer les pièces en résolu.

Enfin, avez vous une idée pour appliquer la couleur au niveau de la pièce et non pas du composant d'assemblage?

 

Bonjour

Ma macro semblait bien fonctionner sur mon assemblage d'essai, mais sur d'autres assemblage, voila qu'elle bloque sur la ligne        

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

"erreur 91 : variable objet ou variable de bloc With non définie"

Bonjour,

Comme déjà dit précédemment :

"Pour récupérer la valeur de la variable sur la pièce il faut que celle-ci soit considérée comme chargée dans Solidworks donc en mode résolu, est-ce le cas dans ton assemblage ?"

Cordialement,

si si, tout est en résolu.

Alors possibilité que cela vienne d'une pièce qui est en état supprimée ...

Mais de toute façon, cela vient de la ligne :

"Set swModel2 = swElement.GetModelDoc2"

qui bloque car la macro ne trouve pas le ModelDoc2 d'un composant pour une raison ou une autre (mode allégé, état supprimé, ...) ce qui renvoie une erreur de ce type. Je vois que la gestion des erreurs n'a pas été faite :-) ... Pour rappel, les macros données ici ne le sont qu'à titre d'exemple et doivent être retravaillées pour à minima ajouter la gestion des erreurs ...

Cordialement,

en effet, y'en a...

Ajoute au minimum la ligne :

"On Error Resume Next"

Juste en dessous la ligne :

"For Each vElement In vElementArr"

Cela aura pour effet de continuer la boucle même si la macro tombe sur une erreur.

Voir ICI.

Cordialement,

1 « J'aime »

Nickel, ca fonctionne parfaitement!

pour améliorer la chose, je vais tenter d'insérer une ligne pour passer tout en mode résolu. j'ai trouvé cette fonction : "LightweightAllResolved" . je vais tenter de l'insérer, avec idéalement une boite de dialogue pour confirmer.

Et la petite question rècurente : si je veux appliquer la couleur sur les pièces au lieu des composants, j'ai l'intuition qu'il faut que je remplace cette ligne
vElementArr = swModel.GetComponents

par quelque chode du genre
Set swCompModel = swApp.ActivateDoc (ou ActivateDoc2 ou encore ActivateDoc3...?)
Suis- je sur la bonne voie?