Resetting variables at end of lisp routine

Resetting variables at end of lisp routine

Anonymous
Not applicable
3,461 Views
10 Replies
Message 1 of 11

Resetting variables at end of lisp routine

Anonymous
Not applicable

I have created a command whereby I want to save the users OSNAP settings, current LAYER, create and set a layer, then run the Autocad REVCLOUD command.  At the end of the routine, I want Autocad to return the OSNAP and current LAYER back to pre-command settings.

 

It seems to return the current layer back, but the osnap settings remain set to 0.  I'm a novice at lisp, obviously, and would like to know how you can run an autocad command within the middle of a lisp routine, and at the end of the command it still runs a few settings to be reset.

 

(The SLAY variable you see below is set in the command line in the CUIX menu file)

 

Also, when you hit ESCAPE halfway through the routine, is there a way it will return all the settings back to before the command was started?  Is it an error checking routine or something I need in it?

 

Can anybody look at it below and provide some direction.  It would be muchly appreciated!

 


(defun C:SREVCLOUD (/ CLAY OSM)
(setvar "cmdecho" 0)
(setq CLAY (getvar "clayer"))
(setq OSM (getvar "osmode"))
(setvar "snapmode" 0)
(setvar "osmode" 0)
(command "-Layer" "M" SLAY "C" "80" "" "" "")
(command "_revcloud" pause pause)
(setvar "clayer" CLAY)
(setvar "osmode" OSM)
)
(princ)
;_ end of defun

 

Thx.

Doug

0 Likes
Accepted solutions (1)
3,462 Views
10 Replies
Replies (10)
Message 2 of 11

ВeekeeCZ
Consultant
Consultant
;Add *error* function in that it automatically falls when is ERROR or ESC.



