unusualbread Posted June 28, 2023 Posted June 28, 2023 Hello, I am looking to get some help hopefully in updating this LISP as below that i found online. it NEARLY does what i need it to do, but it requires the first layout to start with a '0' for some reason. I am basically always looking to create several layout tabs incrementally named as 1, 2, 3, 4, ... 10, 11, 12 etc. For some reason this will not work unless i put a '0' in front of the '1' layout for copying. I don't wish to have a 0 in front of each number. along with this, when it does work, it seems to randomly place the tabs, as opposed to tacking the latest one onto the end. is there any way to fix that as well? I'm also using AutoCAD 2024 LT (thank goodness they added LISPs!!) Thanks in advance!!! (defun c:cnl (/ num idx old bas new) (if (and (= 0 (getvar 'tilemode)) ; make sure some layout is current (setq num (getint "\nNumber of copies of this tab: ")) (setq idx (getint "\nFirst suffix number: ")) (setq old (getvar 'ctab)) ; current name of layout (> (strlen old) 1) ; current name is longer the 1 character (setq bas (substr old 1 (- (strlen old) 2))) ; cut last 2 chars for current name to make base name ) (repeat num (setq str (itoa idx) ; make string of suffix integer str (if (= 1 (strlen str)) ; if is only 1 digit long... (strcat "0" str) ; ... add 0 before str) new (strcat bas str)) ; new name = base + string (if (member new (layoutlist)) ; is the new name already used for layout? (princ (strcat "\nLayout '" new " ' already exists.")) (command "._LAYOUT" "_Copy" old (strcat old ".") ; copy current tab, for new tab would be used dummy name (old + .) to make sure that new layout would be always right behing the old one "._LAYOUT" "_Rename" (strcat old ".") new)) ; rename dummy layout with real new name. (setq idx (1+ idx) ; add 1 to index old new))) ; set new name to old for next copy. (princ) ) Quote
Lee Mac Posted June 28, 2023 Posted June 28, 2023 The following should handle any layout naming convention, either retaining or ignoring leading zeroes: (defun c:copylayout ( / cmd lyt new ) (cond ( (= 1 (getvar 'tilemode)) (princ "\nCommand only available in paperspace.") ) ( (setq cmd (getvar 'cmdecho) lyt (getvar 'ctab) new lyt ) (setvar 'cmdecho 0) (repeat (progn (initget 6) (cond ((getint "\nNumber of layouts to create <1>: ")) (1)) ) (while (member (setq new (LM:suffix++ new)) (layoutlist))) (vl-cmdf "_.-layout" "_c" lyt new) (setq lyt new) ) (setvar 'cmdecho cmd) ) ) (princ) ) (defun LM:suffix++ ( str ) (cond ( (wcmatch str "~*#") (strcat str "1") ) ( (wcmatch str "*9") (strcat (LM:suffix++ (substr str 1 (1- (strlen str)))) "0") ) ( (strcat (substr str 1 (1- (strlen str))) (chr (1+ (ascii (substr str (strlen str))))) ) ) ) ) (princ) I don't think LT fully supports VL/ActiveX, and so the automatic layout ordering may not be possible, but on the off-chance that it does, give this a try: (defun c:sortlayouts ( / lst ord tab ) (vlax-for lyt (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object))) (if (= :vlax-false (vla-get-modeltype lyt)) (setq lst (cons lyt lst) ord (cons (strcase (vla-get-name lyt)) ord) ) ) ) (setq tab 1) (foreach idx (vl-sort-i ord 'compare) (vla-put-taborder (nth idx lst) tab) (setq tab (1+ tab)) ) (princ) ) (defun compare ( a b / x y ) (setq x (ascii a) y (ascii b) ) (cond ( (zerop x)) ( (zerop y) nil) ( (= x y) (compare (substr a 2) (substr b 2))) ( (and (< 47 x 58) (< 47 y 58)) (< (atof a) (atof b)) ) ( (< x y)) ) ) (vl-load-com) (princ) 3 Quote
unusualbread Posted July 10, 2023 Author Posted July 10, 2023 (edited) Thank you! this works well (including the layout sorting)! the only question is, is there a way to do the sort layouts, based on selected layouts? Edited July 10, 2023 by unusualbread Quote
BIGAL Posted July 11, 2023 Posted July 11, 2023 Hmm (vlax-for lyt (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object))) (if (= :vlax-false (vla-get-modeltype lyt)) (setq lst (cons lyt lst) ord (cons (strcase (vla-get-name lyt)) ord) ) ) ) ("D03" "D02" "D01") (setq lst (layoutlist)) ("D01" "d02" "d03") Quote
Lee Mac Posted July 11, 2023 Posted July 11, 2023 (edited) 10 hours ago, BIGAL said: Hmm (vlax-for lyt (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object))) (if (= :vlax-false (vla-get-modeltype lyt)) (setq lst (cons lyt lst) ord (cons (strcase (vla-get-name lyt)) ord) ) ) ) ("D03" "D02" "D01") (setq lst (layoutlist)) ("D01" "d02" "d03") Consider that lst contains the layout objects in my code, not the layout names; ord contains the corresponding layout names and is used as a sorting index. Note that you can't rely on (layoutlist) matching the layout order - observe: Edited July 11, 2023 by Lee Mac Quote
Steven P Posted July 11, 2023 Posted July 11, 2023 4 hours ago, Lee Mac said: Note that you can't rely on (layoutlist) matching the layout order - observe: Did I read somewhere that layout order as shown above is the creation order and not the order it is displayed? Or did I make that up? Quote
Lee Mac Posted July 11, 2023 Posted July 11, 2023 9 minutes ago, Steven P said: Did I read somewhere that layout order as shown above is the creation order and not the order it is displayed? Or did I make that up? You might be right, but either way, without visibility of the implementation, I personally don't rely on the order of layouts returned by (layoutlist). 1 Quote
BIGAL Posted July 12, 2023 Posted July 12, 2023 Good point about creation order, did not check that. Thanks. Quote
Steven P Posted July 12, 2023 Posted July 12, 2023 6 hours ago, BIGAL said: Good point about creation order, did not check that. Thanks. I checked just before home time, that was something my mind made up to trick me..... Quote
Recommended Posts
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.