yusukens82 Posté(e) le 3 juin 2009 Posté(e) le 3 juin 2009 Bonjour Dans mon travail, il m'arrive très très souvent de faire une manipulation très fastidieuse alors que je sais qu'il est possible de passer par une routine, mais étant nul en lisp et VBA, je me tourne vers vous pour demander de l'aide. pour monter cette routine, j'ai définie 3 phases : Phase 1)Activer une fenêtre de présentation : cela reste simple, j'ai donc réussi à l'écrire :(command "PRESENTATION" "E" "Présentation1") Phase 2)Ecrire une routine pour effectuer la commande RECHERCHER avec les options : http://www.trinh-dota.com/Photo/recherche.jpg Phase 3)Selectionner le bloc nommé "CartouchePC" et changer la valeur de l'attribu "Nom" de ce bloc.(Chaque onglet a ce même bloc avec un nom différent") http://www.trinh-dota.com/Photo/cartoucheATT.jpg Merci de votre aide, [Edité le 3/6/2009 par yusukens82]
didier Posté(e) le 4 juin 2009 Posté(e) le 4 juin 2009 coucou visiblement tu as fait des efforts pour être explicite j'ai crû comprendre que tu voulais changer une valeur d'attributdans ton fichier, maisest ce que tous les blocs qui contiennent ces blocs ont ils le même nom ?nom de bloc j'entends. si c'est le cas la position de l'attribut est la même dans chaque blocgenre huitième attribut. donc tu n'as qu'à faire autant de ENTNEXT qu'il fautet tu seras sur le bon attributou bien tu choisis NENTSEL ensuite un SUBST fera l'affaire avant de faire un ENTMOD. si ce n'est pas clair, reviens à la charge amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
(gile) Posté(e) le 4 juin 2009 Posté(e) le 4 juin 2009 Salut, Ou encore, puisque tu connais l'étiquette de l'attribut, tu peux rechercher l'attribut à modifier par son étiquette. Regarde les routines GetAttValue et SetAttValue dans ce message. La fonction LISP layoutlist retourne la liste des onglets de présentation, tu peux donc boucler sur toutes les présentations avec foreach.(foreach layout (layoutlist) ...) Pour naviguer entre les onglets, tu peux utiliser setvar avec la variable "CTAB" :(setvar "CTAB" layout) Dans chacun des onglet tu peux récupérer le le nom d'entité du bloc "CartouchePC" avec ssget et un filtre de sélection :(setq ss (ssget "_X" ; "_X" = toute la base de données (list '(0 . "INSERT") ; type d'objet : référence de bloc '(2 . "CartouchePC") ; nom du bloc (cons 410 layout) ; onglet de présentation ) ) ) La fonction ssname te permet de récupérer le(s) nom(s) d'entité pour les passer à SetAttValue Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
grosseel Posté(e) le 4 juin 2009 Posté(e) le 4 juin 2009 Une autre petite question pour en probléme en relation avec le bout de programme de gile. Comment fait-on si le nom du bloc ("CartouchePC") est une variable. Merci d'avance pour vos réponses.Et encore bravo Gile.
Patrick_35 Posté(e) le 4 juin 2009 Posté(e) le 4 juin 2009 Salut Tu as aussi Mat @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
(gile) Posté(e) le 4 juin 2009 Posté(e) le 4 juin 2009 Une autre petite question pour en probléme en relation avec le bout de programme de gile. Comment fait-on si le nom du bloc ("CartouchePC") est une variable. Je pense que tu pales du filtre de sélection ?On fait comme pour l'onglet de présentation, on construit la paire pointée avec cons pour que la variable soit évaluée (cons 2 nom_du_bloc) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
yusukens82 Posté(e) le 4 juin 2009 Auteur Posté(e) le 4 juin 2009 Bonjour, merci pour vos réponses.J’essaye avec tous vos conseils, de sortir cette fameuse routine, mais avec mes onces de connaissance dans ce domaine je vous avouerez que je n’y arrive pas ! Pouvez-vous m’aider à écrire cette routine? pour vous faciliter la tâche, je joins un fichier avec 6 onglets : - les 3 premiers représentent l’état brut avant la routine - les 3 d’après sont les résultats de cette fameuse routine http:// http://yusukens.free.fr/CADXP/CartouchePC.zip Voila comment je vois le déroulement de la routine :Phase 2) - Activer l’onglet "PRE1" - Rechercher le MTEXT valeur "08" et remplacer par valeur "supprim" - Activer l’onglet "PRE2" - Rechercher le MTEXT valeur "12" et remplacer par valeur "supprim" - Activer l’onglet "PRE3" - Rechercher le MTEXT valeur "50" et remplacer par valeur "supprim" NB : Pour cette phase2 j’ai adapté à 1% une routine trouvé dans le forum, mais le problème est qu’il remplace également les valeurs MTEXT dans l’espace OBJET : (defun c:test (/ ss n txt elst str) (command "PRESENTATION" "E" "PRE1") (and (setq ss (ssget "_X" '((0 . "MTEXT")))) (setq n 0) (while (setq txt (ssname ss n)) (setq elst (entget txt) str (cdr (assoc 1 elst)) ) (while (vl-string-search "08" str) (setq str (vl-string-subst "supprim" "08" str)) ) (entmod (subst (cons 1 str) (assoc 1 elst) elst)) (entupd txt) (setq n (1+ n)) ) ) (princ) ) Phase 3) - Activer l’onglet "PRE1" - Sélectionner le bloc "CartouchePC" et remplacer la valeur "CADXP" par "CAD01" - Activer l’onglet "PRE2" - Sélectionner le bloc "CartouchePC" et remplacer la valeur "CADXP" par "CAD02" - Activer l’onglet "PRE3" - Sélectionner le bloc "CartouchePC" et remplacer la valeur "CADXP" par "CAD03"
grosseel Posté(e) le 4 juin 2009 Posté(e) le 4 juin 2009 Je pense que tu pales du filtre de sélection ?On fait comme pour l'onglet de présentation, on construit la paire pointée avec cons pour que la variable soit évaluée (cons 2 nom_du_bloc) Merci de ta réponse Gile, mais ca na pas résolu mon probléme, l'éditeur Visual Lisp me retourne l'erreur suivante :; erreur: nombre d'arguments insuffisant dans SETQ: (SETQ SEL (SSGET "_X" (QUOTE ((0 . "INSERT") (CONS 2 BLK)))) ACDOC (vla-get-ActiveDocument (vlax-get-acad-object)) LAYS (LAYOUTLIST) (SETQ BLK nil)) Ci-joint le bout de code qui pose probléme : (while (not SEL) (setq SEL (car (entsel "\n Choix du cadre (Bloc) :"))) (setq BLK (cdr (assoc 2 (entget SEL)))) (if SEL (if (not (equal (vla-get-objectname (setq B (vlax-ename->vla-object SEL))) "AcDbBlockReference")) (setq SEL NIL))) ) (setq SEL (ssget "_X" '((0 . "INSERT") (cons 2 BLK)))) ACDOC (vla-get-activedocument (vlax-get-acad-object)) LAYS (layoutlist) (setq BLK NIL)) ) Merci de ta réactivité [Edité le 4/6/2009 par grosseel]
Patrick_35 Posté(e) le 4 juin 2009 Posté(e) le 4 juin 2009 Salut Pour sélectionner des objets sur des présentations, regardez le code dxf 67 on peut de cette manière, éviter de changer de présentation Exemple pour choisir tous les mtexts dans toutes les présentations (setq js (ssget "x" (list (cons 0 "mtext") (cons 67 1)))) grosseel :Tu as une parenthèse de trop @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
grosseel Posté(e) le 4 juin 2009 Posté(e) le 4 juin 2009 ok merci, j'ai résolu mon probléme.Par contre, quelqu'un saurait comment inversé l'ordre de la liste créer avec ssget [Edité le 4/6/2009 par grosseel]
yusukens82 Posté(e) le 4 juin 2009 Auteur Posté(e) le 4 juin 2009 Patrick; Si je comprends bien, il est possible de ne pas chercher dans l'espace OBJET,Par déduction, j'ai remplacé (setq ss (ssget "_X" '((0 . "MTEXT"))))Par(setq js (ssget "x" (list (cons 0 "mtext") (cons 67 1)))) Mais ça ne doit pas être correct car du coup, la routine me renvoie une erreur
Patrick_35 Posté(e) le 4 juin 2009 Posté(e) le 4 juin 2009 Si je comprends bien, il est possible de ne pas chercher dans l'espace OBJET,Oui Mais ça ne doit pas être correct car du coup, la routine me renvoie une erreurLe filtre est bon.Si tu fais le bout de code directement sur la ligne de commande, tu dois avoir quelque chose comme <Selection set: 643e>Si tu as nil, c'est que tu n'as pas de mtext dans les espaces papier et un bug dans la conception du lisp. @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
yusukens82 Posté(e) le 4 juin 2009 Auteur Posté(e) le 4 juin 2009 RE, le code en entier pour la phase2 rectifié pour ne prendre que les onglets : (defun c:test (/ ss n txt elst str) (and (setq js (ssget "x" (list (cons 0 "mtext") (cons 67 1)))) (setq n 0) (while (setq txt (ssname ss n)) (setq elst (entget txt) str (cdr (assoc 1 elst)) ) (while (vl-string-search "08" str) (setq str (vl-string-subst "supprim" "08" str)) ) (entmod (subst (cons 1 str) (assoc 1 elst) elst)) (entupd txt) (setq n (1+ n)) ) ) (princ) ) dans mon fichier : http:// http://yusukens.free.fr/CADXP/CartouchePC.zipou j'ai bien des MTEXT dans les onglets, si je lance la routine, Autocad me renvoit le message :Commande: test ; erreur: type d'argument incorrect: lselsetp nil
Patrick_35 Posté(e) le 4 juin 2009 Posté(e) le 4 juin 2009 Re, Tu as une erreur dans les variablesTu fais un jeu de sélection sur js et tu parcours le jeu de sélection ssErreur de jeunesse ;) grosseeltu fait ta boucle à l'envers. @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
yusukens82 Posté(e) le 4 juin 2009 Auteur Posté(e) le 4 juin 2009 génial, j'ai ensuite adapter selon mes besoins, la phase 2 est maintenant satisfait. je vais essayer de réaliser la phase 3
yusukens82 Posté(e) le 4 juin 2009 Auteur Posté(e) le 4 juin 2009 Je vais déjà essayer de changer la valeur d'un attribut avec GetAttValue Donc selon le lien de Gile : http:// http://www.cadxp.com/modules.php?op=modload&name=XForum&file=viewthread&tid=23000#pid98650 Si je change les Arguments :;;; blk : le nom d'entité du bloc;;; tag : le nom de l'étiquette de l'attribut;;; val : la valeur à attribuerPar les valeurs de mon bloc attribut, j’obtiens : (defun SetAttValue (CartouchePC NOM CAD01 / lst loop) (setq lst (entget (entnext CartouchePC)) loop (= ATTRIB (cdr (assoc 0 lst))) ) (while loop (if (= (strcase NOM) (cdr (assoc 2 lst))) (progn (entmod (subst (cons 1 CAD01) (assoc 1 lst) lst)) (setq loop nil) (entupd CartouchePC) ) (setq lst (entget (entnext (cdr (assoc -1 lst)))) loop (= "ATTRIB" (cdr (assoc 0 lst))) ) ) ) ) La routine ne renvoi aucune erreur, mais ne modifie pas non plus la valeur du bloc attribut.(je sens avoir fais une grosse boulette)
(gile) Posté(e) le 4 juin 2009 Posté(e) le 4 juin 2009 Salut, Tu n'as pas besoin de changer le code. Les attributs d'une fonction LISP (prédéfinie ou définie avec defun) sont les expressions requises par la fonction.Il te suffit de charger la fonction SetAttValue et de l'appeler dans ton code avec les bons attributs : (setq block_ename (car (entsel))) ; le nom d'entité du blocou(if (setq ss (ssget "_X" '((0 . "INSERT") (2 . "CartouchePC") (410 . "PRE1")))) (setq block_ename (ssname ss 0)) ; le nom d'entité du bloc ) et ensuite :(SetAttValue block_ename "NOM" "CAD01") Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
yusukens82 Posté(e) le 5 juin 2009 Auteur Posté(e) le 5 juin 2009 Dessolé,je ne comprend vraiment rien au lisp.ou dois-je insérer insérer ces textes ? ;;; GetAttValue ;;; Attribue une valeur de un attribut ;;; ;;; Arguments ;;; blk : le nom d'entité du bloc ;;; tag : le nom de l'étiquette de l'attribut ;;; val : la valeur à attribuer (defun SetAttValue (blk tag val / lst loop) (if (setq ss (ssget "_X" '((0 . "INSERT") (2 . "CartouchePC") (410 . "PRE1")))) (setq block_ename (ssname ss 0)) ; le nom d'entité du bloc ) (SetAttValue block_ename "NOM" "CAD01") (setq lst (entget (entnext blk)) loop (= "ATTRIB" (cdr (assoc 0 lst))) ) (while loop (if (= (strcase tag) (cdr (assoc 2 lst))) (progn (entmod (subst (cons 1 val) (assoc 1 lst) lst)) (setq loop nil) (entupd blk) ) (setq lst (entget (entnext (cdr (assoc -1 lst)))) loop (= "ATTRIB" (cdr (assoc 0 lst))) ) ) ) )
(gile) Posté(e) le 5 juin 2009 Posté(e) le 5 juin 2009 Salut, Comme dit plus haut, il ne faut pas changer le code SetAttValue, juste appeler la fonction en spécifiant les arguments. Une chose primordiale dans l'automatisation/programmation est l'acquisition des données.Peut elle se faire automatiquement ou une intervention de l'utilisateur est elle nécessaire ? Dans ton exemple, est-ce que la nouvelle valeur de l'attribut "NOM" doit être entrée par l'utilisateur pour chaque bloc "CartouchePC" ou peut elle être déterminée automatiquement par incrémentation ou à partir du nom de la présentation ou autre ? Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
yusukens82 Posté(e) le 5 juin 2009 Auteur Posté(e) le 5 juin 2009 Salut, Dans ton exemple, est-ce que la nouvelle valeur de l'attribut "NOM" doit être entrée par l'utilisateur pour chaque bloc "CartouchePC" ou peut elle être déterminée automatiquement par incrémentation ou à partir du nom de la présentation ou autre ? Une chose primordiale dans l'automatisation/programmation est l'acquisition des données.Peut elle se faire automatiquement ou une intervention de l'utilisateur est elle nécessaire ? Aucune intervention de l'utilisateur, la valeur de l’attribut « NOM » du bloc « CartouchePC » sera prédéfinie dans la routine selon le nom de l’onglet.Dans mon exemple :- l’onglet PRE1, la valeur de l’attribut « NOM » sera toujours « CAD01 »- l’onglet PRE2, la valeur de l’attribut « NOM » sera toujours « CAD02 »- l’onglet PRE3, la valeur de l’attribut « NOM » sera toujours « CAD03 »
(gile) Posté(e) le 5 juin 2009 Posté(e) le 5 juin 2009 (defun c:test (/ ss n ent elst str) ;; pour chaque présentation (foreach layout (layoutlist) ;; remplacer "08" par "supprim" dans les MTEXT (if (setq ss (ssget "_X" (list '(0 . "MTEXT") (cons 410 layout)))) (repeat (setq n (sslength ss)) (setq ent (ssname ss (setq n (1- n))) elst (entget ent) str (cdr (assoc 1 elst)) ) (while (vl-string-search "08" str) (setq str (vl-string-subst "supprim" "08" str)) ) (entmod (subst (cons 1 str) (assoc 1 elst) elst)) (entupd ent) ) ) ;; changer la valeur de l'attribut "NOM" (if (setq ss (ssget "_X" (list '(0 . "INSERT") '(2 . "CartouchePC") (cons 410 layout) ) ) ) (repeat (setq n (sslength ss)) (setq ent (ssname ss (setq n (1- n))) str (strcat "CAD0" (substr layout 4)) ) (SetAttValue ent "NOM" str) ) ) ) (princ) ) ;;; SetAttValue ;;; Attribue une valeur de un attribut ;;; ;;; Arguments ;;; blk : le nom d'entité du bloc ;;; tag : le nom de l'étiquette de l'attribut ;;; val : la valeur à attribuer (defun SetAttValue (blk tag val / lst loop) (setq lst (entget (entnext blk)) loop (= "ATTRIB" (cdr (assoc 0 lst))) ) (while loop (if (= (strcase tag) (cdr (assoc 2 lst))) (progn (entmod (subst (cons 1 val) (assoc 1 lst) lst)) (setq loop nil) (entupd blk) ) (setq lst (entget (entnext (cdr (assoc -1 lst)))) loop (= "ATTRIB" (cdr (assoc 0 lst))) ) ) ) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
yusukens82 Posté(e) le 5 juin 2009 Auteur Posté(e) le 5 juin 2009 merci beaucoup,je viens de tester la routine, la barre de commande me renvoit le message suivant :Commande: test ; erreur: no function definition: SETTATTVALUE
(gile) Posté(e) le 5 juin 2009 Posté(e) le 5 juin 2009 Désolé c'était une faute de frappe, c'est réparé. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
yusukens82 Posté(e) le 5 juin 2009 Auteur Posté(e) le 5 juin 2009 Génial, génial.Chaque nouveau projet, je passe un temps fou à modifier 1par1 chaque Texte et Attribut.Ces routines est une eau bénite. Un grand merci à tous.
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