asptt9 Posté(e) le 9 mars 2013 Posté(e) le 9 mars 2013 Bonjour, Voilà mon problème. J'ai dans mes dessins des blocs nommés "bacréseau2" avec un certains nombre d'attributs et un client me fournit des blocs "bacréseau" avec eux aussi un certain nombre d'attributs. Les attributs de ces deux blocs ne sont pas tous les mêmes, cependant certaines étiquettes sont identiques bien que situées dans un ordre différent.Mon souhait serait de copier la valeur des attributs du bloc bacréseau vers le bloc bacréseau2 pour les étiquettes communes. Les étiquettes concernées se nomment "X","Y","Z-TN","Z-PROF","MARQUE","NUMSERIE","INCERTXY","INCERTZ" et "DATERELEVE". Comment puis-je faire pour copier les valeurs des attributs de ces étiquettes d'un bloc à un autre sans modifier les valeurs des attributs des autres étiquettes présentes dans le bloc qui réceptionne les données. Les valeurs peuvent être soit du texte soit des chiffres décimaux ou non. Ces variables sont donc des "string" J'espère que j'ai été assez clair dans mon énoncé... Merci d'avance pour votre aide
asptt9 Posté(e) le 11 mars 2013 Auteur Posté(e) le 11 mars 2013 J'ai oublié de préciser... La démarche que je voudrais appliquer est choisir un premier bloc (unique), en extraire les attributs concernés et les stocker dans des variables, puis sélectionner un deuxième bloc (unique) et appliquer les valeurs des variables précédentes aux attributs concernés.
Patrick_35 Posté(e) le 11 mars 2013 Posté(e) le 11 mars 2013 Salut Un lisp vite faitA toi de bien faire attention que le nom des étiquettes correspondent bien entre différents blocs. (defun c:catt(/ att bl doc ent sel) (vl-load-com) (setq doc (vla-get-activedocument (vlax-get-acad-object))) (vla-startundomark doc) (and (setq ent (entsel "\nSélectionnez le bloc d'origine : ")) (setq ent (vlax-ename->vla-object (car ent))) (eq (vla-get-objectname ent) "AcDbBlockReference") (eq (vla-get-hasattributes ent) :vlax-true) (princ "\nSélectionnez les blocs destinataires") (ssget (list (cons 0 "insert") (cons 66 1))) (progn (setq att (mapcar '(lambda(x)(cons (strcase (vla-get-tagstring x))(vla-get-textstring x)))(vlax-invoke ent 'getattributes))) (vlax-for bl (setq sel (vla-get-activeselectionset doc)) (foreach ent (vlax-invoke bl 'getattributes) (and (setq ele (assoc (strcase (vla-get-tagstring ent)) att)) (vla-put-textstring ent (cdr ele)) ) ) ) (vla-delete sel) ) ) (vla-endundomark doc) (princ) ) @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
asptt9 Posté(e) le 11 mars 2013 Auteur Posté(e) le 11 mars 2013 Merci beaucoup Patrick_35.J'ai oublié de préciser dans le sujet, j'ai d'autres étiquettes communes aux deux blocs que je ne veux pas copier d'un bloc à l'autre.Ton programme copie toutes les étiquettes communes j'ai l'impression, or j'aimerais, si c'est possible, qu'il sélectionne juste les étiquettes que j'ai mentionné dans l'énoncé.Peux tu me guider car de plus j'ai beaucoup de mal à comprendre le fonctionnement de ton programme vu que je débute à peine.
Patrick_35 Posté(e) le 11 mars 2013 Posté(e) le 11 mars 2013 Voilà qui devrait répondre à ton besoinJ'ai ajouté des commentaires pour faciliter la compréhension du lisp.Si j'ai été un peu trop succinct, n'hésite pas. (defun c:catt(/ att bl doc ent lst sel) (vl-load-com) ; Définir le document actif ainsi que les étiquettes à prendre en compte (setq doc (vla-get-activedocument (vlax-get-acad-object)) lst '("X" "Y" "Z-TN" "Z-PROF" "MARQUE" "NUMSERIE" "INCERTXY" "INCERTZ" "DATERELEVE") ) ; Début du marqueur Undo (idem à _undo _group) (vla-startundomark doc) ; Choix du bloc avec verif si attributs, etc... (and (setq ent (entsel "\nSélectionnez le bloc d'origine : ")) (setq ent (vlax-ename->vla-object (car ent))) (eq (vla-get-objectname ent) "AcDbBlockReference") (eq (vla-get-hasattributes ent) :vlax-true) (princ "\nSélectionnez les blocs destinataires") (ssget (list (cons 0 "insert") (cons 66 1))) (progn ; Création d'une liste contenant l'étiquette avec son texte ; Par exemple '(("X" . "100") ("Y" . "190") ("MARQUE" . "Patrick_35 ;-)")) ; La boucle vl-remove-if-not supprime toutes les étiquettes qui ne nous intéressent pas (n'appartenant donc pas à la liste lst) ; La boucle mapcar constitue la liste avec le nom de l'étiquette et sa valeur (setq att (mapcar '(lambda(x) (cons (strcase (vla-get-tagstring x)) (vla-get-textstring x) ) ) (vl-remove-if-not '(lambda(x) (member (strcase (vla-get-tagstring x)) lst) ) (vlax-invoke ent 'getattributes) ) ) ) ; Boucle pour parcourir la sélection des blocs (vlax-for bl (setq sel (vla-get-activeselectionset doc)) ; Boucle pour parcourir les attributs du bloc (foreach ent (vlax-invoke bl 'getattributes) ; Il ne reste plus qu'à vérifier que l'étiquette trouvé correspond avec une étiquette du bloc de base ; Si oui, on écrit donc la valeur dans l'attribut (and (setq ele (assoc (strcase (vla-get-tagstring ent)) att)) (vla-put-textstring ent (cdr ele)) ) ) ) ; Effacer le jeu de sélection de la mémoire (vla-delete sel) ) ) ; Fin du marqueur Undo (idem à _undo _end) (vla-endundomark doc) ; Silence (princ) ) @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
asptt9 Posté(e) le 11 mars 2013 Auteur Posté(e) le 11 mars 2013 Merci.Ça va tout de suite mieux avec quelques explications!!!Ça a l'air facile comme ça mais je ne suis malheureusement pas capable de créer ce genre de programme tout seul...Il y a une chose que je comprends pas bien: à quoi sert le marqueur undo car pour moi undo signifie annuler la dernière opération alors je ne comprends pas pourquoi on en a besoin dans ce programme. En tout cas ton programme fonctionne exactement comme je l'espérait. Tu ne pouvais pas mieux répondre à mes attentes. Encore merci.
asptt9 Posté(e) le 11 mars 2013 Auteur Posté(e) le 11 mars 2013 Je ne comprends pas non plus l'utilité du (princ) en fin de programme.Qu'est-ce que ça apporte ?
Patrick_35 Posté(e) le 11 mars 2013 Posté(e) le 11 mars 2013 Ça a l'air facile comme ça mais je ne suis malheureusement pas capable de créer ce genre de programme tout seul...Rome ne s'est pas fait en un jour ;) et Cadxp est là pour t'aider. à quoi sert le marqueur undoSi tu dois annuler ta copie d'attribut pour un raison ou une autre, un undo suffit.Si le marqueur undo n'est pas indiqué dans le Lisp, c'est alors la dernière commande qui est annulé, pas que le changement des attributs. Fais un test avec le Lisp qui contient les undomark et un sans et tu vas vite comprendre la nécessité ;) Le princ, c'est pour que rien n'apparaisse à la fin de l'éxecution du Lisp sur la ligne de commande. C'est comme indiqué; un silence. @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
asptt9 Posté(e) le 11 mars 2013 Auteur Posté(e) le 11 mars 2013 Ok,C'est bon à savoir pour le marqueur undo. Merci beaucoup Patrick_35.
azrael Posté(e) le 23 avril 2020 Posté(e) le 23 avril 2020 Bonjour, J'utilise ce fichier Lisp régulièrement. Je me demandais s'il était possible de tenir compte que d'un attribut, celui sélectionné lorsqu'on clique sur bloc ""\nSélectionnezle bloc d'origine : "))" , un peu comme "_eattedit" Encore plus loin ... sélectionnez un, deux ou trois attributs d'un bloc et recopier dans d'autres blocs ? Sinon, c'est déjà très bien comme cela ;)Maxime
Messages recommandés
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 compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant