PrimeTimeAction Posted November 20, 2018 Share Posted November 20, 2018 I have a lisp from @Lee Mac that selects blocks based on attribute values (attached here). Is there a way to limit the search to specific tags of the blocks. For example in case I want to search for a value of "0.5" in "SPEED" attribute tag only for all the blocks in the drawing. Select Blocks by Attribute Value.lsp Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted November 20, 2018 Share Posted November 20, 2018 (edited) Try the following: ;; Select Blocks by Attribute Tag and/or Value - Lee Mac ;; Selects all attributed blocks in the current layout which contain a specified attribute value. (defun c:selblkbyatt ( / att atx ent idx sel str tag ) (setq str (strcase (getstring t "\nSpecify attribute value <any>: ")) tag (strcase (getstring (strcat "\nSpecify attribute tag" (if (= "" str) ": " " <any>: ")))) ) (if (not (= "" str tag)) (if (and (setq sel (ssget "_X" (list '(000 . "INSERT") '(066 . 1) (if (= 1 (getvar 'cvport)) (cons 410 (getvar 'ctab)) '(410 . "Model") ) ) ) ) (progn (repeat (setq idx (sslength sel)) (setq ent (ssname sel (setq idx (1- idx))) att (entnext ent) atx (entget att) flg nil ) (while (and (= "ATTRIB" (cdr (assoc 0 atx))) (not (and (or (= "" str) (wcmatch (strcase (cdr (assoc 1 atx))) str)) (or (= "" tag) (wcmatch (strcase (cdr (assoc 2 atx))) tag)) ) ) ) (setq att (entnext att) atx (entget att) ) ) (if (= "SEQEND" (cdr (assoc 0 atx))) (ssdel ent sel) ) ) (< 0 (sslength sel)) ) ) (sssetfirst nil sel) (princ "\nNo blocks found.") ) ) (princ) ) Edited November 20, 2018 by Lee Mac 2 Quote Link to comment Share on other sites More sharing options...
PrimeTimeAction Posted November 22, 2018 Author Share Posted November 22, 2018 Thanks alot @Lee Mac, it works flawlessly. You are a legend dude. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted November 22, 2018 Share Posted November 22, 2018 You're most welcome! Quote Link to comment Share on other sites More sharing options...
NoamBrand Posted December 13, 2018 Share Posted December 13, 2018 Thanks alot @Lee Mac ,works great! Would it be possible to add an option to choose a specific block name? I have the same attributes in many blocks in my drawing, so this lisp would be much more useful and quick this way. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted December 13, 2018 Share Posted December 13, 2018 The following program will allow you to specify either a block name, attribute tag, or attribute value (or all three), and will return a selection of all blocks matching the given criteria, residing in the current layout: ;; Block Selection - Lee Mac ;; Selects all blocks in the current layout with a given block name or which contain a specified attribute tag and/or value. (defun c:bsel ( / att atx blk cnt ent enx flg idx sel str tag ) (setq blk (strcase (getstring t "\nSpecify block name <any>: ")) tag (strcase (getstring "\nSpecify attribute tag <any>: ")) str (strcase (getstring t (strcat "\nSpecify attribute value" (if (= "" tag blk) ": " " <any>: ")))) ) (if (not (= "" str tag blk)) (if (and (setq sel (ssget "_X" (append '((000 . "INSERT")) (if (not (= "" tag str)) '((066 . 1))) (if (/= "" blk) (list (cons 2 (strcat "`*U*," blk)))) (if (= 1 (getvar 'cvport)) (list (cons 410 (getvar 'ctab))) '((410 . "Model")) ) ) ) ) (progn (repeat (setq idx (sslength sel)) (setq ent (ssname sel (setq idx (1- idx))) enx (entget ent) ) (cond ( (not (or (= "" blk) (wcmatch (strcase (LM:name->effectivename (cdr (assoc 2 enx)))) blk))) (ssdel ent sel) ) ( (member (cdr (assoc 66 enx)) '(nil 0))) ( (progn (setq att (entnext ent) atx (entget att) flg nil ) (while (and (= "ATTRIB" (cdr (assoc 0 atx))) (not (and (or (= "" str) (wcmatch (strcase (cdr (assoc 1 atx))) str)) (or (= "" tag) (wcmatch (strcase (cdr (assoc 2 atx))) tag)) ) ) ) (setq att (entnext att) atx (entget att) ) ) (= "SEQEND" (cdr (assoc 0 atx))) ) (ssdel ent sel) ) ) ) (< 0 (setq cnt (sslength sel))) ) ) (progn (princ (strcat "\n" (itoa cnt) " block" (if (= 1 cnt) "" "s") " found.")) (sssetfirst nil sel) ) (princ "\nNo blocks found.") ) ) (princ) ) ;; Block Name -> Effective Block Name - Lee Mac ;; blk - [str] Block name (defun LM:name->effectivename ( blk / rep ) (if (and (wcmatch blk "`**") (setq rep (cdadr (assoc -3 (entget (cdr (assoc 330 (entget (tblobjname "block" blk)))) '("acdbblockrepbtag") ) ) ) ) (setq rep (handent (cdr (assoc 1005 rep)))) ) (cdr (assoc 2 (entget rep))) blk ) ) (princ) 1 Quote Link to comment Share on other sites More sharing options...
NoamBrand Posted December 16, 2018 Share Posted December 16, 2018 Best lisp ever! Thanks @Lee Mac Quote Link to comment Share on other sites More sharing options...
aqes2 Posted January 14, 2019 Share Posted January 14, 2019 Wow, great lisp @Lee Mac. Thanks. Would it be possible to export this data to excel? Something like search value "0.5" in "speed" attribute tag, but all result go to excel (with value of remaining attributes). Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted January 14, 2019 Share Posted January 14, 2019 (edited) 1 hour ago, aqes2 said: Wow, great lisp @Lee Mac. Thanks. Would it be possible to export this data to excel? Something like search value "0.5" in "speed" attribute tag, but all result go to excel (with value of remaining attributes). Thank you, I'm pleased that you like the program. Whilst your request is certainly possible to achieve, I'm afraid this would not be a quick modification to the current code. Edited January 14, 2019 by Lee Mac Quote Link to comment Share on other sites More sharing options...
NoamBrand Posted January 14, 2019 Share Posted January 14, 2019 1 hour ago, aqes2 said: Wow, great lisp @Lee Mac. Thanks. Would it be possible to export this data to excel? Something like search value "0.5" in "speed" attribute tag, but all result go to excel (with value of remaining attributes). Here is a workaround : Lee Mac lisp gets you the selection set you need. You can then cut the objects and paste them to a new DWG file >express tools>export attributes> save txt file as excel> edit in excel> import attributes> copy blocks back to original DWG. Quote Link to comment Share on other sites More sharing options...
BIGAL Posted January 15, 2019 Share Posted January 15, 2019 Lee what about nentsel pick an attribute, you get block name, tag name and default attribute value, did something using this method. Now where is it. Quote Link to comment Share on other sites More sharing options...
Grrr Posted January 15, 2019 Share Posted January 15, 2019 7 hours ago, BIGAL said: Lee what about nentsel pick an attribute, you get block name, tag name and default attribute value, did something using this method. Now where is it. Recently we're doing this: (while (setq result (LeeDoesAGreatJob)) (apply 'ConstructiveCriticism result) ) Quote Link to comment Share on other sites More sharing options...
NoamBrand Posted January 15, 2019 Share Posted January 15, 2019 On 1/14/2019 at 2:12 PM, NoamBrand said: Here is a workaround : Lee Mac lisp gets you the selection set you need. You can then cut the objects and paste them to a new DWG file >express tools>export attributes> save txt file as excel> edit in excel> import attributes> copy blocks back to original DWG. A more simple workaround would be like this: Lee Mac lisp gets you the selection set you need. express tools>export attributes>select objects: p (this will select the last selection set)> save txt file as excel> edit in excel> import attrattributes. Quote Link to comment Share on other sites More sharing options...
aqes2 Posted January 16, 2019 Share Posted January 16, 2019 @Lee Mac, thank for respond. At least I know it's possible. @NoamBrand, yeah, I know it. I was wondering how do it all by lisp. First my idea was to do few lisp with the same attribute but other value go to .txt and after that to excel. But I failed. And now here. Anyway, thanks for tips, I gratful for your respond. Quote Link to comment Share on other sites More sharing options...
pmxcad Posted November 27, 2019 Share Posted November 27, 2019 On 12/13/2018 at 10:34 PM, Lee Mac said: The following program will allow you to specify either a block name, attribute tag, or attribute value (or all three), and will return a selection of all blocks matching the given criteria, residing in the current layout: ;; Block Selection - Lee Mac ;; Selects all blocks in the current layout with a given block name or which contain a specified attribute tag and/or value. (defun c:bsel ( / att atx blk cnt ent enx flg idx sel str tag ) (setq blk (strcase (getstring t "\nSpecify block name <any>: ")) tag (strcase (getstring "\nSpecify attribute tag <any>: ")) str (strcase (getstring t (strcat "\nSpecify attribute value" (if (= "" tag blk) ": " " <any>: ")))) ) (if (not (= "" str tag blk)) (if (and (setq sel (ssget "_X" (append '((000 . "INSERT")) (if (not (= "" tag str)) '((066 . 1))) (if (/= "" blk) (list (cons 2 (strcat "`*U*," blk)))) (if (= 1 (getvar 'cvport)) (list (cons 410 (getvar 'ctab))) '((410 . "Model")) ) ) ) ) (progn (repeat (setq idx (sslength sel)) (setq ent (ssname sel (setq idx (1- idx))) enx (entget ent) ) (cond ( (not (or (= "" blk) (wcmatch (strcase (LM:name->effectivename (cdr (assoc 2 enx)))) blk))) (ssdel ent sel) ) ( (member (cdr (assoc 66 enx)) '(nil 0))) ( (progn (setq att (entnext ent) atx (entget att) flg nil ) (while (and (= "ATTRIB" (cdr (assoc 0 atx))) (not (and (or (= "" str) (wcmatch (strcase (cdr (assoc 1 atx))) str)) (or (= "" tag) (wcmatch (strcase (cdr (assoc 2 atx))) tag)) ) ) ) (setq att (entnext att) atx (entget att) ) ) (= "SEQEND" (cdr (assoc 0 atx))) ) (ssdel ent sel) ) ) ) (< 0 (setq cnt (sslength sel))) ) ) (progn (princ (strcat "\n" (itoa cnt) " block" (if (= 1 cnt) "" "s") " found.")) (sssetfirst nil sel) ) (princ "\nNo blocks found.") ) ) (princ) ) ;; Block Name -> Effective Block Name - Lee Mac ;; blk - [str] Block name (defun LM:name->effectivename ( blk / rep ) (if (and (wcmatch blk "`**") (setq rep (cdadr (assoc -3 (entget (cdr (assoc 330 (entget (tblobjname "block" blk)))) '("acdbblockrepbtag") ) ) ) ) (setq rep (handent (cdr (assoc 1005 rep)))) ) (cdr (assoc 2 (entget rep))) blk ) ) (princ) Is it possible to modify the Lisp that it also select blocks with no value/emty attributen? Thanks Pmxcad Quote Link to comment Share on other sites More sharing options...
pmxcad Posted November 29, 2019 Share Posted November 29, 2019 Is it possible to modify the Lisp that it also select blocks with no value/emty attributes? Thanks Pmxcad Quote Link to comment Share on other sites More sharing options...
WillO Posted May 6, 2021 Share Posted May 6, 2021 On 12/13/2018 at 4:34 PM, Lee Mac said: The following program will allow you to specify either a block name, attribute tag, or attribute value (or all three), and will return a selection of all blocks matching the given criteria, residing in the current layout: ;; Block Selection - Lee Mac ;; Selects all blocks in the current layout with a given block name or which contain a specified attribute tag and/or value. (defun c:bsel ( / att atx blk cnt ent enx flg idx sel str tag ) (setq blk (strcase (getstring t "\nSpecify block name <any>: ")) tag (strcase (getstring "\nSpecify attribute tag <any>: ")) str (strcase (getstring t (strcat "\nSpecify attribute value" (if (= "" tag blk) ": " " <any>: ")))) ) (if (not (= "" str tag blk)) (if (and (setq sel (ssget "_X" (append '((000 . "INSERT")) (if (not (= "" tag str)) '((066 . 1))) (if (/= "" blk) (list (cons 2 (strcat "`*U*," blk)))) (if (= 1 (getvar 'cvport)) (list (cons 410 (getvar 'ctab))) '((410 . "Model")) ) ) ) ) (progn (repeat (setq idx (sslength sel)) (setq ent (ssname sel (setq idx (1- idx))) enx (entget ent) ) (cond ( (not (or (= "" blk) (wcmatch (strcase (LM:name->effectivename (cdr (assoc 2 enx)))) blk))) (ssdel ent sel) ) ( (member (cdr (assoc 66 enx)) '(nil 0))) ( (progn (setq att (entnext ent) atx (entget att) flg nil ) (while (and (= "ATTRIB" (cdr (assoc 0 atx))) (not (and (or (= "" str) (wcmatch (strcase (cdr (assoc 1 atx))) str)) (or (= "" tag) (wcmatch (strcase (cdr (assoc 2 atx))) tag)) ) ) ) (setq att (entnext att) atx (entget att) ) ) (= "SEQEND" (cdr (assoc 0 atx))) ) (ssdel ent sel) ) ) ) (< 0 (setq cnt (sslength sel))) ) ) (progn (princ (strcat "\n" (itoa cnt) " block" (if (= 1 cnt) "" "s") " found.")) (sssetfirst nil sel) ) (princ "\nNo blocks found.") ) ) (princ) ) ;; Block Name -> Effective Block Name - Lee Mac ;; blk - [str] Block name (defun LM:name->effectivename ( blk / rep ) (if (and (wcmatch blk "`**") (setq rep (cdadr (assoc -3 (entget (cdr (assoc 330 (entget (tblobjname "block" blk)))) '("acdbblockrepbtag") ) ) ) ) (setq rep (handent (cdr (assoc 1005 rep)))) ) (cdr (assoc 2 (entget rep))) blk ) ) (princ) Hi Lee, Is there any way to get this to work with Attributes that are populated by a field? I have hundreds of formed flat bars with a LENGTH attribute populated by a Field. The field is linked to the length of the polyline at the centerline of the piece's thickness (to get the flat length of that piece). When I run the bsel command and input the length (ft'-in frac/in") I get no results. I'm assuming that this is because fields populate the attribute as "######" when editing the attribute definition, and that the command doesn't recognize the field as containing a text value matching my input. Anyway, I want to select all of the parts of the same flat length (assuming all other elements are identical) so that I can assign the same piece mark number to all similar pieces without having to manually/individually examine each one and keep track of their properties (which is how I have been doing it and let me tell you it's no walk in the park). Hopefully I can find a better method, as I have several projects similar to this coming in the future and I would like to save as much time as possible. Thanks in advance! Will O Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted May 6, 2021 Share Posted May 6, 2021 (edited) 9 hours ago, WillO said: Is there any way to get this to work with Attributes that are populated by a field? I have hundreds of formed flat bars with a LENGTH attribute populated by a Field. The field is linked to the length of the polyline at the centerline of the piece's thickness (to get the flat length of that piece). When I run the bsel command and input the length (ft'-in frac/in") I get no results. I'm assuming that this is because fields populate the attribute as "######" when editing the attribute definition, and that the command doesn't recognize the field as containing a text value matching my input. Hi Will, There should be nothing preventing this program operating successfully with attributes containing field expressions, since the attribute value contains the field output (not the field code or ####, unless the field is unevaluated or corrupt). Certainly, in my testing, I can populate an attribute value with a field expression referencing the area of a circle, and then successfully select the target block using my bsel program and specifying the target area. Note that the selection is matching the string value of the attribute with the supplied input, and is not performing a numerical match (therefore, the input must match the content exactly as displayed); furthermore, wildcard operators are permitted in the user input (hence, you may not receive the desired results if your input string inadvertently contains a wildcard operator that you wish to be interpreted as a literal - to mark a wildcard operator as a literal, prefix it with a backquote, e.g. to search for the literal string #1 you would need to enter `#1 otherwise you would select any two digit value ending with a 1). Also note that if your length value is surrounded by other text (even whitespace), you'll need to surround your input string with the asterisk wildcard operator to search for a substring within the candidate attribute values, e.g. *ft'-in frac/in"* Edited May 6, 2021 by Lee Mac 1 Quote Link to comment Share on other sites More sharing options...
WillO Posted May 7, 2021 Share Posted May 7, 2021 16 hours ago, Lee Mac said: Hi Will, There should be nothing preventing this program operating successfully with attributes containing field expressions, since the attribute value contains the field output (not the field code or ####, unless the field is unevaluated or corrupt). Certainly, in my testing, I can populate an attribute value with a field expression referencing the area of a circle, and then successfully select the target block using my bsel program and specifying the target area. Note that the selection is matching the string value of the attribute with the supplied input, and is not performing a numerical match (therefore, the input must match the content exactly as displayed); furthermore, wildcard operators are permitted in the user input (hence, you may not receive the desired results if your input string inadvertently contains a wildcard operator that you wish to be interpreted as a literal - to mark a wildcard operator as a literal, prefix it with a backquote, e.g. to search for the literal string #1 you would need to enter `#1 otherwise you would select any two digit value ending with a 1). Also note that if your length value is surrounded by other text (even whitespace), you'll need to surround your input string with the asterisk wildcard operator to search for a substring within the candidate attribute values, e.g. *ft'-in frac/in"* Thanks Lee! It turns out that I had a ID10T error, and was not entering the length in the correct format (transposed the dash or missed a tick). Wasted a lot of time researching just to figure out I was doing it wrong! BSEL command works like a charm! I have been able to accomplish my part numbering very easily this way. You are the LISP master! Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted May 7, 2021 Share Posted May 7, 2021 No worries Will - those are always the best type of error I'm delighted that you find the program so useful! Quote Link to comment Share on other sites More sharing options...
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.