Replace Selected Blocks

[Original link to AutoCAD tips blog]

The Express Tool called “Replace Block” or command line = BLOCKREPLACE <enter> has been mentioned [HERE] and found on the ribbon (as seen below)

This tool is helpful for replacing blocks globally (through out the entire drawing) but what if you need to simply replace a few selected blocks?…

Alan T. has made an awesome LISP routine called BRE.lsp to accomplish just that.

Here’s how:

  • BRE <enter>
  • Select the block that you want to replace the other selected blocks.
  • Select the blocks that you want replaced
  • <enter> when finished

~enjoy

(defun c:BRE (/ *error* blk f ss temp)
;; Replace multiple instances of selected blocks (can be different) with selected block
;; Size and Rotation will be taken from original block and original will be deleted
;; Required subroutines: AT:GetSel
;; Alan J. Thompson, 02.09.10
;; Found at: http://www.cadtutor.net/forum/showthread.php?48458-Replace-Selected-Block-Or-Blocks-With-Another-Block
(vl-load-com)
(defun *error* (msg)
(and f *AcadDoc* (vla-endundomark *AcadDoc*))
(if (and msg (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*QUIT*,")))
(princ (strcat "\nError: " msg))
)
)
(if
(and
(AT:GetSel
entsel
"\nSelect replacement block: "
(lambda (x / e)
(if
(and
(eq "INSERT" (cdr (assoc 0 (setq e (entget (car x))))))
(/= 4 (logand (cdr (assoc 70 (tblsearch "BLOCK" (cdr (assoc 2 e))))) 4))
(/= 4 (logand (cdr (assoc 70 (entget (tblobjname "LAYER" (cdr (assoc 8 e)))))) 4))
)
(setq blk (vlax-ename->vla-object (car x)))
)
)
)
(princ "\nSelect blocks to be repalced: ")
(setq ss (ssget "_:L" '((0 . "INSERT"))))
)
(progn
(setq f (not (vla-startundomark
(cond (*AcadDoc*)
((setq *AcadDoc* (vla-get-activedocument (vlax-get-acad-object))))
)
)
)
)
(vlax-for x (setq ss (vla-get-activeselectionset *AcadDoc*))
(setq temp (vla-copy blk))
(mapcar (function (lambda (p)
(vl-catch-all-apply
(function vlax-put-property)
(list temp p (vlax-get-property x p))
)
)
)
'(Insertionpoint Rotation XEffectiveScaleFactor YEffectiveScaleFactor
ZEffectiveScaleFactor
)
)
(vla-delete x)
)
(vla-delete ss)
(*error* nil)
)
)
(princ)
)
(defun AT:GetSel (meth msg fnc / ent good)
;; meth - selection method (entsel, nentsel, nentselp)
;; msg - message to display (nil for default)
;; fnc - optional function to apply to selected object
;; Ex: (AT:GetSel entsel "\nSelect arc: " (lambda (x) (eq (cdr (assoc 0 (entget (car x)))) "ARC")))
;; Alan J. Thompson, 05.25.10
(setvar 'errno 0)
(while (not good)
(setq ent (meth (cond (msg)
("\nSelect object: ")
)
)
)
(cond
((vl-consp ent)
(setq good (cond ((or (not fnc) (fnc ent)) ent)
((prompt "\nInvalid object!"))
)
)
)
((eq (type ent) 'STR) (setq good ent))
((setq good (eq 52 (getvar 'errno))) nil)
((eq 7 (getvar 'errno)) (setq good (prompt "\nMissed, try again.")))
)
)
)

About AutoCAD Tips

This blog serves as a knowledge base for myself (and anyone else) so that I can reference tips & tricks that I have learned and also refer others to it as well. I hope that this blog helps you learn at least one tip to make your drafting/design experience better.
This entry was posted in AutoLISP, AutoLISP: Blocks, AutoLISP: Modify, Blocks, Modifying. Bookmark the permalink.

35 Responses to Replace Selected Blocks

  1. Larry Young says:

    What an excellent tool, thank you, i have been looking for a way to do this for a while.

  2. John P says:

    This looks like a pretty useful tool. Unfortunately I have the AutoCad 2013 which does not have access to express tools. Is there another way I can block-replace or can I download Express Tools anywhere?

  3. Tina R. says:

    Is there a way to keep the attributes just like if I were to replace a block globally? With this routine I lose all attributes and have to retype everything in.

  4. Natalija says:

    Hi, I uploaded BRE.lsp successfully but when I try to use it I get this message:
    ; error: bad character read (octal): 0
    I have full version of AutoCAD 2014.
    Would you know what am I doing wrong?
    Thanks,
    Natalija

    • Allen Thompson says:

      I saved mine in notepad first. The loaded it with the Visual Lisp editor then I created the lisp file from that. Did you copy/add everything to the lisp file. Even all of the parentheses?

  5. Allen Thompson says:

    Yes it works perfectly!!! You are the greatest! Autodesks needs to add this to the product!!!

  6. Kristie says:

    I used this lisp in one of my drawings and it worked great. I then tried to use it in another drawing and now getting this error:
    Command: bre
    Error: no function definition: AT:GETSEL
    Command:
    Please let me know if you can help because this is great and I want to be able to use this lisp.

    • AutoCAD Tips says:

      Try adding the following to the bottom of your code:

        (defun AT:GetSel (meth msg fnc / ent)
          ;; meth - selection method (entsel, nentsel, nentselp)
          ;; msg - message to display (nil for default)
          ;; fnc - optional function to apply to selected object
          ;; Ex: (AT:GetSel entsel "\nSelect arc: " (lambda (x) (eq (cdr (assoc 0 (entget (car x)))) "ARC")))
          ;; Alan J. Thompson, 05.25.10
          (setvar 'ERRNO 0)
          (while
            (progn (setq ent (meth (cond (msg)
                                         ("\nSelect object: ")
                                   )
                             )
                   )
                   (cond ((eq (getvar 'ERRNO) 7) (princ "\nMissed, try again."))
                         ((eq (type (car ent)) 'ENAME)
                          (if (and fnc (not (fnc ent)))
                            (princ "\nInvalid object!")
                          )
                         )
                   )
            )
          )
          ent
        )
      
        (if (setq ent
                   (car
                     (AT:GetSel
                       entsel
                       "\nSelect arc: "
                       (lambda (x)
                         (if (eq "ARC" (cdr (assoc 0 (entget (car x)))))
                           (vl-every (function (lambda (p / ss)
                                                 (if (setq ss (ssget "_C" p p '((0 . "LINE"))))
                                                   (setq elst (cons (ssname ss 0) elst))
                                                 )
                                               )
                                     )
                                     (setq plst (list (_pnt (vlax-curve-getStartPoint (car x)))
                                                      (_pnt (vlax-curve-getEndPoint (car x)))
                                                )
                                     )
                           )
                         )
                       )
                     )
                   )
            )
          (progn
            (setq ov (mapcar (function getvar) (setq vl '("CMDECHO" "FILLETRAD"))))
            (setvar 'CMDECHO 0)
            (mapcar (function redraw) elst '(3 3))
            (while (progn (initget 6)
                          (setq fr (getdist (trans (vlax-curve-getStartPoint ent) 0 1)
                                            (strcat "\nSpecify new fillet radius <Current="
                                                    (rtos (cdr (assoc 40 (entget ent))))
                                                    ">: "
                                            )
                                   )
                          )
                   )
              (setvar 'FILLETRAD fr)
              (if (vl-cmdf "_.fillet" (list (car elst) (car plst)) (list (cadr elst) (cadr plst)))
                (progn (entdel ent) (setq ent (entlast)))
              )
            )
          )
        )
        (*error* nil)
        (princ)
      )
    • Allen Thompson says:

      Please read the post below. This routine works great..

  7. Allen Thompson says:

    I found a lisp routine that works like a charm.. its called BRE. Enjoy!

    (defun c:BRE (/ *error* blk f ss temp)
    ;; Replace multiple instances of selected blocks (can be different) with selected block
    ;; Size and Rotation will be taken from original block and original will be deleted
    ;; Required subroutines: AT:GetSel
    ;; Alan J. Thompson, 02.09.10
    ;; Found at: http://www.cadtutor.net/forum/showthread.php?48458-Replace-Selected-Block-Or-Blocks-With-Another-Block
    (vl-load-com)
    (defun *error* (msg)
    (and f *AcadDoc* (vla-endundomark *AcadDoc*))
    (if (and msg (not (wcmatch (strcase msg) “*BREAK*,*CANCEL*,*QUIT*,”)))
    (princ (strcat “\nError: ” msg))
    )
    )
    (if
    (and
    (AT:GetSel
    entsel
    “\nSelect replacement block: ”
    (lambda (x / e)
    (if
    (and
    (eq “INSERT” (cdr (assoc 0 (setq e (entget (car x))))))
    (/= 4 (logand (cdr (assoc 70 (tblsearch “BLOCK” (cdr (assoc 2 e))))) 4))
    (/= 4 (logand (cdr (assoc 70 (entget (tblobjname “LAYER” (cdr (assoc 8 e)))))) 4))
    )
    (setq blk (vlax-ename->vla-object (car x)))
    )
    )
    )
    (princ “\nSelect blocks to be repalced: “)
    (setq ss (ssget “_:L” ‘((0 . “INSERT”))))
    )
    (progn
    (setq f (not (vla-startundomark
    (cond (*AcadDoc*)
    ((setq *AcadDoc* (vla-get-activedocument (vlax-get-acad-object))))
    )
    )
    )
    )
    (vlax-for x (setq ss (vla-get-activeselectionset *AcadDoc*))
    (setq temp (vla-copy blk))
    (mapcar (function (lambda (p)
    (vl-catch-all-apply
    (function vlax-put-property)
    (list temp p (vlax-get-property x p))
    )
    )
    )
    ‘(Insertionpoint Rotation XEffectiveScaleFactor YEffectiveScaleFactor
    ZEffectiveScaleFactor
    )
    )
    (vla-delete x)
    )
    (vla-delete ss)
    (*error* nil)
    )
    )
    (princ)
    )
    (defun AT:GetSel (meth msg fnc / ent good)
    ;; meth – selection method (entsel, nentsel, nentselp)
    ;; msg – message to display (nil for default)
    ;; fnc – optional function to apply to selected object
    ;; Ex: (AT:GetSel entsel “\nSelect arc: ” (lambda (x) (eq (cdr (assoc 0 (entget (car x)))) “ARC”)))
    ;; Alan J. Thompson, 05.25.10
    (setvar ‘errno 0)
    (while (not good)
    (setq ent (meth (cond (msg)
    (“\nSelect object: “)
    )
    )
    )
    (cond
    ((vl-consp ent)
    (setq good (cond ((or (not fnc) (fnc ent)) ent)
    ((prompt “\nInvalid object!”))
    )
    )
    )
    ((eq (type ent) ‘STR) (setq good ent))
    ((setq good (eq 52 (getvar ‘errno))) nil)
    ((eq 7 (getvar ‘errno)) (setq good (prompt “\nMissed, try again.”)))
    )
    )
    )

  8. JH says:

    What an awesome tool! Saved me MANY hours of tedious manual work. Thanks so much!

  9. Stephanie says:

    Do you have anything updated for Mac? I get the message “; error: vl-load-com not supported on “Mac OS X Version 10.6 (x86_64)””

  10. This would be a life saver if I could get this to work. I’ve tried loading and using it but when I select the blocks I want to replace they just disappear?? What am I doing wrong?
    Thanks
    Justine

    • AutoCAD Tips says:

      Please use the code from the following link. It has been updated by Alan and when I tested it in ACAD 2015 it worked fine. One issue that I experienced was when a block that was previously scaled when I inserted it, when I ran the BRE.lsp it scaled up as well. So I am wondering if the blocks that you are tring to replace have been scaled…

      All credit goes to Alan Thompson for putting together great routines – Thanks Alan
      http://www.cadtutor.net/forum/showthread.php?48458-Replace-Selected-Block-Or-Blocks-With-Another-Block&p=359585&viewfull=1#post359585

      • Allen Thompson says:

        I use the BRE in combination with the Filter command. I have a cad file that has been exported from Revit. So all the blocks have a similar prefix but varying information in the block name. Filter allows me to isolate all the similar blocks and the I use BRE to change them to a single block/name.. If you have any issues/questions please do not hesitate to ask

      • Ar great. Yes this is similar to what I’m doing. I work in Illustrator to start with and then bring the artwork into CAD to detail up for construction. When you bring Symbols (Illustrator’s version of Blocks) in from Illustrator CAD annoyingly gives each symbol a separate definition Block 1, Block 2 etc. I’m using BRE to select all these separate definitions of essentially the same block and redefine them as one block/one name.
        I’ll certainly get in contact if I need any more help, thanks…you’ve been great.
        J

  11. Brandon says:

    I used this BRE.lsp and it works fairly well. I am impressed with the functionality. I do have two small requests that may be beneficial to everyone. When replacing the block, it seems that a new object is created because any dynamic fields (tables or labels) that I had pointing to the original block are broken when I use the BRE command. Also, attribute data is lost when replacing with new block.

    Would you please consider rewriting this LISP to allow for maintaining the same entity/object name and also preserve attribute data from the old block? Thank you for considering my request.

    • AutoCAD Tips says:

      Try the following Lisp

      
      ;; Swamp Blocks and retain Attribute values
      ;; Tharwat
      ;; http://www.autolisp.com/forum/threads/698-Attribute-exchange
      (defun c:SwampBlockWithATTs (/ *error* sourec SelectionSet selectionsetname attreq
                     atts i intger nxt e
                    )
        (vl-load-com)
        ;;; ============== ----------------------- ====================;;;;
        ;;; =              Author : Tharwat Al Shoufi                  ;;;;
        ;;; =             Contact :tharwat313@yahoo.com                ;;;;
        ;;; =       Lisp to replace Attributed Blocks by another       ;;;;
        ;;; =   and keeping the selected Attributes values as they are ;;;;
        ;;; =                in the new inserted ones                  ;;;;
        
        (defun *error* (msg)
          (and attreq (setvar 'attreq attreq))
          (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
              (princ (strcat "\n** Error: " msg " **"))
          )
          (princ)
        )
        (setq acdoc (vla-get-ActiveDocument (vlax-get-acad-object)))
        (if
          (and (progn (princ "\n Select source Attributed Block  :")
                      (setq source (ssget "_+.:S" '((0 . "INSERT") (66 . 1))))
               )
               (progn
                 (princ "\n Select Attributed Blocks to be changed :")
                 (setq i -1
                       SelectionSet
                        (ssget "_:L" '((0 . "INSERT") (66 . 1)))
                 )
               )
          )
           (progn
             (if (not (eq (setq attreq (getvar 'attreq)) 0))
               (setvar 'attreq 0)
             )
             (vla-StartUndoMark acdoc)
             (repeat (setq intger (sslength SelectionSet))
               (setq selectionsetname
                      (ssname SelectionSet
                              (setq intger (1- intger))
                      )
               )
               (foreach x (vlax-invoke
                            (vlax-ename->vla-object selectionsetname)
                            "getattributes"
                          )
                 (setq atts (cons (vla-get-textstring x) atts))
               )
               (vl-cmdf "_.-insert"
                        (cdr (assoc 2 (entget (ssname source 0))))
                        (cdr (assoc 10 (entget selectionsetname)))
                        ""
                        ""
               )
               (setq nxt (entnext (entlast)))
               (while
                 (not
                   (eq (cdr (assoc 0 (setq e (entget nxt))))
                       "SEQEND"
                   )
                 )
                  (if (eq "ATTRIB" (cdr (assoc 0 e)))
                    (entmod (subst (cons 1 (nth (setq i (1+ i)) (reverse atts)))
                                   (assoc 1 e)
                                   e
                            )
                    )
                  )
                  (setq nxt (entnext nxt))
                  (if (eq (1+ i) (length atts))
                    (setq i -1)
                  )
               )
               (entdel selectionsetname)
             )
             (setvar 'attreq attreq)
             (vla-EndUndoMark acdoc)
           )
           (princ)
        )
        (princ)
      )
      

    • Allen Thompson says:

      BRE is a Great Command! Saved me tons of time changing and replace large numbers of blocks. I use it in conjunction with the filter command. Especially when working with Revit exported files.

      • Natalija says:

        I tried BRE.lsp and didn’t have luck but SWAPBLK.lsp works. Only thing that is not that great is that replacing block has to be named as one word:

        (defun c:SWAPBLK (/ SELECTIONSET COUNT NBLK BLOCK ELIST)
        (princ “\n SWAPBLK”)
        (setvar “cmdecho” 0)
        (setvar “osmode” 0)
        (prompt “\nSelect blocks to be swapped to another:”)
        (setq SELECTIONSET (ssget) COUNT 0)
        (setq NBLK (getstring “\nName of swapping block:”))
        (repeat (sslength SELECTIONSET)
        (setq BLOCK (ssname SELECTIONSET COUNT))
        (setq ELIST (entget BLOCK))
        (setq ELIST (subst (cons 2 NBLK)(assoc 2 ELIST) ELIST))
        (entmod ELIST)
        (entupd BLOCK)
        (setq COUNT (+ COUNT 1))
        )
        (princ)
        )
        (princ “\nSWAPBLK loaded.”)
        (princ)

      • Phil Southby says:

        BRE works great except all of the blocks are -90degrres out, what am i doing wrong?

  12. Vj says:

    Thank you Alan T. Awesome tool…excellent job

  13. Samiul Islam says:

    how can i keep the blocks in the same scale

  14. ZAC says:

    I think the lsp file worked, however, rather than replacing my block, it deleted the existing block… how do I change this? I am brand new to Auto Lisp.

  15. gopakumar says:

    i have learned something new today thank you

  16. André Gato says:

    does any have this for Mac?

Leave a comment