Don't quote me on this. I haven't even tried it.
;;; ==========================================================================
;;; File : PLOTALL.LSP
;;; Purpose : Provides PLOTALL and -PLOTALL commands to plot all paper space
;;; layouts in the current drawing, thereby working around the
;;; "Layout of order" item in January 2003 Bug Watch.
;;; Author : Steve Johnson for Cadalyst magazine.
;;; Notes : Expects to find PLOTALL.DCL in search path.
;;; Uses AutoCAD 2000+ Visual LISP functions.
;;; Only tested on AutoCAD 2002.
;;; ==========================================================================
;; ---------------------------------------------------------------------------
;; Function: C:PLOTALL
;; Purpose : Dialogue box version of command to plot all paper space layouts
;; in the current drawing.
;; Global : PLOTALL-DEVICE: string containing name of plot device, e.g.
;; "\\\\server\\plotter" or
;; "plotter.pc3"
;; PLOTALL-QTY: number of each layout to plot
;; PLOTALL-ORDER: order in which to plot (string)
;; PLOTALL-REV: reverse order? (boolean: T = reverse)
;; Local : dclfile: full filename of "PlotAll.dcl" file
;; dcl#: DCL ID number
;; device-list: list of available plot devices
;; order-list: list of order strings
;; device#: index number of chosen device in device-list
;; order#: index number of chosen order in order-list
;; quantity: temporary number of each layout to plot
;; ---------------------------------------------------------------------------
(defun C:PLOTALL (/ ; Functions
init_vars init_tiles call_ok
; Variables
dclfile dcl# device-list order-list device# order# quantity
)
;; ---------------------------------------------------------------------------
;; Function: init_vars
;; Purpose : Sets up variables prior to invoking dialogue box.
;; ---------------------------------------------------------------------------
(defun init_vars ()
(if (not PLOTALL-DEVICE) (setq PLOTALL-DEVICE "None"))
(if (not PLOTALL-QTY) (setq PLOTALL-QTY 1))
(if (not PLOTALL-ORDER) (setq PLOTALL-ORDER "Alpha"))
(setq
device-list (plotall_device_list)
order-list '("Alpha" "Numeric" "Tab")
order# (- (length order-list) (length (member PLOTALL-ORDER order-list)))
quantity PLOTALL-QTY
)
(if (and PLOTALL-DEVICE (member PLOTALL-DEVICE device-list))
(setq
device#
(- (length device-list) (length (member PLOTALL-DEVICE device-list)))
)
(setq device# 0)
)
) ; End init_vars
;; ---------------------------------------------------------------------------
;; Function: init_tiles
;; Purpose : Sets up dialogue box tiles prior to invoking dialogue box.
;; ---------------------------------------------------------------------------
(defun init_tiles ()
(action_tile "accept" "(call_ok)")
(start_list "device_list")
(foreach one device-list
(add_list one)
)
(end_list)
(start_list "order_list")
(foreach one order-list
(add_list one)
)
(end_list)
(set_tile "device_list" (itoa device#))
(set_tile "order_list" (itoa order#))
(set_tile "reverse" (if PLOTALL-REV "1" "0"))
(set_tile "quantity" (itoa quantity))
) ; End init_tiles
;; ---------------------------------------------------------------------------
;; Function: call_ok
;; Purpose : Callback function for OK button. Ensures a quantity greater than
;; 0 and a device other than "None".
;; ---------------------------------------------------------------------------
(defun call_ok ()
(if (> (setq quantity (atoi (get_tile "quantity"))) 0)
(if (> (setq device# (atoi (get_tile "device_list"))) 0)
(progn
(setq
PLOTALL-DEVICE (nth device# device-list)
PLOTALL-ORDER (nth (atoi (get_tile "order_list")) order-list)
PLOTALL-REV (= (get_tile "reverse") "1")
PLOTALL-QTY quantity
)
(done_dialog 1)
)
(set_tile "error" "Must choose a plot device")
)
(set_tile "error" "Quantity must be 1 or more")
)
) ; End call_ok
;; Start C:PLOTALL -----------------------------------------------------------
(cond
((not (findfile (setq dclfile "PlotAll.dcl")))
(alert "Cannot find PlotAll.dcl")
)
((< (setq dcl# (load_dialog dclfile)) 0) ; Error
(prompt (strcat "\nCannot load " dclfile "."))
)
((not (new_dialog "plotall_main" dcl#)) ; Error
(prompt (strcat "\nProblem with " dclfile "."))
)
(T ; No DCL problems: fire it up
(init_vars)
(init_tiles)
(setq action (start_dialog))
(unload_dialog dcl#)
(if (= action 1)
(plotall_layouts PLOTALL-DEVICE PLOTALL-QTY PLOTALL-ORDER PLOTALL-REV)
)
)
)
(princ)
) ; End C:PLOTALL
;; ---------------------------------------------------------------------------
;; Function: C:-PLOTALL
;; Purpose : Command line version of command to plot all paper space layouts
;; in the current drawing.
;; Global : PLOTALL-DEVICE: string containing name of plot device
;; PLOTALL-QTY: number of each layout to plot
;; PLOTALL-ORDER: order in which to plot (string)
;; PLOTALL-REV: reverse order? (boolean: T = reverse)
;; Local : device: temporary string containing name of plot device
;; device-list: list of available plot devices
;; order: temporary order in which to plot (string)
;; rev: temporary reverse order? (boolean: T = reverse)
;; quantity: temporary number of each layout to plot
;; ---------------------------------------------------------------------------
(defun C:-PLOTALL (/ device device-list order rev quantity)
(if (not PLOTALL-DEVICE) (setq PLOTALL-DEVICE "None"))
(if (not PLOTALL-QTY) (setq PLOTALL-QTY 1))
(if (not PLOTALL-ORDER) (setq PLOTALL-ORDER "Alpha"))
(setq device (getstring T (strcat "\nPlot device <" PLOTALL-DEVICE ">: ")))
(if (= device "") (setq device PLOTALL-DEVICE))
(cond
((= device "None")
(prompt "\nMust specify a plot device.")
)
((not
(member
(strcase device)
(mapcar 'strcase (setq device-list (plotall_device_list)))
)
)
(foreach one device-list
(if (/= one "None")
(prompt (strcat one "\n"))
)
)
(prompt "Must specify one of the above plot devices.\n")
)
(progn
(initget "Alpha Numeric Tab")
(setq
order
(getkword
(strcat
"\nPlot order [Alpha/Numeric/Tab] <" PLOTALL-ORDER ">: "
)
)
)
(if order (setq PLOTALL-ORDER order))
(initget "Yes No")
(setq
rev
(getkword
(strcat
"\nReverse order [Yes/No] <" (if PLOTALL-REV "Yes" "No") ">: "
)
)
)
(if rev (setq PLOTALL-REV (= rev "Yes")))
(initget 6) ; Positive integer
(setq
PLOTALL-DEVICE device
quantity
(getint (strcat "\nNumber of copies <" (itoa PLOTALL-QTY) ">: "))
)
(if quantity (setq PLOTALL-QTY quantity))
(plotall_layouts PLOTALL-DEVICE PLOTALL-QTY PLOTALL-ORDER PLOTALL-REV)
)
)
(princ)
) ; End C:-PLOTALL
;; ---------------------------------------------------------------------------
;; Function: plotall_device_list
;; Purpose : Returns list of strings of all available plot devices.
;; Local : curdwg: current drawing object
;; pslayout: paper space layout object
;; ---------------------------------------------------------------------------
(defun plotall_device_list (/ curdwg pslayout)
(vl-load-com)
(setq
curdwg (vla-get-ActiveDocument (vlax-get-Acad-Object))
pslayout (vla-get-Layout (vla-get-PaperSpace curdwg))
)
; Call RefreshPlotDeviceInfo before GetPlotDeviceNames
(vla-RefreshPlotDeviceInfo pslayout)
(vlax-safearray->list (vlax-variant-value (vla-GetPlotDeviceNames pslayout)))
) ; End plotall_device_list
;; ---------------------------------------------------------------------------
;; Function: plotall_layouts
;; Purpose : Plots all paper space layouts in current drawing to a specified
;; plot device, in the specified quantity.
;; Params : DEVICE: string containing name of plot device
;; QTY: number of each layout to plot
;; ORDER: order in which to plot ("Alpha" "Numeric" "Tab")
;; REV: boolean: if T, reverse plot order
;; Local : curdwg: current drawing object
;; layout-array: safearray of a single layout name string
;; layout-list: list of layout name strings
;; plot: plot object (needed to actually perform plot)
;; errmsg: returned object from failed plot attempt
;; ---------------------------------------------------------------------------
(defun plotall_layouts (DEVICE QTY ORDER REV /
; Functions
delnth sortlist str_num_sort tab_sort
; Variables
curdwg layout-array layout-list plot errmsg)
;; ---------------------------------------------------------------------------
;; Function: delnth
;; Purpose : Returns a list with the Nth item deleted
;; Params : N: index number of item to delete (0 is first item in list)
;; LST: list to delete from
;; Local : #: item counter
;; tlst: temporary list
;; ---------------------------------------------------------------------------
(defun delnth (N LST / # tlst)
(setq # 0)
(while (and LST (/= # N))
(setq
tlst (cons (car LST) tlst)
LST (cdr LST)
# (1+ #)
)
)
(reverse (append (reverse (cdr LST)) tlst))
) ; End delnth
;; ---------------------------------------------------------------------------
;; Function: sortlist
;; Purpose : Sorts a list, allowing any function to be used for item comparison.
;; Params : LST: list to sort
;; FUN: name of function to apply to test for "lower": could be a
;; built-in function (e.g. >) or a user defined function,
;; possibly defined on the spot using lambda.
;; ---------------------------------------------------------------------------
(defun sortlist (LST FUN / size # pos high item tmplst)
(repeat (1- (setq size (length LST)))
(setq
# 1 ; Position of 1st item to compare with highest item
pos 0 ; Position of initial highest item
high (nth 0 LST) ; Value of initial highest item
)
(while (< # size) ; Walk through the whole list, finding the highest item
(if (apply FUN (list high (setq item (nth # LST)))) ; Test for higher
(setq ; Found a higher item, so record its:
high item ; value,
pos # ; position
)
)
(setq # (1+ #)) ; Test next item
)
(setq
tmplst (cons high tmplst) ; Stick highest item at start of temp list
LST (delnth pos LST) ; Delete highest item from main list,
size (- size 1) ; and reduce size of main list
)
)
(cons (car LST) tmplst) ; Add last (lowest) item to start and return
) ; End sortlist
;; ---------------------------------------------------------------------------
;; Function: str_num_sort
;; Purpose : Sorts a list of layouts into tab number order.
;; Params : LST: list of sublists to sort. Each sublist contains a tab
;; number index integer and a layout name string.
;; ---------------------------------------------------------------------------
(defun str_num_sort (LST / split_str_num str_num_compare)
;; ---------------------------------------------------------------------------
;; Function: split_str_num
;; Purpose : Divides a string into 3 parts: string prefix, numeric middle and
;; string suffix.
;; Params : STR: string to split
;; Local : #: loop counter/character index
;; ch: current character
;; slen: string length
;; s1: string prefix
;; s2: string containing numeric middle
;; s3: string prefix
;; Returns : Always a list containing a string, a real and a string. If any of
;; these elements do not exist, defaults of "", 0.0 and "" are used.
;; ---------------------------------------------------------------------------
(defun split_str_num (STR / # ch slen s1 s2 s3)
(setq
# 0
slen (strlen STR)
s1 ""
)
(while (and (<= (setq # (1+ #)) slen) (not s3))
(if (wcmatch (setq ch (substr STR # 1)) "[0123456789.]")
(if s2
(setq s2 (strcat s2 ch))
(setq s2 ch)
)
(if s2
(setq s3 (substr STR # 1))
(setq s1 (strcat s1 ch))
)
)
)
(list s1 (if s2 (atof s2) 0.0) (if s3 s3 ""))
) ; End split_str_num
;; ---------------------------------------------------------------------------
;; Function: str_num_compare
;; Purpose : Compares 2 lists. Each list contains a tab number index integer
;; and a layout name string. The tab number is ignored and the
;; layout name string is divided into 3 parts: string prefix,
;; numeric middle and string suffix. The comparison is then performed
;; on the first then second, then third items, then on the string as
;; a whole.
;; Params : X, Y: lists to compare
;; Local : xlist: list of 3 parts derived from X layout name string
;; ylist: list of 3 parts derived from Y layout name string
;; Returns : T if X < Y, else nil.
;; ---------------------------------------------------------------------------
(defun str_num_compare (X Y / xlist ylist)
(setq
xlist (split_str_num (cadr X))
ylist (split_str_num (cadr Y))
)
(if (= (car xlist) (car ylist)) ; if 1st are equal
(if (= (cadr xlist) (cadr ylist)) ; if 2nd are equal
(if (= (caddr xlist) (caddr ylist)) ; if 3rd are equal
(< (cadr X) (cadr Y)) ; then ascending on whole string
(< (caddr xlist) (caddr ylist)) ; else ascending on 3rd
)
(< (cadr xlist) (cadr ylist)) ; else ascending on 2nd
)
(< (car xlist) (car ylist)) ; else ascending on 1st
)
) ; End str_num_compare
;; Start str_num_sort --------------------------------------------------------
(reverse (sortlist LST 'str_num_compare))
) ; End str_num_sort
;; ---------------------------------------------------------------------------
;; Function: tab_sort
;; Purpose : Sorts a list of layouts into tab number order.
;; Params : LST: list of sublists to sort. Each sublist contains a tab
;; number index integer and a layout name string.
;; Local : #: index integer counter
;; retlst: sorted list to return
;; ---------------------------------------------------------------------------
(defun tab_sort (LST / # retlst)
(setq # 1)
(while (< (length retlst) (length LST))
(foreach one LST
(if (= (car one) #)
(setq
retlst (cons one retlst)
# (1+ #)
)
)
)
)
retlst
) ; End tab_sort
;; Start plotall_layouts -----------------------------------------------------
(vl-load-com)
(setq
curdwg (vla-get-ActiveDocument (vlax-get-Acad-Object))
layout-array (vlax-make-safearray vlax-vbString '(0 . 0))
)
(vlax-for layout (vla-get-Layouts curdwg)
(if (/= (vla-get-Name layout) "Model")
(setq
layout-list
(cons
(list (vla-get-TabOrder layout) (vla-get-Name layout))
layout-list
)
)
)
)
(cond
((= ORDER "Numeric")
(setq layout-list (str_num_sort layout-list))
)
((= ORDER "Tab")
(setq layout-list (tab_sort layout-list))
)
)
(if (not REV) ; Layout list to be reversed?
(setq layout-list (reverse layout-list))
)
(foreach layout layout-list
(prompt
(strcat
"\nPlotting layout " (itoa (car layout)) ", \""
(cadr layout) "\"...\n"
)
)
(setq
layout-array (vlax-safearray-fill layout-array (cdr layout))
plot (vla-get-Plot curdwg)
)
(vla-SetLayoutsToPlot plot layout-array)
(vla-put-NumberOfCopies plot QTY)
(setq errmsg (vl-catch-all-apply 'vla-PlotToDevice (list plot DEVICE)))
(if (vl-catch-all-error-p errmsg)
(prompt
(strcat
"\nERROR: Plot failed due to following condition:\n "
(vl-catch-all-error-message errmsg)
"\n"
)
)
)
)
(princ)
) ; End plotall_layouts
(princ)
;;; ==========================================================================
;;; End PLOTALL.LSP
;;; ==========================================================================
Comes with a dialog box too.
//// -------------------------------------------------------------------------
//// File : PlotAll.dcl
//// Author : Steve Johnson
//// Purpose : Dialogue box definition for PLOTALL command.
//// -------------------------------------------------------------------------
/// --------------------------------------------------------------------------
/// Turn off error checking
/// --------------------------------------------------------------------------
dcl_settings : default_dcl_settings { audit_level = 0; }
/// --------------------------------------------------------------------------
/// Widget: plotall_main
/// This is the main PLOTALL dialogue box.
/// --------------------------------------------------------------------------
plotall_main : dialog {
label = "PlotAll.lsp - Plots all layouts in current drawing";
: popup_list {
key = "device_list";
label = "Device ";
}
spacer;
: row {
: popup_list {
key = "order_list";
label = "Order ";
}
: toggle {
key = "reverse";
label = "Reverse";
}
}
spacer;
: edit_box {
key = "quantity";
label = "Quantity";
}
spacer;
ok_cancel;
errtile;
}
/// --------------------------------------------------------------------------
/// End PlotAll.dcl
/// --------------------------------------------------------------------------