aridzv Posted August 30, 2023 Posted August 30, 2023 (edited) Hi. I have a lisp that required me to select objects (blocks in this case). I can select all the identical objects (blocks) in the drawing with _selectsimilar and by the _selectsimilar condtions. is it possible to use it in a lisp instead of the (setq ss (ssget '((0 . "INSERT"))))? thanks, aridzv. *edit: I got this so far: (setq sl (entget)) (command "_selectsimilar" sl "") I need help on how do I put it in to a selection set... Edited August 30, 2023 by aridzv Quote
Lee Mac Posted August 30, 2023 Posted August 30, 2023 You can use the "X" mode string to interrogate the entire drawing database, with an appropriate filter list to target the block properties that you desire, e.g. for block name you might use the following (though, not that for dynamic blocks you'll also need to test for anonymous references) (ssget "_X" '((0 . "INSERT") (2 . "YourBlockName"))) 1 Quote
aridzv Posted August 30, 2023 Author Posted August 30, 2023 (edited) 30 minutes ago, Lee Mac said: You can use the "X" mode string to interrogate the entire drawing database, with an appropriate filter list to target the block properties that you desire, e.g. for block name you might use the following (though, not that for dynamic blocks you'll also need to test for anonymous references) (ssget "_X" '((0 . "INSERT") (2 . "YourBlockName"))) Hi @Lee Mac I'm using this code to select the block and pass it's name: (setq newblock1 (entsel "\nPick instance of new block: ")) (setq newname1 (getpropertyvalue (car newblock1) "EffectiveName~Native")) ;;this is the ssget: (ssget "_X" '((0 . "INSERT") (2. newname1))) ;;I get this error: Pick instance of new block: PVC PIPE GRAY DN63-PN10 3d select blocks,Enter To End Selection ; ----- LISP : Call Stack ----- ; [0]...C:REPLACEBLOCKS1 ; [1].....C:RBS <<-- ; ; ----- Error around expression ----- ; '((0 . "INSERT") (2.0 NEWNAME1)) I get the block effective name (Pick instance of new block: PVC PIPE GRAY DN63-PN10 3d), but it is failing in the insert ((ssget "_X" '((0 . "INSERT") (2. newname1))). what am I doing wrong? Edited August 30, 2023 by aridzv Quote
aridzv Posted August 30, 2023 Author Posted August 30, 2023 (edited) O.K. I've got it to work... (setq BlkName (vla-get-effectivename (vlax-ename->vla-object (car (entsel "\nSelect block to replace: ")))));; select the block to replace (setq ss (ssget "_X" (list (cons 0 "INSERT") (cons 2 BlkName ))));; create the list by the block name @Lee Mac Thanks, Excellent idea and much simpler than the solution I initially thought. aridzv Edited August 30, 2023 by aridzv Quote
Lee Mac Posted August 31, 2023 Posted August 31, 2023 Yes - if using variable data, you'll need to construct the ssget filter list using list/cons as opposed to using a quoted literal list - I explain this in more detail in my tutorial here. Note that, if using dynamic blocks, you may also need to include anonymous block references in the initial selection, and then test the effective name of each acquired block reference, removing those which do not match the effective name of the target block. 1 Quote
aridzv Posted August 31, 2023 Author Posted August 31, 2023 (edited) 24 minutes ago, Lee Mac said: Yes - if using variable data, you'll need to construct the ssget filter list using list/cons as opposed to using a quoted literal list - I explain this in more detail in my tutorial here. Thanks for the explenation and the tutorial. 24 minutes ago, Lee Mac said: Note that, if using dynamic blocks, you may also need to include anonymous block references in the initial selection, and then test the effective name of each acquired block reference, removing those which do not match the effective name of the target block. Definitely. but in this case I need the entity name. later in the lisp I do need the effective name including an Anonymous block effective name (Getting the Anonymous block effective name in bricscad was an affair by itself...). thanks, aridzv. Edited August 31, 2023 by aridzv Quote
aridzv Posted August 31, 2023 Author Posted August 31, 2023 1 hour ago, Lee Mac said: Note that, if using dynamic blocks, you may also need to include anonymous block references in the initial selection, and then test the effective name of each acquired block reference, removing those which do not match the effective name of the target block. Damm... You were right... Here is the revised code to select the blocks by their effective name: (setq newblock1 (entsel "\nSelect block to replace: ")) (setq BlkName (getpropertyvalue (car newblock1) "EffectiveName~Native")) ;;Bricscad (setq ss (ssget "_X" (list (cons 0 "INSERT") (cons 2 BlkName )))) Quote
aridzv Posted August 31, 2023 Author Posted August 31, 2023 (edited) @Lee Mac The problem seems to be a lot more complicated than I thought... I've managed to get the effctive name this way: (setq newblock1 (entsel "\nSelect block to replace: ")) (setq BlkName (getpropertyvalue (car newblock1) "EffectiveName~Native")) ;;Bricscad and for regular blocks the list ss is created but for *U blocks the: (setq ss (ssget "_X" (list (cons 0 "INSERT") (cons 2 BlkName )))) fails to create the list. Edited September 1, 2023 by aridzv Quote
aridzv Posted August 31, 2023 Author Posted August 31, 2023 (edited) well... found a function named "BlockSSET" that create a selection set of *U type blocks (dynamic for autocad,parametric for bricscad etc...) by their effective names, and used it to generate the selction set this way: (setq newblock1 (entsel "\nSelect block to replace: ")) (setq BlkName (getpropertyvalue (car newblock1) "EffectiveName~Native")) ;;Bricscad ;;if the user selects something, inputs a ne block name AND it exists in the dwg... (if (and (setq ss (BlockSSET BlkName));; call BlockSSET with the *U block effective name and this is the function: ; Function to create a selection set of standard & dynamic blocks ; That have the same Effective name (defun BlockSSET (blname / sset ss-dyn num ent effname) (vl-load-com) ; ensure that ActiveX is loaded. (if (not (setq sset (ssget "X" (list (cons 2 blname))))) ; Select block with standard method. This will also capture dynamic blocks in their default state. (setq sset (ssadd)) ; if nothing is found then create and empty selection set ) (if (setq ss-dyn (ssget "X" (list (cons 2 "`*U*")))) ; select all anonymous blocks. this will also capture any dynamic blocks that have been worked with (progn ; If anonymous blocks found, check for the given effective name (setq num 0) ; zero counter (repeat (sslength ss-dyn) ; repeat for the number of objects in the selection set (setq ent (ssname ss-dyn num)) ; find the entity name (setq effname (getpropertyvalue ent "EffectiveName~Native")) ; Find the EffectiveName of the block (if (= blname effname) ; if the blockname matches the effective name (ssadd ent sset) ; then add it to the original selection set ); end if (setq num (1+ num)) ; Increment the counter by one ) ) ) ; return the gathered selection set sset ) *note that the method to get the effective name is for bricscad. aridzv. *EDIT: Here is the final lisp: (defun c:ReplaceBlockS_all () (c:RBS_all)) (defun c:RBS_all (/ answr ent idx newblock newname newname1 BlkName blk newblock newblock1 obj ss M1 M2 M3 C1 C2 C3 E1 E2 E3 ITD GR ORD QTY QTY1 SYS UN MANDIA MANGR x) (vl-load-com) (setvar "CMDECHO" 0) (command ".undo" "be") (setvar "CMDECHO" 1) (setq newblock1 (entsel "\nSelect block to replace: ")) (setq BlkName (getpropertyvalue (car newblock1) "EffectiveName~Native")) ;;Bricscad (if (and (setq ss (BlockSSET BlkName));; get selection set by effective name using "BlockSSET" Function ;;(setq newblock (entget (car (entsel "\nPick instance of new block: ")))) ;;Autocad (setq newblock (entsel "\nPick instance of new block: ")) ;;Bricscad (setq newname (getpropertyvalue (car newblock) "EffectiveName~Native")) ;;Bricscad ;;(setq newname (cdr (assoc 2 newblock))) ;;Autocad (tblobjname "BLOCK" newname) (vl-catch-all-apply (setq M1 (LM:getattributevalue (car newblock) "MAN1"))) (vl-catch-all-apply (setq M2 (LM:getattributevalue (car newblock) "MAN2"))) (vl-catch-all-apply (setq M3 (LM:getattributevalue (car newblock) "MAN3"))) (vl-catch-all-apply (setq C1 (LM:getattributevalue (car newblock) "CAT1"))) (vl-catch-all-apply (setq C2 (LM:getattributevalue (car newblock) "CAT2"))) (vl-catch-all-apply (setq C3 (LM:getattributevalue (car newblock) "CAT3"))) (vl-catch-all-apply (setq E1 (LM:getattributevalue (car newblock) "ERP1"))) (vl-catch-all-apply (setq E2 (LM:getattributevalue (car newblock) "ERP2"))) (vl-catch-all-apply (setq E3 (LM:getattributevalue (car newblock) "ERP3"))) (vl-catch-all-apply (setq ITD (LM:getattributevalue (car newblock) "ITEM_DESCRIPTION"))) (vl-catch-all-apply (setq GR (LM:getattributevalue (car newblock) "GRUOP"))) (vl-catch-all-apply (setq UN (LM:getattributevalue (car newblock) "UNIT"))) (vl-catch-all-apply (setq MANDIA (LM:getattributevalue (car newblock) "MANIFOLD_DIA"))) (vl-catch-all-apply (setq MANGR (LM:getattributevalue (car newblock) "MANIFOLD_GRUOP"))) ;;(vl-catch-all-apply (setq ORD (LM:getattributevalue (car newblock) "ORDER"))) ;; don't change ;;(vl-catch-all-apply (setq SYS (LM:getattributevalue (car newblock) "SYSTEM"))) ;; don't change (vl-catch-all-apply (setq QTY (LM:getattributevalue (car newblock) "QUANTITY"))) ;; don't change ;; (setq M2 (strcase (vla-get-tagstring "MAN2"))) ;; (setq M3 (strcase (vla-get-tagstring "MAN3"))) ;; (setq C1 (strcase (vla-get-tagstring "CAT1"))) ;; (setq C2 (strcase (vla-get-tagstring "CAT2"))) ;; (setq C3 (strcase (vla-get-tagstring "CAT3"))) ;; (setq E1 (strcase (vla-get-tagstring "ERP1"))) ;; (setq E2 (strcase (vla-get-tagstring "ERP2"))) ;; (setq E3 (strcase (vla-get-tagstring "ERP3"))) ;; (setq ITD (strcase (vla-get-tagstring "ITEM_DESCRIPTION"))) ;; (setq GR (strcase (vla-get-tagstring "GRUOP"))) ;; (setq ORD (strcase (vla-get-tagstring "ORDER"))) ;; (setq QTY (strcase (vla-get-tagstring "QUANTITY"))) ;; (setq SYS (strcase (vla-get-tagstring "SYSTEM"))) ;; (setq UN (strcase (vla-get-tagstring "UNIT"))) ;; (setq MANDIA (strcase (vla-get-tagstring "MANIFOLD_DIA"))) ;; (setq NANGR (strcase (vla-get-tagstring "MANIFOLD_GRUOP"))) );; close and (progn (setq idx -1) (while (setq ent (ssname ss (setq idx (1+ idx)))) (setq obj (vlax-ename->vla-object ent)) (vla-put-name obj newname);;change the name ;;(if (setq x (getpropertyvalue ent "d1")) (if (ispropertyvalid ent "d1~MCAD") (progn (vl-catch-all-apply (setq QTY1 (LM:getattributevalue ent "QUANTITY"))) (vl-catch-all-apply (setq QTY1 (* 1000 (atof QTY1)))) (vl-catch-all-apply (setq QTY1 (rtos QTY1 2 3))) (vl-catch-all-apply (setpropertyvalue ent "d1" QTY1)) ) ) (vl-catch-all-apply (LM:setattributevalue ent "MAN1" M1)) (vl-catch-all-apply (LM:setattributevalue ent "MAN2" M2)) (vl-catch-all-apply (LM:setattributevalue ent "MAN3" M3)) (vl-catch-all-apply (LM:setattributevalue ent "CAT1" C1)) (vl-catch-all-apply (LM:setattributevalue ent "CAT2" C2)) (vl-catch-all-apply (LM:setattributevalue ent "CAT3" C3)) (vl-catch-all-apply (LM:setattributevalue ent "ERP1" E1)) (vl-catch-all-apply (LM:setattributevalue ent "ERP2" E2)) (vl-catch-all-apply (LM:setattributevalue ent "ERP3" E3)) (vl-catch-all-apply (LM:setattributevalue ent "ITEM_DESCRIPTION" ITD)) (vl-catch-all-apply (LM:setattributevalue ent "GRUOP" GR)) (vl-catch-all-apply (LM:setattributevalue ent "UNIT" UN)) (vl-catch-all-apply (LM:setattributevalue ent "MANIFOLD_DIA" MANDIA)) (vl-catch-all-apply (LM:setattributevalue ent "MANIFOLD_GRUOP" MANGR)) ;;(vl-catch-all-apply (LM:setattributevalue ent "ORDER" ORD)) ;; DON'T CHANGE ;;(vl-catch-all-apply (LM:setattributevalue ent "QUANTITY" QTY)) ;; DON'T CHANGE ;;(vl-catch-all-apply (LM:setattributevalue ent "SYSTEM" SYS)) ;; DON'T CHANGE ;;(vla-put-textstring "MAN1" M1) ;;(vla-put-textstring "MAN2" M2) ;;(vla-put-textstring "MAN3" M3) ;;(vla-put-textstring "CAT1" C1) ;;(vla-put-textstring "CAT2" C2) ;;(vla-put-textstring "CAT3" C3) ;;(vla-put-textstring "ERP1" E1) ;;(vla-put-textstring "ERP2" E2) ;;(vla-put-textstring "ERP3" E3) ;;(vla-put-textstring "ITEM_DESCRIPTION" ITD) ;;(vla-put-textstring "GRUOP" GR) ;;(vla-put-textstring "ORDER" ORD) ;;(vla-put-textstring "QUANTITY" QTY) ;;(vla-put-textstring "SYSTEM" SYS) ;;(vla-put-textstring "UNIT" UN) (vla-update obj) );;end while );;end Main progn );;end Main if (command ".undo" "end") (princ (strcat "\nReplaced " (itoa idx) " blocks......")) (command "_.attsync" "_name" newname) (princ) );;end defun ;; Get Attribute Value - Lee Mac ;; Returns the value held by the specified tag within the supplied block, if present. ;; blk - [ent] Block (Insert) Entity Name ;; tag - [str] Attribute TagString ;; Returns: [str] Attribute value, else nil if tag is not found. (defun LM:getattributevalue ( blk tag / val enx ) (while (and (null val) (setq blk (entnext blk)) (= "ATTRIB" (cdr (assoc 0 (setq enx (entget blk))))) ) (if (= (strcase tag) (strcase (cdr (assoc 2 enx)))) (setq val (cdr (assoc 1 (reverse enx)))) ) ) ) ;; Set Attribute Value - Lee Mac ;; Sets the value of the first attribute with the given tag found within the block, if present. ;; blk - [ent] Block (Insert) Entity Name ;; tag - [str] Attribute TagString ;; val - [str] Attribute Value ;; Returns: [str] Attribute value if successful, else nil. (defun LM:setattributevalue ( blk tag val / enx ) (if (and (setq blk (entnext blk)) (= "ATTRIB" (cdr (assoc 0 (setq enx (entget blk)))))) (if (= (strcase tag) (strcase (cdr (assoc 2 enx)))) (if (entmod (subst (cons 1 val) (assoc 1 (reverse enx)) enx)) (progn (entupd blk) val ) ) (LM:setattributevalue blk tag val) ) ) ) ; Function to create a selection set of standard & dynamic blocks ; That have the same Effective name (defun BlockSSET (blname / sset ss-dyn num ent effname) (vl-load-com) ; ensure that ActiveX is loaded. (if (not (setq sset (ssget "X" (list (cons 2 blname))))) ; Select block with standard method. This will also capture dynamic blocks in their default state. (setq sset (ssadd)) ; if nothing is found then create and empty selection set ) (if (setq ss-dyn (ssget "X" (list (cons 2 "`*U*")))) ; select all anonymous blocks. this will also capture any dynamic blocks that have been worked with (progn ; If anonymous blocks found, check for the given effective name (setq num 0) ; zero counter (repeat (sslength ss-dyn) ; repeat for the number of objects in the selection set (setq ent (ssname ss-dyn num)) ; find the entity name (setq effname (getpropertyvalue ent "EffectiveName~Native")) ; Find the EffectiveName of the block (if (= blname effname) ; if the blockname matches the effective name (ssadd ent sset) ; then add it to the original selection set ); end if (setq num (1+ num)) ; Increment the counter by one ) ) ) ; return the gathered selection set sset ) Edited September 1, 2023 by aridzv 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.