Cycle Current Layer up or down the Layer List

Cycle Current Layer up or down the Layer List

Anonymous
Not applicable
2,688 Views
17 Replies
Message 1 of 18

Cycle Current Layer up or down the Layer List

Anonymous
Not applicable

Hello,

 

I'm trying to figure a way to switch the current layer up/down the layer list by 1 layer, in attempt to bind a lisp or macro to Page Up and Page Down keys on my keyboard.

 

Does anyone have a lisp built for handling something like this? Autocad doesn't seem to have anything built in to acheive this.

 

And I've tried binding marcos to my keyboard keys via the keyboard software (Razer) and using ALT+H etc. but since I use the menu bar it doesn't get to the ribbon to hit the Home tab. (Idea was to bind a macro for Alt+H, LA, Up Arrow, ESC)

 

Cheers

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

pendean
Community Legend
Community Legend
0 Likes
Message 3 of 18

Anonymous
Not applicable

This really has nothing to do with what I was asking.

Message 4 of 18

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

.... 

I'm trying to figure a way to switch the current layer up/down the layer list by 1 layer....


Are you talking about only changing what the current Layer is, without any other operations such as turning off other Layers?  The LAYWALK command [an Express Tool in earlier versions, somewhere along the way made into a "native" command] lets you step up and down through the Layer list with the up and down arrow keys, setting each Layer current and turning off all others as you go, if that will do for you -- you "walk" through the Layers and see each one isolated.  It has an option to leave you with the one you're looking at current and isolated when you close it, or revert to whatever the situation was when you started.  But if you just want to change the current Layer but leave others displayed, that shouldn't be difficult to make a routine to do.  It would involve making a list of Layer names, sorting it alphabetically instead of in creation order if that's what you need, then for the stepping, finding the position of the current Layer in that list and making the one either before or after it current instead.

Kent Cooper, AIA
0 Likes
Message 5 of 18

Anonymous
Not applicable

Kent, yes I am trying to cycle trough without changing anything else. For a short and sweet explaination; I want to press "BUTTON X" to set the current layer one up layer in the list, and "BUTTON Y" to set current down one. 

 

I've recently discovered LAYWALK, very usefully command, but it doesn't do what I am trying to do.

 

I was trying to avoid having to write a new LISP myself, but I'll start one up when I get some downtime at the office.

 

Thank you for the input.

0 Likes
Message 6 of 18

ВeekeeCZ
Consultant
Consultant

The LISP could be like this. What shortcut you assign to this in CUI is up to you.

 

