Aller au contenu

Sélection rapide de blocs par valeur d\'attribut ?


gillespj

Messages recommandés

Bonjour,

 

Je cherche un lisp qui permettrait de sélectionner différents blocs ayant la même valeur d'attribut.

 

Par Ex :

3 types de blocs : arbre, chaise et poteau

l'attribut commun : TAILLE

Valeur de l'attribut : petit, moyen, grand

 

Je veux sélectionner tous les blocs dont l'attribut TAILLE = grand

 

Merci.

Lien vers le commentaire
Partager sur d’autres sites

Salut

 

Un petit LISP.

L'utilisateur sélectionne un attribut et tous les blocs ayant la même étiquette et la même valeur sont sélectionnés.

 

(defun c:ssatt (/ att elst tag val ss1 ss2 n ent)
 (and
   (setq att (car (nentsel "\nSélectionnez l'attribut source: ")))
   (setq elst (entget att))
   (setq tag (cdr (assoc 2 elst))
  val (cdr (assoc 1 elst))
  ss2 (ssadd)
   )
   (setq ss1 (ssget "_X" '((0 . "INSERT") (66 . 1))))
   (repeat (setq n (sslength ss1))
     (setq ent	(ssname ss1 (setq n (1- n)))
    att	(entnext ent)
     )
     (while (= (cdr (assoc 0 (setq elst (entget att)))) "ATTRIB")
(if (and (= (cdr (assoc 2 elst)) tag)
	 (= (cdr (assoc 1 elst)) val)
    )
  (ssadd ent ss2)
)
(setq att (entnext att))
     )
   )
   (sssetfirst nil ss2)
 )
 (princ)
) 

 

 

[Edité le 5/2/2008 par (gile)]

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

Une nouvelle version (plus polyvalente).

L'utilisateur entre l'étiquette de l'attribut à la ligne de commande ou fait Entrée, Espace ou clic droit pour le sélectionner à l'écran. Si l'étiquette à été entrée, il entre ensuite la valeur de l'attribut.

 

(defun c:ssatt (/ att elst tag val ss1 ss2 n ent)
 (and
   (setq att (getstring "\nEntrez l'étiquette ou [b]: "))
   (if	(or (= att "") (= att " "))
     (and (setq att (car (nentsel "\nSélectionnez l'attribut source: ")))
   (= (cdr (assoc 0 (setq elst (entget att)))) "ATTRIB")
   (setq tag (cdr (assoc 2 elst))
	 val (cdr (assoc 1 elst))
   )
     )
     (setq tag	(strcase att)
    val	(getstring "\nEntrez la valeur de l'attribut: ")
     )
   )
   (setq ss2 (ssadd))
   (setq ss1 (ssget "_X" '((0 . "INSERT") (66 . 1))))
   (repeat (setq n (sslength ss1))
     (setq ent	(ssname ss1 (setq n (1- n)))
    att	(entnext ent)
     )
     (while (= (cdr (assoc 0 (setq elst (entget att)))) "ATTRIB")
(if (and (= (cdr (assoc 2 elst)) tag)
	 (= (cdr (assoc 1 elst)) val)
    )
  (ssadd ent ss2)
)
(setq att (entnext att))
     )
   )
   (sssetfirst nil ss2)
 )
 (princ)
) 

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

J'ai essayé ta 1ère version, que du bonheur ;)

Cela fonctionne même avec des attributs invisibles (pour peu que ATTRCRAN soit actif, bien sur)

 

Va bien m'être utile ce p'tit bout de code , suffisait d'y penser.

 

Merci

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

 

Hello

 

Cette routine est tres pratique, encore merci !

 

Cependant pour moi elle a un micro-défaut : elle sélectionne TOUS les blocs avec l'attribut correspondant dans TOUT l'espace inter-galactique d'AutoCAD !

 

Je désire avoir AUSS la possibilité de sélectionner classiquement une partie de mon dessin "à l'instant T" en plus bien sur de la sélection GLOBALE ... :)

 

Merci d'avance, Le Decapode

 

 

Autodesk Expert Elite Team

Lien vers le commentaire
Partager sur d’autres sites

Voilà :

 

(defun c:ssatt (/ att elst tag val ss1 ss2 n ent)
 (and
   (setq att (getstring "\nEntrez l'étiquette ou [b]: "))
   (if	(or (= att "") (= att " "))
     (and (setq att (car (nentsel "\nSélectionnez l'attribut source: ")))
   (= (cdr (assoc 0 (setq elst (entget att)))) "ATTRIB")
   (setq tag (cdr (assoc 2 elst))
	 val (cdr (assoc 1 elst))
   )
     )
     (setq tag	(strcase att)
    val	(getstring "\nEntrez la valeur de l'attribut: ")
     )
   )
   (setq ss2 (ssadd))
   (sssetfirst nil nil)
   (princ "\nSélectionnez les blocs ou [b]: ")
   (or	(setq ss1 (ssget '((0 . "INSERT") (66 . 1))))
(setq ss1 (ssget "_X" '((0 . "INSERT") (66 . 1))))
   )
   (if	ss1
     (repeat (setq n (sslength ss1))
(setq ent (ssname ss1 (setq n (1- n)))
      att (entnext ent)
)
(while (= (cdr (assoc 0 (setq elst (entget att)))) "ATTRIB")
  (if (and (= (cdr (assoc 2 elst)) tag)
	   (= (cdr (assoc 1 elst)) val)
      )
    (ssadd ent ss2)
  )
  (setq att (entnext att))
)
     )
   )
   (sssetfirst nil ss2)
 )
 (princ)
) 

 

[Edité le 7/2/2008 par (gile)]

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

  • 5 mois après...

Salut,

 

Les versions ci dessus ne fonctionnent pas avec les attributs contenus dans des blocs dynamiques.

 

Voici une nouvelle version (Visual LISP) qui fonctionne aussi avec les blocs dynamiques.

 

L'utilisateur sélectionne l'attribut, puis, soit fait une sélection (fenêtre ou capture) qui sera filtrée, soit fait Entrée, Espace ou clic droit pour étendre la sélection à tout le dessin.

 

;; Sélection par valeur d'attribut (gile)
(defun c:ssatt (/ doc att elst tag val name ss1 ss2)
 (vl-load-com)
 (and
   (setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))
   (setq att (car (nentsel "\nSélectionnez l'attribut source: ")))
   (setq att (vlax-ename->vla-object att))
   (= (vla-get-ObjectName att) "AcDbAttribute")
   (setq tag (vla-get-TagString att)
  val (vla-get-TextString att)
  blk (vla-ObjectIDToObject doc (vla-get-OwnerId att))
  name (if (vlax-property-available-p blk 'EffectiveName)
	 (vla-get-EffectiveName blk)
	 (vla-get-Name blk)
       )
  ss2 (ssadd)
   )
   (princ "\nSélectionnez les blocs ou [b]: ")
   (or
     (ssget (list '(0 . "INSERT")
	   '(66 . 1)
	   (cons 2 (strcat name ",`*U*"))
     )
     )
     (ssget "_X"
     (list '(0 . "INSERT")
	   '(66 . 1)
	   (cons 2 (strcat name ",`*U*"))
     )
     )
   )
   (vlax-for blk (setq ss1 (vla-get-ActiveSelectionSet doc))
     (if (= name
     (if (vlax-property-available-p blk 'EffectiveName)
       (vla-get-EffectiveName blk)
       (vla-get-Name blk)
     )
  )
(foreach a (vlax-invoke blk 'GetAttributes)
  (if (and (= (vla-get-TagString a) tag)
	   (= (vla-get-TextString a) val)
      )
    (ssadd (vlax-vla-object->ename blk) ss2)
    T
  )
)
T
     )
   )
   (not (vla-delete ss1))
   (sssetfirst nil ss2)
 )
 (princ)
) 

 

[Edité le 13/7/2008 par (gile)]

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

  • 3 semaines après...

Sur la proposition n°8 de (gile)

 

en changeant simplement:

(= (vla-get-TextString a) val)

par

(wcmatch (vla-get-TextString a) val)

 

M'a permis de faire un filtrage plus fin avec les caractères génériques.

Bon il faut bien connaitre l'usage de wcmatch et des caractères pouvant être employés lorsque le programme demande "Entrez la valeur de l'attribut:" , mais c'est super efficace.

 

Voilà pour ceux que cela pourrait intéresser, ou si (gile) veut encore perfectionner sa routine.

(la dernière proposition en VL, comme elle est montée ne permet pas cela, ou il faut modifier la ligne: val (vla-get-TextString att) et faire un getstring à la place)

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

Dois-je déduire que seul le visual lisp permet d'extraire les attributs d'un bloc dynamique?

 

Non, dans ce cas là, j'utilise Visual LISP pour récupérer le nom de la définition du bloc (EffectiveName).

Quand on insère et qu'on modifie les propriétés d'un bloc dynamique, il devient un bloc anonyme.

On peut peut-être récupérer le "EffectiveNmae" du bloc avec les listes DXF, mais je n'ai pas cherché.

Par conte, pour récupérer les propriétés dynamiques du bloc, Visual LISP semble incontournable.

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Peut-on avoir le même mais au lieu de sélectionner un attribut, pouvoir rentrer directement

au clavier la valeur de cet attribut?

 

Le fait de sélectionner l'attribut permet de récupérer plus d'information que la seule valeur de l'attribut (nom du bloc, étiquette de l'attribut). Ces données sont utiles pour filtrer la sélection.

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Voici notre probleme:

 

Dans un plan architecte les locaux sont désignés par des blocs à attributs, parmis ces attributs

un code permet de reconnaitre le type de local par exemple BUR-01 désigne un bureau de

type 1, nous voudrions savoir , en arrivant sur le plan , combien de locaux "BUR-01" il y a et où

ils se trouvent.

Actuellement on y arrive avec "burst" puis "sélection rapide" texte index "BUR-01"

 

mais en voyant ce post...

 

D'où ma question précedante...

Lien vers le commentaire
Partager sur d’autres sites

  • 1 mois après...

Bonjour,

cet outil m'intéresserai vraiment, malheureusement il sélectionne tous les blocs du dessin sans distinction de nom.

Est-il possible de modifier le lisp afin qu'il ne sélectionne uniquement les blocs avec attributs sélectionnés UNIQUEMENT DES BLOCS A PARTIR DUQUEL J'AI CLIQUE ?

(j'espère qu'on m'a compris car c'était pas très clair...)

 

Merci.

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

Il serait temps que tu te mettes au LISP, funkkybebel, à chaque fois qu'un routine t'intéresses, il faudrait lui apporter des modifications...

 

Dans ce cas là, je ne comprends vraiment pas ta demande, le LISP (dernière version) sélectionne tous les blocs DE MÊME NOM dont la valeur DU MÊME ATTRIBUT est identique.

 

[Edité le 26/9/2008 par (gile)]

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Je dois avoir un problème avec mes blocs.

Je réessayerai lundi au bouleau.

Quand à me mettre au lisp j'ai bien essayé, et tu comprendras bien que ce genre de lisp n'est pas du niveau d'un débutant...entre nous le lisp n'est pas le plus facile des languages.

J'ai déjà trituré des programmes lisp (grâce aux commentaires laissées à l'intérieur heureusement) mais ajouter une fonction telle que celle là je m'avoue vaincu.

 

J'ai pourtant bien cru que ça le faisais mais ça ne sélectionne qu'un seul bloc.

 

[Edité le 26/9/2008 par funkkybebel]

Lien vers le commentaire
Partager sur d’autres sites

Bonjour,

en effet il s'agissait bien d'une erreur d'utilisation de ma part, ouf gile :)

 

Par contre l'idée suivante est toujours bonne n'est-ce pas :

 

Est-il d'ailleurs possible de le rajouter dans la liste de ssm : on cocherai la case attribut et du coup le lisp ssm chercherait tous les blocs selectionnés par Attribut...le pied.

 

Merci pour cet outil génial,

Salutations.

 

 

Lien vers le commentaire
Partager sur d’autres sites

Est-il d'ailleurs possible de le rajouter dans la liste de ssm : on cocherai la case attribut et du coup le lisp ssm chercherait tous les blocs selectionnés par Attribut

 

Le problème est que ssm et ssatt ne fonctionnent pas de la même façon.

ssm s'appuie sur la sélection d'une entité (une référence de bloc, par exemple), ssatt sur celle d'une sous entité (attribut).

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

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é