OrionLG PostĂ©(e) le 18 novembre 2021 PostĂ©(e) le 18 novembre 2021 Bonjour Ă tous J'utilise depuis longtemps AutoCAD et je me lance dans le LISP quelques temps đŹ. Je trouve Ă©normĂ©ment d'aide sur ce forum et je profite de ma demande pour remercier tout le monde đ. Malheureusement lĂ je me heurte Ă un problĂšme que je ne comprend pas et je ne trouve pas la solution malgrĂ© toutes mes recherches.  Le but final de mon script est de changer le facteur de largeur des attribut donc la valeurs (le texte affichĂ©) correspond au texte entrĂ© en argument du script. J'arrive Ă changer le facteur de largeur d'attribut sans problĂšme mais je suis incapable de rĂ©cupĂ©rer la valeur de l'attribut...đ¶. Quand j'utilise la fonction "vla-get-TextString" je lis la valeur par dĂ©faut et non la valeur actuelle. Idem si j'utilise "vla-put-TextString", je modifie uniquement la valeur par dĂ©faut et non la valeur actuelle. (defun test ($text / blocks bo eo ao) ;;$text : Ătiquette de l'attribut (vl-load-com) (setq blocks (vla-get-Blocks (vla-get-ActiveDocument (vlax-get-acad-object)))) (vlax-for bo blocks (vlax-for eo bo (if (and(= (vla-get-ObjectName eo) "AcDbAttributeDefinition") (= (vla-get-TagString eo) $text) ) ; end of and (progn ;(vla-put-ScaleFactor eo 1) (princ "Ătiquette : ") (princ (vla-get-tagString eo)) (princ " - Valeur : ") (princ (vla-get-TextString eo)) (terpri) ) ) ) ) ) Auriez-vous une idĂ©e d'oĂč pourrait venir l'erreur ??? Je vous remercie d'avance pour votre aide.  Citer
Luna Posté(e) le 18 novembre 2021 Posté(e) le 18 novembre 2021 Coucou, Je ne maßtrise pas vraiment le Visual LISP mais je pense que cela vient du fait que tu utilises la définition de bloc, et non la référence de bloc. Donc pour une définition de bloc tu ne peux accéder/modifier que les valeurs par défaut des attributs. Je suppose que ton but est de modifier les références et non les définitions donc pour cela tu dois faire un jeu de sélection (ou une sélection manuelle) avec tes blocs. En LISP, tu as les fonctions (ssget) et (entsel) pour récupérer un jeu de sélection ou un nom d'entité. Je ne connais pas l'équivalent en Visual LISP s'il y en a un, donc il faut penser à faire une conversion (vlax-ename->vla-object) pour utiliser le bon type d'argument dans tes fonctions Visual LISP. Bisous, Luna Citer
OrionLG PostĂ©(e) le 18 novembre 2021 Auteur PostĂ©(e) le 18 novembre 2021 Merci beaucoup @Luna pour ta rĂ©ponse et l'explication. Merci aussi pour la diffĂ©rence entre Visual LISP et LISP. Je ne comprenais pas pourquoi certaines fonctions Ă©taient Ă©crites avec "vla" devant đ€Šââïž. Malheureusement le but de ce LISP est d'ĂȘtre utilisĂ© dans un script SCR pour appliquer la modification dans un certains nombre de fichiers DWG. Je ne peux donc pas utiliser la sĂ©lection manuelle (ou alors il faudra cliquer sur le bloc Ă chaque page đ€). Je pense que tout pourrait ĂȘtre gĂ©rĂ© en LISP mais je n'ai pas assez de connaissance pour le programmer pour le moment đ„. Je vais continuer de creuser. OrionLG Citer
didier PostĂ©(e) le 18 novembre 2021 PostĂ©(e) le 18 novembre 2021 Bonjour @Orion_LG Pour ce faire il va falloir crĂ©er un "jeu de sĂ©lection" dans le dessin. Puisque vous ĂȘtes apprenti, je me permets de vous diriger vers mon site. Si des incomprĂ©hensions persistent, revenez- Ă la charge avec une question. Bon apprentissage, bienvenue. Amicalement Citer Ăternel dĂ©butant... Mon site perso : Programmer dans AutoCAD
OrionLG PostĂ©(e) le 18 novembre 2021 Auteur PostĂ©(e) le 18 novembre 2021 Merci pour le conseil et pour l'accueil. Je vais faire ça. Le jeu de sĂ©lection me parle, je l'avais oubliĂ©. đJe vais refaire le script en LISP (et non VLISP) et repartir sur de bonnes bases Cordialement Citer
Luna PostĂ©(e) le 18 novembre 2021 PostĂ©(e) le 18 novembre 2021 @OrionLG, il n'y a pas besoin de rĂ©-Ă©crire en LISP ou Visual LISP, on peut mixer les deux et les deux sont des langages fonctionnels. La seule diffĂ©rence vient du fait que le Visual LISP est dĂ©rivĂ© du Visual Basic donc la logique de programmation diffĂšre Ă©tant donnĂ© que le Visual Basic est un langage de programmation orientĂ© objet. Pour que le script fonctionne correctement il faudra ouvrir les .dwg donc je pense que la fonction (ssget) peut marcher correctement avec l'option "_X" et un filtre sur les blocs. Petite question : tes blocs sont-ils dynamiques ? Si c'est le cas il faudra faire le tri des blocs en post-sĂ©lection sinon le tri se fera via la sĂ©lection. Je te conseille de te familiariser avec le langage qui te semble le plus cohĂ©rent, donc si tu as appris via le Visual LISP autant continuer ainsi. Si tu as besoin d'aide, le forum est lĂ , et les sites de formations AutoLISP sont trĂšs nombreux (comme te l'a proposĂ© didier par exemple). Il est fortement conseillĂ© de commencer avec des programmes simples et de dĂ©cortiquer les Ă©tapes complexes en une suite d'Ă©tapes simples. đ Bisous, Luna Citer
OrionLG PostĂ©(e) le 13 dĂ©cembre 2021 Auteur PostĂ©(e) le 13 dĂ©cembre 2021 Bonjour Ă tous. Merci beaucoup @Luna pour ton retour. Je ne l'avais pas vu đ„ car j'Ă©tais en arrĂȘt quelques temps. En fait je prĂ©fĂšre le LISP. J'avais copiĂ© une routine en Visual LISP sans trop avoir saisir la diffĂ©rence. Mais je prĂ©fĂšre continuer en LISP (mĂȘme si j'aime beaucoup le VB... mais pas pour le moment pour AutoCAD). Je viens de finir mon script en LISP et il fonctionne...normalement. Je me suis aidĂ© de l'excellent script "REPSTRING" que nous utilisons trĂšs souvent. Pour rĂ©pondre Ă ta question, les blocs ne sont pas dynamiques. J'ai en effet optĂ© pour l'option "ssget", bien vu đ. Ci-joint le code. Ăa pourra peu-ĂȘtre servir Ă d'autres. Il faut encore que je l'optimise je pense mais il est fonctionnel (defun ChangLargAttrib (string factor) (setq ss (ssget "X" (list (cons 0 "INSERT")))) ; Si ss non nil (if ss (progn (repeat (sslength ss) ; RĂ©pĂ©ter autant de fois que d'entitĂ©s dans ss (setq ent (ssname ss 0)) ; ent = nom de l'entitĂ© (setq en (entget ent)) ; en = liste DXF de l'entitĂ© (setq etype (cdr (Assoc 0 en))) ; etype = Type d'entitĂ© (INSERT dans le cas prĂ©sent) *** Ă supprimer *** (if (assoc 66 en) ; Test si la variable 66 (Drapeau "entitĂ© suivent") est Ă 1 (progn (setq textattrib (entnext ent)) (while (= (cdr (assoc 0 (entget textattrib))) "attrib") ; test si entitĂ© est un attribut (setq suben (entget textattrib)) ; suben = liste dxf de l'attribut (setq stg (cdr (assoc 1 suben))) (if (= stg string) (progn (setq fact (cdr (assoc 41 suben))) (entmod (subst (cons 41 factor) (assoc 41 suben) suben)) ) ) (setq textattrib (entnext textattrib)) ) (entupd ent) ) ) (ssdel ent ss) ) ) ) ) (defun c:ChLargAttrib () (SETQ STRING (GETSTRING T "\nTEXTE Ă REDIMENSIONNER : ")) (SETQ FACTOR (GETREAL "\nFACTEUR DE LARGEUR : ")) (ChangLargAttrib STRING FACTOR) )  L'avantage est qu'on peut l'exĂ©cuter via un script .scr du genre : OUVRIR "chemin du fichier" ChLargAttrib Texte_Ă _modifier 0.9 ; Nouveau facteur _qsave FERMER OUVRIR "chemin du fichier" ChLargAttrib Texte_Ă _modifier 0.9 ; Nouveau facteur _qsave FERMER Merci encore pour votre aide. Amicalement OrionLG Citer
Luna PostĂ©(e) le 13 dĂ©cembre 2021 PostĂ©(e) le 13 dĂ©cembre 2021 Coucou, il y a 9 minutes, OrionLG a dit : (if (assoc 66 en) Pour info tu n'as pas besoin de cette ligne si tu l'intĂšgres directement dans ton filtre de sĂ©lection (cela permettra Ă ton programme d'aller plus vite Ă©galement), comme ci-dessous : (setq ss (ssget "_X" '((0 . "INSERT") (66 . 1)))) Tu peux mĂȘme trier tes blocs en fonction de leur nom. Car actuellement tous tes blocs possĂ©dant des attributs sont modifiĂ©s mais si tu veux ne modifier que certaines dĂ©finition de blocs, tu peux filtrer suivant le code DXF 2 comme suit : (setq ss (ssget "_X" '((0 . "INSERT") (66 . 1) (2 . "NomBloc1,NomBloc2,NomBloc3")))) Il faut savoir que les wild-card characters sont autorisĂ©s dans la liste des filtres de sĂ©lection autrement dit tu peux avoir un filtre comme ceci pour ton code DXF 2 : (setq ss (ssget "_X" '((0 . "INSERT") (66 . 1) (2 . "*Bloc*")))) Ici, tous les blocs dont leur nom contient la chaĂźne "Bloc" sont pris en compte. Si tu dĂ©sires spĂ©cifier le nom via une variable, la fonction ' (= (quote)) ne fonctionne plus et il te faudra utiliser la fonction (list) et (cons) comme ceci : (setq var1 "NomBloc1,TCPoint*,*Bloc*" ss (ssget "_X" (list '(0 . "INSERT") '(66 . 1) (cons 2 var1)))) Je te conseille Ă©galement de dĂ©clarer tes variables localement pour ne pas ĂȘtre emmerdĂ© plus tard ! Je te conseille le site de (gile) et didier concernant ce point pour mieux comprendre le fonctionnement et le pourquoi. il y a 22 minutes, OrionLG a dit : (defun c:ChLargAttrib () Bisous, Luna   Citer
OrionLG PostĂ©(e) le 13 dĂ©cembre 2021 Auteur PostĂ©(e) le 13 dĂ©cembre 2021 Coucou đ Merci encore pour ton retour. En effet, ça va plus vite en intĂ©grant (66 . 1) dans le filtre đđ Malheureusement le nom des blocs oĂč il faut changer les facteurs de largeur ne sont pas toujours identiques. Je les scanne donc tous. Mais ça va vite car on n'a jamais Ă©normĂ©ment d'entitĂ©s. Par contre je garde prĂ©cieusement tes conseils pour un prochain script. J'en ai un en cours oĂč ils me seront utiles. Concernant la dĂ©claration des variables je vais creuser ça. J'ai dĂ©couvert la derniĂšre fois le site de @didier. Et j'ai depuis un moment Ă cĂŽtĂ© de moi en papier et sur mon PC l'excellent PDF "Introduction Ă AutoLISP" de @(gile) ainsi que ses scripts đ. OrionLG Citer
Messages recommandés