Aller au contenu

Changer la valeur d'un attribut d'un bloc - LISP


Pragma

Messages recommandés

Bonjour,

 

Je suis nouveau sur ce forum. C'est la première fois que j'écris un sujet, que ce soit ici ou ailleurs. N'hésitez donc pas à me reprendre si je fais quelque chose de travers.

 

J'ai l'habitude de frafouiller sur internet pour trouver les réponses à mes questions mais, compte tenu de ma deadline sur ce sujet, je me suis dit qu'il étant peut être temps d'accepter l'aide des plus érudits.

 

Je commence en LISP. D'habitude pour ce qui est de l'automatisation AUTOCAD j'utilise VBA pour des raisons de transfert de donnée avec d'autre application comme Excel. Ici je souhaite créer une routine directement sur AutoCAD.

 

Ce que j'ai :

 

- Un dessin Autocad dans lequel j'ai plusieurs présentations

- Sur Chaque présentation se trouve un bloc - Le même bloc, même nom, mêmes attributs ... - Ce bloc ne se trouve qu'une seule fois sur chaque présentation

- Ce bloc possède plusieurs attributs

 

Ce que je veux faire :

 

- Changer la valeur de deux des attributs du blocs

- L'un prendra toujours la même valeur

- L'autre prendra une valeur différente selon qu'il soit sur telle ou telle présentation.

 

[Pour la suite, je ne sais pas si ma façon de raisonner correspond à la façon de travailler en LISP ...]

 

Je veux donc parcourir les présentations une à une. (J'imagine un "for each" ...)

Trouver, dans cette présentation, le bloc portant le nom du bloc cible.

Parcourir les attribut de ce bloc et, lorsque l'étiquette correspond à l'attribut que je veux modifier, changer la valeur de cet attribut par une autre valeur.

 

Je poste ce message avec l'état actuel de mes connaissance en LISP (Cad pas grand chose). Je continue bien sûr à chercher de mon côté et posterais au fur et à mesure mes avancées.

 

D'avance, merci.

  • Downvote 1
Lien vers le commentaire
Partager sur d’autres sites

Salut

 

Regarde plutôt du coté des champs avec les expressions diesel que de vouloir faire du lisp.

C'est beaucoup plus simple.

 

Tu peux utiliser le nom du fichier (numéro de plan), la variable ctab (nom de l'onglet) et avec les expressions diesel.

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Lien vers le commentaire
Partager sur d’autres sites

Salut

 

Regarde plutôt du coté des champs avec les expressions diesel que de vouloir faire du lisp.

C'est beaucoup plus simple.

 

Tu peux utiliser le nom du fichier (numéro de plan), la variable ctab (nom de l'onglet) et avec les expressions diesel.

 

@+

 

 

Merci Pour cette réponse rapide !

 

Je suis aller fouiner du coté des expressions DIESEL et j'ai trouvé des petites choses qui me seront bien utiles, donc merci pour le conseil :)

 

Notamment CTAB pour récupérer le nom de l'onglet et l'afficher dans un bloc. Et ça c'est cool quand on a à écrire le nom de la présentation qu'une seule fois. Car oui, mes onglets sont nommés avec des petits nom bien à moi et non avec 01, 02, 03 ...

Je sais que ce mode de fonctionnement en fait hurler certains ... mais à chacun sa façon de travailler ;)

 

Puisqu'on parle des champs avec expression DIESEL voici quelques problèmes dont je cherche la solution en ce moment :

 

- A : Récupérer dans un champs le nombre d'onglet (Pb de pagination).

J'en suis à une solution de ce type : $(getvar,NbrPage) avec NbrPage défini en LISP par (setq NbrPage (length (layoutlist))) mais je n'arrive pas encore à créer un LISP qui calcule NbrPage puis lance la mise à jour des champs avec la prise en compte des variables définies en amont.

 

- B : Récupérer dans un champs la position de l'onglet par rapport aux autres (tj pb de pagination). Et là je ne connais pas encore assez bien la gestion des onglets et la façon dont ils sont définis dans Autocad pour savoir si c'est possible.

 

- C : Récupérer dans un champs (lui même dans un bloc) la valeur d'un champs qui se trouve dans un autre bloc ... sorte de champ-ception ... mais là je n'ai pas encore commencé à chercher !!

 

Pour en revenir à mon problème initial :

 

L'idée est de pouvoir cibler précisément un attribut et en changer sa valeur. Je pars aujourd'hui de l'hypothèse que le bloc qui contient cet attribut est unique dans la présentation (par la suite je me poserai le problème de la multiplicité de ce bloc).

 

Pour modifier les valeurs d'un bloc dynamique depuis une application excel j'avais écrit ceci (à titre d'exemple) :

 

VBA **********************************************************************************

 

Set blockRefObj = MonPlan.ModelSpace.InsertBlock(insertionPnt, CheminBloc, 1, 1, 1, 0)

varPropDyn = blockRefObj.GetDynamicBlockProperties

For i = LBound(varPropDyn) To UBound(varPropDyn)

If varPropDyn(i).PropertyName = "L1X" Then varPropDyn(i).Value = L1X

If varPropDyn(i).PropertyName = "L2X" Then varPropDyn(i).Value = L2X

If varPropDyn(i).PropertyName = "L1Y" Then varPropDyn(i).Value = L1Y

If varPropDyn(i).PropertyName = "L2Y" Then varPropDyn(i).Value = L2Y

 

[...]

********************************************************************************** VBA

 

Je me demande s'il est possible d'avoir une approche similaire en LISP ou si je suis complètement à côté de la plaque avec ce mode de fonctionnement ...

 

 

D'après ce que j'ai compris des formules DIESEL, leur utilisation supposerai que le champs concerné soit toujours remplis par le même calcul (la même expression DIESEL) or je veux pouvoir donner à l'attribut une valeur dont la méthode de calcul change ...

 

Et j'en suis arriver à la conclusion que trouver une solution à mon pb A cité plus haut pourrait m'aider dans ma quête !!

 

Je ne sais pas si je me fait comprendre ...

 

En tous cas, merci encore pour votre première réponse et espérant que vous pourrez m'aider d'avantage :)

Lien vers le commentaire
Partager sur d’autres sites

Le première chose était d'éliminer ce qui est faisable avec les champs.

 

Pour répondre à tes questions et comme tu maitrise vb, je répondrais donc en vlisp

 

Connaitre le nombre total d'onglets en diesel n'est pas possible. Pour cela, tu as

(1- (vla-get-count (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object))))) ; Le -1 pour enlever l'espace objet

 

