PrimeTimeAction Posted November 20, 2018 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
Lee Mac Posted November 20, 2018 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
PrimeTimeAction Posted November 22, 2018 Author Posted November 22, 2018 Thanks alot @Lee Mac, it works flawlessly. You are a legend dude. Quote
NoamBrand Posted December 13, 2018 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
Lee Mac Posted December 13, 2018 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
aqes2 Posted January 14, 2019 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
Lee Mac Posted January 14, 2019 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
NoamBrand Posted January 14, 2019 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
BIGAL Posted January 15, 2019 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
Grrr Posted January 15, 2019 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
NoamBrand Posted January 15, 2019 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
aqes2 Posted January 16, 2019 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
pmxcad Posted November 27, 2019 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
pmxcad Posted November 29, 2019 Posted November 29, 2019 Is it possible to modify the Lisp that it also select blocks with no value/emty attributes? Thanks Pmxcad Quote
WillO Posted May 6, 2021 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
Lee Mac Posted May 6, 2021 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
WillO Posted May 7, 2021 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
Lee Mac Posted May 7, 2021 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
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.