Jump to content

Batch run a lisp program


Recommended Posts

Posted

I have a lisp program that I use to setup things on a dxf file and it then saves it to .dwg.  I would like to add to the program to be able to batch run it on all the .dxf files that are in the folder of the open .dxf file that the lisp is initiated from.  This would need to be also able to run on just the single drawing as well.  I would like help on creating the batch/single drawing code.  This needs to be able to run on AutoCAD LT 2024 or newer.  Can this be done all through lisp or does the lisp need to create scripts to run?  Thank for the help!!

 

I'll insert my existing code that works on single dxf's here:

;;; BBSSHOP.LSP
;;;
;;; This program sets up drawing variables and performs a series of commands
;;; based on the original script provided.

;; Load the Visual LISP extensions to work with ActiveX
(vl-load-com)

;;;------------------------------------------------------------------
;;; Helper Function to Create a Text Style
;;;------------------------------------------------------------------
(defun create_text_style (tstyle_name font_file txt_hgt /)
  ;; Added one more "" to answer all prompts from the -STYLE command
  (command "-STYLE" tstyle_name font_file txt_hgt "" "" "" "" "")
  (princ (strcat "\nText style '" tstyle_name "' created."))
)

;;;------------------------------------------------------------------
;;; Helper Function to Create a Dimension Style
;;; This function is updated to handle optional settings for the new styles.
;;;------------------------------------------------------------------
(defun create_dim_style (dstyle_name tstyle_name arrow_size txt_hgt ext_beyond ext_offset txt_gap /)

  ;; Set all base dimension style variables first
  (setvar "DIMZIN" 3)
  (setvar "DIMTAD" 1)
  (setvar "DIMTIH" 0)
  (setvar "DIMLUNIT" 4)
  (setvar "DIMFRAC" 2)
  (setvar "DIMRND" 0.0625)
  (setvar "DIMTMOVE" 2)
  (setvar "DIMBLK" "_CLOSED")
  (setvar "DIMLDRBLK" "_CLOSED")
  (setvar "DIMTXSTY" tstyle_name)
  (setvar "DIMASZ" arrow_size)
  (setvar "DIMTXT" txt_hgt)
  (setvar "DIMEXE" ext_beyond)
  (setvar "DIMEXO" ext_offset)
  (setvar "DIMGAP" txt_gap)

  ;; If creating the alternate style, set the specific overrides.
  ;; Otherwise, ensure standard settings are applied.
  (if (wcmatch dstyle_name "*_CONT")
    (progn
      (setvar "DIMSD1" 1)     ; Suppress Dimension Line 1
      (setvar "DIMSE1" 1)     ; Suppress Extension Line 1
      (setvar "DIMJUST" 2)    ; Text horizontal position to 2nd extension line
    )
    (progn
      (setvar "DIMSD1" 0)     ; Ensure Dimension Line 1 is ON for standard styles
      (setvar "DIMSE1" 0)     ; Ensure Extension Line 1 is ON for standard styles
      (setvar "DIMJUST" 0)    ; Ensure text is centered for standard styles
    )
  )

  ;; Save all the current DIM... settings into a new style
  (command "-DIMSTYLE" "SAVE" dstyle_name)
  (princ (strcat "\nDimension style '" dstyle_name "' created."))
)

