Looking for a Lisp to replace a block with another version of the same block in several drawings (Batch)

Looking for a Lisp to replace a block with another version of the same block in several drawings (Batch)

jesusrperezd
Enthusiast Enthusiast
3,348 Views
41 Replies
Message 1 of 42

Looking for a Lisp to replace a block with another version of the same block in several drawings (Batch)

jesusrperezd
Enthusiast
Enthusiast

Hi everyone, I have looked for something similar here but have not succeeded.

 

I have several drawings in a folder that I need to open one by one, delete a block, purge the block, and finally paste the new block version.

 

The new block version is in another dwg, which I copied with the base point 0,0. The pasting is in the same coordinate, 0,0. All the blocks (the new version) and the old to be replaced have the same name and are located in the layout at 0,0 (not in the model). I do need to run the purge command after deleting so the block is pated with the new changes.

 

I'm wondering if any of you have an LISP file that can help me automate this process.

 

The inputs could be the Block name, the route of the new block version, and the folder route with the other drawings where the block will be replaced. Another option could be that the lisp is executed over the drawings opened in the current session, and the new block is taken from the active drawing where the command is executed.

0 Likes
Accepted solutions (1)
3,349 Views
41 Replies
Replies (41)
Message 21 of 42

DGCSCAD
Collaborator
Collaborator

Updated code:

 

;Batcher_Block.lsp
;Description: Batch Process to replace block with another block in multiple drawings.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Start Main Batch Process

