Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Update blocks & attributes LISP

39 REPLIES 39
SOLVED
Reply
Message 1 of 40
Klingi162
17058 Views, 39 Replies

Update blocks & attributes LISP

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! Smiley Happy

39 REPLIES 39
Message 21 of 40
Lee_Mac
in reply to: CADbloke

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!

Message 22 of 40
CADbloke
in reply to: Lee_Mac

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.

- - - - - - -
working on all sorts of things including www.tvCAD.tv & www.CADreplace.com
Message 23 of 40
F.Camargo
in reply to: Lee_Mac

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

 

Message 24 of 40
peter_jeffs
in reply to: CADbloke

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

Message 25 of 40
ramcharger318
in reply to: Klingi162

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.

Message 26 of 40
gdefilo
in reply to: ramcharger318

Hi ramcharger318,

 

maybe a little lisp like this would help:

 

http://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/batch-wblock-of-blocks-in-drawing/td-...

 

Then you could run the Lee Mac's program.

 

Hope this helps,

Giancarlo

 

Message 27 of 40
ramcharger318
in reply to: gdefilo

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

Message 28 of 40
gdefilo
in reply to: ramcharger318

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

 

Message 29 of 40
ramcharger318
in reply to: gdefilo

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

Message 30 of 40
bryan.sanders
in reply to: Lee_Mac

@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

Message 31 of 40
Lee_Mac
in reply to: bryan.sanders

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)

 

Message 32 of 40
bryan.sanders
in reply to: Lee_Mac

Works perfectly! Thanks @Lee_Mac 

Message 33 of 40
Rude_H
in reply to: Lee_Mac

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

 

 

 

Message 34 of 40
bryan.sanders
in reply to: Rude_H

@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

 

Message 35 of 40
Rude_H
in reply to: bryan.sanders

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 

Message 36 of 40
bryan.sanders
in reply to: Rude_H

@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 

 

http://lee-mac.com/autoloading.html  

Message 37 of 40
raghib.boctor
in reply to: Lee_Mac

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

Message 38 of 40
Sea-Haven
in reply to: raghib.boctor

Google Getfiled lisp function.

Message 39 of 40
lmnDCJSJ
in reply to: Klingi162

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?


Message 40 of 40
bryan.sanders
in reply to: Klingi162

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. 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost