Hey guys,
I'm new in this forum and l would need your help.
I'm using a blocklibrary, where I stored all my blocks, most of them have attributes.
Now I'd like to simplify my workflow and want to update the blocks that I inserted in a drawing trough LISP.
Is there a way to update all inserted blocks and attributes of the whole drawing a once? The idea is, that the LISP checks the whole blocklibrary and updates the inserted blocks that to not match with the once from the library.
thanks for your help!
Solved! Go to Solution.
Solved by Lee_Mac. Go to Solution.
When writing the code I thought the ATTSYNC command accepted wildcards, so that a comma-delimited string could be passed to updated all blocks whose block name was found in the string - but if this didn't work for you, your modifications seem fine.
Thank you for your compliments - I'm delighted to hear that the code is useful!
Lee, indeed your code is ultra-useful, thanks again.
As proof of why I can't have good things, here is a version butchered by me to redefine just the blocks you have selected ...
;; Butchered by CADbloke from the mighty-fine work known as ==> Redefine All Blocks - Lee Mac (defun c:RedefineSelectedBlocks (/ bln dir doc dwg lst obj org spc blk) (setq dir "D:\\Dropbox\\Fox Sports working DWGs\\Blocks") ;; Directory of Block Library; nil to use Support Path (if dir (setq dir (strcat (vl-string-right-trim "\\" (vl-string-translate "/" "\\" dir) ) "\\" ) ) (setq dir "") ) (cond ((= 4 (logand 4 (cdr (assoc 70 (tblsearch "layer" (getvar 'clayer)))) ) ) (princ "\nCurrent layer locked.") ) ((setq doc (vla-get-activedocument (vlax-get-acad-object)) spc (vla-get-modelspace doc) org (vlax-3D-point 0 0) ) (terpri) ;Prints a newline to the command line (if (setq ss (ssget "I" '((0 . "INSERT") (66 . 1)))) (progn (foreach blk (mapcar 'vlax-ename->vla-object (mapcar 'cadr (ssnamex ss)) ) (setq bln (vla-get-name blk)) (if (setq dwg (findfile (strcat dir bln ".dwg"))) (progn (princ (strcat "Redefining block: " dwg "\n")) (setq obj (vla-insertblock spc org dwg 1.0 1.0 1.0 0.0) ) (if (= :vlax-true (vla-get-hasattributes obj)) (setq lst (vl-list* bln lst)) ) (vla-delete obj) ) (princ (strcat "Unable to locate block: " dir bln ".dwg\n") ) ) ; if ) ; foreach block (terpri) ;Prints a newline to the command line (if lst (progn (princ "Synchronising attributes for redefined blocks...\n" ) (foreach blk lst (progn (princ (strcat "\n" blk " ")) (vl-cmdf "_.attsync" "_N" blk) ) ;progn ) ;foreach ) ) (textscr) (vla-regen doc acallviewports) ) ) ; progn & if Selection set has blocks ) ; setq doc etc. ) (princ) ) (vl-load-com) (princ)
but what I really want to know ... how do you get the syntax highlighting right here - my lisp is all dull grey.
Hi,
I need to update a block in many drawings. And that code seems to be what I'm looking for.
But I don't know how to used it.
Anybody Can help me out, please?
Block Name: Sdoor.dwg
Block Path: C:\Users\Owner\Desktop\blocks
Files: Project arq1.dwg; Project arq2.dwg; Project arq3.dwg
File Path: C:\Users\Owner\Desktop\documents
Thank in advance
Hi, sorry to resurrect an old post, but I'm in need of your help!
I'm using the amazing redefall lisp to manage hundreds of blocks across a project (thanks Lee), and have a number of blocks with a visibility parameter (i.e. they are dynamic). Unfortunately the redefall routine won't pick up the dynamic blocks. Is there a way to amend the code to include them?
Pete
Can this Lisp be easily changed to redefine the blocks from a file? All the blocks that I have are in one file and WBLOCK would take a long time.
Hi ramcharger318,
maybe a little lisp like this would help:
Then you could run the Lee Mac's program.
Hope this helps,
Giancarlo
I have already done this. I would like to skip this step, because I don't want to update the individual block file when I update the block inside my working file.
Thanks
Well,
what about using DesignCenter, instead?
You can use it to insert, insert and redefine or redefine the blocks (one block at a time) between two different files.
Of course it's not useful if you have got hundreds of blocks to redefine.
Hope this helps,
Giancarlo
I have about 10 blocks in 16 files. It would be nice if you could select multiple blocks in design center and redefine them.
Thanks
@Lee_Mac How can the code be modified to search sub directories?
Your code is definitely what I'm looking for. We have something like 600 blocks and over time some have been modified and I need a way to update existing drawings. I can point the LISP to our main block library directory easily enough but we have several sub directories that our blocks are in. I'm a novice when it comes to writing code but I'm learning. Any help would be appreciated.
Example:
C:\blocks\ACMS
C:\blocks\ANNOTATION
C:\blocks\EI_DIAGRAM
C:\blocks\EI_LAYOUT
You could make use of my recursive Find File function from here in the following way:
;; Redefine All Blocks - Lee Mac
(defun c:redefall ( / bln dir doc dwg lst obj org spc )
(setq dir "C:\\Blocks") ;; Root directory of Block Library
(cond
( (not (and dir (vl-file-directory-p (setq dir (vl-string-right-trim "\\" (vl-string-translate "/" "\\" dir))))))
(princ "\nPlease specify a valid directory.")
)
( (= 4 (logand 4 (cdr (assoc 70 (tblsearch "layer" (getvar 'clayer))))))
(princ "\nCurrent layer locked.")
)
( (setq doc (vla-get-activedocument (vlax-get-acad-object))
spc (vla-get-modelspace doc)
org (vlax-3D-point 0 0)
)
(terpri)
(vlax-for blk (vla-get-blocks doc)
(if
(and
(= :vlax-false (vla-get-isxref blk))
(= :vlax-false (vla-get-islayout blk))
(not (wcmatch (setq bln (vla-get-name blk)) "`**,*|*"))
)
(if (setq dwg (LM:findfile (strcat bln ".dwg") dir))
(progn
(princ (strcat "Redefining block: " dwg "\n"))
(setq obj (vla-insertblock spc org dwg 1.0 1.0 1.0 0.0))
(if (= :vlax-true (vla-get-hasattributes obj))
(setq lst (vl-list* "," bln lst))
)
(vla-delete obj)
)
(princ (strcat "Unable to locate block: " bln ".dwg\n"))
)
)
)
(if lst
(progn
(princ "Synchronising attributes for redefined blocks...\n")
(vl-cmdf "_.attsync" "_N" (apply 'strcat (cdr lst)))
)
)
(textscr)
(vla-regen doc acallviewports)
)
)
(princ)
)
;; Findfile - Lee Mac
;; Searches the supplied directory and all subdirectories of the supplied directory for the specified file.
;; fnm - [str] File to search, e.g. "MyFile.txt"
;; dir - [str] Root directory
;; Returns: [str] Full filename of file if found, else nil.
(defun LM:findfile ( fnm dir )
(setq dir (vl-string-right-trim "\\" (vl-string-translate "/" "\\" dir)))
(cond
( (findfile (strcat dir "\\" fnm)))
( (vl-some '(lambda ( x ) (LM:findfile fnm (strcat dir "\\" x)))
(vl-remove "." (vl-remove ".." (vl-directory-files dir nil -1)))
)
)
)
)
(vl-load-com) (princ)
Dear Lee,
I try to get this LISP routine working in AutoCAD 2019.
Can you explain me what to do to get this working?
I have some (5) blocks in a folder (C:\Redefall) which should be inserted in several existing .dwg drawings and than redefine them all.
What do I have to change in this listing?
Regards,
Rudi
@Rude_H I'm using it with AutoCAD 2018 & 2020. All you should really have to do is modify the lisp file to point to whatever directory you have your blocks in.
Change this:
(setq dir "C:\\Blocks") ;; Root directory of Block Library
To this per your example:
(setq dir "C:\\Redefall") ;; Root directory of Block Library
Thank you @bryan.sanders for your extra info and @Lee_Mac for this nice lisp! It is very useful to me.
Just one extra question, i have to start the Lisp again every time. Is there a way that AutoCAD does load it standard at startup?
Regards,
Rudi
@Rude_H using the start up suite is probably the easiest way to have the lisp always loaded but there are other ways to do it too, like you could add it directly to your CUI using the CUI editor for instance. You can also load lisp files on demand with a button macro. Here are some links that should help.
Automatically-load-AutoLISP-routines.html
this lisp is awesome lee_mac,
is there a way to make the lisp ask for a file location instead of having to change the location every time within the lisp
Amazing lisp, but for some reason, my dynamic blocks dont get redefined, I tried to add more visibility states, but they dont show after the redefineall.
Anyone else have this bug? is it just the dynamic blocks that are bugged?
I just tested it with a few of our dynamic block and it work on all of them; sort of. Of the three blocks I tested 2 updated completely with no additional intervention. The third block did not look like it had updated on screen but opening up the block definition in the block editor everything looked fine. After saving the block while in the block editor, then exiting the block editor, the last block also displayed correctly on screen. So yeah, the lisp file did update the block definitions in the current file but not all the blocks refreshed on screen for some reason.