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.
Welcome aboard!
Usually people use xrefs instead insert standard blocks.
I think we can skip the step of comparing block definition, just search the whole drawing, if there is any block name exists in the library, just insert it from the library and redefine the block in the drawing.
hey,
thanks for the quick reply.
The thing is I got many blocks in the drawing and don't want to search for every single block seperately.
We also want to use it in the office. so if I tell my colleges that I changed a block, they just need to press a shortcut and every block (including its attributes) is updated. therefore its the only way to make it with a LISP that compares the blocks from its library...
I guess there is way to attach additional information to each block definition to indicate its version (I saw it in AutoCAD Architectural?), but I am not familar with the method. Let's wait for other people's help.
The following code will redefine all blocks in the drawing for which a drawing file of the same name is found either within a specific directory, or within an AutoCAD Support File Search Path (SFSP):
;; Redefine All Blocks - Lee Mac (defun c:redefall ( / bln dir doc dwg lst obj org spc ) (setq dir nil) ;; 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) ) (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)) "`**,_*,*|*")) (setq dwg (findfile (strcat dir bln ".dwg"))) ) (progn (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) ) ) ) (if lst (vl-cmdf "_.attsync" "_N" (apply 'strcat (cdr lst)))) (vla-regen doc acallviewports) ) ) (princ) ) (vl-load-com) (princ)
Alter the value of the dir variable to source blocks from a specific directory, or set this variable to nil (the current value) to source blocks from the AutoCAD SFSP or working directory.
hey Lee Mac,
thanks for the code.
It looks like that's the one I was looking for. The only problem is, that its for an english autoCAD version. I guess for an german one I would need to put some "_" somewhere in front of the comands I guess (but where??? ), because when I run the script, AutoCAD just says: regenerating model
my second point is the directory of the block library: do you right it like that? -->
(setq dir "I:\AutoCAD block Library")
sorry for this questions but I'm not that fit with scripting.
@Anonymous wrote:The only problem is, that its for an english autoCAD version. I guess for an german one I would need to put some "_" somewhere in front of the comands I guess, because when I run the script, AutoCAD just says: regenerating model
The program should work with all language versions of AutoCAD - the drawing will be automatically regenerated after all blocks have been redefined.
@Anonymous wrote:my second point is the directory of the block library: do you right it like that? -->
(setq dir "I:\AutoCAD block Library")
Not quite -
Since the backslash character is an escape character in AutoLISP, you will need to use either single forward slashes or double-backslashes for filepath delimiters, e.g.:
(setq dir "I:\\AutoCAD block Library")
Or alternatively:
(setq dir "I:/AutoCAD block Library")
I hope this helps!
It seems, that I'm still doing something wrong.
This is how I do it:
I load your LISP with "appload" and when I run the comand "redefall" it doesn't update my blocks from the library at all.
I checked it because I added some lines in the block and in the drawing where I inserted it I tried the LISP and the new lines didn't show up. only when I manually insert the block again you see the update.
The only result is "Regenerating model".
what am I doing wrong?
I can report that the program is performing successfully in my testing, so perhaps the configuration is incorrect - please try this 'verbose' version which will provide more feedback to the user:
;; Redefine All Blocks - Lee Mac (defun c:redefall ( / bln dir doc dwg lst obj org spc ) (setq dir "I:\\AutoCAD block Library") ;; 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) (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 (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 lst (progn (princ "Synchronising attributes for redefined blocks...\n") (vl-cmdf "_.attsync" "_N" (apply 'strcat (cdr lst))) ) ) (textscr) (vla-regen doc acallviewports) ) ) (princ) ) (vl-load-com) (princ)
thanks, but no change.
It just writes "Unable to locate block: I:\\AutoCAD block Library\testblock.dwg
Is it possible to integrate the LISP in any other way than trough "appload"?
Does it have a problem, because I'm using AutoCAD 2010 Architecture?
thanks for your patience
@Anonymous wrote:thanks, but no change.
It just writes "Unable to locate block: I:\\AutoCAD block Library\testblock.dwg
This would indicate that there is no drawing with filename testblock.dwg residing within the directory I:\AutoCAD block Library - can you confirm that this drawing is present?
Have you altered the program in any way?
I didn't change anything from your file...well I changed the filepath to a new location, just to try if this makes any change.
The new blocklibrary is now " I:\AutoCAD Blöcke\template\"
this is what appeared when i run the LISP:
Befehl: REDEFALL
Unable to locate block: I:\AutoCAD Blöcke\template\Adler.dwg
Unable to locate block: I:\AutoCAD Blöcke\template\adler logo.dwg
Unable to locate block: I:\AutoCAD Blöcke\template\Bemassungsstricherl.dwg
Unable to locate block: I:\AutoCAD Blöcke\template\A$C553C1C71.dwg
Regeneriert Layout.
Regeneriert Modell.
so I opend a new file to be sure that I didn't miss any blocks and just inserted one specific block. now only this appears:
Befehl: redefall
Regeneriert Modell.
so far so good, but it still doesn't update any changes from this one block file...
so when I for example add some lines in the block and save it and then I run the Lisp in the file where I inserted this specific block and no lines show up.
@Anonymous wrote:this is what appeared when i run the LISP:
Befehl: REDEFALL
Unable to locate block: I:\AutoCAD Blöcke\template\Adler.dwg
Unable to locate block: I:\AutoCAD Blöcke\template\adler logo.dwg
Unable to locate block: I:\AutoCAD Blöcke\template\Bemassungsstricherl.dwg
Unable to locate block: I:\AutoCAD Blöcke\template\A$C553C1C71.dwg
Can you confirm that the drawing files (Adler.dwg / adler logo.dwg / etc.) are present in the folder I:\AutoCAD Blöcke\template?
I already changed it, so all the blocks are present.
still this:
Befehl: redefall
Regeneriert Layout.
Regeneriert Modell.
nothing else shows up. I already tried everything, but won't work.
@Anonymous wrote:I already changed it, so all the blocks are present.
still this:
Befehl: redefall
Regeneriert Layout.
Regeneriert Modell.
nothing else shows up. I already tried everything, but won't work.
I'm not really sure what else to suggest...
Providing that there are non-anonymous block definitions in your drawing, you should be receiving some messages whether the blocks can be found or not...
Hey Lee,
I found one of your old scripts in an other forum and this one works perfectly. It doesn't do the whole trick but maybe you can help me to add the last step. The only thing thats missing is the part that say to replace every block from a specific folder path. Now it just replaces only the blocks that I really put in one by one...
The Rest works great...half way there!!!
Thats your Code:
(defun c:ReDef ( / *error* oc spc doc block b )
(vl-load-com)
;; © Lee Mac 2010
;; Full filename needed if block is not in the support path
(setq BlocksToRedefine
'(
"I:\\AutoCAD Blöcke\\Template\\Support\\__Ausführung_A0.dwg"
"I:\\AutoCAD Blöcke\\Template\\Support\\__Ausführung_A1.dwg"
"I:\\AutoCAD Blöcke\\Template\\Support\\__Ausführung_A2.dwg"
)
)
(defun *error* ( msg )
(and oc (setvar 'CMDECHO oc))
(or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
(princ (strcat "\n** Error: " msg " **")))
(princ)
)
(setq spc
(vlax-get (vla-get-ActiveDocument (vlax-get-acad-object))
(if (= 1 (getvar 'CVPORT)) 'PaperSpace 'ModelSpace)
)
)
(setq oc (getvar 'CMDECHO)) (setvar 'CMDECHO 0)
(foreach block BlocksToRedefine
(if (setq b (findfile (strcat block (if (not (vl-filename-extension block)) ".dwg" ""))))
(progn
(vla-delete
(vla-insertblock spc
(vlax-3D-point '(0. 0. 0.)) b 1. 1. 1. 0.
)
)
(vl-cmdf "_.attsync" "_N" (vl-filename-base b))
)
(princ (strcat "\n** Cannot Find Block: " block " **"))
)
)
(setvar 'CMDECHO oc)
(princ)
)
If you could tell me which part I have to replace everything works like a miracle
Thx already for your great help Lee!
@Anonymous wrote:'(
"I:\\AutoCAD Blöcke\\Template\\Support\\__Ausführung_A0.dwg"
"I:\\AutoCAD Blöcke\\Template\\Support\\__Ausführung_A1.dwg"
"I:\\AutoCAD Blöcke\\Template\\Support\\__Ausführung_A2.dwg"
)
Now I see that your block names start with underscores - the previous program was excluding any blocks with an underscore prefix (since these are usually dimension style blocks).
Try the following code:
;; Redefine All Blocks - Lee Mac (defun c:redefall ( / bln dir doc dwg lst obj org spc ) (setq dir "I:\\AutoCAD Blöcke\\Template\\Support") ;; 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) (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 (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 lst (progn (princ "Synchronising attributes for redefined blocks...\n") (vl-cmdf "_.attsync" "_N" (apply 'strcat (cdr lst))) ) ) (textscr) (vla-regen doc acallviewports) ) ) (princ) ) (vl-load-com) (princ)
Hey Lee Mac,
I didn't look in the forum for quite a while and just noticed, that you already answered a while a go.
Your new script works like a miracle (whouldn't expect different 😉 ), thanks a lot for that. It does exactly what it should do.
I appreciate that.
I'm going to donate on your site and hope you keep on going to help us Neebies!
Cheers Klingi
This is brilliant ... but the ATTYNC part didn't work for me until I changed these parts ...
- (setq lst (vl-list* "," bln lst)) + (setq lst (vl-list* bln lst))
...and ...
- (vl-cmdf "_.attsync" "_N" (apply 'strcat (cdr lst))) +++
(foreach blk lst (vl-cmdf "_.attsync" "_N" blk)
);foreach
... and , of course, added "blk" to the locals declaration at the top of the file.
Thanks for writing the Lee, you're a Leegend. 😉
Can't find what you're looking for? Ask the community or share your knowledge.