ASTERIXII Posté(e) le 22 août 2011 Posté(e) le 22 août 2011 Bonjour,Je recherche la façon en lisp de [surligneur] lire la valeur [/surligneur]d'un Attribut pour l'exploiter dans le reste de mon programme.Je n'arrive pas à récuperer la valeur de 191.00 de lst (une liste ?)Ensuite comment modifier le lisp si j'ai 2 attributs ? NGFZ et NIVEAU Nom du bloc : NGFXNom de l'attribut : NGFZ La routine est de la "récup" de plusieurs lisp Routine : (Defun C:NGF () (setq BN "NGFX") (setq EN (cdr (assoc -2 (tblsearch "BLOCK" BN)))) (while EN (setq EL (entget EN)) (if (= (cdr (assoc 0 EL)) "ATTDEF") (setq TAGL (cons (cdr (assoc 2 EL)) TAGL))) (setq EN (entnext EN)) ) ;******************************************* (if TAGL (progn (setq TAGS (car TAGL) TAGT (cdr TAGL) ) (foreach TAG TAGT (setq TAGS (strcat TAGS " " TAG)) ) ) ); fin if TAGL ;******************************************* (initget TAGS) (setq Esel "NGFZ") (setq ESel (xstrcase ESel)) (if (member ESel TAGL) (setq Pass 'T TG ESel ) (prompt "\nInvalid attribute name.") ); fin if ;******************************************* (Setq SS1 (SsGet "_X" (List (Cons 0 "INSERT") (Cons 2 bn) (Cons 66 1) ) ) N (If SS1 (SsLength SS1) 0) ) ;******************************************* (setq ss ss1) (setq n 0) (repeat (sslength ss) (setq na (ssname ss n) e1 (entget na) lst (acet-insert-attrib-get (list na 1)) ;<---- la valeur de lst est ((NGFZ 191.00)) blk (cdr (assoc 2 e1)) hnd (cdr (assoc 5 e1)) lst3 (append lst3 (list (list hnd blk lst))) );setq ;******************************************* ) ; fin defun[Edité le 22/8/2011 par ASTERIXII]
didier Posté(e) le 22 août 2011 Posté(e) le 22 août 2011 coucou faire des copier-coller dans des routines sans vraiment savoir ce qui se passe n'est pas, à mes yeux, une bonne méthode essaie de te taper ton code, tu comprendras bien mieux ce que tu fais ton cas est simple tu choisis ton bloc(setq ent (car (entsel))) tu recherches la valeur de l'attributje fais simple, je sais que mon attribut à changer est le premier attribut du bloc(setq valatt (cdr(assoc 1 (entget (entnext ent)))))en français je mémorise le code 1 de la liste de définition de la première entité suivante de mon bloc (attribut en première position) ensuite tu la modifies avec entmod, tu connais ? amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
ASTERIXII Posté(e) le 22 août 2011 Auteur Posté(e) le 22 août 2011 Bonjour,Pour la methode, c'est que j'ai le niveau débutant et que la gestion des blocs et compliqué.Ensuite, je ne veux pas selectionner le bloc ni modifier l'attribut mais seulementlire la valeur.Dans mon code [surligneur] lst (acet-insert-attrib-get (list na 1)) ;<---- la valeur de lst est la valeur que je cherche[/surligneur]mais je n'arrive pas à la passer à une variable [Edité le 22/8/2011 par ASTERIXII]
didier Posté(e) le 22 août 2011 Posté(e) le 22 août 2011 coucou ???c'est une variable, même qu'elle s'appelle lst ????? mais je n'arrive pas à la passer à une variable ??????????????????????????????? amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
(gile) Posté(e) le 22 août 2011 Posté(e) le 22 août 2011 Salut, Je suis entièrement d'accord avec la remarque de Didier, à fortiori si tu es débutant. je ne veux pas selectionner le bloc Cette remarque illustre bien que tu comprends pas précisément ce que tu fais (ni ce que tu veux faire).Si tu ne sélectionne pas de référence de bloc, comment le programme peut-il deviner la valeur de quelle référence de bloc il doit trouver ? Quand tu utilises tblsearch, tu cherches dans une table des blocs une définition de bloc (et pas une référence). Une définition de bloc ne contient que des définitions d'attributs qui n'ont pas de valeur (si ce n'est une valeur par défaut). Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
ASTERIXII Posté(e) le 22 août 2011 Auteur Posté(e) le 22 août 2011 je voulais dire pas avec la souris C'est une chaine de C ou une liste ? [Edité le 22/8/2011 par ASTERIXII]
didier Posté(e) le 22 août 2011 Posté(e) le 22 août 2011 coucou je crois bien qu'on parle d'une même voix, avec (gile) ;) à ASTERIXII, quand on débute, je file la métaphore de l'enfant sans te manquer de respecton append à marcher avant d’appendre à courir, c'est sûr que si tu copies-colles des morceaux de routines à droite et à gauchetu vas dans le mur tête baissée. il faut se fixer un objectif très simple pour commencer. tu vas trouver TA façon d’appréhender les chosesmoi je passe par l'ordre des attributs lorsque je fais dans le simpleun autre passera par le contrôle de l'étiquettechacun sa route mais on arrive au même point. efface ta routine,repars d'une feuille blancheles anciens combattants, comme moi, avaient un environnement hostile pour apprendrevous, les nouveaux venus, avez l'éditeur lisp, rien que ça c'est une révolutionservez-vous-en tonnerre de Brest! amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
ASTERIXII Posté(e) le 22 août 2011 Auteur Posté(e) le 22 août 2011 Vraiment un grand merci, vous êtes d’un grand secours. Je pensais être dans la section débutant, mais il doit y avoir encore plus bas. J’ai cherché avant de poser la question, pas comme d’autre, (la preuve une partie du code), mais à chaque fois c’était pour modifier l’attribut ou l’exporter. Enfin bref ce n’est pas ici ou aujourd’hui que je vais trouver la réponse Bonne soirée aux anciens combattants !
(gile) Posté(e) le 22 août 2011 Posté(e) le 22 août 2011 Re, Je ne pense pas que les conseils donnés soient de mauvais conseils.T'aider à continuer dans le sens où tu as commencé serait par contre une fort mauvaise chose. Ton code utilise des fonctions issues des express tools ou non renseignée (acet-insert-attrib-get ou xstrcase) là où des fonction LISP natives renseignées dans l'aide feraient très bien l'affaire. Des portions de codes sont inutiles ou contradictoires : (Setq SS1 (SsGet "_X" (List (Cons 0 "INSERT") (Cons 2 bn) (Cons 66 1) ) ) N (If SS1 (SsLength SS1) 0) ) puis : (setq ss ss1) (setq n 0) Les variables ne sont pas localisées : des doublons vont s'ajouter à TAGL à chaque appel de la commande... Commence par poser clairement ce que tu veux faire en réfléchissant à comment y arriver avant d'écrire une seule ligne de code :Connaitre la valeur d'un attribut -> quel attribut de quel bloc=> Comment obtenir l'entité bloc ?=> Comment accéder aux attributs dans un bloc ?=> Comment récupérer la valeur d'un attribut particulier ? Là on pourra peut-être te guider et tu apprendras bien plus. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
didier Posté(e) le 23 août 2011 Posté(e) le 23 août 2011 coucou à moins de me fourvoyer,il me semble détecter de l'ironie dans tes propos. si tu décides de prendre les choses ainsi, libre à toimais dis-toi quand même que je n'ai pas pris le clavierpris le temps de taper un début d'exemplepour me voir revenir en réponse des propos irascibles. t'imagine un prof qui se prend des réflexions dans le troncheparce que l'école c'est compliqué sans les copier-coller... si tu changes d'avis, tu trouveras de l'aide icidans le cas contraire, bonne chance. amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
ASTERIXII Posté(e) le 23 août 2011 Auteur Posté(e) le 23 août 2011 Re,Questionquel est la difference entre :(setq ent (car (entsel))) ;selection souris qui donne comme valeur [surligneur] [/surligneur]et (setq ent2 (cdr (assoc -2 (tblsearch "BLOCK" BN)))) ; selection par codequi donne comme valeur [surligneur] [/surligneur] Pourquoi des valeurs differentes ? Suivant le début de code de didier (Defun C:NGF ()(setq BN "NGFX")(setq ent (car (entsel))) ;selection souris (setq ent2 (cdr (assoc -2 (tblsearch "BLOCK" BN)))) ; selection par code (prompt "\n******* ent *****")(princ ent)(prompt "\n******* ent2 *****")(princ ent2) (setq valatt (cdr(assoc 1 (entget (entnext ent))))) (prompt "\n******* valatt *****")(princ valatt))
didier Posté(e) le 23 août 2011 Posté(e) le 23 août 2011 coucou le premier donne le nom de la sous-entité qu'est l’attribut du bloc sélectionné le deuxième donne le nom de l'entité dans la définition des tables de blocs. rien à voir entre les deux le premier sert à "jouer" sur l'entité sélectionnéechanger la valeur de l'attribut, son calque, son style ... le deuxième sert à redéfinir les qualités du bloc(dans tout le fichier dessin) sans doute que l'excellent (gile) sera plus explicite tellement il maîtrise la théorie de la chose. il serait tout de même utile que tu expliques où tu veux en venir amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
ASTERIXII Posté(e) le 23 août 2011 Auteur Posté(e) le 23 août 2011 Merci pour cette réponse construtive, effectivement, en jouant avec la fonction(setq valatt2 (cdr(assoc 2 (entget ent2)))) ou ent2 provient de tblsearch "BLOCK" je viens de voir que je n'ai que des infos sur le bloc et l'attribut, mais pas sa valeur. Bref, ou je veux en venir, en faisant simple:J'ai un bloc dans mon plan avec un attributNom du bloc NGFX nom de l'attribut NGFZje veux récuperer la valeur de l'attribut pour l'utiliser dans mon programme.Mais la " [surligneur] sélection[/surligneur]" de l'attribut ne doit pas se faire avec la souris, mais par le programme, puisqu'il connait le nom
VDH-Bruno Posté(e) le 23 août 2011 Posté(e) le 23 août 2011 Bonjour ASTERIXII, Le problème posé, n’est pas vraiment un souci de programmation mais plutôt un problème d’inconnue en trop ( ou d’une donnée manquante), explications : Ce que je connais : Nom du bloc NGFX nom de l'attribut NGFZ Ce que je cherche : je veux récuperer la valeur de l'attribut pour l'utiliser dans mon programme. Comment je procède : la " sélection" de l'attribut ne doit pas se faire avec la souris, mais par le programme, puisqu'il connait le nom Bien tenté mais hélas ça ne suffit pas. Effectivement il connait le nom de la référence de bloc (NGFX), et dans le cas ou j’ai un seul bloc NGFX insérer dans mon dessin je peux me servir de cette donnée pour sélectionner mon bloc et extraire la valeur de l’attribut NGFZ. Mais dans le cas ou j’ai plusieurs référence du bloc NGFX insérer dans mon dessin comment faire, comment cibler la valeur que je veux extraire, au mieux si il y a 5 références du bloc NGFX je peux les sélectionner et extraire les valeurs de leurs attributs respectifs soit 5 valeurs sans savoir laquelle je recherche en particulier. Voilà ou on bloque pour pouvoir t’aider par la suite..A+ Apprendre => Prendre => Rendre
ASTERIXII Posté(e) le 23 août 2011 Auteur Posté(e) le 23 août 2011 Effectivement , bonne question il n'y à qu'un bloc dans le dessin. Je vais plus loin dans l'explication de mon but. Je recherche une methode pour memoriser une valeur (NGF) dans mon dessin, pour qu'à la prochaine ouverture du plan, je la retrouve automatiquement, et sans passer par un fichier en ecriture.C'est pour cette raison que j'ai pensé au bloc, mais il y à peut-être une autre solution ?
(gile) Posté(e) le 23 août 2011 Posté(e) le 23 août 2011 Re, Il faut bien faire la différence entre : définition de bloc et référence de bloc. Une définition de bloc (dxf : BLOCK) est un enregistrement d'un certain nombres d'entités graphiques plus, éventuellement, une ou plusieurs définitions d'attributs (dxf : ATTDEF). C'est une entité non graphique enregistrée dans le dessin dans la table des blocs. On crée des définitions de bloc avec la commande BLOC.Quand on modifie une définition de bloc (depuis l'éditeur de bloc ou par programmation) ces modifications seront répercutées sur toutes les références à cette définition insérées dans le dessin. Une référence de bloc (dxf : INSERT) est une entité graphique qui n'est, comme son nom l'indique, qu'une référence à une définition de bloc. On crée des référence de blocs avec la commande INSERER et en choisissant une définition dans la table des blocs du dessin ou en sélectionnant un fichier DWG ou encore en important une définition depuis un autres dessin (DesignCenter ou Palette). Dans les deux derniers cas, la définition du bloc est ajoutée à la table du dessin courant.Si la définition de bloc contient des définitions d'attributs, la référence insérée contiendra des références d'attributs (dxf : ATTRIB) dont les valeurs sont les seuls objets modifiables dans une référence de bloc. Les fonctions tblsearch, tblnext, tblobjname cherche dans les tables (de blocs, de calques, etc) et n'accèdent donc qu'à des objets non graphiques (enregistrements ou définitions). Pour accéder aux référence de blocs, entités graphiques insérées dans les espaces objet ou papier (ces espaces sont aussi des sortes de définitions de blocs "ouvertes" comme on ouvre une définition de bloc dans l'éditeur de bloc), pour accéder aux références, donc, il faut les sélectionner avec ou sans intervention de l'utilisateur. La fonction entsel permet de sélectionner une seule entité avec intervention de l'utilisateur et retourne, en cas de succès une liste contenant le nom d'entité (type ENAME) et le point cliqué (coordonnées SCU courant). La fonction ssget permet de sélectionner une ou plusieurs entités avec ou sans intervention de l'utilisateur. Elle retourne un jeu de sélection (type PICKSET) qui contient, entre autres, les entités sélectionnées.Utilisée sans intervention utilisateur, ssget soit parcourt l'intégralité des espaces (option "_X") ; soit sélectionne les entités sous le point spécifié ; soit encore fait une sélection par fenêtre ou capture polygonale en fonction des points spécifiés.L'utilisation de filtres de sélection permet de limiter la sélection à un onglet donné, à un ou plusieurs calques, à un ou plusieurs types d'entité, etc. On accède ensuite aux entités contenu dans un jeu de sélection avec la fonction ssname à laquelle il faut passer comme arguments le jeu de sélection et l'indice de l'entité (0 pour la première).(ssname ss 0) retourne donc le nom d'entité de la première entité contenue dans ss. Quand tu as enfin obtenu le nom d'entité (ENAME) de ta référence de bloc, pour atteindre les références attributs, il faut utiliser la fonction entnext qui retourne l'entité dans la base de donnée suivant celle qui est passée en argument.Quand on insère un bloc avec attributs dans un dessin, la référence de bloc est d'abord ajoutée à la base de données, puis chacune des références d'attributs puis un objet de type SEQEND qui indique la fin de la séquence pour une référence de bloc et ses attributs.On utilise donc entnext dans une boucle, jusqu'à rencontrer un objet de type SEQEND ou tant que les objets sont de type ATTRIB pour récupérer tous les attributs ou en recherche un en particulier. Comme tu peux le voir, Didier n'avais pas tort en disant que tu cherches peut-être à courir avant de savoir marcher, l’objectif que tu t'es donné demande déjà quelque, bonnes connaissances en LISP sachant que pour utiliser tout ça il faut aussi connaitre les instructions de base concernant les listes (d'association), les boucles while, etc. Pour t'aider, je te propose une routine polyvalente qui requiert un nom d'entité (ENAME) comme argument et retourne une liste contenant une paire pointée par attribut, chaque paire étant du type : (TAG . valeur). ;; GetAttribs ;; Retourne une liste de paire pointées (TAG . Value) par attribut contenus dans le bloc ;; ;; Argument ;; ent : le nom d'entité (ENAME) de la référence de bloc (defun GetAttribs (ent / elst lst) ;; Entité suivant celle passée en argument (setq ent (entnext ent)) ;; Boucle tant que ent est de type ATTRIB (while (= "ATTRIB" (cdr (assoc 0 (setq elst (entget ent))))) ;; ajoute à la liste une paire pointée (TAG . valeur) et passe à l'entité suivante (setq lst (cons (cons (cdr (assoc 2 elst)) (cdr (assoc 1 elst))) lst) ent (entnext ent) ) ) ;; valeur de retour : la liste inversée (reverse lst) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
didier Posté(e) le 23 août 2011 Posté(e) le 23 août 2011 coucou on va s'y mettre à trois !!! effectivement; il est primordial, vital, essentiel, non-négociable ...de cibler ce qu'on veut faire, être au moins capable de le verbaliserl'ordi ne fera que ce qu'on lui dit de faire je peux faire une routine qui travaille sur TOUS les blocs du dessin et qui rajoute par exemple un préfixe à la valeur de l'attribut.il faudra utiliser un "filtre de sélection" puis une boucle, tu connais ou pas ? mais pour viser tel bloc et que tu ne veuilles pas le sélectionner à la souris ???sauf à ce qu'il soit unique dans le fichier comme nous le disait VDH-Bruno, je sais pas faire. je te l'ai demandé en MP, je te le re-demande en publicfais passer un fichier AVEC DES EXPLICATIONSdu style j'ai ça avant la routine...je veux ça après le traitement. il faut reconnaître qu'on est conciliants, non ? amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
(gile) Posté(e) le 23 août 2011 Posté(e) le 23 août 2011 S'il n'y a qu'un seul bloc dans le dessin, utilise ssget avec l'option "_X" et un filtre avec le nom du bloc (regarde l'aide pour ssget ainsi que le lien vers les filtre en bas de page).ssname avec l'indice 0 devrait te retourne le nom d'entité du bloc et la routine ci-dessus la valeur pour l'étiquette que tu veux. Bon courage... Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
ASTERIXII Posté(e) le 23 août 2011 Auteur Posté(e) le 23 août 2011 Je tiens vraiment à vous remerciez. J'ai enfin la solution, même si je ne la comprends pas !j'ai regardé l’aide D’autocad sur le sujet, mais après ssget, je n’ai pas trouvé le sujet sur les filtres.J’ai bien trouvé les codes de groupe pour SSGET X mais dans une doc de 1989 !, et j’ai pas d’explication sur (Cons 66 1 ).Je trouvais l’ancienne doc d’autocad plus pratique ! Alors suivant la dernière idée de Gile j’ai (encore) recopié une partie du code du début, ou j’ai retrouvé ssget et ssname.Je savais que la gestion des blocs était compliqué, mais pas à ce point la !J’ai aussi trouvé mon erreur dans la gestion de la variable lst.Bon merci encore pour votre aide.Amicalement (Defun C:NGF ()(setq BN "NGFX") ; nom du bloc (Setq SS (SsGet "_X" (List (Cons 0 "INSERT") (Cons 2 bn) (Cons 66 1) ) ) N (If SS (SsLength SS) 0) ) ;*********************** (setq n 0) (repeat (sslength ss) (setq na (ssname ss n) lst (acet-insert-attrib-get (list na 1)) );setq);********************** (setq NGFref (nth 0 lst))(setq NGFref (car (cdr NGFref)))(setq NGFref (atof NGFref)) ); fin defun
VDH-Bruno Posté(e) le 23 août 2011 Posté(e) le 23 août 2011 Re, J'ai enfin la solutionC’est le principal, c’est bien :) . En reprenant le cheminement proposé par (gile) tu aurais également pu y arriver comme cela avec GetAttribs: (defun c:NGF () (atof (cdar (GetAttribs (ssname (ssget "_X" '((2 . "NGFX"))) 0)))) ) Sinon je profite de l’occasion pour te conseiller d’archiver la réponse n°16 de (gile), cela te fera un excellent support sur les blocs. Je suis admiratif de la qualité et de la richesse de son intervention. Bon courage pour la suiteA+ (Ps : Au passage (gile) si tu me lis je te remercie pour l’article sur les vecteurs déposé sur AcadLabs)(Ps bis : Et merci à Didier d’être l’initiateur d’AcadLabs (site que je découvre), pour l’instant j’exploite ses ressources en espérant pouvoir l’enrichir un jour..). Apprendre => Prendre => Rendre
didier Posté(e) le 23 août 2011 Posté(e) le 23 août 2011 coucou je te remercie, VDH-Bruno, de ces encouragementsje manque de temps étant expatrié depuis plus d'un an pour agrémenter le sitemais les interventions de 'gile) sont là pour pallier mes absences. quant à ASTERIXII,tu n'empruntes pas le bon chemin. oublie DEFINITIVEMENT le copier-collerne serait-ce que pour sentir les erreurs que tu commetspar exemple des parenthèses manquantes ou autres joyeusetés.il est ESSENTIEL de taper le code pour s'approprier le langage. dans ton exemple tu choisis un bloc uniquealors pourquoi fais-tu une boucle ?et pourquoi utilises-tu le acet-insert-attrib-get le genre de truc qu'on ne tape jamais à la main allez, bon courage à toi amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
(gile) Posté(e) le 23 août 2011 Posté(e) le 23 août 2011 Je ne peux qu'abonder dans le sens de Didier. - Soit su tu veux apprendre et alors il faut te retrousser les manches, utiliser l'éditeur Visual LISP, faire des tests, des erreurs et refaire des tests jusqu'à comprendre tes erreurs. Si tu fais (quand même) des copier/coller, privilégie les routines (comme celles que j'ai donné ci-dessus) et décortique les (toujours dans l'éditeur) jusqu'à les comprendre et te les approprier. on apprend aussi beaucoup en lisant des codes écrits par d'autre à condition de les comprendre.L'avantage des routines (fonctions LISP personnalisées) c'est qu'on peut les utiliser comme des fonctions LISP natives (si tant est qu'elles soient chargées) et se constituer ainsi une bibliothèque de nouvelles fonctions. - Soit tu veux une solution toute faite, alors fais en la demande clairement :"Dans mon dessin, je n'ai qu'un seul bloc nommé "NGFX" dont je veux récupérer la valeur de l'attribut dont l'étiquette est "NGFZ" sous forme de réel."Et là, ceux qui savent pourront te répondre facilement ou ceux qui veulent apprendre trouveront un exercice qu'ils essayeront de résoudre. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
didier Posté(e) le 23 août 2011 Posté(e) le 23 août 2011 coucou :) pas mieux ;) amicalement :cool: Éternel débutant... Mon site perso : Programmer dans AutoCAD
rom1_am Posté(e) le 23 août 2011 Posté(e) le 23 août 2011 Bonjour, D'après ce que tu dis dans la réponse 15: Je recherche une methode pour memoriser une valeur (NGF) dans mon dessin, pour qu'à la prochaine ouverture du plan, je la retrouve automatiquement, et sans passer par un fichier en ecriture.C'est pour cette raison que j'ai pensé au bloc, mais il y à peut-être une autre solution ? Je pense qu'il serait plus simple d'utiliser une variable système (USERI1-5, USERR1-5, PROJECTNAME) pour répondre à ce besoin.Et le code pour récupérer la valeur serait également plus simple. a+ _______________________________R.A.Développeur AutoCAD C#.netwww.danialu.fr
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