itacad Posted February 12, 2018 Posted February 12, 2018 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 Quote
ronjonp Posted February 12, 2018 Posted February 12, 2018 The FIND command can create a selection set of objects with the same value. Quote
Grrr Posted February 12, 2018 Posted February 12, 2018 (edited) 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 February 16, 2018 by Grrr Quote
Lee Mac Posted February 12, 2018 Posted February 12, 2018 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) ) Quote
BIGAL Posted February 13, 2018 Posted February 13, 2018 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")))))) Quote
ronjonp Posted February 13, 2018 Posted February 13, 2018 (edited) 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 February 13, 2018 by ronjonp Quote
itacad Posted February 13, 2018 Author Posted February 13, 2018 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! Quote
itacad Posted February 16, 2018 Author Posted February 16, 2018 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 Quote
Grrr Posted February 16, 2018 Posted February 16, 2018 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.. Quote
itacad Posted February 22, 2018 Author Posted February 22, 2018 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 Quote
Grrr Posted February 23, 2018 Posted February 23, 2018 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) 1 Quote
itacad Posted February 24, 2018 Author Posted February 24, 2018 :shock: Incredible! it'is perfect! I am a bit ashamed because I have not contributed at all... With the hope that it will also be useful to others, I sincerely thank you! Quote
BIGAL Posted February 25, 2018 Posted February 25, 2018 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. Quote
Grrr Posted February 25, 2018 Posted February 25, 2018 :shock:Incredible! it'is perfect! I am a bit ashamed because I have not contributed at all... 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. Quote
Lee Mac Posted February 25, 2018 Posted February 25, 2018 Thank you for your acknowledgement Grrr, happy to have inspired. Quote
Grrr Posted February 25, 2018 Posted February 25, 2018 Thank you for your acknowledgement Grrr, happy to have inspired. Pleased to hear that Lee, Just making sure your hard effort and help won't remain unmentioned. Quote
rlx Posted February 25, 2018 Posted February 25, 2018 yeah thankx a lot Grrr , had just one brain cell left and it exploded just by looking at your code 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 Quote
Grrr Posted February 25, 2018 Posted February 25, 2018 yeah thankx a lot Grrr , had just one brain cell left and it exploded just by looking at your code 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. Quote
saran Posted March 9, 2021 Posted March 9, 2021 (edited) 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 March 9, 2021 by saran Quote
Recommended Posts
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.