(defun c:LayerNext (/ a b c d e )
  (while (setq a (tblnext "LAYER" (null a)))
    (if (not (wcmatch (cdr (assoc 2 a)) "*|*"))
      (setq b (cons (cdr (assoc 2 a)) b))))
  (setq b (acad_strlsort b)
	e (cond ((cadr (member (getvar 'CLAYER) b)))
		((car b))))
  (setvar 'CLAYER e)
  (princ)
)

(defun c:LayerPrevious (/ a b c d e )
  (while (setq a (tblnext "LAYER" (null a)))
    (if (not (wcmatch (cdr (assoc 2 a)) "*|*"))
      (setq b (cons (cdr (assoc 2 a)) b))))
  (setq b (acad_strlsort b)
	e (cond ((cadr (member (getvar 'CLAYER) (reverse b))))
		((car (reverse b)))))
  (setvar 'CLAYER e)
  (princ)
)

Based on @Lee_Mac's code found here. Thanks for that.

Message 7 of 18

M_Hensley
Advisor
Advisor

As for assigning macros to a key in AutoCAD, AutoHOOK makes anything possible.

 

http://www.command-digital.com/autohook.htm

 

 

Message 8 of 18

Kent1Cooper
Consultant
Consultant

@Kent1Cooper wrote:
... that shouldn't be difficult to make a routine to do.  It would involve making a list of Layer names, sorting it alphabetically instead of in creation order if that's what you need, then for the stepping, finding the position of the current Layer in that list and making the one either before or after it current instead.

Another approach, that eliminates repetitions by pulling the repetitive parts out into functions that are called by the actual commands:

 

(defun laylist (/ lay)
  (while (setq lay (cdadr (tblnext "layer" (not lay))))
    (if (not (wcmatch lay "*|*")) (setq lays (cons lay lays)))
  )
  (setq
    lays (acad_strlsort lays); omit if you don't want them alphabetical

    clay (getvar 'clayer)
  )
)

 

(defun laych ()
  (setvar 'clayer
    (cond
      ((cadr (member clay lays)))
      ((car lays))
    )
  )
)

 

(defun C:L> (/ lays clay)
  (laylist)
  (laych)
)

 

(defun C:L< (/ lays clay)
  (laylist)
  (setq lays (reverse lays))
  (laych)
)

 

EDIT:  Would there ever be the possibility of Frozen Layers?  Both BeekeeCZ's and my routines will have a problem with those.  Should it check for that?  It could just leave them out of the list, or it could bypass them when it comes to them in stepping and go on to the next, or it could Thaw them, or it could report that it can't set the next Layer current and leave the present current Layer, or it could ask whether you want to Thaw it, or .....

Also, if a Layer is Off, it can set it current, but is there any point?  Should it check for that, and what should it do with those Layers?

Kent Cooper, AIA
Message 9 of 18

Kent1Cooper
Consultant
Consultant
Accepted solution

@Kent1Cooper wrote:
....  Would there ever be the possibility of Frozen Layers?  ....

Here's a version with the same command names that bypasses any Frozen Layer(s), and notifies the User if it has done so.  It notifies the User of the new current Layer in any case [even though that will also be apparent in the Layer indicator in the Ribbon or Properties box or Layer pulldown].

Kent Cooper, AIA
Message 10 of 18

Anonymous
Not applicable

Thanks everyone, been a great help!

 

They all work great, I do like the idea of having the frozen bypassed and alerted. Thanks for that Kent.

 

Cheers

0 Likes
Message 11 of 18

lecheconagujas
Participant
Participant

Sorry about reviving this old thread, I was just looking for this exact functionality and found this script. Is there a way to adapt it so that it will also move pre-selected objects (if any) between layers?

0 Likes
Message 12 of 18

Kent1Cooper
Consultant
Consultant

@lecheconagujas wrote:

.... Is there a way to adapt it so that it will also move pre-selected objects (if any) between layers?


 

Try the attached LayerStepsCSS.lsp [the CSS is for Change Selection Set].  Untested  [I'm on a computer without AutoCAD], so if it doesn't work, write back with any error messages or a description of what happened, and I'll try to fix it.

Kent Cooper, AIA
0 Likes
Message 13 of 18

lecheconagujas
Participant
Participant

Thanks for the quick reply!

I just tried it and I get this when I use L< or L> on a pre-selected object

Invalid option keyword.
; error: Function cancelled
Enter property to change [Color/LAyer/LType/ltScale/LWeight/Thickness/TRansparency/Material/Annotative]:

 It works as usual when nothing is selected

0 Likes
Message 14 of 18

Kent1Cooper
Consultant
Consultant

I'll be able to check later today, but for now, try taking the selection part [ ss "" ] out of this line:

 

(command "_.chprop" ss "" "_layer" lay ""); change to current Layer

 

Change to:

 

(command "_.chprop" "_layer" lay ""); change to current Layer

Kent Cooper, AIA
0 Likes
Message 15 of 18

Kent1Cooper
Consultant
Consultant

@Kent1Cooper wrote:

I'll be able to check later today....


... and did.  It seems to work.  Here's the revised version:

;;  LayerStepsCSS.lsp [command names: L> & L<]
;;  To Step through Layers, setting current the one after [L>] or the one
;;    before [L<] the current Layer in the alphabetical list of Layer names,
;;    and to Change a pre-selected Selection Set [if any] to that Layer.
;;    Notifies User of new current Layer.  If there is a pre-selection of object(s),
;;      changes them to that Layer.
;;  Only sets current -- does not e.g. turn all others off as LAYWALK does.
;;  Bypasses Frozen and Xref-dependent Layers [can't be set current], but
;;    not those that are Off.  Notifies User when bypassing Frozen Layer(s).
;;  Kent Cooper, 12 July 2020

(defun laylist (/ ldata lay)
  (while (setq ldata (tblnext "layer" (not ldata)))
    (if (not (wcmatch (setq lay (cdadr ldata)) "*|*")); not Xref-dependent
      (setq lays (cons lay lays)); list of all non-Xref-dependent Layers
    ); if
    (if (= (logand (cdr (assoc 70 ldata)) 1) 1); Frozen
      (setq layfr (cons lay layfr)); list of Frozen Layer(s)
    ); if
  ); while
  (setq lays (acad_strlsort lays))
); defun

(defun laych (/ lay layfrstr)
  (setq
    lay (getvar 'clayer)
    layfrstr "" ; initially empty
    ss (ssget "_I"); pre-selected object(s) if any
  ); setq
  (while
    (and
      (setq lay
        (cond
          ((cadr (member lay lays))); next one, or
          ((car lays)); back to beginning
        ); cond
      ); setq
      (member lay layfr); Frozen [stop (while) at un-Frozen Layer]
    ); and
    (setq layfrstr (strcat layfrstr " " lay)); add to string of Frozen Layer names, and
  ); while -- go on to next
  (setvar 'clayer lay)
  (if (/= layfrstr "") (prompt (strcat "\nBypassed Frozen Layer(s)" layfrstr ".")))
  (if ss ; pre-selection?
    (progn ; then
      (command "_.chprop" "_layer" lay ""); change to current Layer
      (sssetfirst nil ss); re-select/highlight/grip
    ); progn
  ); if
  (prompt
    (strcat
      "\nCurrent Layer set to"
      (if ss ", and object(s) moved to, " " ")
      lay
      "."
    ); strcat
  ); prompt
  (princ)
); defun

(defun C:L> (/ lays layfr clay)
  (laylist)
  (laych)
); defun

(defun C:L< (/ lays layfr clay)
  (laylist)
  (setq lays (reverse lays))
  (laych)
); defun

(prompt "\nType L> to make next Layer current, L< to make previous Layer current, and move selection (if any) to it.")

 

Kent Cooper, AIA
Message 16 of 18

lecheconagujas
Participant
Participant

Works like a charm, thanks a lot!

0 Likes
Message 17 of 18

Anonymous
Not applicable

How do I use the lsp file after I load that? Please explain in normal language. I am not a techy guy.

0 Likes
Message 18 of 18

Kent1Cooper
Consultant
Consultant

Both the beginning and the end of the code in Message 15, and of the file in Message 9 if that's what you're talking about, tell you.  [If you loaded the Code in Message 12, it needs the correction described in Message 14 and incorporated in Message 15.]

 

For any custom-defined command, the command name that you type in [or put into a macro in a Tool Palette button or something] is always the part immediately following the C and colon  in  (defun C:  .  In this case, there are two  commands defined in the file --   L<   is the command to go to the previous Layer name, and   L>   to go to the next one.  [It's a little unusual to include punctuation characters in command names, but some of them are allowed.]

Kent Cooper, AIA