Aller au contenu

Concaténer des attributs suivant une condition (bloc-valeur)


Messages recommandés

Posté(e)

Bonjour,

Je souhaite créer une chaine de caractères à partir de certains attributs d’un bloc nommé "CARTOUCHE".

Ce bloc étant présent plusieurs fois dans le dessin (dans les onglets), j’ai besoin d’une correspondance de valeur (entrée manuellement) et de la valeur d’une étiquette d'attribut "N°DOC" valeur unique.

Lorsque je trouve le bloc concerné, je concatène quelques uns des attributs. ("AFFAIRE" "PHASE" etc..)

(defun c:concat() 
(setq monbloc (ssget "X" '((2 . "CARTOUCHE"))))
(setq valeur (getstring "Valeur:"))

(setq lis (ssget "_X" (list '(0 . "INSERT") (cons 2 monbloc))))
(setq y (sslength lis))
(setq a 0)
(setq b 0)
(setq c 0)
(while (or (< a y) (= c 1))
	(setq detect (ssname lis a)) 
	(setq ent (entnext detect))
	(setq verif "debut")
	(setq b 0)
	(while (/= verif "fin")
		(cond 
			(= (cdr (assoc 1(entget ent))) "AFFAIRE")
				(progn 
					(setq affaire (assoc 2(entget ent)))
					(setq b (+ b 1))
				)
			(= (cdr (assoc 1(entget ent))) "PHASE")
				(progn 
					(setq phase (assoc 2(entget ent)))
					(setq b (+ b 1))
				)
			(= (cdr (assoc 1(entget ent))) "EMETEUR")
				(progn 
					(setq emet (assoc 2(entget ent)))
					(setq b (+ b 1))
				)
			(= (cdr (assoc 1(entget ent))) "LOT")
				(progn 
					(setq lot (assoc 2(entget ent)))
					(setq b (+ b 1))
				)
			(= (cdr (assoc 1(entget ent))) "DOCUMENT")
				(progn 
					(setq doc (assoc 2(entget ent)))
					(setq b (+ b 1))
				)
			(= (cdr (assoc 1(entget ent))) "ZONE")
				(progn 
					(setq zone (assoc 2(entget ent)))
					(setq b (+ b 1))
				)
			(= (cdr (assoc 1(entget ent))) "NIVEAU")
				(progn 
					(setq niv (assoc 2(entget ent)))
					(setq b (+ b 1))
				)
			(= (cdr (assoc 1(entget ent))) "N°DOC")
				(progn 
					(if (= (cdr (assoc 2(entget ent))) valeur)
						(progn 
							(setq numdoc (assoc 2(entget ent)))
							(setq b (+ b 1))
							(setq c 1))
						)
					)
				)
			(= (cdr (assoc 1(entget ent)) "INDICE")
				(progn 
					(setq indice (assoc 2(entget ent)))
					(setq b (+ b 1))
				)
		)
		(if (> b 9)(setq verif "fin"))
	)
(setq a (+ a 1))
)
   (setq sortie (strcat affaire "_" phase "_" emet "_" lot "_" doc "_" zone "_" niv "_" numdoc "_" indice))
   (alert sortie)
)
(princ)

Le code est indéniablement très... lourd ou simpliste et en plus je m'arrache les cheveux ;) Help!

J'ai l'erreur: valeur de liste SSGET incorrecte

Merci

Posté(e)

Bonsoir Zebzeb,

Pour cette ligne

 

(setq lis (ssget "_X" (list '(0 . "INSERT") (cons 2 monbloc)))) 

 

La variable monbloc que tu enregistres est une sélection. Hors le code de groupe 2 correspond au nom du bloc sous forme de string. Je te laisse faire les corrections nécessaires.

 

Je ne comprend d'ailleur pas pourquoi tu fais cette sélection en 2 fois ?

Bon courage

Olivier

Posté(e)

Bonsoir Olivier

Merci pour ta réponse...

Mais je ne comprends pourquoi tu dis 2 fois la sélection, et je sais pas qu’elle sont les corrections nécessaires.

La première fois c'est (censé l'être) pour le nom du bloc concerné

La deuxième c'était pour faire la sélection des blocs de ce nom

Je ne connais pas vraiment le lisp, je bidouille avec ce je comprends (ou crois comprendre), j'ai donc besoin encore de votre aide.

A la base j'avais trouvé ce lisp:

(defun c:sk (/ dxf ent)

 (defun dxf (code ent) (cdr (assoc code (entget ent))))

 (if (and (setq ent (car (entsel "\nSelect an Attributed Block: ")))
          (eq "INSERT" (dxf 0 ent))
          (= 1 (dxf 66 ent)))

   (while (not (eq "SEQEND" (dxf 0 (setq ent (entnext ent)))))
     (princ (strcat "\n\nAtt_Tag:" (dxf 2 ent) "\nAtt_Value: " (dxf 1 ent)))))

 (princ)
)

Mais après avoir l'après-midi à essayer de remplacer

(entsel "\nSelect an Attributed Block: ")

par

(ssget "X" '((2 . "CARTOUCHE")))

... Sans succès

Encore un peu d'aide s’il vous plait, merci

Posté(e)

Ok,

Entsel te donnes le nom de l'entité et le point de sélection. La fonction car permettant de ne conserver que le om de l'entité. La fonction ssget te donnes elle une sélection. Tu devras ensuite faire défiler les diférents objets de cette sélection pour obtnir traiter chaque entité.

Pour faire défiler les entités regarde la fonction ssname à insérer dans une boucle.

(setq n 0); compteur
(setq ss (ssget));enregistrement d'une sélection
(repeat (sslength ss); boucle autant de fois qu'il y a d'entité dans la sélection
(ssname ss n); récupération du nom de la n-1 entité.
)

 

Olivier

Posté(e)
Mais je ne comprends pourquoi tu dis 2 fois la sélection

 

Tu peux sélectionner tous les blocs désirés en une seule fois avec

 

(ssget "_X" '((0 . "insert") (2 . "cartouche")))

 

Le "_X" permet déjà de traiter l'ensemble des objets du dessin.

Ensuite le reste permet de filtrer les blocs puis peux qui ont pour nom cartouche.

 

Le lisp sur les blocs n'est pas des plus simple pour un début car il te faudra ensuite faire défiler les objets à l'intérieur du bloc. Tu trouveras de nombreux exemples sur le forum. Une recherche avec SEQUEND devrais te permettre de les trouver facilement.

 

J'espère t'avoir aidé.

 

Olivier

Posté(e)

Il est évident que je n'est pas tes connaissances, je tente tant bien que mal d'adapter ce que tu à écris...

; erreur: type d'argument incorrect: lselsetp nil

 

(defun c:concat() 
(setq n 0); compteur
(setq valeur (getstring "Valeur:"))
(setq ss (ssget "X" '((2 . "CARTOUCHE"))));enregistremss d'une sélection
(repeat (sslength ss); boucle autant de fois qu'il y a d'ssité dans la sélection
(ssname ss n); récupération du nom de la n-1 ssité.
	(cond 
		(= (cdr (assoc 1(ssget ss))) "AFFAIRE")
		(progn 
			(setq affaire (assoc 2(ssget ss)))
			(setq b (+ b 1))
		)
		(= (cdr (assoc 1(ssget ss))) "PHASE")
		(progn 
			(setq phase (assoc 2(ssget ss)))
			(setq b (+ b 1))

.....etc

		(= (cdr (assoc 1(ssget ss))) "N°DOC")
		(progn 
			(if (= (cdr (assoc 2(ssget ss))) valeur)
				(progn 
					(setq numdoc (assoc 2(ssget ss)))
					(setq b (+ b 1))
					(setq c 1))
				)
			)
		)
		(= (cdr (assoc 1(ssget ss)) "INDICE")
			(progn 
				(setq indice (assoc 2(ssget ss)))
				(setq b (+ b 1))
			)
		)
)
(setq sortie (strcat affaire "_" phase "_" emet "_" lot "_" doc "_" zone "_" niv "_" numdoc "_" indice))
(princ sortie)
(princ)
)

Je tourne en rond ...

Posté(e)

(= (cdr (assoc 1(ssget ss))) "AFFAIRE") 

 

Pour obtenir le code dxf d'un objet il faut utilisé la fonction entget et non ssget.

 

De plus comme je te les déjà dit le première boucle permet de faire défilé les blocs. Les informations que tu recherchent sont situés sur les objets attributs. Il te faut donc faire une seconde boucle sur les entités de ce blocs.

 

Voici un exemple

 

Olivier

Posté(e)

J’ai suivi le lien ainsi que beaucoup d’autre, j'aurais passé une partie de la nuit sans résultat probant, donc j'ai donc tout extrait et fait un traitement sur Excel, histoire de gagner quand même un peu de temps.

Mais si toutefois une bonne âme pouvait me dépatouillé le problème, j’en lui en serais reconnaissant.

Bon week-end

Posté(e)

Bonjour,

 

Essaie avec ce petit lisp:

 

(defun C:CONCAT ( / bloc tag tags val ss i result found b attlist att )

 (setq bloc "CARTOUCHE"  ; nom du bloc
       tag "N°DOC"       ; étiquette de l'attribut à rechercher
       tags '("AFFAIRE" "PHASE" "EMET" "LOT" "DOC" "ZONE" "NIV" "NUMDOC" "INDICE") ; liste des attributs à concaténer
       ;;;~~~~~~~~~~~~~~~~~~~~~~~~~~~
       val (getstring T "\nValeur à rechercher: ")
       ss (ssget "_X" (list (cons 0 "INSERT") (cons 2 bloc)))
       i 0
       result ""
 )
 (if (and ss (not (zerop (strlen val))))
   (progn
     (vl-load-com)
     (while (and (not found) (< i (sslength ss)))
       (setq b (vlax-ename->vla-object (ssname ss i))
             attlist (mapcar '(lambda (x) (cons (vla-get-TagString x) (vla-get-TextString x)))(vlax-invoke b 'GetAttributes))
             i (1+ i)
       )
       (and
         (setq att (assoc (strcase tag) attlist))
         (= (strcase (cdr att)) (strcase val))
         (setq found T)
       )
     );while
     (setq ss nil)
   );progn
 );if ss
 (cond
   (found
     (foreach a tags
         (if (setq att (assoc (strcase a) attlist))
           (setq result (strcat result "_" (cdr att)))
           (setq result (strcat result "_???"))
         )
     )
     (alert (princ (strcat "\n" (substr result 2))))
   )
   (T
     (alert (princ "\nAucun résultat !"))
   )
 );cond
 (princ)
)

Posté(e)

Hello

 

Un Micro-Conseil d'un vieux Decapode !

 

Je vois que tu utilises des caracteres speciaux dans tes noms/etiquettes d'attributs : N°DOC

Pourquoi pas : NO_DOC

 

Tu ne peux pas savoir (moi non plus d'ailleurs) combien de problemes et bugs,

j'ai evite dans ma longue vie informatique en utilisant AUCUN caractere special (y compris le blanc/espace)

dans les noms de fichiers, calques, blocs, etiquettes, styles, tables, champs, etc ...

 

lecrabe

Autodesk Expert Elite Team

Posté(e)

Bonjour

 

C'est exactement ce que je voulais un très grand MERCI à toi Brice.

 

Un Micro-Conseil d'un vieux Decapode !

Oui je sais le Crable, mais les blocs ne sont pas de moi je récupère les plans en l'état.

 

Bonne journée

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 compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • 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é