Connaitre la position d'un onglet dans la liste des onglets

(vla-get-taborder (vla-item (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object))) "Mon_Onglet"))

 

Pour créer une liste avec leurs positions

(vlax-for lay (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object)))
 (setq lst (cons (cons (vla-get-name lay) (vla-get-taborder lay)) lst))
)

 

Et pour interroger la liste

(cdr (assoc "Mon_Onglet" lst))

(cdr (assoc "Model" lst)) --> 0

 

Pour récuperer la valeur d'un champ et l'affecter à un autre attribut, un exemple

; Faire des champs dynamiques entre une définition de départ et une autre
(defun c:cor(/ at1 at2 bl1 bl2 bou)
 (and	(setq bl1 (entsel "\nBloc origine : "))
(setq bl1 (vlax-ename->vla-object (car bl1)))
(eq (vla-get-objectname bl1) "AcDbBlockReference")
(setq bl2 (entsel "\nBloc destination "))
(setq bl2 (vlax-ename->vla-object (car bl2)))
(eq (vla-get-objectname bl2) "AcDbBlockReference")
   (progn
     (setq at1 (vlax-invoke bl1 'getattributes)
    at2 (vlax-invoke bl2 'getattributes)
    bou 0
     )
     (while (nth bou at1)
(and (> bou 2)
     (< bou 8)
  (vla-put-textstring (nth bou at2)
		      (strcat "%<\\AcObjProp Object(%<\\_ObjId "
			      (itoa (vla-get-objectid (nth bou at1)))
			      " >%).TextString>%"
		      )
  )
)
(setq bou (1+ bou))
     )
   )
 )
 (princ)
)

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Lien vers le commentaire
Partager sur d’autres sites

Bonjour,

 

Je suis en train de faire mes petits test pour comprendre les petit bouts de code que vous m'avez donné.

 

Je crois m'en sortir avec la plupart sauf :

 

Le passage avec getattributes ...

 

Mon petit test :

 

[...]

 

(setq acadObj (vlax-get-acad-object))

(setq doc (vla-get-ActiveDocument acadObj))

(setq Bl (vla-get-blocks doc))

 

(while

(<= n NbrPage)

(setq Nom_Onglet (car (nth n lst)))

(setq Num_Onglet (cdr (nth n lst)))

(vlax-for bl1 (vla-item Bl "Cartouche")

(setq at1 (vlax-invoke bl1 'get-attributes)

)

(print at1)

 

(setq n (1+ n))

)

)

 

[...]

 

Je ne suis pas sûr de comprendre ce que fais cette ligne :

(setq at1 (vlax-invoke bl1 'get-attributes))

 

J'ai vu ici :

https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-ActiveX/files/GUID-3E8E1756-F45D-4CCE-838B-00FBC0374278-htm.html

 

Qu'ils utilisent (setq varAttributes (vlax-variant-value (vla-GetAttributes blockRefObj)))

 

Peux importe ce que je test j'ai l'erreur suivante : erreur: Le serveur ActiveX a renvoyé l'erreur: nom inconnu: GetAttributes

 

 

Qu'est censé retourner (vlax-invoke bl1 'get-attributes) ? une liste des attributs de bl1 ? (ça m'arrangerait :) )

 

Je pense que je n'ai pas encore saisi cette partie ou qu'il me manque une notion importante en LISP ...

 

Auriez vous une idée de ce que j'ai loupé ?

 

Cordialement,

Lien vers le commentaire
Partager sur d’autres sites

Salut

 

Par exemple

(setq mbl (vlax-ename->vla-object (car (entsel)))) ; Sélection d'un bloc avec attributs

Cette ligne renvoie la liste des attributs

(vlax-safearray->list (vlax-variant-value (vla-getattributes mbl)))

Ce qui la même chose que celle-ci. C'est un raccourci.

(vlax-invoke mbl 'getattributes)

 

Après une rapide lecture de ton code, il me semble que tu recherches tous les blocs nommés "Cartouche".

Un exemple pout les sélectionner tous.

(ssget "x" (list (cons 2 "Cartouche")))

Pour parcourir la sélection

(vlax-for ent (setq sel (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object))))
...
)
(vla-delete sel) ; Efface la sélection

ou pour tester en ligne de commande

(setq sel (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object))))
(setq ent (vla-item sel 0))

Et trouver son onglet

(vla-get-layout (vla-objectidtoobject (vla-get-database ent)(vla-get-ownerid ent)))

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Lien vers le commentaire
Partager sur d’autres sites

un site?

je chercher plutôt un pdf, j'aime bien ce format, on peu y faire des notes, surligner des trucs faire des signets... in site c'est un peu figé coté utilisateur. Le site de Didier, j'y passe... mais même en "vacances" je cours après le temps...

mais j'avais perdu ce lien... cette fois, je le note ! merci

Lien vers le commentaire
Partager sur d’autres sites

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité