Hi.
I need help with this code.
The routine below help to delete group of blocks by name, but if the blocks are on locked layers, these are not removed.
How can improve the lisp?
Thanks
(defun c:deleteblock (/ rn ss) (defun Jd (realname) (setq ss (ssget "x" (list '(0 . "INSERT")(cons 2 (strcat "`*U*," REALNAME))))) (mapcar '(lambda (x) (if (not (eq REALNAME (vla-get-effectivename (vlax-ename->vla-object (cadr x))))) (ssdel (cadr x) ss))) (ssnamex ss)) (setq ss_len (sslength ss)) (command "_erase" ss "") ) (setq rn (vla-get-effectivename (vlax-ename->vla-object (car (entsel "\nSelect the block you want to delete:"))))) (jd rn) (princ (strcat "\n" (itoa ss_len) " Blocks called \"" rn "\" has been deleted")) (princ) )
@jjorovi wrote:....
The routine below help to delete group of blocks by name, but if the blocks are on locked layers, these are not removed.
How can improve the lisp?
...
Probably the simplest thing to do would be to just unlock all Layers before the erase command, and then return to the previous Layer settings afterwards:
....
(command
"_.layer" "_unlock" "*" ""
"_erase" ss ""
"_layerp"
); end command
....
@jjorovi wrote:Very simple solution.
Thanks for the help Kent!
You're welcome. My first thought had been to extract the Layer from the entity data for each Block, and when locked, unlock that Layer to remove the Block with (entdel) instead of Erase, and then lock it again. But it didn't take long to realize how cumbersome that would be compared to just unlocking them all, regardless, and not having to care whether the Layers of individual Blocks are locked.
It occurs to me now to wonder: might they ever be on frozen Layers? Without trying it, I don't know, but I suspect (ssget) would find those Blocks, but probably Erase wouldn't remove them. If that's true, you might want to thaw all Layers, in addition to unlocking them.
@jjorovi wrote:Hi.
I need help with this code.The routine below help to delete group of blocks by name, but if the blocks are on locked layers, these are not removed.
How can improve the lisp?
Thanks
A quick mod for ---> This thread <----
(defun c:deleteblock (/ effnme a ent entl setl e)
(vl-load-com)
(vlax-for a (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))
(if (eq :vlax-true (vla-get-lock a))
(progn
(vla-put-lock a :vlax-false)
(setq l (cons a l))
)
)
)
(setq effnme (lambda (x)
(vla-get-effectivename
(if (eq (type x) 'ENAME)
(vlax-ename->vla-object x)
x))))
(princ "\nselect block to delete: ")
(if (setq ent (ssget "_:S" '((0 . "INSERT"))))
(progn
(setq entl (effnme (ssname ent 0)))
(ssget "x" (list (cons 2 (strcat entl ",`*U*"))))
(vlax-for
itm (vla-get-ActiveSelectionSet
(vla-get-ActiveDocument
(vlax-get-acad-object)))
(if (eq (effnme itm) entl)
(vla-delete itm)))
(princ (strcat "\nall blocks named "
entl
" have now been deleted")))
(princ "\nNo Block Selected:"))(foreach a l (vla-put-lock a :vlax-true))
(princ)
)
Unllocked->Delete-> locked
HTH
Kent1Cooper wrote:
....
It occurs to me now to wonder: might they ever be on frozen Layers? Without trying it, I don't know, but I suspect (ssget) would find those Blocks, but probably Erase wouldn't remove them. ....
Never mind thawing. I tried it out, and yes, (ssget) does find such things, and Erase does remove them when part of a selection set named in its object selection sequence, even when they're on frozen Layers.
How I can click on other blocks to remove them one by one, without invoking the command again?
@jjorovi wrote:How I can click on other blocks to remove them one by one, without invoking the command again?
In simplest terms, something like this re-arrangement/modification [untested]:
(defun c:deleteblock (/ blk rn ss)
(command "_.layer" "_unlock" "*" "")
(while
(setq blk (car (entsel "\nSelect the block you want to delete:"))); as long as User picks something
(setq
rn (vla-get-effectivename (vlax-ename->vla-object blk))
ss (ssget "x" (list '(0 . "INSERT") (cons 2 (strcat "`*U*," rn))))
); setq
(mapcar
'(lambda (x)
(if (not (eq rn (vla-get-effectivename (vlax-ename->vla-object (cadr x)))))
(ssdel (cadr x) ss)
); if
); lambda
(ssnamex ss)
); mapcar
(setq ss_len (sslength ss))
(command "_erase" ss "")
(prompt (strcat "\n" (itoa ss_len) " Blocks called \"" rn "\" have been deleted."))
); while
(command "_layerp"); re-lock any Layers that were unlocked
(princ)
); defun
But that could use a lot of enhancements, such as checking whether what the User picked is, in fact, a Block, asking again if it isn't or on a missed pick, and typical error handling.
The code works fine.
Thank you both for helping me. I hope to collaborate and repay the help received.
Technically, code that internally unlocks a layer before deleting objects essentially negates the purpose of locking the layer. I wouldn't call that an improvement. Layers should be unlocked by the user, not by some blackbox process.
Just my 2 cents.