Jump to content
itacad

Select blocks by attribute TAG

Recommended Posts

itacad

Hello...I find a lot of solution for select blocks by an attribute values, but I did not find any solution for select all blocks in a file that have an attributes with the same tag.

For example I want to select all the blocks that have the attribute tag "SIGLA"...I did not find a way by using normal autocad procedures or commands...

Regards

Share this post


Link to post
Share on other sites
ronjonp

The FIND command can create a selection set of objects with the same value.

Share this post


Link to post
Share on other sites
Grrr

This should work. Sorry for the coding style (I was bored) :

 

(defun C:test ( / tmp )
 (if 
   (setq tmp
     ((lambda (every L / tmp) (if (apply '= (mapcar 'length (list L (setq tmp (every L))))) tmp))
       (lambda (L / tmp) (if (setq tmp (eval (car L))) (cons tmp (every (cdr L)))))
       '( (if (not vlax-get-acad-object) (alert "(vl-load-com)") t)
         (ssget "_X" '((0 . "INSERT")(66 . 1)))
         (car (nentsel "\nPick attribute: "))
         ''(87 97 116 99 104 97 32 108 111 111 107 105 110 103 32 102 111 114 63)
       )
     )
   )
   (apply
     '(lambda ( c a b d / enx v nSS i e o nm n atts nmL )
       (and a b
         (member '(0 . "ATTRIB") (setq enx (entget b)))
         (setq v (mapcar '(lambda (x) (cdr (assoc x enx))) '(2 1)))
         (setq nSS (ssadd))
         (repeat (setq i (sslength a))
           (or
             (and 
               (setq nm (vlax-get (setq o (vlax-ename->vla-object (setq e (ssname a (setq i (1- i)))))) 'EffectiveName))
               (setq atts (vlax-invoke o 'GetAttributes))
               nmL (setq n (cdr (assoc nm nmL)))
               ( (lambda (x) (equal v (mapcar (function vlax-get) (list x x) '(TagString TextString)) 1e-3)) (nth n atts) )
               (ssadd e nSS)
             ); and
             (and
               (setq n -1)
               (vl-some (function (lambda (x) (setq n (1+ n)) (if (equal v (mapcar (function (lambda (xx) (vlax-get x xx))) '(TagString TextString)) 1e-3) n))) atts)
               (setq nmL (cons (cons nm n) nmL))
               (ssadd e nSS)
             ); and
           ); or
         ); repeat
       ); and
       (and nSS (/= 0 (sslength nSS)) (sssetfirst nil nSS))
     ); lambda
     tmp
   )
 )
 (princ)
)
(vl-load-com) (princ)

Edited by Grrr

Share this post


Link to post
Share on other sites
Lee Mac

I don't think the code need be quite so complex - here is a simple example:

(defun c:selbytag ( / a e i n s x )
   
   (setq n "SIGLA")
   
   (if (setq s (ssget "_X" '((0 . "INSERT") (66 . 1))))
       (repeat (setq i (sslength s))
           (setq i (1- i)
                 e (ssname  s i)
                 a (entnext e)
                 x (entget  a)
           )
           (while (and (= "ATTRIB" (cdr (assoc 0 x))) (/= n (strcase (cdr (assoc 2 x)))))
               (setq a (entnext a)
                     x (entget  a)
               )
           )
           (or (= "ATTRIB" (cdr (assoc 0 x))) (ssdel e s))
       )
   )
   (sssetfirst nil s) (princ)
)

Share this post


Link to post
Share on other sites
BIGAL

Re lee's code, for a block that you can see on screen use this, non hard coded answer.

 

(setq n (cdr (assoc 2 (entget (car (nentsel "pick attribute"))))))

Share this post


Link to post
Share on other sites
ronjonp

Here's a VL variant:

(defun c:foo (/ s tag)
 (setq tag "SIGLA")
 (if (setq s (ssget '((0 . "INSERT") (66 . 1))))
   (foreach e (vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))
     (and (null (vl-some '(lambda (x) (eq (vla-get-tagstring x) (strcase tag)))
		  (vlax-invoke (vlax-ename->vla-object e) 'getattributes)
	 )
   )
   (ssdel e s)
     )
   )
 )
 (sssetfirst nil s)
 (princ)
)
(vl-load-com)

Edited by ronjonp

Share this post


Link to post
Share on other sites
itacad

thank you all! tomorrow I'll try them all...

In the meantime, looking with google, I found other possible solutions...I read what "Information for new members" says about link so, for completeness, I'll pass you the link and it will be ok you'll read what i have found.

I write to you as soon as possible!

Share this post


Link to post
Share on other sites
itacad

Hello to everyone! I tried the various lisp and these are my conclusions...I apologize if they are inaccurate but it was a full week, I did not have time and I report the "immediate result"...:

1) the Grrr's lisp stopped after the pick of the attribute (I'll try it again)...but I like the idea of select by click an attribute!

2) the ronjob's lisp is ok and I like that it works by a selection area

3) selbytag is ok and it works also with frozen layer that it is very useful for me...at the moment I prefer this lisp.

Maybe to exercise I'll try to write a lisp that includes all three...

 

The other solution I have found in internet are these:

https://forums.autodesk.com/t5/autocad-forum/selecting-blocks-with-same-attribute-values/td-p/4791745 (very interesting)

https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/select-all-blocks-by-typing-attributes-tag/td-p/7377964

 

the next step is it to extrapolate the values contained in the chosen attribute for count them!

I tried the express command attext but it generates useless txt file...I will try to find some method that generate file .csv (I hope it exists).

 

I love Lee Mac lisp like Count Attributes Value or Block Counter because they organize the data in tables or csv files, but I need to work only with the values of the tag attribute I choose for the selection.

 

I thank you again and I greet you

Share this post


Link to post
Share on other sites
Grrr

1) the Grrr's lisp stopped after the pick of the attribute (I'll try it again)...but I like the idea of select by click an attribute!

 

Doh! Fixed.. :oops:

Share this post


Link to post
Share on other sites
itacad

Thank you Grrr! I try your (fixed) lisp and it works very well but...it works using attribute value rather than attribute tag...(it selects the blocks that have the same value in the attribute tag selected...sorry for my english).

It is very useful...I already had a like like that, but mine was not readable (.FAS), so I will use yours!

Furthermore, your program also selects frozen blocks, while mine only those in the selection area.

But my initial question concerned how select all the blocks with a certain attribute tag without evaluating the content

It would be nice to have all these combinations in one lisp, and decide what to select:

- attribute tag or attribute value

- all blocks in the drawing or blocks in a selected area

maybe I'll open a topic to ask how I can differentiate these choices!

thanks for now

Share this post


Link to post
Share on other sites
Grrr

itacad,

I still don't understand what you mean by "without evaluating the content".

However this should work out your problem:

 

(defun C:SelBlksByAttTag ( / msg dcl des dch dcf r )
 
 (vl-some (function (lambda (x / msg) (and (vl-catch-all-error-p (setq msg (vl-catch-all-apply (eval x)))) (prompt (strcat "\nError: " (vl-catch-all-error-message msg))))))
   '(
     (function 
       (lambda nil 
         (and (setq dcl (vl-filename-mktemp nil nil ".dcl")) (setq des (open dcl "w"))
           (mapcar (function (lambda (x) (princ (strcat "\n" x) des))) 
             '("SelBlksByAttTag : dialog"
               "{ label = \"Select by Attribute\"; spacer_1;"
               "  : boxed_column"
               "  { label = \"Attribute options\";"
               "    : toggle { label = \"Tag\"; key = \"at\"; value = 1; }"
               "    : toggle { label = \"Value\"; key = \"av\"; value = 1; }"
               "  }"
               "  spacer;"
               "  : boxed_radio_column"
               "  { label = \"Block Selection\";"
               "    : radio_button { label = \"All\"; key = \"sx\"; value = 1; }"
               "    : radio_button { label = \"Manual\"; key = \"ss\"; }"
               "  }"
               "  spacer;"
               "  : column"
               "  {"
               "    : toggle { label = \"Same Name Blocks\"; key = \"b\"; alignment = centered; }"
               "  }"
               "  spacer_1; ok_cancel; : text { key = \"error\"; }"
               "}"
             ); list
           ); mapcar
           (not (setq des (close des))) (< 0 (setq dch (load_dialog dcl))) (new_dialog "SelBlksByAttTag" dch)
           (progn 
             (action_tile "accept"
               (vl-prin1-to-string
                 (quote
                   (
                     (lambda ( / tmp )
                       (cond 
                         ( (not (setq tmp (apply 'append (mapcar '(lambda (x) (if (= "1" (get_tile x)) (list x))) '("at" "av")))))
                           (set_tile "error" "Specify Attribute Option!")
                         )
                         ( (setq r (append (list (= "1" (get_tile "b"))) (vl-some '(lambda (x) (if (= "1" (get_tile x)) (list x))) '("sx" "ss")) tmp))
                           (done_dialog 1) 
                         )
                       ); cond
                     ); lambda
                   )
                 ); quote
               ); vl-prin1-to-string
             ); action_tile
             (/= 1 (setq dcf (start_dialog)))
           ); progn
           (setq r nil)
         ); and
       ); lambda
     ); function 
     (function 
       (lambda ( / nfo SS L )
         (cond
           ( (not r) )
           ( 
             (not
               (setq nfo
                 ('((f)(setvar 'errno 0) (f))
                   '(( / e enx o )
                     (cond
                       ( (= 52 (getvar 'errno)) nil)
                       (
                         (or
                           (not (setq e (car (nentsel "\nPick Attribute <exit>: ")))) 
                           (not (member '(0 . "ATTRIB") (setq enx (entget e)))) 
                           (and (= 7 (getvar 'errno)) (princ "\nMissed, try again.") (setvar 'errno 0))
                         )
                         (f)
                       )
                       ( (setvar 'errno 52) (setq o (vlax-ename->vla-object e))
                         (cons (vla-get-EffectiveName (vlax-ename->vla-object (cdr (assoc 330 enx)))) (mapcar '(lambda (x) (vlax-get o x)) '(TagString TextString)))
                       )
                     )
                   )
                 )
               ); setq nfo
             ); not
           )
           (
             (not
               (setq SS 
                 (ssget (cdr (assoc (cadr r) '(("ss" . "_:L-I")("sx" . "_X")))) 
                   (append 
                     '((0 . "INSERT") (66 . 1))
                     (if (car r) (list (cons 2 (strcat "`**," (car nfo)))))
                     (list (if (= 1 (getvar 'cvport)) (cons 410 (getvar 'ctab)) '(410 . "Model")))
                   ); append
                 ); ssget
               ); setq SS
             ); not
           )
           (
             (
               '(( b / bnm i o ) 
                 (setq i (sslength SS))
                 (cond 
                   (b
                     (setq bnm (car nfo))
                     (repeat i (and (eq bnm (vla-get-EffectiveName (setq o (vlax-ename->vla-object (ssname SS (setq i (1- i))))))) (setq L (cons o L))))
                   ); b
                   ( (repeat i (setq L (cons (vlax-ename->vla-object (ssname SS (setq i (1- i)))) L))) )
                 ); cond
                 (not L)
               ); list
               (car r)
             )
           )
           (
             (
               '(( m v / nSS ) 
                 (setq nSS (ssadd))
                 (vl-some (function (lambda (a b) (if (equal a m) (eval b))))
                   '(("at" "av")("at")("av"))
                   '(
                     (foreach x L (and (vl-some '(lambda (att) (equal v (mapcar '(lambda (xx) (vlax-get att xx)) '(TagString TextString)))) (vlax-invoke x 'GetAttributes)) (ssadd (vlax-vla-object->ename x) nSS)))
                     (progn (setq v (car v)) (foreach x L (and (vl-some '(lambda (att) (eq (vlax-get att 'TagString) v)) (vlax-invoke x 'GetAttributes)) (ssadd (vlax-vla-object->ename x) nSS))))
                     (progn (setq v (cadr v)) (foreach x L (and (vl-some '(lambda (att) (eq (vlax-get att 'TextString) v)) (vlax-invoke x 'GetAttributes)) (ssadd (vlax-vla-object->ename x) nSS))))
                   ); list
                 ); vl-some
                 (sssetfirst nil nSS)
               ); list
               (cddr r)
               (cdr nfo)
             )
           )
         ); cond
       ); lambda
     ); function
   ); list
 ); vl-some
 
 '(((87 114 105 116 116 101 110 32 98 121) (71 114 114 114) (67 114 101 100 105 116 115 32 116 111) (76 101 101 32 77 97 99))
   (104 116  116  112 58 47 47 119	119 119 46 99 97 100 116  117 116  111 114 46 110	101  116  47 102 111 114 117 109 47 115 104 111  119	116 104 114 101 97 100 
     46 112 104 112 63 49 48	50 55 56 54 45 83 101 108 101 99 116  45 98	108  111 99 107 115 45 98 121 45 97 116 116 114 105 98 117 116 101 45 84 65 71
   )
 )
 
 (vl-catch-all-apply 'eval
   '(
     (progn
       (and (< 0 dch) (unload_dialog dch))
       (and (eq 'FILE (type des)) (close des))
       (and (eq 'STR (type dcl)) (findfile dcl) (vl-file-delete dcl))
     ); progn
   ); list
 ); vl-catch-all-apply
 (princ)
); defun
(vl-load-com) (princ)

 

SelBlksByAttTag.jpg

Share this post


Link to post
Share on other sites
itacad

:o:shock::D

Incredible! it'is perfect!

I am a bit ashamed because I have not contributed at all...:oops:

With the hope that it will also be useful to others, I sincerely thank you!

Share this post


Link to post
Share on other sites
BIGAL

Grrr like the.

 

(setq dcl (vl-filename-mktemp nil nil ".dcl")) (setq des (open dcl "w"))
(princ (strcat "\n" x) des)))

 

Much easier than write-line fo, learn something new everyday. Maybe a foreach method.

Share this post


Link to post
Share on other sites
Grrr
:o:shock::D

Incredible! it'is perfect!

I am a bit ashamed because I have not contributed at all...:oops:

With the hope that it will also be useful to others, I sincerely thank you!

 

Glad it worked out and you are wellcome. :)

Just be careful when explaining your request, I understood this part and I think its enough:

It would be nice to have all these combinations in one lisp, and decide what to select:

- attribute tag or attribute value

- all blocks in the drawing or blocks in a selected area

 

 

 

Grrr like the.

 

(setq dcl (vl-filename-mktemp nil nil ".dcl")) (setq des (open dcl "w"))
(princ (strcat "\n" x) des)))

 

Much easier than write-line fo, learn something new everyday. Maybe a foreach method.

 

The overall dcl-on-the-fly technique (more precisely: the good DCL wrapping) was demonstrated by Lee Mac, so these stuff kinda originated from him (atleast I was introduced about this from him).

Although to avoid again using 80% of his style in this code, I've decided to experiment would it work by using the error-trapping techniques only. (seems to work: erases the temporarily created .dcl file)

So that explains the bit frustrating code (Lee's style was to wrap everything within a single cond function and exit with (*error* nil) in the end).

 

In the end I did a conclusion that for these type of dialogs (that contain toggles and radio_buttons) is enough to define action_tile just for the 'accept' key and manipulate/check input there.

Share this post


Link to post
Share on other sites
Lee Mac

Thank you for your acknowledgement Grrr, happy to have inspired. :thumbsup:

Share this post


Link to post
Share on other sites
Grrr
Thank you for your acknowledgement Grrr, happy to have inspired. :thumbsup:

 

Pleased to hear that Lee,

Just making sure your hard effort and help won't remain unmentioned. :)

Share this post


Link to post
Share on other sites
rlx

yeah thankx a lot Grrr , had just one brain cell left and it exploded just by looking at your code :ouch:

 

so if you don't hear from me again , then I am probably still out there ... somewhere ... looking for a replacement...

 

oh and thank you too Lee

Share this post


Link to post
Share on other sites
Grrr
yeah thankx a lot Grrr , had just one brain cell left and it exploded just by looking at your code :ouch:

 

so if you don't hear from me again , then I am probably still out there ... somewhere ... looking for a replacement...

 

oh and thank you too Lee

 

Just hit a few beers to wake-up the philosopher inside of you, and you'll be fine. :beer:

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×