Hsanon Posted September 2, 2023 Posted September 2, 2023 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 ???? Quote
aridzv Posted September 2, 2023 Posted September 2, 2023 (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 September 2, 2023 by aridzv Quote
Hsanon Posted September 2, 2023 Author Posted September 2, 2023 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 ???? Quote
aridzv Posted September 2, 2023 Posted September 2, 2023 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. Quote
BIGAL Posted September 2, 2023 Posted September 2, 2023 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 1 Quote
Hsanon Posted September 3, 2023 Author Posted September 3, 2023 I shall try this on Monday and revert.... however, my blocks don't have attributes..... so will attsync have any effect??? Regards !!!!! Quote
aridzv Posted September 3, 2023 Posted September 3, 2023 (edited) @Hsanon if you don't have attributes so you don't need attsync. Edited September 3, 2023 by aridzv 1 Quote
exceed Posted September 4, 2023 Posted September 4, 2023 (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 ; 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 September 4, 2023 by exceed 2 Quote
Hsanon Posted September 5, 2023 Author Posted September 5, 2023 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. Quote
exceed Posted September 5, 2023 Posted September 5, 2023 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. 1 Quote
Hsanon Posted September 7, 2023 Author Posted September 7, 2023 Oh. Maybe I didn't understand the steps. Apologies Let me try it again Quote
ronjonp Posted September 7, 2023 Posted September 7, 2023 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) ) 1 Quote
Hsanon Posted September 11, 2023 Author Posted September 11, 2023 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 Quote
JAYY Posted December 5 Posted December 5 Do you have an illustration of how to use this in AutoCAD ronjonp? Quote
masterfal Posted December 13 Posted December 13 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 Quote
ronjonp Posted December 13 Posted December 13 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 Quote
Recommended Posts
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.