In this recent post we looked at an approach combining AutoLISP with a script generated on-the-fly to get around the fact that (command "_.OPEN" …) does nothing when SDI == 0. As mentioned in a comment in the post, I realised that the approach of using a single master script to do this is more prone to failure: a number of commands can cause scripts to stop executing, for instance, so it would be better practice to minimise the operations contained in a particular script to increase the application’s fault tolerance.
This modified approach was suggested by a member of our Engineering team in a recent thread (one that I came across after Monday’s post). It uses a data file to store a list of the drawings to process and only creates a script to load – and launch processing on – the next drawing in that list:
(defun C:BATCH(/ dwgs lsp-name data-name)
(setq dwgs '("C:/A.DWG" "C:/B.DWG" "C:/C.DWG" "C:/D.DWG")
lsp-name "c:/tmp.lsp"
data-name "c:/dwgs.tmp"
)
(create-drawing-list data-name dwgs)
(process-next-drawing data-name lsp-name "(create-circle)" T T)
(princ)
)
(defun create-circle()
(command "_.CIRCLE" "10,10,0" "5")
)
(defun create-drawing-list(data dwgs / f dwg)
;; Create data file containing the DWG names
(setq f (open data-name "w"))
(foreach dwg dwgs
(write-line dwg f)
)
(close f)
)
;; Get the first drawing from the list, removing it
(defun get-next-drawing(data / dwg dwgs f)
;; Read in the whole list of DWGs
(setq f (open data "r")
dwgs '()
)
(while (setq dwg (read-line f))
(setq dwgs (cons dwg dwgs))
)
(close f)
;; Reverse the list, take the head and write
;; back the remainder to the file
(if (> (length dwgs) 0)
(progn
(setq dwgs (reverse dwgs)
dwg (car dwgs)
dwgs (cdr dwgs)
)
(setq f (open data "w"))
(foreach dwg dwgs
(write-line dwg f)
)
(close f)
)
)
dwg
)
;; Process the current drawing and use a script to open
;; the next one in the list
(defun process-next-drawing(data lsp func save first / scr)
(setq scr "c:/tmp.scr")
;; We only want to run the function if not the first
;; time called... the same for save
(if (not first)
(progn
(eval (read func))
(if save
(command "_.QSAVE")
)
)
)
;; Get the next DWG name from the file
(setq dwg (get-next-drawing data))
;; If there is one, create a script to open it, reload
;; the application and process our function
(if dwg
(progn
(create-script scr data dwg lsp save first)
(command "_.SCRIPT" scr)
)
;; For the last drawing we simply close it and
;; delete the now-empty data file
(progn
(vl-file-delete data)
(vl-file-delete scr)
(command "_.CLOSE")
)
)
)
;; Create a script to close the current drawing and
;; open the next, calling back to our process function
;; (after having loaded the file that defines it)
(defun create-script(scr data dwg lsp save first / f)
(setq f (open scr "w"))
(if (not first)
(write-line "_.CLOSE" f)
)
(write-line
(strcat "_.OPEN \"" dwg "\"") f
)
(write-line
(strcat "(load \"" lsp "\")") f
)
(write-line
(strcat
"(process-next-drawing \""
data "\" \"" lsp "\" \"" func "\" "
(if save "T" "nil") " nil)"
)
f
)
(close f)
(princ)
)
I hope this is useful to people – as mentioned before, please do provide feedback on how/whether this works for you…