Need Assistance Creating a Lisp To Set the Active Layout

Need Assistance Creating a Lisp To Set the Active Layout

tim_crouse
Collaborator Collaborator
2,446 Views
16 Replies
Message 1 of 17

Need Assistance Creating a Lisp To Set the Active Layout

tim_crouse
Collaborator
Collaborator

I am trying to create a lisp to add to the acad startup suit that will force the first layout to become the active layout when the drawing is first opened.

 

Here is what I have so far, but it does not seem to do anything, nor does it generate an error:

 

Best Regards

-Tim C.

 

;; add this to the acad starup suit to force the first layout to be the active layout tab
(defun SetFirstLayoutActive ()
(vl-load-com)
(if (setq layout (car (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object)))))
(vla-put-ActiveLayout (vla-get-activedocument (vlax-get-acad-object)) layout)
(prompt "No layouts found.")
)
)

;; call example
;; (SetFirstLayoutActive)

0 Likes
2,447 Views
16 Replies
Replies (16)
Message 2 of 17

pendean
Community Legend
Community Legend

pendean_0-1715019905642.png

 

0 Likes
Message 3 of 17

DGCSCAD
Advisor
Advisor

Quick solution is to use the predefined function "layoutlist", and grab the first element:

 

(setq 1stLayout (car (layoutlist)))
(command "_.layout" "s" 1stLayout)

AutoCad 2018 (full)
Win 11 Pro
0 Likes
Message 4 of 17

john.uhden
Mentor
Mentor

@DGCSCAD & @tim_crouse ,

Even easier...

Command: (setvar "ctab" (car (layoutlist)))
"Layout1"

John F. Uhden

0 Likes
Message 5 of 17

CodeDing
Mentor
Mentor

Maybe not the fastest, but you could use this and it'll work every time:

;; Forces the first layout to be the active layout tab
(defun SetFirstLayoutActive ( / LayoutListOrdered)
  (defun LayoutListOrdered ( / dLays lays oLays cnt)
    (setq dLays (cdr (assoc -1 (dictsearch (namedobjdict) "ACAD_LAYOUT"))))
    (setq lays (mapcar '(lambda (l) (cons (cdr (assoc 71 (dictsearch dLays l))) l)) (layoutlist)))
    (repeat (1- (setq cnt (1+ (length lays))))
      (setq oLays (cons (cdr (assoc (setq cnt (1- cnt)) lays)) oLays))
    );repeat
  );defun
  (setvar 'CTAB (car (LayoutListOrdered)))
  (princ)
)

 

P.S. There will ALWAYS be at least 1 layout tab.

0 Likes
Message 6 of 17

CodeDing
Mentor
Mentor

@john.uhden wrote:

@DGCSCAD & @tim_crouse ,

Even easier...

Command: (setvar "ctab" (car (layoutlist)))
"Layout1"


It seems like a lot of people forget that the (layoutlist) function does NOT always return the correct order of the layouts!

0 Likes
Message 7 of 17

komondormrex
Mentor
Mentor

the first member of the collection must be gotten via vla-item, not a car.

this should work.

 

 

(defun SetFirstLayoutActive (/ layout)
	(if (setq layout (vla-item (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object))) 0))
		(vla-put-ActiveLayout (vla-get-activedocument (vlax-get-acad-object)) layout)
		(prompt "No layouts found.")
	)
	(princ)
)

 

 

 

0 Likes
Message 8 of 17

CodeDing
Mentor
Mentor

@komondormrex wrote:

 

(defun SetFirstLayoutActive (/ layout)
	(if (setq layout (vla-item (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object))) 0))
		(vla-put-ActiveLayout (vla-get-activedocument (vlax-get-acad-object)) layout)
		(prompt "No layouts found.")
	)
)

 


^^^ This code will also NOT always set the first layout tab to current

Message 9 of 17

komondormrex
Mentor
Mentor

@CodeDing wrote:

^^^ This code will also NOT always set the first layout tab to current


like when? 

0 Likes
Message 10 of 17

CodeDing
Mentor
Mentor

Not everybody creates layouts and leaves them in their original positions. It is common for many companies to have templates with multiple premade layouts which have been rearranged in some way. So for cautions sake, we should try to account for this.

 

