Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

find and replace group of blocks that are SELECTED

30 REPLIES 30
SOLVED
Reply
Message 1 of 31
Jroper
17920 Views, 30 Replies

find and replace group of blocks that are SELECTED

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?

30 REPLIES 30
Message 2 of 31
Kent1Cooper
in reply to: Jroper


@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.]

Kent Cooper, AIA
Message 3 of 31
pbejse
in reply to: Kent1Cooper


@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]

 

Message 4 of 31
Jroper
in reply to: Kent1Cooper

I think that will do the trick! Thank you.
Message 5 of 31

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?


"Revit Lies in the tension between what we want to do and what can be done!"
Message 6 of 31
mconway
in reply to: Kent1Cooper

5 Years later!! Still making a difference!  Thanks!

At your service,
__________________________________________________
Mark A Conway –Director of Design Technology | Gilmore & Associates, Inc.

Autodesk Certified Instructor
AutoCAD Certified Professional
AutoCAD Civil 3D Certified Professional
Autodesk Certified BIM Specialist for Roads and Highways
Message 7 of 31
Anonymous
in reply to: mconway

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.")




Message 8 of 31
Anonymous
in reply to: Anonymous

Thanks for that great command! I was looking for exactly this for a long time.

I'm having two problems though:

  • is there another way to specify the new block instead of writing the block name by hand? I've got really complicated long block names, and it would be easier to simply select the new block
  • and it seems to take the attributes of the old block along, even if the new block doesn't even have these attributes.
Message 9 of 31
Kent1Cooper
in reply to: Anonymous

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.

Kent Cooper, AIA
Message 10 of 31
anderson51
in reply to: Kent1Cooper

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?

Message 11 of 31
Kent1Cooper
in reply to: anderson51


@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?

Kent Cooper, AIA
Message 12 of 31
anderson51
in reply to: Kent1Cooper

One that is already in the drawing...typing in the command line does nothing for me.


Message 13 of 31
Kent1Cooper
in reply to: anderson51


@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?

 

Kent Cooper, AIA
Message 14 of 31
anderson51
in reply to: Kent1Cooper

That worked, thank you


Message 15 of 31
sharpl
in reply to: Jroper

Brilliant, love when everything works like a clock, thx!!! :)))

 

Message 16 of 31
Crass
in reply to: Kent1Cooper

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!

-----
AutoCAD 2018/2021
AutoCAD Civil 3D 2021
Message 17 of 31
Kent1Cooper
in reply to: Crass


@Crass wrote:

.... I have a series of older "dumb" blocks that I'm trying to replace with newer "smart" blocks. .... I cannot get the Attribute Definitions to come in ....


Does running ATTSYNC afterwards help?

Kent Cooper, AIA
Message 18 of 31
Crass
in reply to: Kent1Cooper

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!

-----
AutoCAD 2018/2021
AutoCAD Civil 3D 2021
Message 19 of 31
Hamza.itani
in reply to: Kent1Cooper

Hi Kent,

In your BlockReplace lisp, can step 1 have the option to select the desired block instead of typing its name?

Thanks!

Message 20 of 31
Kent1Cooper
in reply to: Hamza.itani


@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.]

Kent Cooper, AIA

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report