;;;------------------------------------------------------------------
;;; Helper Function to Create a Multileader Style
;;;------------------------------------------------------------------
(defun create_mleader_style (mlstyle_name setArrowSize setBreakSize setDoglegLength setLandingGap tstyle_name /)

  ;; Get the dictionary of MLeader styles
  (setq dict (dictsearch (namedobjdict) "ACAD_MLEADERSTYLE"))
  (setq vDict (vlax-ename->vla-object (cdr (assoc -1 dict))))

  ;; Add a new MLeader style object
  (setq sty (vlax-invoke-method vDict 'AddObject mlstyle_name "AcDbMLeaderStyle"))

  ;; Set the properties for the new style
  (vlax-put-property sty 'ArrowSymbol "_Closed")
  (vlax-put-property sty 'ArrowSize setArrowSize)
  (vlax-put-property sty 'BreakSize setBreakSize)
  (vlax-put-property sty 'DoglegLength setDoglegLength)
  (vlax-put-property sty 'LandingGap setLandingGap)
  (vlax-put-property sty 'TextLeftAttachmentType 1)
  (vlax-put-property sty 'TextRightAttachmentType 5)
  (vlax-put-property sty 'TextStyle tstyle_name)
  
  ;; Set multileader style as active
  (setvar "CMLEADERSTYLE" mlstyle_name)

  (princ (strcat "\nMultileader style '" mlstyle_name "' created."))
)

;;;------------------------------------------------------------------
;;; Main Function: BBSSHOP
;;;------------------------------------------------------------------
(defun c:BBSSHOP ()
  (setvar "SNAPMODE" 0)
  (setvar "UCSICON" 0)

  (cond
    ;; CZEPIECE
    ((tblsearch "BLOCK" "CZEPIECE")
      ;; 1. Define style names and sizes
      (setq text_style "CZE_TEXT")
      (setq dim_style "CZE_DIM")
      (setq dim_style_cont (strcat dim_style "_CONT"))
      (setq ml_style "CZE_ML")
      
      ;; 2. Create the text style first
      (create_text_style
        text_style      ; tstyle_name
        "SIMPLEX.SHX"   ; font_file
        0.062           ; txt_hgt
      )

      ;; 3. Create the dimension styles
      (create_dim_style
        dim_style       ; dstyle_name
        text_style      ; tstyle_name
        0.065           ; arrow_size
        0.062           ; txt_hgt
        0.05            ; ext_beyond
        0.4             ; ext_offset
        0.021           ; txt_gap
      )
      (create_dim_style
        dim_style_cont  ; dstyle_name
        text_style      ; tstyle_name
        0.065           ; arrow_size
        0.062           ; txt_hgt
        0.05            ; ext_beyond
        0.4             ; ext_offset
        0.021           ; txt_gap
      )
      
      ;; Restore the primary dimension style to make it active
      (command "-DIMSTYLE" "R" dim_style)
     
      ;; 4. Create the multileader style
      (create_mleader_style
        ml_style        ; mlstyle_name
        0.065           ; setArrowSize
        0.062           ; setBreakSize
        0.062           ; setDoglegLength
        0.031           ; setLandingGap
        text_style      ; tstyle_name
      )
    )

    ;; ASMPIECE
    ((tblsearch "BLOCK" "ASMPIECE")
      ;; 1. Define all style names
      (setq text_style_detail "ASM_TEXT_DETAIL")
      (setq text_style_bom "ASM_TEXT_BOM")
      (setq text_style_assy "ASM_TEXT_ASSY")
      (setq dim_style_detail "ASM_DIM_DETAIL")
      (setq dim_style_detail_cont (strcat dim_style_detail "_CONT"))
      (setq dim_style_assy "ASM_DIM_ASSY")
      (setq dim_style_assy_cont (strcat dim_style_assy "_CONT"))
      (setq ml_style_detail "ASM_ML_DETAIL")
      (setq ml_style_assy "ASM_ML_ASSY")

      ;; 2. Create the 3 text styles
      (create_text_style text_style_detail "SIMPLEX.SHX" 0.108)
      (create_text_style text_style_bom "SIMPLEX.SHX" 0.1)
      (create_text_style text_style_assy "SIMPLEX.SHX" 0.0805)

      ;; 3. Create the 4 dimension styles
      (create_dim_style
        dim_style_detail    ; dstyle_name
        text_style_detail   ; tstyle_name
        0.0675              ; arrow_size
        0.108               ; txt_hgt
        0.0675              ; ext_beyond
        0.0675              ; ext_offset
        0.0365              ; txt_gap
      )
      (create_dim_style
        dim_style_detail_cont ; dstyle_name
        text_style_detail   ; tstyle_name
        0.0675              ; arrow_size
        0.108               ; txt_hgt
        0.0675              ; ext_beyond
        0.0675              ; ext_offset
        0.0365              ; txt_gap
      )
      (create_dim_style
        dim_style_assy      ; dstyle_name
        text_style_assy     ; tstyle_name
        0.0503              ; arrow_size
        0.0805              ; txt_hgt
        0.0302              ; ext_beyond
        0.2715              ; ext_offset
        0.0269              ; txt_gap
      )
      (create_dim_style
        dim_style_assy_cont ; dstyle_name
        text_style_assy     ; tstyle_name
        0.0503              ; arrow_size
        0.0805              ; txt_hgt
        0.0302              ; ext_beyond
        0.2715              ; ext_offset
        0.0269              ; txt_gap
      )

      ;; Restore the assembly dimension style to make it active
      (command "-DIMSTYLE" "R" dim_style_assy)
      
      ;; 4. Create the 2 multileader styles
      (create_mleader_style
        ml_style_detail     ; mlstyle_name
        0.0675              ; setArrowSize
        0.108               ; setBreakSize
        0.108               ; setDoglegLength
        0.054               ; setLandingGap
        text_style_detail   ; tstyle_name
      )
      (create_mleader_style
        ml_style_assy       ; mlstyle_name
        0.0503              ; setArrowSize
        0.0805              ; setBreakSize
        0.0805              ; setDoglegLength
        0.04025             ; setLandingGap
        text_style_assy     ; tstyle_name
      )
    )
    
    ;; INT_COL
    ((tblsearch "BLOCK" "INT_COL")
      ;; 1. Define style names and sizes
      (setq text_style "INT_TEXT")
      (setq dim_style "INT_DIM")
      (setq dim_style_cont (strcat dim_style "_CONT"))
      (setq ml_style "INT_ML")
      
      ;; 2. Create the text style first
      (create_text_style
        text_style      ; tstyle_name
        "SIMPLEX.SHX"   ; font_file
        0.07            ; txt_hgt
      )

      ;; 3. Create the dimension styles
      (create_dim_style
        dim_style       ; dstyle_name
        text_style      ; tstyle_name
        0.065           ; arrow_size
        0.07            ; txt_hgt
        0.06            ; ext_beyond
        0.26            ; ext_offset
        0.023           ; txt_gap
      )
      (create_dim_style
        dim_style_cont  ; dstyle_name
        text_style      ; tstyle_name
        0.065           ; arrow_size
        0.07            ; txt_hgt
        0.06            ; ext_beyond
        0.26            ; ext_offset
        0.023           ; txt_gap
      )

      ;; Restore the primary dimension style to make it active
      (command "-DIMSTYLE" "R" dim_style)
     
      ;; 4. Create the multileader style
      (create_mleader_style
        ml_style        ; mlstyle_name
        0.065           ; setArrowSize
        0.07            ; setBreakSize
        0.07            ; setDoglegLength
        0.035           ; setLandingGap
        text_style      ; tstyle_name
      )
    )

    ;; WEBB
    ((tblsearch "BLOCK" "WEBB")
      ;; 1. Define style names and sizes
      (setq text_style "WEB_TEXT")
      (setq dim_style "WEB_DIM")
      (setq dim_style_cont (strcat dim_style "_CONT"))
      
      ;; 2. Create the text style first
      (create_text_style
        text_style      ; tstyle_name
        "SIMPLEX.SHX"   ; font_file
        0.08            ; txt_hgt
      )

      ;; 3. Create the dimension styles
      (create_dim_style
        dim_style       ; dstyle_name
        text_style      ; tstyle_name
        0.05            ; arrow_size
        0.08            ; txt_hgt
        0.02            ; ext_beyond
        0.06            ; ext_offset
        0.02            ; txt_gap
      )
      (create_dim_style
        dim_style_cont  ; dstyle_name
        text_style      ; tstyle_name
        0.05            ; arrow_size
        0.08            ; txt_hgt
        0.02            ; ext_beyond
        0.06            ; ext_offset
        0.02            ; txt_gap
      )

      ;; Restore the primary dimension style to make it active
      (command "-DIMSTYLE" "R" dim_style)
    )
  )

   ;; Run AutoCAD Commands
   (command "-LINETYPE" "SET" "BYLAYER" "")
   (command "-INSERT" "PART_PAGE_SETUP.dwg" "0,0" "1" "1" "0")
   (command "-PURGE" "B" "*" "N")
   (command "-PURGE" "LA" "*" "N")
   (setvar "FILEDIA" 0)
   (command "-PLOT" "n" "Layout1" "B-SIZE PDF" "" "" "y" "n")
   (setvar "FILEDIA" 1)
  
   ;; --- START: Copy Layout from Template ---
   (princ "\nImporting layout from template...")
   (setq new_layout_name (vl-filename-base (getvar "DWGNAME")))
   (setq template_path (findfile "PART_PAGE_SETUP.dwg"))

   (if template_path
     (progn
       (princ (strcat "\nTemplate found: " template_path))
       
       ;; Switch to Model tab to prevent deleting the active layout
       (setvar "CTAB" "Model")
       
       ;; --- CORRECTED: Use (layoutlist) to check for existing layouts ---
       (setq layout_list (layoutlist))

       ;; 1. Delete the target layout name if it already exists (to overwrite).
       (if (member new_layout_name layout_list)
         (command "-LAYOUT" "D" new_layout_name)
       )
       
       ;; 2. Delete the *source* layout name if it exists in the current drawing.
       (if (member "PART_PAGE_SETUP" layout_list)
         (command "-LAYOUT" "D" "PART_PAGE_SETUP")
       )

       ;; 3. Import the layout from the template.
       (command "-LAYOUT" "T" template_path "PART_PAGE_SETUP")
       
       ;; 4. Rename the newly imported layout.
       (command "-LAYOUT" "R" "PART_PAGE_SETUP" new_layout_name)
       
       ;; 5. After the new layout is secure, delete the original "Layout1".
       (if (and (/= (strcase "Layout1") (strcase new_layout_name))
                (member "Layout1" (layoutlist)) ; Check updated list
           )
         (command "-LAYOUT" "D" "Layout1")
       )
       
       (princ (strcat "\nSuccessfully created layout: " new_layout_name))
     )
     (princ "\nERROR: Could not find 'PART_PAGE_SETUP.dwg' in AutoCAD's support file paths.")
   )
   ;; --- END: Copy Layout from Template ---
   
   ;; Finalize and Clean Up
   (command "ZOOM" "EXTENTS")
   (command "REGEN")
   (command "SAVEAS" "" "")

  (princ "\nBBSSHOP routine complete.")
  (princ)
)

 

Posted

Have you looked at using a script ? 

 

Basically its a multi line file with extension .SCR, it would be like this. It just executes every line opening and closing dwg files. 

 

open DWG1
(load "myfixlisp")
Open dwg2
(load "myfixlisp")
open dwg3
(load "myfixlisp")

 Google "script writer"

 

You may be able to pick a directory and write the script, then run it, using a lisp.  Lee-mac has a good "get a list of dwgs in a directory".

  • Like 1
Posted
4 hours ago, BIGAL said:

Have you looked at using a script ? 

 

Basically its a multi line file with extension .SCR, it would be like this. It just executes every line opening and closing dwg files. 

 

open DWG1
(load "myfixlisp")
Open dwg2
(load "myfixlisp")
open dwg3
(load "myfixlisp")

 Google "script writer"

 

You may be able to pick a directory and write the script, then run it, using a lisp.  Lee-mac has a good "get a list of dwgs in a directory".

 

 

@BIGAL do you know if there is a way to get the .scr file to be deleted at the end of the lisp routine or will this have to be manually deleted?

Here is my function that creates the .scr file and executes it:

(defun c:BBSSHOP ( / *error* old_cmdecho mode dwg_dir dxf_files scr_path scr_file readonly_files open_files confirm_dir current_dwg lsp_path scr_full_path current_basename)
    ;; --- Error Handling Setup ---
    (defun *error* (msg)
        (if old_cmdecho (setvar "cmdecho" old_cmdecho))
        (setvar "FILEDIA" 1) ; Ensure file dialogs are on
        (princ (strcat "\nError: " msg))
        (princ)
    )
    (setq old_cmdecho (getvar "cmdecho"))
    (setvar "cmdecho" 0)

    ;; --- Step 1: Ask the user for the processing mode first ---
    (initget "Current All") ; FIX: Removed space from initget string
    (setq mode (getkword "\nProcess [Current/All] drawing(s) in folder? <Current>: "))
    (if (not mode) (setq mode "Current")) ; Default to Current if user presses Enter

    ;; --- Step 2: If "All", confirm directory BEFORE doing anything else ---
    (if (= mode "All")
        (progn
            (setq dwg_dir (getvar "DWGPREFIX"))
            (if (or (not dwg_dir) (= dwg_dir ""))
                (progn
                    (princ "\nERROR: Current drawing is not saved. Cannot find other drawings.")
                    (setq mode "Cancel") ; Cancel the operation
                )
                (progn
                    (princ (strcat "\nThis command will process all drawings in:\n" dwg_dir))
                    (initget "Yes No")
                    (if (= "No" (getkword "\nIs this the correct directory? [Yes/No] <Yes>: "))
                        (progn
                            (princ "\nOperation cancelled by user.")
                            (setq mode "Cancel") ; Cancel the operation
                        )
                    )
                )
            )
        )
    )

    ;; --- Proceed only if the operation was not cancelled ---
    (if (/= mode "Cancel")
        (progn
            ;; --- Step 3: Process the Currently Open Drawing (happens in both modes) ---
            (princ "\nProcessing the current drawing...")
            (BBSSHOP-CORE)
            (command "_QSAVE" "" "")
            (princ "\nProcessing of current drawing complete.")

            ;; --- Step 4: If "All" was selected, run the batch script on OTHER files ---
            (if (= mode "All")
                (progn
                    (princ "\n'All' selected. Now preparing to process other DXF files...")
                    (setq current_basename (vl-filename-base (getvar "DWGNAME")))
                    (setq scr_path "_batch_process.scr"
                          scr_full_path (strcat dwg_dir scr_path)
                    )
                    
                    ;; --- FIX: Get all DXF files, then remove the one that matches the current drawing's base name ---
                    (setq dxf_files (vl-directory-files dwg_dir "*.dxf" 1))
                    (setq dxf_files (vl-remove-if '(lambda (x) (= (strcase (vl-filename-base x)) (strcase current_basename))) dxf_files))

                    (cond
                        ((not dxf_files)
                            (princ "\nNo other .dxf files found to process.")
                        )
                        ((setq readonly_files (get-readonly-files dwg_dir dxf_files))
                            (princ "\n\nERROR: The following files are read-only and cannot be processed:")
                            (foreach f readonly_files (princ (strcat "\n  - " f)))
                        )
                        ((setq open_files (get-open-drawings-to-close dxf_files dwg_dir))
                            (princ "\n\nERROR: The following files are already open and must be closed first:")
                            (foreach f open_files (princ (strcat "\n  - " f)))
                        )
                        (t
                            ;; --- Build the script for OTHER files only ---
                            (setq lsp_path (vl-string-translate "\\" "/" (findfile "BBSSHOP.lsp")))
                            (setq scr_file (open scr_full_path "w"))
                            
                            (write-line "FILEDIA 0" scr_file)
                            (foreach dxf_file dxf_files
                                (setq full_path (vl-string-translate "\\" "/" (strcat dwg_dir dxf_file)))
                                (write-line (strcat "_OPEN \"" full_path "\"") scr_file)
                                (write-line (strcat "(load \"" lsp_path "\")") scr_file)
                                (write-line "(BBSSHOP-CORE)" scr_file)
                                (write-line "_QSAVE" scr_file)
                                (write-line "" scr_file)
                                (write-line "" scr_file)
                                (write-line "_CLOSE" scr_file)
                            )
                            (write-line "FILEDIA 1" scr_file)
                            (write-line "(princ \"\nBatch script for other drawings is complete.\")" scr_file)
                            (close scr_file)

                            ;; --- Launch the script ---
                            (princ (strcat "\nGenerated script to process " (itoa (length dxf_files)) " other drawings."))
                            (princ "\nStarting batch process...")
                            (command "SCRIPT" scr_full_path)
                        )
                    )
                )
            )
        )
    )
    
    (setvar "cmdecho" old_cmdecho)
    (setq *error* nil)
    (princ "\nBBSSHOP routine finished.")
)

 

Posted (edited)

If you load & run a Script within AutoCAD, it will process the drawings one-at-a-time in series. 

 

As I understand it, AutoCAD LT supports Core Console - if that's true - then use a Windows Shell Menu to allow you to select multiple DXF files in Explorer, right click, and batch process them in parallel (aka at the same time).

 

Here's a sample .REG file to create the Windows Shell Menu: 

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell\RightClickDxfToDwg]
@="LT 2026 DXF to DWG"
"AppliesTo"=".dxf"
; "Icon"="C:\\Program Files\\Autodesk\\AutoCAD LT 2026\\accoreconsole.exe"
"HasLUAShield"=""

[HKEY_CLASSES_ROOT\*\shell\RightClickDxfToDwg\command]
@="\"C:\\Program Files\\Autodesk\\AutoCAD LT 2026\\accoreconsole.exe\" /i \"%1\" /p \"<YourProfileNameHere>\" /product \"<YourProductHere>\" /language \"en-US\" /s \"C:\\<YourFilePathHere>\\<YourScriptFileNameHere>.scr\""

 

Here's a sample .SCR file that will open DXF and save to DWG: 

(command "._saveas" "" "")

 

Edited by BlackBox
Posted (edited)
2 hours ago, C. Roberts said:

@BIGAL do you know if there is a way to get the .scr file to be deleted at the end of the lisp routine or will this have to be manually deleted?

 

Delete script file: Just my paranoia that I will set up the delete to remove the wrong thing, I set my temporary script files to have the same name for each function and then next time I run the function this script file is overwritten. I do the same with DCL 'on the fly' code and temporary files from that. A third thing I do is save these files in the temporary files location (and BIgAl has a handy routine to clear the temporary files out - unless I renamed it look on this site for 'cleanuptemp' - run as and when you want)

 

This is what I use to write to temporary files

 

(setq fo (open (setq fname (vl-filename-mktemp "-File_Nme-" (getvar "TEMPPREFIX") ".scr")) "w"))

 

where fo is the pointer in the LISP to the script file being created

Edited by Steven P
Posted

Below is my batch routine, search it for (setq batchfiletype "*.dwg") and modify it to (setq batchfiletype "*.dxf") t osee if it works.

 

 

 

 

Posted

Like others write same script file all the time then only one ever exists.

 

Part 2 I reset my temporary directory to a top level "d:\acadtemp" much easier to find, you may be horrified as to how much junk is in there. To reset or find, Options, Files,"Temporary directory""

 

Save Multi toggles to a support directory as its auto loaded.

 

cleanup temp.lsp

Multi toggles.lsp

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...