vinz34 Posté(e) le 8 janvier 2008 Posté(e) le 8 janvier 2008 Salut Matt, Ta solution donne tous les attributs qui suivent ceux du bloc sélectionné.C'est pourquoi j'avais mis une condition d'arret au "seqend". Changer l'attribut ne me parît pas bien compliqué, j'attends un peu de voir si quelqu"n d'autre se lance.Je crois que Lovecraft peut commencer à répondre... Pour info, c'est bien l'étiquette de l'attribut qui s'appelle "DATE" ?
Patrick_35 Posté(e) le 8 janvier 2008 Posté(e) le 8 janvier 2008 Donc, voici ma version vlisp comme promis (defun c:vblat_pat(/ sel) (while (setq sel (entsel)) (if (eq (vla-get-objectname (setq sel (vlax-ename->vla-object (car sel)))) "AcDbBlockReference") (if (eq (vla-get-hasattributes sel) :vlax-true) (alert (substr (apply 'strcat (mapcar '(lambda (x) (strcat "\n" (vla-get-tagstring x) "\t: " (vla-get-textstring x))) (vlax-invoke sel 'getattributes))) 2)) (princ "\nCe bloc n'a pas d'attributs.") ) (princ "\nCe n'est pas un bloc.") ) ) (princ) ) ps : Matt666, tu as un souci avec ton lisp car tu ne testes pas la fin des entités qui composent le bloc avec le seqend, ce qui fait que si je clique un bloc, je peux me retrouver avec une liste impressionnante d'attributs (et pas obligatoirement la liste de tout les attributs (tout dépend de celui que l'on sélectionne. Si c'est le dernier bloc créé, je n'aurai que ses attributs)pps : vinz34, l'affichage ne respecte pas l'ordre des attributs (c'est juste une inversion dans un strcat)ppps : pour la date, un champ peut suffir @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
Matt666 Posté(e) le 8 janvier 2008 Auteur Posté(e) le 8 janvier 2008 Hum hum... C'est bien de donner des exercices... Quand on ne sait pas y répondre :casstet: (defun c:vblat_matt (/ ent str) (while (or (not (setq ent (car (entsel "\nSélectionner un bloc :")))) (/= (cdr (assoc 0 (entget ent))) "INSERT") ) ) (if (cdr (assoc 66 (entget ent))) (progn (setq str "\nCe bloc contient un ou des attributs : ") (while (and (setq ent (entnext ent)) (eq (cdr (assoc 0 (entget ent))) "ATTRIB") ) (if (<= (strlen (cdr (assoc 2 (entget ent)))) 5) (setq str (strcat str "\n" (cdr (assoc 2 (entget ent))) " ->\t\t" (cdr (assoc 1 (entget ent))) )) (setq str (strcat str "\n" (cdr (assoc 2 (entget ent))) " ->\t" (cdr (assoc 1 (entget ent))) )) ) ) (alert str) ) (princ "\nCe bloc ne contient pas d'attribut.") ) (princ) ) Oui, Bien vu patrick_35 et Vinz34, il y avait une condition manquante.... pour la date, un champ peut suffirC'est juste pour l'exercice... "Chacun compte pour un, et nul ne compte pour plus d'un."
vinz34 Posté(e) le 8 janvier 2008 Posté(e) le 8 janvier 2008 Salut, Ma proposition : (defun c:vblat_vinz (/ e elist date) (while (or (not (setq e (car (entsel "\nSélectionner un bloc :")))) (/= (cdr (assoc 0 (setq elist (entget e)))) "INSERT") ) ) (if (assoc 66 elist) (progn (setq e (entnext e)) (while e (cond ((= (cdr (assoc 0 (setq elist (entget e)))) "ATTRIB") (progn (setq date (strcat (substr (rtos (getvar "cdate")) 7 2) "." (substr (rtos (getvar "cdate")) 5 2) "." (substr (rtos (getvar "cdate")) 1 4) ) ) (if (= (cdr (assoc 2 elist)) "DATE") (entmod (subst (cons 1 date) (assoc 1 elist) elist)) ) (setq e (entnext e)) ) ) ((= (cdr (assoc 0 (setq elist (entget e)))) "SEQEND") (setq e nil) ) ) ) ) (princ "\nCe bloc ne contient pas d'attribut.") ) (princ) ) PS : Patrick, J'ai beau chercher, je n'y comprends rien au vlisp, enfin je le comprends mais je ne saurais pas le refaire.Je ne sais pas d'où sortent des commandes comme "vla-get-hasattributes" ou "vla-get-tagstring" introuvables dans la documentation du développeur d'Autocad. Pour l'ordre d'affichage des attributs, si j'avais à les classer ce serait par ordre alphabétique avec "acad_strlsort".
Patrick_35 Posté(e) le 8 janvier 2008 Posté(e) le 8 janvier 2008 Vinz34Si tu le comprends, c'est déjà un grand pas :)Je vais t'expliquer une démarche simple avec le vlisp.tu sélectionnes un objet.(setq ent (car (entsel)))que tu transformes en objet vla.(setq ent (vlax-ename->vla-object ent))pour connaître ses propriétés (ou liste des dxf mais sauce vla).(vlax-dump-object ent) Donc, pour savoir par exemple si j’ai des attributs (code 66 en dxf), je trouve dans la liste HasAttributes.Je fais un (vla-get-HasAttributes ent) qui me retourne :vlax-true. J’ai bien des attributs :) (un :vlax-false egal faux) Pour les méthodes applicables (ou autrement dit, les commandes applicables à l'objet).(vlax-dump-object ent T)Je constate que j’ai GetAttributes, autrement dit, pour récupérer les attributs (chouette, je n’ai pas besoin d’une boucle pour faire le trie, comme en autolisp :) ) Un (vla-GetAttributes ent) me retourne un #<variant 8201 ...> qu’il va falloir transformer.Donc un (vlax-variant-value (vla-GetAttributes ent)) me retourne un #<safearray...>Grrrr, il va encore falloir convertir.Donc un (vlax-safearray->list (vlax-variant-value (vla-GetAttributes ent))) me donne enfin ma liste d’attributs.Heureusement, il y a plus court avec un (vlax-invoke ent ‘GetAttributes) qui me donne directement cette liste.Il ne reste plus qu’a jouer avec un mapcar et un apply sur ma liste d'attributs (que de l’autolisp :o ;) ). Maintenant, si tu veux une aide sur les objets (si, si, elle existe sur autocad)tu lances vba (alt+f11)tu lances l'explorateur d'objets (f2)et pour retrouver ce que je t'ai expliqué plus haut avec le vlax-dump-object, comme par exemple pour notre exemple de bloc avec attributs, tu vas dans AcadBlocReference (tu remarqueras que la variable ent a par exemple comme valeur #<VLA-OBJECT IAcadBlockReference2 17074654> si c'est un bloc qui a été choisi) et tu auras les détails avec une aide et des exemples (en vba :( ;) )Dans l'explorateur d'objets, il n'est pas évident au début de bien comprendre les différentes classes, mais on arrive petit à petit à saisir la logique. @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
pascal19 Posté(e) le 8 janvier 2008 Posté(e) le 8 janvier 2008 1 journée d'absence...maintenant faut que je traduise...c'est en effet un peu rapide pour moi mais vous en faites passi j'ai une question précise je le ferai savoir...
vinz34 Posté(e) le 8 janvier 2008 Posté(e) le 8 janvier 2008 Pascal19, Désolé, on ne t'as pas vu depuis jeudi, alors je pensais que tu avais oublié ce sujet. Patrick_35 Merci beacoup de m'éclairer, j'y vois déja plus clair.Je vais enfin pouvoir me pencher sur ce language bien plus puissant que l'autolisp.
lovecraft Posté(e) le 8 janvier 2008 Posté(e) le 8 janvier 2008 bonjour, ah la c'est du grand art patrick,je connaissais la reponse en autolisp car j'avais dejàn un travail similaire avec des polylignes 3D donc le meme principe avec des blocs avec atribut. Donc j'ai essayé de de trouver un solution en vlisp que je decouvre grace a vous. Une grand merci pour cette explication détaillée. @plus http://www.youtube.com/user/CADMINATOR?feature=mhee
Matt666 Posté(e) le 9 janvier 2008 Auteur Posté(e) le 9 janvier 2008 Dément, une explication de code VLISP !!! Je commence à comprendre, aussi...Merci patrick_35 !!! "Chacun compte pour un, et nul ne compte pour plus d'un."
pascal19 Posté(e) le 16 janvier 2008 Posté(e) le 16 janvier 2008 oui oui je suis là mais pas trop le temps...surtout aujourd'hui désolémais je continu à suivre ce post.a+
pascal19 Posté(e) le 28 janvier 2008 Posté(e) le 28 janvier 2008 Bonjour à tous Pour relancer un peu ce spécial débutant, j'ai besoin d'un lisputilisant ce qui a été fait precedemment:a partir d'une sélection de bloc je voudrai exploser les blocs sans attributs (explode)et exploser en conservant les attributs les blocs à attributs (burst) j'ai fait ça: (defun c:exblatt(/ blatt) (setq sel1 (ssget)) (setq compteur 0) (setq longsel1 (sslength sel1))(while (< compteur longsel1) (setq entite (ssname sel1 compteur)) (setq blatt (cdr (assoc 66 (entget entite)))) (if (<> blatt nil) (command "burst" entite) (command "_explode" entite) ) (setq compteur (1+ compteur)) ) ) mais ça marche pas à priori à cause de "burst"... D'avance merci
bonuscad Posté(e) le 28 janvier 2008 Posté(e) le 28 janvier 2008 mais ça marche pas à priori à cause de "burst"... Je pense aussi ! Le problème vient que BURST n'est pas une commande "originelle" mais une fonction lisp définissant une nouvelle commande.Utiliser "command" pour l'utiliser fonctionne, mais le problème est que cette fonction de redonnera pas la main à ta fonction lisp appelante. Le mieux est d'ouvrir le fichier burst.lsp dans les express et de voir quelle fonction tu pourrait utiliser. J'ai rapidement jeté un coup d'oeil et je pense qu'il faudrait utiliser la fonction:(Defun BURST-ONE (BNAME / .....) ......) donc dans ton code et dans ta boucle (while, faire (BURST-ONE entite) au lieu de (command 'burst entite) Voilà, j'ai pas testé, mais je pense que comme ceci, cela fonctionnera Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius
lili2006 Posté(e) le 28 janvier 2008 Posté(e) le 28 janvier 2008 Bonsoir à toutes et tous, Testé vite fait avec cette écriture => (defun c:exblatt(/ blatt) (setq sel1 (ssget)) (setq compteur 0) (setq longsel1 (sslength sel1)) (while ((setq entite (ssname sel1 compteur)) (setq blatt (cdr (assoc 66 (entget entite)))) (if ( blatt nil) (BURST-ONE entite) (command "_explode" entite) ) (setq compteur (1+ compteur)) ) ) AutoCAD renvoi => Commande:Commande: EXBLATTChoix des objets: 295 trouvé(s)Choix des objets:; erreur: no function definition: Commande: Civil 3D 2025 - COVADIS_18.3b https://www.linkedin...3%ABt-95313341/
pascal19 Posté(e) le 29 janvier 2008 Posté(e) le 29 janvier 2008 Moi non plus ça marche pas...j'arrive pas à lancer burst-one, même en lançant (burs-one) seul, il veut pas rentrer dans le sous-programme (nombre d'arguments insuffisants)
bonuscad Posté(e) le 29 janvier 2008 Posté(e) le 29 janvier 2008 ; erreur: no function definition: <> S'assurer dans le code que burst est disponible, donc il faudrait rajouter: (if (not c:burst) (load"burst")) Mais le problème est que dans la fonction (c:burst ( / burst-one ....)) burst-one est déclarée en variable locale, donc inaccessible.Si vous bidouillez (déconseillé) le fichier burst.lsp en enlevant les variables locales, ça fonctionne j'arrive pas à lancer burst-one La fonction (burst-one) demande obligatoirement un argument, qui est le nom de l'entité.(burst-one (car (entsel))) est par exemple un appel valide. Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius
lili2006 Posté(e) le 29 janvier 2008 Posté(e) le 29 janvier 2008 Bonsoir à toutes et tous, Merci bonuscad, mais pourquoi écris-tu => ? Si vous bidouillez [surligneur] (déconseillé)[/surligneur] le fichier burst.lsp en enlevant les variables locales, ça fonctionne Civil 3D 2025 - COVADIS_18.3b https://www.linkedin...3%ABt-95313341/
bonuscad Posté(e) le 31 janvier 2008 Posté(e) le 31 janvier 2008 Il n'est jamais bon de modifier un fichier (qui fonctionne parfaitement) surtout venant des express. En effet ces outils sont interdépendant pour l'initialisation (variables etc..) et les gestions d'erreur, pour s'en persuader, il suffit des rendre le chemin inaccessible, de faire une copie d'une fonction (par exemple burst.lsp) dans un autre dossier déclaré, et d'essayer de le lancer :casstet: Aux mieux je suggère de faire une copie dans les express en changeant le nom du fichier et en changeant aussi les noms des fonctions principales liées à burst même. Comme ça l'original sera préservé ainsi que le fonctionnement des Express ;) Ou alors sans toucher à rien, faire comme au début: un appel par (command) , mais celui devra être la dernière exécution du code. Pas top et limité pour les possibilités d'inclure ce code des express... :( [Edité le 31/1/2008 par bonuscad] Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius
pascal19 Posté(e) le 31 janvier 2008 Posté(e) le 31 janvier 2008 J'ai une solution, je suis tout fiermais les pro du lisp vont surement trouver à redire... en fait j'ai grugé, comme j'y arrivais pas, j'ai mis les blocs à attribut dans un jeu de sélection (sel2): (defun c:exblatt(/ blatt) (setq sel1 (ssget)) (setq sel2 (ssadd)) (setq compteur 0) (setq longsel1 (sslength sel1))(while (< compteur longsel1) (setq entite (ssname sel1 compteur)) (setq blatt (cdr (assoc 66 (entget entite)))) (if (/= blatt nil) (ssadd entite sel2) (command "_.explode" entite) ) (setq compteur (1+ compteur)) ) ) ensuite j'ai associé un boutton a la macro suivante: ^C^C(load"exblatt.lsp");exblatt; _.PSELECT;!sel2;;burst; Résultat sur une sélection de blocs, en cliquant le bouttonautocad explose les blocs et fait "burst" sur les blocs à attributce que je voulais...
vinz34 Posté(e) le 31 janvier 2008 Posté(e) le 31 janvier 2008 Salut, Ca faisait longemps. Je ne donnerai pas l'avis d'un pro, mais tu simplifier tes setq : setq sel1 (ssget)) (setq sel2 (ssadd)) (setq compteur 0) (setq longsel1 (sslength sel1)) (setq sel1 (ssget)) sel2 (ssadd) compteur 0 longsel1 (sslength sel1)) En tout cas, je vois que tu as fait de beaux progrès. [Edité le 31/1/2008 par vinz34]
lili2006 Posté(e) le 31 janvier 2008 Posté(e) le 31 janvier 2008 Bonsoir à toutes et tous, Merci bonuscad pour tes explications. Bravo à vous autres. PS : A priori ne fonctionne pas sur tous les blocs dyn ! Civil 3D 2025 - COVADIS_18.3b https://www.linkedin...3%ABt-95313341/
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