Jump to content

Select blocks by attribute TAG


itacad

Recommended Posts

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

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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)
)

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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!

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

: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!

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

: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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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:

Link to comment
Share on other sites

  • 3 years later...

can any one help me

above post is to select number block which has same value of 1 attribute in a block

but i need to select the blocks which has same value of  2 attribute in a block

i.e., single block is having multiply attribute Tags  (Tag1, Tag2 & Tag3)

Thank in advance

 

Edited by saran
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...