Swap between first and last layouts

Swap between first and last layouts

h_s_walker
Mentor Mentor
923 Views
17 Replies
Message 1 of 18

Swap between first and last layouts

h_s_walker
Mentor
Mentor

Ok so the code below is what I've got, but I'm sure there's a more efficient way.

What I want to do is count how many layouts are in a drawing and swap between the first and last layouts (no matter what they're called)

Also if it's not the first layout selected it needs to swap to that first.

The code below uses some variables from other code that people helped me with.

I'm using AutoCAD LT 2025

 

(defun c:ToggleFirstLastLayout ()
(vl-load-com)
;;  (setq layoutNames '()) ; Initialize an empty list to hold layout names
  (setq layouts (vla-get-Layouts (vla-get-ActiveDocument (vlax-get-acad-object)))) ; Get all layouts

(setq listlayouts (layorder))  
  (setq firstLayout (car listlayouts)) ; Get the first layout
    (setq lastLayout (last listlayouts)) 
  (setq layoutCount (vla-get-Count layouts))


  (setq numLayouts (vla-get-Count layouts))

  (if (> numLayouts 1)
    (progn
      (setq currentLayoutName (getvar "CTAB")) ; Get current layout name

      (if (= currentLayoutName (car listlayouts))
          (progn
            (command "_-LAYOUT" "SET" (last listlayouts)) ; Switch to last layout
          )
          (progn
            (command "_-LAYOUT" "SET" (car listlayouts)) ; Switch to first layout
          )
      )
    )
    (princ "\nThere are less than two layouts (excluding ModelSpace).")
  )
  (princ)
)

 

Howard Walker
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Left Handed and Proud

0 Likes
Accepted solutions (1)
924 Views
17 Replies
Replies (17)
Message 2 of 18

Brock_Olly
Collaborator
Collaborator

I asked gemini for you, perhaps he (it?) holds the answers.

https://g.co/gemini/share/91cd185a7a6a

0 Likes
Message 3 of 18

ВeekeeCZ
Consultant
Consultant

Few notes.

* missing (layorder) sub

* variables not localized!

* why is info that there isn't 2+ layouts important?

* I don't understand why you're looking for an efficient way - are you going to switch it 100 times per second? If it works and you wrote it yourself, just be happy about it. We can write you 10 versions a few milliseconds faster than yours, will you be happier?

 

 

 

0 Likes
Message 4 of 18

h_s_walker
Mentor
Mentor

@ВeekeeCZ 

The variables are loaded up in the startup app suite.

As I've said in other threads I'm a newb on lisp. If it was VBA I could write it myself easily.

As you hsve pointed out it's not very efficient not having variables local to the lisp. It will break if somene accidently deletes the relevant lisp from the startup app

Howard Walker
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Left Handed and Proud

0 Likes
Message 5 of 18

ВeekeeCZ
Consultant
Consultant

@h_s_walker wrote:

@ВeekeeCZ 

The variables are loaded up in the startup app suite.

variables? You probably mean that missing subfunction. Ok, but if you post something to revise, you should post all of it.

 

As I've said in other threads I'm a newb on lisp. If it was VBA I could write it myself easily.

Sure, but does it really need to be the most efficient code possible? Rather, focus on correctness, readability, simplicity, functionality. Efficiency is the result of experience... It's better to fully understand (and possibly fix) the less efficient code that otherwise.

 

As you hsve pointed out it's not very efficient not having variables local to the lisp. It will break if somene accidently deletes the relevant lisp from the startup app

Localization is not so much about efficiency (nowadays we all have plenty of RAM) but rather about preventing errors and interferences.

 


 

0 Likes
Message 6 of 18

h_s_walker
Mentor
Mentor

@ВeekeeCZ I'm a total newb with lisp. I need as much help as possible

@Brock_Olly I used ChatGTP. Also I've just tried that and LT doesn't like vl-item

Howard Walker
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Left Handed and Proud

0 Likes
Message 7 of 18

ВeekeeCZ
Consultant
Consultant

Oh, that explains a lot. So never mind what I've said.

0 Likes
Message 8 of 18

cadffm
Consultant
Consultant

 

First of all: Thank you, apart from the missing custom function layorder, a good post.

Program name & version
Source code, all necessary code must be included here / was probably an oversight.
You can program (vba), are familiar with forums, that makes it fun to answer.

 

>>"but I'm sure there's a more efficient way"

What is efficient? Sure, you can skip some variable

(setq currentLayoutName (getvar "CTAB")) ; Get current layout name

(if (= currentLayoutName (car listlayouts))

vs

(if (= (getvar "CTAB") (car listlayouts))

 

 

and unneeded statement like both "(progn...)",

but for this task, ir doesn't hurts! I wouldn't change the code because of the efficient question, it's fine.

 


There is NO real need of the count, and 100% no need for 2x
(setq layoutCount (vla-get-Count layouts))
(setq numLayouts (vla-get-Count layouts))

 

What is ALWAYS TRUE, because (vla-get-Count layouts) is incl MODEL layout and you have minimum 1 Paperspace layout = 2minimum
(if (> numLayouts 1)



Use the english command&options, or use the international calls (prefered),
to use _-LAYOUT followed by SET, doesn't make sense.
(command "_-LAYOUT" "SET"

vs

(command ".-LAYOUT" "SET" englisch ONLY

(command "_.-LAYOUT" "_SET" international

 

 

---

 

<<"and LT doesn't like vl-item"

No Autodesk product like "vl-item", that's AI 

 

@cadffm - this post has been edited due to Community Rules & Etiquette violation

Sebastian

0 Likes
Message 9 of 18

ВeekeeCZ
Consultant
Consultant

Good post, but wrong recipient. That should be OpenAI.

0 Likes
Message 10 of 18

cadffm
Consultant
Consultant

?

I only responded to posts from h_s_walker.

But maybe I understand everything a little less well today, I'm sick in bed and shouldn't be concerned with CAD

Sebastian

0 Likes
Message 11 of 18

komondormrex
Mentor
Mentor

@h_s_walker 

hoping this will do the job in lt

 

(defun c:ToggleFirstLastLayout (/ layout_list first_last_list)
		(vlax-map-collection (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object)))
		'(lambda (layout) (setq layout_list (append layout_list (list (list (vla-get-taborder layout) layout)))))
	)
	(princ "\nTotal amount of layouts is: ")
	(princ (1- (length layout_list)))
	(if (< 2 (length layout_list)) 
		(progn
			(setq layout_list (cdr (vl-sort layout_list '(lambda (l1 l2) (< (car l1) (car l2)))))
				  first_last_list (reverse (list (car layout_list) (last layout_list)))
				  layout_list (subst (list (car (car layout_list)) (cadr (car first_last_list))) (car layout_list) layout_list)
				  layout_list (subst (list (car (last layout_list)) (cadr (cadr first_last_list))) (last layout_list) layout_list)
			)
			(mapcar '(lambda (layout) (vla-put-taborder (cadr layout) (car layout))) layout_list)
			(princ "\nLayouts \"")
			(princ (vla-get-name (cadr (car layout_list))))
			(princ "\" and \"")
			(princ (vla-get-name (cadr (last layout_list))))
			(princ "\" were swapped")
		)
	)
	(princ)
)

 

0 Likes
Message 12 of 18

h_s_walker
Mentor
Mentor

@komondormrex unfortunately that's not what I want.

I don't want the layouts to swap. I want the layouts to stay in the same order and either the first or last layout to be selected.

Howard Walker
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Left Handed and Proud

0 Likes
Message 13 of 18

pendean
Community Legend
Community Legend

@h_s_walker wrote:

I don't want the layouts to swap...


But that's the title of your post AND the body of your initial post... literally. Go ahead and change them now to TOGGLE perhaps.

 

Looks like you just want the ability to jump between first and last layout with a LISP after counting the total because you don't use SSM at all where they would be a click away, is that correct?

 

0 Likes
Message 14 of 18

cadffm
Consultant
Consultant

He already has a working code,

the question was whether it could be made more efficient or not.

Sebastian

0 Likes
Message 15 of 18

komondormrex
Mentor
Mentor
Accepted solution

understood. just like that?

 

(defun c:Toggle_First_Last_Layout (/ layout_list)
	(vlax-map-collection (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object)))
		'(lambda (layout) (setq layout_list (append layout_list (list (list (vla-get-taborder layout) layout)))))
	)
	(princ "\nTotal amount of layouts is: ")
	(princ (1- (length layout_list)))
	(if (< 2 (length layout_list)) 
		(progn
			(cond
				((= 1 (vla-get-taborder (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object)))))
					(vla-put-activelayout (vla-get-activedocument (vlax-get-acad-object)) (cadr (assoc (1- (length layout_list)) layout_list)))
				)
				((= (1- (length layout_list)) (vla-get-taborder (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object)))))
					(vla-put-activelayout (vla-get-activedocument (vlax-get-acad-object)) (cadr (assoc 1 layout_list)))
				)
				(t (vla-put-activelayout (vla-get-activedocument (vlax-get-acad-object)) (cadr (assoc 1 layout_list))))
			)
			(princ "\nCurrent layout toggled to \"")
			(princ (vla-get-name (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object)))))
			(princ "\"")
	  	)
	)
	(princ)
)

 

 

Message 16 of 18

komondormrex
Mentor
Mentor

command methods not the best idea to work with the layouts toggling. anyway it was fun to write that.

0 Likes
Message 17 of 18

h_s_walker
Mentor
Mentor

@komondormrex just what I wanted. Thank you

Howard Walker
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Left Handed and Proud

0 Likes
Message 18 of 18

Sea-Haven
Mentor
Mentor

I have used this for years, you can go to any layout, use 1 for first and a big number for last, it also supports go to Model use 0. Needs multi getvals.lsp. 

 

; GOTO layout just like other goto a page
; By Alan H 2013
; menu command [GOTO]^c^C^p(load "goto")
; enter a big number like 99 to jump to last if 100+ layouts then 123 etc
; Model space is 0 zero GOTO 0

(defun C:goto ( / x alllayouts laynum num)
(setq dcl (vl-filename-mktemp nil nil ".dcl") )
(setq des (open dcl "w") )
(foreach x 
'(
"ddgetvalAH : dialog {"
"	label =\"Go To A Layout\" ;"
" : column {"
" width =25;"
"spacer_1 ;"
": edit_box {"
"    key = \"key1\";"
" label = \"Enter layout number\";"
"     edit_width = 5;"
"     edit_limit = 4;"
"   is_enabled = true ;"
"   allow_accept=true ;"
"    }"
"    }"
"spacer_1 ;"
"ok_cancel;}"
)
(write-line x des)
); foreach
(close des)
(setq dcl_id (load_dialog dcl))
  (if (not (new_dialog "ddgetvalAH" dcl_id))
    (exit)
  )
  (setq but "key1")
  (action_tile "accept" "(setq num (atoi (get_tile but)))(done_dialog)")
  (action_tile "cancel" "(done_dialog)")
  (start_dialog)
  (unload_dialog dcl_id)
 (vl-file-delete dcl)

(setq alllayouts (vla-get-Layouts (vla-get-activedocument (vlax-get-acad-object))))
(SETQ LAYNUM 0)
(vlax-for x alllayouts
(Setq laynum (+ 1 laynum))
) ;total number of layouts
(if (> num laynum)
(setq num (- laynum 1))
)
(vlax-for lay alllayouts
(if (= num (vla-get-taborder lay))
(setvar "ctab" (vla-get-name lay))
)
)
)

; I often type it wrong so added this one also
(defun C:goot ()
(c:goto)
) ; defun

 

 

SeaHaven_0-1739235497672.png

 

0 Likes