Hi,
I having real difficulty finding a lisp that will find and replace blocks. There are plenty out there and AutoCAD 2013 and lower has a Find and Replace Blocks. However, the frustrating catch is I can seem to find a routine that will allow me to replace only those blocks that I select with a selection set of my choosing. The built in function replaces all of them and will not let you exclude some. We have PID drawings that we want to replace valves on, but not all valves. We don't want to rename. We don't need to BEDIT the existing block.
1) Pick group of blocks
2) specify a new block that will replace all instances of old block
3) replace inserted block with different block. Leaving others alone.
I'm thinking this should be easy, but my search has failed. The blocks in question are not dynamic or attributed either.
Can anyone point me in the right direction?
Solved! Go to Solution.
Solved by Kent1Cooper. Go to Solution.
@Anonymous wrote:....
1) Pick group of blocks
2) specify a new block that will replace all instances of old block
3) replace inserted block with different block. Leaving others alone.
....
I use the attached BlockReplace.lsp, and in the situation you describe, its BRS command [= Block Replace: Selected]. A small difference it has from your description is that it does your step 2) before your step 1), but I assume you can live with that.
[As on another thread today, for some reason it wouldn't let me attach the file with the .lsp ending --
"The file type doesn't match the type of its contents". This time I zipped it, so you'll need to extract it from there.]
@Kent1Cooper wrote:
[As on another thread today, for some reason it wouldn't let me attach the file with the .lsp ending --
"The file type doesn't match the type of its contents". This time I zipped it, so you'll need to extract it from there.]
I attached a lisp file on another thread just to try if it will do same but seems to work [Chrome not IE]
Hi,
I have a drawing with A dynamic block "Block A" with Hatch "Hatch 1". But I want to select certain number of that block and change the hatch only or insulation thickness.
Is it possible to do this with dynamic block. retaining all other parameter properties?
5 Years later!! Still making a difference! Thanks!
Does anyone know why the BlockReplace.lsp mentioned above would not load in Civil3d 2015.
I used it wonderfully in Map3d 2018, but my new job uses Civil3D 2015. When I try to load the lisp using appload, as I Did before, it errors saying the Lisp could not be loaded.
For reference, this is the code, in case its something in there...
;; BlockReplace.lsp ;; Two commands: BRS = Block Replace: Selected; BRA = Block Replace: All ;; Both commands: ;; 1) Ask User for Block name to use to replace other Blocks with. ;; 2) Ask again for Block name if it is neither defined in current drawing nor ;; a drawing in a Support File Search Path. ;; 3) Remember that Block name [separately for each], and offer as default on ;; subsequent use. If no default yet in current command, offer default from ;; other command if present; if not, regular Insert's default if present. ;; 4) Retain layer, insertion point, scales, rotation, extrusion direction, any ;; overrides, etc. of all replaced Block insertions. ;; 5) Also replace any Minsert objects among selection in BRS or of correct ;; Block name in BRA. ;; See further details at head of each command definition. ;; Kent Cooper, last edited 10 October 2012 (vl-load-com) (defun brerr (errmsg) (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break")) (princ (strcat "\nError: " errmsg)) ); if (command "_.undo" "_end") (setvar 'cmdecho cmde) (princ) ); defun -- brerr (defun *ev (ltr); evaluate what's in variable name with letter (eval (read (strcat "*br" ltr "name"))) ); defun - *ev (defun brsetup (this other / temp) (setq cmde (getvar 'cmdecho)) (setvar 'cmdecho 0) (command "_.undo" "_begin") (while (or (not temp); none yet [first time through (while) loop] (and (not (*ev this)) (not (*ev other)) (= temp (getvar 'insname) "")) ; no this-command or other-command or Insert defaults yet, on User Enter (and ; availability check (/= temp ""); User typed something other than Enter, but (not (tblsearch "block" temp)); no such Block in drawing, and (not (findfile (strcat temp ".dwg"))); no such drawing in Search paths ); and ); or (setq temp (getstring (strcat (if (and temp (/= temp "")) "\nNo such Block or Drawing available." "") "\nBlock to Replace existing Block(s) with" (cond ((*ev this) (strcat " <" (*ev this) ">")); prior Block in this command, if any ((*ev other) (strcat " <" (*ev other) ">")); prior Block in other command, if any ((/= (getvar 'insname) "") (strcat " <" (getvar 'insname) ">")); Insert's default, if any (""); no default on first use if no this-command or other-command or Insert defaults ); cond ": " ); strcat ); getstring & temp ); setq ); while (set (read (strcat "*br" this "name")) (cond ((/= temp "") temp); User typed something ((*ev this)); default for this command, if any ((*ev other)); default for other command, if any ((getvar 'insname)); Enter on first use with Insert's default ); cond ); set (if (not (tblsearch "block" (*ev this))); external drawing, not yet Block in current drawing (command "_.insert" (*ev this) nil); bring in definition, don't finish Inserting ); if ); defun -- brsetup (defun C:BRS ; = Block Replace: Selected ;; To Replace User-selected Block(s) of any name(s) with User-specified Block name. ;; [Notice of selected Block(s) on locked Layers is within selection; not listed at end ;; as in BRA; off or frozen Layers are irrelevant with User selection.] ;; Rejects Xrefs, but does replace any Windows Metafile objects among selection. (/ *error* cmde ss repl notrepl ent) (setq *error* brerr) (brsetup "s" "a") (prompt (strcat "\nTo replace Block insertion(s) with " *brsname ",")) (setq ss (ssget ":L" '((0 . "INSERT"))); Blocks/Xrefs/Minserts/WMFs on unlocked Layers repl (sslength ss) notrepl 0 ); setq (repeat repl (setq ent (ssname ss 0)) (if (not (assoc 1 (tblsearch "block" (cdr (assoc 2 (entget ent)))))); not Xref (vla-put-Name (vlax-ename->vla-object ent) *brsname); then (setq notrepl (1+ notrepl) repl (1- repl)); else ); if (ssdel ent ss) ); repeat (prompt (strcat "\n" (itoa repl) " Block(s) replaced with " *brsname ".")) (if (> notrepl 0) (prompt (strcat "\n" (itoa notrepl) " Xref(s) not replaced."))) (command "_.undo" "_end") (setvar 'cmdecho cmde) (princ) ); defun -- BRS (defun C:BRA ; = Block Replace: All ;; To Replace All insertions of designated Block name with User-specified different Block. ;; Designation of Block name to replace by either selection of Block or Typing. ;; Replaces insertions in all spaces and layouts. ;; Does not replace those on locked or frozen Layers [does on Layers that are off, but ;; see comments below to not replace those], or nested insertions. (/ *error* cmde done esel edata oldname ss repl notrepl ent elay layst) (setq *error* brerr) (brsetup "a" "s") (while (not done) (setvar 'errno 0) (initget "Type") (setq esel (entsel (strcat "\nSelect Block to replace all instances with " *braname " or [Type-it]: " ); strcat ); entsel ); setq (cond ( (= esel "Type") (while (not (and (setq oldname (getstring "\nBlock name: ")) (tblsearch "block" oldname); Block definition exists in drawing ); and ); not (prompt "\nBlock name not defined --") ); while (setq done T) ); Type-it condition ( (= (getvar 'errno) 0); picked something (if (and (setq edata (entget (car esel))) (wcmatch (cdr (assoc 0 edata)) "INSERT") (setq oldname (cdr (assoc 2 edata))) (not (assoc 1 (tblsearch "block" oldname))); not Xref ); and (setq done T); then (prompt "\nSelected object not a Block/Minsert/WMF --"); else ); if ); picked-something condition ((prompt "\nNothing selected --")); missed -- 'errno = 7 ); cond ); while (setq ss (ssget "_X" (list '(0 . "INSERT") (cons 2 oldname))); all such Blocks/Minserts repl (sslength ss) notrepl 0 ); setq (repeat repl (setq ent (ssname ss 0) elay (tblsearch "layer" (cdr (assoc 8 (entget ent)))) layst (cdr (assoc 70 elay)); contains frozen/locked status ); setq (if (or (= (logand layst 1) 1) (= (logand layst 4) 4)); on locked [1] or frozen [4] Layer ;; to have it NOT replace those on Layers that are turned OFF, replace above line with following lines: ;; (if (or (= (logand layst 1) 1) (= (logand layst 4) 4) (minusp (cdr (assoc 62 elay)))) ;; ; on locked [1] or frozen [4] or off [negative color number] Layer (setq notrepl (1+ notrepl) repl (1- repl)); then (vla-put-Name (vlax-ename->vla-object ent) *braname); else ); if (ssdel ent ss) ); repeat (prompt (strcat "\n" (itoa repl) " " oldname " Block(s) replaced with " *braname ".")) (if (> notrepl 0) (prompt (strcat "\n" (itoa notrepl) " on locked/frozen Layer(s) not replaced."))) ;; if NOT replacing those on Layers that are turned OFF, replace above line with following line: ;; (if (> notrepl 0) (prompt (strcat "\n" (itoa notrepl) " on off/locked/frozen Layer(s) not replaced."))) (command "_.undo" "_end") (setvar 'cmdecho cmde) (princ) ); defun -- BRA (prompt "\nBlock Replace: BRS = Select insertion(s), BRA = All insertions of selected Block.")
Thanks for that great command! I was looking for exactly this for a long time.
I'm having two problems though:
I've had in mind to add a select-a-source-Block option for some time -- this will be an inducement to get around to working that in.
It was developed without Attributes in mind. I was hoping ATTSYNC would take care of it, but no.... Nor does REGEN, nor closing and re-opening the drawing. I guess simply substituting the Block name into the insertions is too simplistic an approach when Attributes are involved. I'll have to think about that -- any suggestions are welcome.
Hi @Kent1Cooper
For step 2, how do you specify which block you want to replace? I cannot pick on the block in model space, nor can I type the block name into the command line?
@anderson51 wrote:
Hi @Kent1Cooper
For step 2, how do you specify which block you want to replace? I cannot pick on the block in model space, nor can I type the block name into the command line?
I have had in mind to edit to allow picking a Block, but for me, typing in a Block name at the command line works. Are you typing a Block name that is already in the drawing. or a drawing that's in the Support File Search path list?
@anderson51 wrote:
One that is already in the drawing...typing in the command line does nothing for me.
Are you by any chance using a Block name that has a space [or spaces] in it? If so, put a T after the two (getstring function names:
….
(setq temp
(getstring T
(strcat
(if (and temp ....
and
….
(setq oldname (getstring T "\nBlock name: "))
....
If that's not it, are there any messages?
Hi @Kent1Cooper and others here - I came across this older thread while trying to answer this same question and was curious if anyone had any new ideas. I have a series of older "dumb" blocks that I'm trying to replace with newer "smart" blocks. I've tried the LSP routine and the BLOCKREPLACE command from express tools and similarly, I cannot get the Attribute Definitions to come in therefore turning the smart blocks back into dumb ones. The dynamic properties remain but the ATTDEFs get lost. Any thoughts or workarounds would be much appreciated. Thanks!
Doh! I didn't even try. I misread above and thought you had said that ATTSYNC didn't fix the problem. Tried it now and it works. Thank you!
Hi Kent,
In your BlockReplace lisp, can step 1 have the option to select the desired block instead of typing its name?
Thanks!
@Hamza.itani wrote:
... can step 1 have the option to select the desired block instead of typing its name? ....
[I've had in mind to make that adjustment for a long time -- maybe this will be my inducement to get around to it.]
Can't find what you're looking for? Ask the community or share your knowledge.