View Full Version : batch replace dynamic blocks and keep attributes, visbility, flip state...
Astro
2nd Nov 2009, 03:05 pm
Hi all,
I am sure my request already exist somewhere but could not find it:oops:.
I have a lot of drawings (over 1000) containing dynamic blocks with attributes from our symbol library. And our symbol library has been updated. Now i have to update all these drawings with the updated blocks :(
I need a lisp to do this tasks:
open drawings one by one stored in a folder
scan the drawing for blocks from a predifined list (e.g. block1, block2, block3,...)
if this blocks exists, replace it by new block with the same name (new block is stored in a drawing or folder)
keep the block rotation, the block visibility, flip state, scale (if old block was rotated by 90°, the new one will also be rotated by 90°; if visibility state was open the new one will also be open...)
keep the attribute values from old blocks and update the new block when insertedMaybe exporting all these informations to excell with the attribute extraction tool from autocad and then reuse these informations could be a godd idea :unsure:
Hope somebody can help me out. This will save my life
Freerefill
2nd Nov 2009, 06:01 pm
This sounds like a job for my batch engine, though I don't have much experience with dynamic blocks. If someone could figure out how to do it for one drawing, it would be easy to do it for all of them.
*EDIT*
I just whipped this up, run it on a drawing and let me know if it works. Just replace the "C:/" with whatever directory your blocks are in. Be sure to use a forward-slash, not the usual Windows back-slash.
(defun c:blkrep2( / ss blkPth blkLst blkNam)
(setq blkPth "C:/")
(setq ss (ssget "X" '((410 . "MODEL")(0 . "INSERT"))))
(if ss (setq blkLst (mapcar '(lambda (x) (cdr (assoc 2 (entget x)))) (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))))
(while blkLst
(setq blkLst (vl-remove (setq blkNam (car blkLst)) blkLst))
(if (findfile (strcat blkPth blkNam))
(progn (vl-cmdf "-insert" (strcat blkNam "=" blkPth blkNam) "Y")(vl-cmdf))
)
)
(princ)
)
Astro
3rd Nov 2009, 10:26 am
Thank's for your help.
Unfortunatly it's not working... :oops: Maybe i am doing something wrong?
Freerefill
3rd Nov 2009, 01:17 pm
Are you getting an error message of some sort? Also, I've set the filter to only select blocks on Modelspace. Are your blocks in Paperspace?
alanjt
3rd Nov 2009, 02:39 pm
Last edited by Freerefill : Yesterday at 02:16 pm. Reason: Note to self: don't submit code without first making sure it's awesome.
LoL Awesome. :lol:
Astro
3rd Nov 2009, 05:14 pm
No, i'm not getting any error message. My symbols are in modelspace.
What i do,
In the lisp i replaced the "C:/" by "C:/PID/" ("new" block is inside)
I open the drawing containing the "old" blocks
i load the lispwhen i type the command on the command line, nothing seem to happen:oops:
Thank you so much for your help
Freerefill
3rd Nov 2009, 05:22 pm
That means it's either not finding a selection set, or the selection set isn't returning a list of blocks. For some reason, I'm betting on the former. Would it be possible to upload a sample drawing so I could see what you're working with? It wouldn't need to be extravagant, just have at least three "old" blocks in the drawing.
Astro
3rd Nov 2009, 05:40 pm
In attachments a drawing containig 3 old blocks inside :)
Freerefill
3rd Nov 2009, 05:51 pm
Thanks! Made a few tweaks. First problem was what I thought: I wasn't properly getting the name of the dynamic block, so naturally it wouldn't find the file. Second thing was that I didn't include the extension when I checked to see if the file was there, so naturally it wouldn't work >>'
Anyway, try this now:
(defun c:blkrep2( / ss blkPth blkLst blkNam)
(vl-load-com)
(setq blkPth "C:/")
(setq ss (ssget "X" '((410 . "MODEL")(0 . "INSERT"))))
(if ss (setq blkLst (mapcar '(lambda (x) (vla-get-effectivename (vlax-ename->vla-object x))) (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))))
(while blkLst
(setq blkLst (vl-remove (setq blkNam (car blkLst)) blkLst))
(if (findfile (strcat blkPth blkNam ".dwg"))
(progn (vl-cmdf "-insert" (strcat blkNam "=" blkPth blkNam ".dwg") "Y")(vl-cmdf))
)
)
(princ)
)
Astro
3rd Nov 2009, 05:56 pm
Thank you for your quick answer.
I try it, but have this message now, :cry:
Block TEST references itself
*Invalid*
Unknown command "Y". Press F1 for help.
Freerefill
3rd Nov 2009, 06:01 pm
That error occurs when you have a block nested within a block (say, a block "TEST" nested inside a block named "TEST"). I think it may also pop up if you try to insert a block named "TEST" inside of a drawing named "TEST," but I'm not positive on that one.
Check to make sure your blocks aren't referencing themselves. That might not be the case, as I tried it and it worked for me. Also, as a tip, when dealing with blocks and replacing blocks, PURGE often! Too many times, I've tried to replace a block and gotten a slew of errors, only to find out that the old block definition was hanging around. ><
*EDIT*
Think I got it. Do you have your blocks saved as blocks within a file of the same name as the block? That is to say, if you open up TEST.dwg, does it contain a block named TEST?
*EDIT AGAIN*
I did some snooping, seems this problem is common and the trick to inserting dynamic blocks is to create them using wblock. I don't really understand it as, again, I've got zero experience with dynamic blocks, but here are two links I found that should help:
http://www.cadtutor.net/forum/showthread.php?t=33335
http://discussion.autodesk.com/forums/thread.jspa?threadID=749883&tstart=0
Powered by vBulletin™ Version 4.1.2 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.