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,
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?