LayoutOrder.gif

Message 11 of 17

john.uhden
Mentor
Mentor

@CodeDing ,

I haven't used it in 20 years, but by Jove, your'e right!

John F. Uhden

Message 12 of 17

paullimapa
Mentor
Mentor

Attached is dwg with first Layout shown on dwg screen as "Page-1"

paullimapa_0-1715030403040.png

Using @komondormrex code:

(defun SetFirstLayoutActive (/ layout)
	(if (setq layout (vla-item (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object))) 0))
		(vla-put-ActiveLayout (vla-get-activedocument (vlax-get-acad-object)) layout)
		(prompt "No layouts found.")
	)
)

(SetFirstLayoutActive) will make Layout "A" active but that's not the first listed.

Now using @CodeDing code:

(defun SetFirstLayoutActive ( / LayoutListOrdered)
  (defun LayoutListOrdered ( / dLays lays oLays cnt)
    (setq dLays (cdr (assoc -1 (dictsearch (namedobjdict) "ACAD_LAYOUT"))))
    (setq lays (mapcar '(lambda (l) (cons (cdr (assoc 71 (dictsearch dLays l))) l)) (layoutlist)))
    (repeat (1- (setq cnt (1+ (length lays))))
      (setq oLays (cons (cdr (assoc (setq cnt (1- cnt)) lays)) oLays))
    );repeat
  );defun
  (setvar 'CTAB (car (LayoutListOrdered)))
  (princ)
)

(SetFirstLayoutActive) now properly makes Layout "Page-1" active.

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 13 of 17

john.uhden
Mentor
Mentor

Blast it all!!

I had the solution all written, but not saved, when I caught an authentication error hitting the Post button.

If you guys and gals don't figure it out, then I'll have to reconstruct it from my Autolog.

Okay, here it is per the log file.  Clean it up and try it out.

It all has to do with each layout's TabOrder.

Command: (defun GetLayoutbyOrder ( # / j doc layouts Layout Name)
(_>   ;; where # is the nth layout in order of
(_>   ;;   the layout names as displayed
(_>   ;;   from left to right, counting from 0.
(_>   ;;   "Model" is always the first or 0th.
(_>   ;; Where # is higher than 1- the number of layouts,
(_>   ;;   the function will return nil.
(_>   (setq doc (vla-get-activedocument (vlax-get-acad-object)))
(_>   (setq layouts (vla-get-layouts doc))
(_>   (setq Count (vlax-get layouts 'Count) j -1)
(_>   (while (and (not Name)(< (setq j (1+ j)) Count))
((_>     (setq layout (vla-item layouts j))
((_>     (if (= # (vlax-get layout 'TabOrder))
(((_>       (setq Name (vlax-get layout 'Name))
(((_>     )
((_>   )
(_> )

 

John F. Uhden

0 Likes
Message 14 of 17

komondormrex
Mentor
Mentor

is that better?

(defun set_first_layout_active (/ layout_collection tab_list)
	(setq layout_collection (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object))))
	(vlax-for layout layout_collection
		(setq tab_list (append tab_list (list (cons (vla-get-taborder layout) layout))))
	)
	(setq tab_list (vl-sort tab_list '(lambda (layout_1 layout_2) (< (car layout_1) (car layout_2)))))  
	(vla-put-activeLayout (vla-get-activedocument (vlax-get-acad-object)) (cdadr tab_list))
	(princ)
)
0 Likes
Message 15 of 17

paullimapa
Mentor
Mentor

Bingo!!!


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 16 of 17

komondormrex
Mentor
Mentor

@CodeDing @john.uhden

i did suspect that, hence i rewrote the code supposedly generated by almighty chatgpt. 

Message 17 of 17

Sea-Haven
Mentor
Mentor

My $0.05,note creation date.

 

 

; 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)
 (if (not AH:getvalsm)(load "Multi Getvals.lsp"))
(setq num (atoi (nth 0  (AH:getvalsm (list "Go To A Layout" "Enter layout number" 5 4 "1")))))
(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

 

Multi getvals save to a support path so auto loads.

 

SeaHaven_0-1715126571680.png

 

0 Likes