(defun C:REVCLOUD (/ *error* CLAY OSM CMD SNP)

(defun *error* (errmsg) ;runs automatically if error or ECS
(if (not (wcmatch errmsg "Function cancelled, quit / exit abort, console break"))
(princ (strcat "\nError: " errmsg)))

(setvar "clayer" CLAY)
(setvar "osmode" OSM)
(setvar "snapmode" SNP)
(setvar "cmdecho" CMD)
(princ)
)


(setq CMD (getvar "cmdecho"))
(setq CLAY (getvar "clayer"))
(setq OSM (getvar "osmode"))
(setq SNP (getvar "snapmode"))

(setvar "cmdecho" 0)
(setvar "snapmode" 0)
(setvar "osmode" 0)

(command "-Layer" "M" SLAY "C" "80" "" "" "")
(command "_revcloud")
(while (> (getvar 'CMDACTIVE) 0)
(command PAUSE))

(setvar "clayer" CLAY)
(setvar "osmode" OSM)
(setvar "cmdecho" CMD)
(setvar "snapmode" SNP)
)
(princ)
;_ end of defun
0 Likes
Message 3 of 11

ВeekeeCZ
Consultant
Consultant

BTW SLAY is some kind of global variable? You may use this.

 

(command "-Layer" "M" "ActualNameOfLayerThatBecomesTheCurrent" "C" "80" "" "" "")

0 Likes
Message 4 of 11

Anonymous
Not applicable
Thanks so much for the help! I'm going to try it this morning.

And yes, SLAY is a global variable. I run the revcloud command from a few different spots in my menu that need to place the cloud on a different layer. So I assign the layer name in the CUIX file for whichever layer corresponds to that particular call of the revcloud function. I hope I'm doing it properly? It seems to work.

Doug
0 Likes
Message 5 of 11

Anonymous
Not applicable
It seems to work great, except for the LAYER part. It doesn't seem to recognize making the LAYER asked for in the CUIX file (G-REV in this instance) and placing the revcloud on that layer, then returning the current layer to it's pre-command state.

It handles all the other variables perfectly, though. Retains the snaps nicely.

In the CUIX file, the command line reads as such:
^C^C(setq SLAY "G-REV");REVCLOUD

I've copied your input into my lisp file as such:

(defun C:REVCLOUD (/ *error* CLAY OSM CMD SNP)

(defun *error* (errmsg) ; runs automatically if error of ESC
(if (not (wcmatch errmsg "Function cancelled, quit / exit abort, console break"))
(princ (strcat "\nError: "errmsg)))
(setvar "clayer" CLAY)
(setvar "osmode" OSM)
(setvar "snapmode" SNP)
(setvar "cmdecho" CMD)
(princ)
)

(setq CMD (getvar "cmdecho"))
(setq CLAY (getvar "clayer"))
(setq OSM (getvar "osmode"))
(setq SNP (getvar "snapmode"))

(setvar "cmdecho" 0)
(setvar "snapmode" 0)
(setvar "osmode" 0)

(command "-Layer" "M" SLAY "C" "80" "" "" "")
(command "_revcloud")
(while (> (getvar 'CMDACTIVE) 0)
(command PAUSE))

(setvar "clayer" CLAY)
(setvar "osmode" OSM)
(setvar "cmdecho" CMD)
(setvar "snapmode" SNP)
)
(princ)
;_ end of defun


It doesn't give me any errors. It just doesn't recognize creating the layer part.

Thx.
Doug
0 Likes
Message 6 of 11

Anonymous
Not applicable
Accepted solution

Hi Doug,

 

Spotting your post.

 

Seems to be two things not running:   You have defined a Command REVCLOUD when AutoCAD has a REVCLOUD.  Using "_REVCLOUD" in the function is fine, but outside LISP it still calls the Original AutoCAD REVCLOUD.  ie bypasses your defun and hence no layer setting.

My policy is not to override any existing AutoCAD commands with new defun command unless you really want to.

 

1.  The C:REVCLOUD 

Change to:

(defun C:REVCLOUD1 (/ *error* CLAY OSM CMD SNP)

and eveything works.

 

2.  (command "-Layer" "M" SLAY "C" "80" "" "" "")  has to many "" 

Change to:

(command "-Layer" "M" SLAY "C" "80" "" "")

On error this would have reset thank's to *error* function

 

and change your menu to:

^C^C(setq SLAY "G-REV");REVCLOUD1

 

This works fine for me.

 

Cheers

Brent

Message 7 of 11

Anonymous
Not applicable
Perfect! Thanks so much for the help!!

Doug
0 Likes
Message 8 of 11

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

....

My policy is not to override any existing AutoCAD commands with new defun command unless you really want to.

.... 

Change to:

(defun C:REVCLOUD1 (/ *error* CLAY OSM CMD SNP)

....


I was going to suggest that you can UNDEFINE the native command, and define your own under the original name.  The benfit of doing so is that you don't always need to type in the full command name as you've defined it, because even menu icons [as long as they call for the command name without a period prefix] and command aliases will call up your new definition of it.  This would be the approach:

 

(command "_.undefine" "REVCLOUD")

(defun C:REVCLOUD (....

 

And then, if for some reason you do want to use the native command, for example to draw one on a different Layer than the one automatically set by your new definition, or with Snap left on, you can use the period prefix to get at it:

 

.REVCLOUD

 

Usually, that native command is invoked that way somewhere within the new definition, which will typically just add stuff around it [Layer setting, System Variable settings, resettings of those, etc.].  And I've used that approach for a few things, such as the PasteBlock command that forces you to give the resulting Block a meaningful Block name in place of the usual "A$C2B2D5D64" kind of thing, recently brought up in this thread.

 

BUT I find that in this particular case, that doesn't work!  Once it's been undefined, trying .REVCLOUD or _.REVCLOUD returns an unknown-command error, just as trying the plain un-prefixed REVCLOUD command does, whether manually at the Command: prompt or in a (command) function.  So apparently REVCLOUD is a horse of a different color from most native commands.  I thought maybe it was an Express Tool, but it's not, although I think it was originally, but was made "native" a long time ago.  I can only assume something of that distinction has "survived" its importing into the "native" program, some things seem to be more "native" than others, and apparently even though Undefine works on something, that doesn't necessarily mean it's going to be usable in its native form with that period prefix.  So always test before incorporating something like this into a (defun) or macro or Script.

Kent Cooper, AIA
0 Likes
Message 9 of 11

Kent1Cooper
Consultant
Consultant

@ВeekeeCZ wrote:
....
 (defun *error* (errmsg) ;runs automatically if error or ECS
 (if (not (wcmatch errmsg "Function cancelled, quit / exit abort, console break"))
 (princ (strcat "\nError: " errmsg)))
....

One thing you should change:

 

There should be no spaces after the commas in the (wcmatch) pattern string:

 

(if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))

 

The way (wcmatch) uses comma-delimited strings, it's looking for what's separated by commas to be complete and exact string possibilities.  The kind of error that's going to send "quit / exit abort" as an error message is not going to include a space at the beginning of that, so as you have it, that message will not be bypassed as intended.

Kent Cooper, AIA
Message 10 of 11

ВeekeeCZ
Consultant
Consultant
Thank you. I know how the command works, but over this particular, I never thought about. In half of the cases got it right in half of this bad. It's the copy-paste. Thanks again.
0 Likes
Message 11 of 11

Anonymous
Not applicable

 

My thoughts as well.

When I Undefined REVCLOUD when testing this I also found the native REVCLOUD was invisible regardless of calling with .REVCLOUD or _.REVCLOUD.  Unusal this time.

Changing the defun name was my fastest solution in this case.

All good.

0 Likes