Jump to content

Replacing old blocks with the same name new block


Recommended Posts

Posted

Hi.... I have a bunch of older drawings with standard office blocks inserted. 

Now these blocks of the same name have been updated and improved.

It's a painful process to rename the old block and then insert the new block with the same name (otherwise the old block remains) 

 

Any lisp suggestions which can automate this process ???? 

Posted (edited)

what about insert the new block to the drawing,

bcause a block with that name already exist,

you will be sasked if you want to re-dfine it,choose yes.

if you have attributes with that block use attsync command,choose the new block you have just inserted as the block to sync.

 

hope it will help.

aridzv.

Edited by aridzv
Posted

Thanks. Will try that on Monday ...

 

Howver there are many many blocks in the drawing.... 

Would there be a way to bring in a bunch of new standard blocks and have them auto redefined ??? 

Maybe by inserting the new standard blocks in a new fresh drawing, and inserting that new drawing (with all the std blocks ) into the old drawing, and have it auto redefine the blocks ???? 

Is it even possible in autocad ????

Posted

Well,

I think you should take this approach:

1. Insert all the new block to the drawing in one place. 

2. Use a lisp that will enable you to select those blocks and apply attsync command on them.

 

Posted

Like aridzv

 

1. Insert a new block to 0,0

2. apply attsync  (command "attsync" "S" (entlast))

3 (command "Erase" (entlast) "") you dont need to keep the block that has been inserted.

4 Repeat for all blocks

 

  • Like 1
Posted

I shall try this on Monday and revert.... however, my blocks don't have attributes..... so will attsync have any effect??? 

Regards !!!!! 

Posted (edited)

@Hsanon

if you don't have attributes so you don't need attsync.

 

 

Edited by aridzv
  • Like 1
Posted (edited)

1. Create a dwg file containing new blocks.

2. Select blocks to be modified using QSELECT or layer filter in the drawing to be modified.

3. Copy with CopyBase (Ctrl+Shift+C) 0,0

4. ERASE and PURGE for Delete Blocks.

5. Insert the DWG file containing the new block into the drawing using XREF.

6. in XREF window INSERT(not BIND) that for merging

   this will make the new blocks into the original drawing.

7. Paste the CopyBase block from the clipboard with Ctrl+V 0,0

  Since the copybased inform contains only the block name, it is pasted as a new block.

8. Delete the inserted XREF.

 

 

or try this routine

spacer.png

; REPLACEBLOCKS - 2023.09.04 exceed
; Replace existing blocks with duplicate names with copied blocks.

