Aller au contenu

Lire la valeur d'un attribut de bloc


Messages recommandés

Posté(e)

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.

 

Posté(e)

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

Posté(e)

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

Posté(e)

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

Posté(e)

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

Posté(e)

@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

  • 4 semaines aprĂšs...
Posté(e)

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

Posté(e)

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

 

 

Posté(e)

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

Invité
RĂ©pondre Ă  ce sujet


×   CollĂ© en tant que texte enrichi.   Coller en tant que texte brut Ă  la place

  Seulement 75 Ă©moticĂŽnes maximum sont autorisĂ©es.

×   Votre lien a Ă©tĂ© automatiquement intĂ©grĂ©.   Afficher plutĂŽt comme un lien

×   Votre contenu prĂ©cĂ©dent a Ă©tĂ© rĂ©tabli.   Vider l’éditeur

×   Vous ne pouvez pas directement coller des images. Envoyez-les depuis votre ordinateur ou insĂ©rez-les depuis une URL.

×
×
  • CrĂ©er...

Information importante

Nous avons placĂ© des cookies sur votre appareil pour aider Ă  amĂ©liorer ce site. Vous pouvez choisir d’ajuster vos paramĂštres de cookie, sinon nous supposerons que vous ĂȘtes d’accord pour continuer. Politique de confidentialitĂ©