(defun c:Batcher (/ wutdir wutfiles scrfile n2 scrline)
(vl-load-com)
	(setq wutdir (LM:browseforfolder "Select directory to process:" "C:\\" 512));;;<--Starting Directory
	(setq wutfiles (vl-directory-files wutdir "*.dwg"))
	(setq scr_name (strcat wutdir "\\scrfile.scr"))
	(setq scrfile (open scr_name "w"))
	(close scrfile)
	(setq scrfile (open scr_name "a"))
(foreach n wutfiles
	(setq n2 (strcat "\""wutdir "\\" n "\""))
	(setq n2 (vl-string-translate "\\" "\\" n2))
	(setq scrline (strcat "open" " " n2 " " "(load\"batcher_block\")" " " "batcher_insert" " " "qsave" " " "close"))
	(write-line scrline scrfile)
	(princ)
)
	(close scrfile)
(command "script" scr_name)
(princ "\n***Batch complete.***")
(princ)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;START Batcher_Insert

(defun c:batcher_insert ()
(command "_.INSERT" "TMP=G:\\STILL NEED THE CORRECT PATH\\TMP" \E)
(princ)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;START Browse for Folder
;; THANKYOU Mr. M!
;; Browse for Folder  -  Lee Mac
;; Displays a dialog prompting the user to select a folder.
;; msg - [str] message to display at top of dialog
;; dir - [str] [optional] root directory (or nil)
;; bit - [int] bit-coded flag specifying dialog display settings
;; Returns: [str] Selected folder filepath, else nil.

(defun LM:browseforfolder ( msg dir bit / err fld pth shl slf )
    (setq err
        (vl-catch-all-apply
            (function
                (lambda ( / app hwd )
                    (if (setq app (vlax-get-acad-object)
                              shl (vla-getinterfaceobject app "shell.application")
                              hwd (vl-catch-all-apply 'vla-get-hwnd (list app))
                              fld (vlax-invoke-method shl 'browseforfolder (if (vl-catch-all-error-p hwd) 0 hwd) msg bit dir)
                        )
                        (setq slf (vlax-get-property fld 'self)
                              pth (vlax-get-property slf 'path)
                              pth (vl-string-right-trim "\\" (vl-string-translate "/" "\\" pth))
                        )
                    )
                )
            )
        )
    )
    (if slf (vlax-release-object slf))
    (if fld (vlax-release-object fld))
    (if shl (vlax-release-object shl))
    (if (vl-catch-all-error-p err)
        (prompt (vl-catch-all-error-message err))
        pth
    )
)
(princ)
AutoCad 2018 (full)
Win 11 Pro
0 Likes
Message 22 of 42

paullimapa
Mentor
Mentor

The \E cancels out of the Insert command since you don’t want to insert another instance of the now redefined block. So this simple builtin method works regardless if the block has attributes and where (Model or Layout) the block is currently inserted in the dwg. A similar method to a \E would be the following:

(command "_.INSERT" "My Block=C:\\Autodesk\\My Block")(command)

Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 23 of 42

paullimapa
Mentor
Mentor

perhaps instead of writing into the script file to load another lisp routine just write this single line of lisp code in the script 

(command "_.INSERT" "TMP=G:\\STILL NEED THE CORRECT PATH\\TMP" \E "_.Resume")

FYI: After running the /E inside a script you’ll have to include the Resume command in order for the script to continue after a cancel is sent. 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
Message 24 of 42

DGCSCAD
Collaborator
Collaborator

@paullimapa wrote:

The \E cancels out of the Insert command since you don’t want to insert another instance of the now redefined block. So this simple builtin method works regardless if the block has attributes and where (Model or Layout) the block is currently inserted in the dwg. A similar method to a \E would be the following:

 

(command "_.INSERT" "My Block=C:\\Autodesk\\My Block")(command)

 


Thank you for that.

 

Is there any documentation for this? I did a bit of digging, but not finding anything.

 

 

AutoCad 2018 (full)
Win 11 Pro
0 Likes
Message 25 of 42

paullimapa
Mentor
Mentor

Not that I’m aware. I just learned this trick when I saw it used on another post either on this forum or another.  I forgot. 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
Message 26 of 42

jesusrperezd
Enthusiast
Enthusiast

Hello @DGCSCAD @ec-cad @paullimapa, thanks for helping me and trying to find a solution. Please check the attached Zip file.

 

The folder contains the 'New block.dwg' file, which contains the new block TMP. The block TMP is a complete title block with attributes; the attribute values do not need to be saved; I can update them later.

 

There is a subfolder called 'Old Blocks'. It contains two dwg files, 'Old Block 1' and 'Old Block 2'. Each file contains a different version of block TMP. The program should replace the old version with the new one located in the 'New block.dwg' file.

 

I do know there are different approaches to do this, but I'm trying to do it as quickly & automatically as possible.

 

Please let me know if you have any comments or question.

 

0 Likes
Message 27 of 42

DGCSCAD
Collaborator
Collaborator

@jesusrperezd wrote:

Hello @DGCSCAD @ec-cad @paullimapa, thanks for helping me and trying to find a solution. Please check the attached Zip file.

 

The folder contains the 'New block.dwg' file, which contains the new block TMP. The block TMP is a complete title block with attributes; the attribute values do not need to be saved; I can update them later.

 

There is a subfolder called 'Old Blocks'. It contains two dwg files, 'Old Block 1' and 'Old Block 2'. Each file contains a different version of block TMP. The program should replace the old version with the new one located in the 'New block.dwg' file.

 

I do know there are different approaches to do this, but I'm trying to do it as quickly & automatically as possible.

 

Please let me know if you have any comments or question.

 


Ok, thank you for that.

 

Could you copy the folder path to the new block from your PC and paste it here? This is an important piece of information needed to complete the lisp/batch routine. It needs to know where to find the new block.

AutoCad 2018 (full)
Win 11 Pro
0 Likes
Message 28 of 42

jesusrperezd
Enthusiast
Enthusiast
Yes, sure. C:\Users\JP\Desktop\tes lisp\Files
that is the folder where the 'New Block.dwg' is

Is there a way to input or select this, let's say I want to run it in other directories or PCs ?
0 Likes
Message 29 of 42

DGCSCAD
Collaborator
Collaborator

@jesusrperezd wrote:
Yes, sure. C:\Users\JP\Desktop\tes lisp\Files
that is the folder where the 'New Block.dwg' is

Is there a way to input or select this, let's say I want to run it in other directories or PCs ?

Yes, that is possible using vl-propagate. I'd like to get this version sorted out first:

 

Is the name of the block "TMP" or "New Block"?

AutoCad 2018 (full)
Win 11 Pro
0 Likes
Message 30 of 42

jesusrperezd
Enthusiast
Enthusiast
The block is named 'TMP', and it is in a cad file named 'New Block.dwg'
0 Likes
Message 31 of 42

DGCSCAD
Collaborator
Collaborator

@jesusrperezd wrote:
The block is named 'TMP', and it is in a cad file named 'New Block.dwg'

Well, that complicates things a bit.

 

Wblock the "TMP" block out to the same directory as it's parent drawing (keeping it's name as "TMP.dwg"), then this code should work if it's called from a support/trusted folder:

 

;Batcher_Block.lsp
;Description: Batch Process to replace block with another block in multiple drawings.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Start Main Batch Process

(defun c:Batcher (/ wutdir wutfiles scrfile n2 scrline)
(vl-load-com)
	(setq wutdir (LM:browseforfolder "Select directory to process:" "C:\\" 512));;;<--Starting Directory
	(setq wutfiles (vl-directory-files wutdir "*.dwg"))
	(setq scr_name (strcat wutdir "\\scrfile.scr"))
	(setq scrfile (open scr_name "w"))
	(close scrfile)
	(setq scrfile (open scr_name "a"))
(foreach n wutfiles
	(setq n2 (strcat "\""wutdir "\\" n "\""))
	(setq n2 (vl-string-translate "\\" "\\" n2))
	(setq scrline (strcat "open" " " n2 " " "(load\"batcher_block\")" " " "batcher_insert" " " "qsave" " " "close"))
	(write-line scrline scrfile)
	(princ)
)
	(close scrfile)
(command "script" scr_name)
(princ "\n***Batch complete.***")
(princ)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;START Batcher_Insert

(defun c:batcher_insert ()
(command "_.INSERT" "TMP=C:\\Users\\JP\\Desktop\\tes lisp\\Files\\TMP" \E "_.Resume")
(princ)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;START Browse for Folder
;; THANKYOU Mr. M!
;; Browse for Folder  -  Lee Mac
;; Displays a dialog prompting the user to select a folder.
;; msg - [str] message to display at top of dialog
;; dir - [str] [optional] root directory (or nil)
;; bit - [int] bit-coded flag specifying dialog display settings
;; Returns: [str] Selected folder filepath, else nil.

(defun LM:browseforfolder ( msg dir bit / err fld pth shl slf )
    (setq err
        (vl-catch-all-apply
            (function
                (lambda ( / app hwd )
                    (if (setq app (vlax-get-acad-object)
                              shl (vla-getinterfaceobject app "shell.application")
                              hwd (vl-catch-all-apply 'vla-get-hwnd (list app))
                              fld (vlax-invoke-method shl 'browseforfolder (if (vl-catch-all-error-p hwd) 0 hwd) msg bit dir)
                        )
                        (setq slf (vlax-get-property fld 'self)
                              pth (vlax-get-property slf 'path)
                              pth (vl-string-right-trim "\\" (vl-string-translate "/" "\\" pth))
                        )
                    )
                )
            )
        )
    )
    (if slf (vlax-release-object slf))
    (if fld (vlax-release-object fld))
    (if shl (vlax-release-object shl))
    (if (vl-catch-all-error-p err)
        (prompt (vl-catch-all-error-message err))
        pth
    )
)
(princ)

 

AutoCad 2018 (full)
Win 11 Pro
0 Likes
Message 32 of 42

paullimapa
Mentor
Mentor

Here are the  steps to Wblock the TMP block:

Open the New Block.dwg and run the Wblock command. On the top select under Source the Block option and then your TMP block from the drop down list. Then at the bottom under Destination make sure the location to save the block is set as:

C:\Users\JP\Desktop\tes lisp\Files

Then select Ok button to complete the process  Now you should see this dwg:

C:\Users\JP\Desktop\tes lisp\Files\TMP.dwg


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 33 of 42

paullimapa
Mentor
Mentor

If you want to run @DGCSCAD code from other PCs then you’ll have to save his lisp file and your TMP.dwg to a location on the network which is accessible by everyone. Also to make it easy to load the lisp code that folder location needs to be added under those PCs AutoCADs Options>Files>Support File Search Path and Trusted Locations

Then @DGCSCAD code needs to be updated to that folder location to find the TMP block. 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 34 of 42

jesusrperezd
Enthusiast
Enthusiast

Hey guys, please bear with me.

 

I did the Wdblock process as @paullimapa described. I also added the folder to the support file and trusted.

 

I ran the 'Batcher' command from a drawing located in the folder, and got the following error

Command:
Command: (load"batcher") ; error: LOAD failed: "batcher"
Command: batcher_insert Unknown command "BATCHER_INSERT". Press F1 for help.

0 Likes
Message 35 of 42

paullimapa
Mentor
Mentor

Since the lisp file is named batcher_block.lsp then you need to type this at the command prompt:

 

(load"batcher_block")

 

 Then the command to run the function is called:

Batcher

Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 36 of 42

DGCSCAD
Collaborator
Collaborator
Accepted solution

@jesusrperezd wrote:

Hey guys, please bear with me.

 

I did the Wdblock process as @paullimapa described. I also added the folder to the support file and trusted.

 

I ran the 'Batcher' command from a drawing located in the folder, and got the following error

Command:
Command: (load"batcher") ; error: LOAD failed: "batcher"
Command: batcher_insert Unknown command "BATCHER_INSERT". Press F1 for help.


I ran it with no issues, so it appears you may have missed a step or two.

 

Here's Step-by-Step instructions to hopefully get you on the right track:

 

  1. Delete any instance of Batcher_Block.lsp on your PC.
  2. Download the newest version of Batcher_Block.lsp from message 31 above.
  3. Move the new Batcher_Block.lsp to the the support/trusted path.
  4. Start a New drawing.
  5. Load (drag/drop) Batcher_Block.lsp into the new drawing.
  6. Type: Batcher
  7. Select the folder where the files to change reside.

 

AutoCad 2018 (full)
Win 11 Pro
Message 37 of 42

jesusrperezd
Enthusiast
Enthusiast

Finally, IT WORKS!!! Thank you so much, @DGCSCAD, and to everyone who helped with this.

Message 38 of 42

DGCSCAD
Collaborator
Collaborator

Glad you got it sorted. 🙂

 

Don't forget about the clean-up. The scrfile.scr will remain in the target directory. I haven't figured out a way to delete that file programmatically after everything finishes.

 

Attempts have been made:

 

<snip>

(close scrfile)
;(vl-bb-set 'Tester001 (strcat "(vl-file-delete " scr_name ")"))
;(setq end_line (vl-bb-ref 'Tester001))
(command "script" scr_name)
(princ "\n***Batch complete.***")
;(vl-file-delete scr_Name)
(D-Leet-SCR)
(princ)

)

 

(defun D-Leet-SCR ( / del_scr)
(princ "\nTest it")
(vl-file-delete scr_Name)
;(vl-bb-ref 'Tester001)
;(princ "\n(vl-file-delete scr_Name)")
;(initget "Yes No")
;(setq del_scr (getkword "\nDelete Script File? [Yes/No] <Y> "))
;(if (or (= del_scr nil) (= del_scr "Yes")) (vl-file-delete scr_Name))
)

..still working on it.

 

@ec-cad  @paullimapa  Thank you for the assist.

AutoCad 2018 (full)
Win 11 Pro
0 Likes
Message 39 of 42

paullimapa
Mentor
Mentor

Can’t delete it since the script is in use. Or create the script file in the temp folder and then just leave it there. 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 40 of 42

Sea-Haven
Mentor
Mentor

@paullimapa Clean up the temp folder. Add scr files. 

 

 

0 Likes