(defun c:REPLACEBLOCKS (/ *error* answer ss thisdrawing mspace 
                        entl myline ent ssl index bnamelist entp 
                        objp objtype bname bnlen recoverlist
                        bnold bntemp rcl 1blk fromname toname 
                        ssb n e1 edata )
  (vl-load-com)
  (defun *error* (msg) 
    (if (/= msg "Function cancelled") 
      (princ (strcat "\nError: " msg))
    )
    (vla-EndUndoMark thisdrawing)
    (princ)
  )
  
  (setq thisdrawing (vla-get-activedocument (vlax-get-acad-object)))
  (setq mspace (vla-get-modelspace thisdrawing))
  (vla-startundomark thisdrawing)
  
  (princ "\n Replace existing blocks with duplicate names with copied blocks.")
  (princ "\n you need to copy the block from another drawing and then run this command.")
  (setq answer (getstring "\n If you already copied, press the space bar / If not, press ESC."))
  (setq ss (ssadd))
  (if (setq entl (entlast))
    (progn)
    (progn
      (setq myline (vla-addline mspace (vlax-3d-point (list 0 0 0))(vlax-3d-point (list 1 1 1))))
      (setq entl (entlast))
      (ssadd entl ss)
    )
  )
  (setvar 'cmdecho 0)
  (command "pasteclip" "0,0")
  (while (setq ent (entnext entl))
    (ssadd ent ss)
    (setq entl ent)
  )
  (setq ssl (sslength ss))
  (setq index 0)
  (setq bnamelist '())
  (repeat ssl
    (setq entp (ssname ss index))
    (setq objp (vlax-ename->vla-object entp))
    (setq objtype (vlax-get-property objp 'EntityName))
    ;(princ objtype)
    (if (= objtype "AcDbBlockReference")
      (progn
        (setq bname (vlax-get-property objp 'effectivename))
        (setq bnamelist (cons bname bnamelist))
      )
    )
    (setq index (+ index 1))
  )
  (setq bnamelist (vl-sort bnamelist '<))
  ;(princ bnamelist)
  (repeat ssl
    (setq entp (ssname ss 0))
    (entdel entp)
    (ssdel entp ss)
  )
    
  ;; Unique  -  Lee Mac
  ;; Returns a list with duplicate elements removed.
  
  (defun LM:Unique ( l )
      (if l (cons (car l) (LM:Unique (vl-remove (car l) (cdr l)))))
  )

  (setq bnamelist (LM:Unique bnamelist))
  ;(princ bnamelist)
  
  (setq bnlen (length bnamelist))
  (setq recoverlist '())
  (repeat bnlen
    (setq bnold (car bnamelist))
    (setq index 0)
    (setq bntemp (strcat bnold "-TEMP"))
    (while (tblsearch "BLOCK" bntemp)
      (setq bntemp (strcat bnold "-TEMP" (vl-princ-to-string index)))
      (setq index (+ index 1))
    )
    (vla-put-Name (vla-item (vla-get-blocks thisdrawing) bnold) bntemp)
    (setq recoverlist (cons (list bntemp bnold) recoverlist))
    (setq bnamelist (cdr bnamelist))
  )

  (vla-PurgeAll thisdrawing)
  (setq ss (ssadd))
  (setq entl (entlast))
  (if (= entl nil)
    (progn
      (setq myline (vla-addline mspace (vlax-3d-point (list 0 0 0))(vlax-3d-point (list 1 1 1))))
      (setq entl (entlast))
      (ssadd entl ss)
    )
  )
  
  (command "pasteclip" "0,0")
  (while (setq ent (entnext entl))
    (ssadd ent ss)
    (setq entl ent)
  )
  (repeat ssl
    (setq entp (ssname ss 0))
    (entdel entp)
    (ssdel entp ss)
  )  

  (setq rcl (length recoverlist))
  (setq index 0)
  (repeat rcl
    (setq 1blk (nth index recoverlist))
    (setq fromname (car 1blk))
    (setq toname (cadr 1blk))
    (if (setq ssb (ssget "_X" (list (cons 2 fromname))))
      (repeat (setq n (sslength ssb))
        (setq e1 (ssname ssb (setq n (1- n))))
        (setq edata (entget e1))
        (entmod (subst (cons 2 toname) (cons 2 fromname) edata))
        (entupd e1)
      )
    )    
    (setq index (+ index 1))
  )
  (command "redraw")
  (vla-PurgeAll thisdrawing)
  (setvar 'cmdecho 1)
  (vla-EndUndoMark thisdrawing)
  (princ)
)

 

This is a rough routine, so it's not elegant.

It's just an idea, so someone better can edit it.

 

how to use it

1. Copy new blocks to copy base.

2. Run REPLACEBLOCKS on the drawing to be replaced.

 

How it Works

1. Paste the copybased items once and add them to the selection set.

2. Since entlast is used to insert into the selection set, a temporary line is created in case entlast does not exist. (although it is almost never necessary...)

3. Collect block names by cycling through the selection set.

4. Filter out unique names.

5. Delete temporarily pasted objects and lines.

6. Find the corresponding block name in the blocks of this drawing.

7. Change the name to one with -TEMP. In case of duplicates, add serial numbers after that -TEMP.

8. Create a list by pairing the original name and TEMP name. To return it to its original state later.

9. Delete the existing block definition with PurgeAll.

10. PasteSpec again and paste the block from the clipboard to create a new definition. and then delete them.

11. Revert to the name changed with entmod.

12. Run purgeall again to delete the TEMP block definition.

13. End

 

Since the temporary block is pasted twice and the temporary line is also created and deleted, it is best to check the area near 0,0 once. It worked fine in my tests, but I didn't assume all the scenarios.

Edited by exceed
  • Like 2
Posted

thank you for the effort....... its a bit cumbersome though. is there a way of automatically renaming drawings in the new blocks, inserting them into the drawing and then renaming them back into the original?? That seems to be a bit easier.

Posted
9 minutes ago, Hsanon said:

thank you for the effort....... its a bit cumbersome though. is there a way of automatically renaming drawings in the new blocks, inserting them into the drawing and then renaming them back into the original?? That seems to be a bit easier.

 

give me a explain, what's the difference between this 2 steps and the comment above.

 

On 9/4/2023 at 9:06 AM, exceed said:

how to use it

1. Copy new blocks to copy base.

2. Run REPLACEBLOCKS on the drawing to be replaced.

  • Like 1
Posted

Oh.  Maybe I didn't understand the steps. 

Apologies 🙏🙏

Let me try it again 

Posted

This is what I use. It requires that your new blocks location is added to the search path so they can be found. The old blocks that have the same name will be redefined.

(defun c:foo (/ file out)
  (vlax-for x (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
    (if	(not (wcmatch (strcase (vla-get-name x)) "*|*"))
      (setq out (cons (vla-get-name x) out))
    )
  )
  (setvar 'cmdecho 0)
  (foreach x out
    (if	(setq file (findfile (strcat x ".dwg")))
      (progn (command ".-INSERT" (strcat x "=" file) nil)
	     (and (ssget "_x" (list '(0 . "insert") (cons 2 x) '(66 . 1)))
		  (command "._attsync" "name" x)
	     )
      )
    )
  )
  (setvar 'cmdecho 1)
  (princ)
)

 

  • Like 1
Posted

heyyyy  that works pretty well..... but it also changes some blocks which do not need to be changed.

Would it be possible to list out the blocks in a dialog box ????

if not, its still fantastic !!!!!

And many thanks to all of you who have helped 

  • 1 year later...
Posted

Do you have an illustration of how to use this in AutoCAD ronjonp? 

Posted
On 9/8/2023 at 2:44 AM, ronjonp said:

This is what I use. It requires that your new blocks location is added to the search path so they can be found. The old blocks that have the same name will be redefined.

(defun c:foo (/ file out)
  (vlax-for x (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
    (if	(not (wcmatch (strcase (vla-get-name x)) "*|*"))
      (setq out (cons (vla-get-name x) out))
    )
  )
  (setvar 'cmdecho 0)
  (foreach x out
    (if	(setq file (findfile (strcat x ".dwg")))
      (progn (command ".-INSERT" (strcat x "=" file) nil)
	     (and (ssget "_x" (list '(0 . "insert") (cons 2 x) '(66 . 1)))
		  (command "._attsync" "name" x)
	     )
      )
    )
  )
  (setvar 'cmdecho 1)
  (princ)
)

 

 

this is brilliant. i've been after something like this for years!! wish i knew about it before. better late than never though

should really be a default option in cad

thanks for sharing ronjonp

Posted
23 minutes ago, masterfal said:

 

this is brilliant. i've been after something like this for years!! wish i knew about it before. better late than never though

should really be a default option in cad

thanks for sharing ronjonp

Glad to help :)

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...