Resetting Variables Is Throwing Errors?????

Resetting Variables Is Throwing Errors?????

Anonymous
Not applicable
1,824 Views
14 Replies
Message 1 of 15

Resetting Variables Is Throwing Errors?????

Anonymous
Not applicable

Hello everyone,

First off I want to say if at any point I am doing something wrong please correct me. I am learning everything I can but it is quite the process. I've come a long way so far and hope to keep learning more.

So.... 

I am trying to put some lines of code into an acaddoc.lsp to:

1. Get the system variables at the startup and store them

2. Define another function to reset the variables to the original values, that I can put in all my other code. 

 

The reason for this is that when some of the commands I have are ran it changes things like the osmode and highlight etc etc, but the problem is that it never gets changed back. 

My thought is that if I define them at the startup I can then throw them in all the other code..

Here is some of what I am working with 

Here below I am attempting to retrieve the current System variables.... this is in my acaddoc.lsp file

(defun SB:old_stm_variables (/ highlight cmddia filedia mirrtext pickadd pickauto pickfirst sdi selectionpreview)
  (setq highlight (getvar "highlight")
        cmddia (getvar "cmddia")
        filedia (getvar "filedia")
        mirrtext (getvar "mirrtext")
        pickadd (getvar "pickadd")
        pickauto (getvar "pickauto")
        pickfirst (getvar "pickfirst")
        sdi (getvar "sdi")
        selectionpreview (getvar "selectionpreview")
        osmode (getvar "osmode")
        )
   (princ "\nRetrieved Current System Variables")
  (princ)
  )
(SB:old_stm_variables)

Next I define the function to reset them to their original state. also in the acaddoc.lsp file

I will then put this at the end of my other custom commands.  

(defun SB:reset_variables (/ highlight cmddia filedia mirrtext pickadd pickauto pickfirst sdi selectionpreview)
(setvar "highlight" highlight)     ; when ran this throws an error below >>>
(setvar "cmddia" cmddia)           ;>>>error: AutoCAD variable setting rejected: "highlight" nil
(setvar "filedia" filedia)
(setvar "mirrtext" mirrtext)
(setvar "pickadd" pickadd)
(setvar "pickauto" pickauto)
(setvar "pickfirst" pickfirst)
(setvar "sdi" sdi)
(setvar "selectionpreview" selectionpreview)
(setvar "osmode" osmode)
  (princ "\nSystems Variables Have Been Reset")
  (princ)
    )

Any thoughts or suggestions? 

Also why is it not accepting the highlight variable???

 

Thanks for all the help!

 

 

 

 

 

 

 

0 Likes
1,825 Views
14 Replies
Replies (14)
Message 2 of 15

Kent1Cooper
Consultant
Consultant

It's because you localized those variables  in the save-the-System-Variables routine.  That means they disappear when that routine ends.  So they no longer exist when the resetting routine looks for them.  Just do:

 

(defun SB:old_stm_variables ()

  (setq highlight (getvar ....

 

In a broader context, you can localize those within a larger command definition, so that after it's done and the resetting routine has made use of them, then  they will disappear:

 

(defun C:YourCommandDefinition (/ highlight cmddia .... sdi selectionpreview .... and others for the command)

  (SB:old_stm_variables); save them

  .... command do its thing ....

  (SB:reset_variables); reset them

  (princ)

); defun

 

You don't want them localized in the resetting one, either -- that will make them nil within that unless they get (setq)'d inside it.  Similarly, just do:

 

(defun SB:reset_variables ()
  (setvar "highlight" ....

Kent Cooper, AIA
0 Likes
Message 3 of 15

Anonymous
Not applicable

Ohhhhhhh 

Okay... I see, that makes a lot more sense.

 

Thanks Kent!

 

 

0 Likes
Message 4 of 15

ronjonp
Mentor
Mentor

Recent post HERE for restoring variables too.

 

You could simplify a bit to save all your variables and values in a couple of lists so you're only calling *vars* and *vals* like so:

;; Define your variables list in a global list
(setq *vars*
       '(highlight cmddia filedia mirrtext pickadd pickauto pickfirst sdi selectionpreview osmode)
)
;; Returns: (HIGHLIGHT CMDDIA FILEDIA MIRRTEXT PICKADD PICKAUTO PICKFIRST SDI SELECTIONPREVIEW OSMODE)

;; Store the values of those variables in a global list
(setq *vals* (mapcar 'getvar *vars*))
;; Returns: (1 1 1 0 1 5 1 0 3 16388)

;; Change your variables as needed
(mapcar 'setvar *vars* '(0 0 0 1 0 4 0 0 1 0))

;; Then simply use this to return them to their original value
(mapcar 'setvar *vars* *vals*)
0 Likes
Message 5 of 15

Anonymous
Not applicable

To anyone who wants to answer...

 

Now that I have a handle on resetting the variables. 

Just to clarify, correct me if im wrong. 

I am going to put that into the acaddoc file and call it in all the other lisp files where I need it.... 

 

After that am I going to need to make use of an error?

 

0 Likes
Message 6 of 15

ronjonp
Mentor
Mentor

Why are you using global variables? I'd define the *error* function within the program and not use globals. Did you read the post at CadTutor?

 

Simple example:

(defun c:foo (/ *error* vals vars)
  ;; Error handler
  (defun *error* (msg)
    (mapcar 'setvar vars vals)
    (if	(not (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*"))
      (princ (strcat "\nError: " msg))
    )
    (princ)
  )
  ;; Define your variables list
  (setq	vars
	 '(highlight cmddia filedia mirrtext pickadd pickauto pickfirst sdi selectionpreview osmode)
  )
  ;; Returns: (HIGHLIGHT CMDDIA FILEDIA MIRRTEXT PICKADD PICKAUTO PICKFIRST SDI SELECTIONPREVIEW OSMODE)
  ;; Store the values of those variables
  (setq vals (mapcar 'getvar vars))
  ;; Returns: (1 1 1 0 1 5 1 0 3 16388)
  ;; Change your variables as needed
  (mapcar 'setvar vars '(0 0 0 1 0 4 0 0 1 0))
  ;; Your code
  ;; HERE
  ;; Then simply use this to return them to their original value
  (mapcar 'setvar vars vals)
  (princ)
)

 

0 Likes
Message 7 of 15

Kent1Cooper
Consultant
Consultant

@ronjonp wrote:

Why are you using global variables? I'd define the *error* function within the program and not use globals. ....


 

I can see doing it if  you have a big-enough collection of System Variables that you always  want dealt with, though not as "fully" global ones, but localized within any containing routine [but left as "global" within these sub-routines].  If they replace the collection of blue variable names in Message 2 there with something like your 'vars' and 'vals' variable names, it can reduce the code in a lot of routines to just have those function calls [also in the middle example in Message 2] in lots of .lsp files, rather than including the whole list in every routine  as in your (setq)ing of the 'vars' variable in Messages 4 & 6.

 

But I don't  typically do it with an external function like that.  I usually do it more like in your suggestion, simply because the nature of the routine greatly affects which  System Variables I want dealt with -- some need PEDITACCEPT turned off, some need UCSFOLLOW turned off, most but not all need OSMODE and CMDECHO turned off, but very few need exactly the same combination  as any other.  So I let each routine deal with the particular set of them applicable to what it's doing.

Kent Cooper, AIA
0 Likes
Message 8 of 15

ronjonp
Mentor
Mentor

@Kent1Cooper wrote:

@ronjonp wrote:

Why are you using global variables? I'd define the *error* function within the program and not use globals. ....


 

....

 

But I don't  typically do it with an external function like that.  I usually do it more like in your suggestion, simply because the nature of the routine greatly affects which  System Variables I want dealt with -- some need PEDITACCEPT turned off, some need UCSFOLLOW turned off, most but not all need OSMODE and CMDECHO turned off, but very few need exactly the same combination  as any other.  So I let each routine deal with the particular set of them applicable to what it's doing.


Agreed (y). IMO, having one solution that tries to fit all programs is just begging for headaches down the road. 

 

0 Likes
Message 9 of 15

Anonymous
Not applicable

I have about 40 different files to do which are all having pretty much the same issues. 

 

0 Likes
Message 10 of 15

Anonymous
Not applicable

Is it a solution to each individual program more than it is just resetting the users preferences/settings(system variables) when the command is over, failed, or canceled? 

If that's the case, then I agree it would be a headache. If you can get the users settings at the startup with getvar and define the function to reset them there too would that not be a good option getting rid of some clutter in the code and having one "parent" code to reset your settings rather than 40 different files? 

I keep thinking of it kind of like your own variable... (setq x "John") 

I have all these instances and if something needs to be changed all I have to do is change one piece of code.....

rather than having to go and change every instance of John to Mike... is it not like that?

Also I read your comment earlier opened the link but then forgot to go back and read it.

Reading it now.  

0 Likes
Message 11 of 15

scot-65
Advisor
Advisor
Here is a strategy to consider:

If one structures the program in such a way as to not
make any system and/or drawing and/or user changes
during the user input section of the code, one will not
need error handlers to begin with.

If a specific setting is required from the user (such as "_nea"),
and the user's settings does not have this available as default,
then it is not your concern to adjust the user's settings during
the user input section of your code.

Once the user input is satisfied, and has been tested as being
valid, it is now time to set the environment and execute the code.
When finished, reset the environment. (sandbox anyone?)

Hint: Avoid gathering user input by issuing a command and
"pause" inside the command [with exceptions].

Also consider the strategy of allowing the user to create a new
object using the current environment and when finished,
(entget/ssget "Last") and direct appropriately. But first one
will have to check if in fact the user did not cancel during
this process.

DON'T MESS WITH MY OSMODE!

???

Scot-65
A gift of extraordinary Common Sense does not require an Acronym Suffix to be added to my given name.

0 Likes
Message 12 of 15

Anonymous
Not applicable

Okay, that is all great and I will build off of it.

Maybe you can tell me this, why does the highlight get thrown off when its NOT celled and then putting (setvar "highlight" 1) at the end does NOT set it back to 1...? 

This is extremely frustrating.

Which is the reason that lead me to take a different approach then just (setvar "highlight" 1) (setvar "osmode" 4159at the end of the code, granted, on a case to case basis.

 

Where is the pulling out hair emoji...? Is there a code for that? lol 

Thanks for the input!

0 Likes
Message 13 of 15

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

.... why does the highlight get thrown off when its NOT celled and then putting (setvar "highlight" 1) at the end does NOT set it back to 1...?  ....


 

I think we would need to see the rest of the revised code context to evaluate.

 

If [several if's here...] you're really dealing with (setvar "hightlight" highlight) using the variable  as originally, and  if you "caught" my first Reply too quickly, maybe you didn't catch the last part of it, which was an Edit shortly after the original posting.  If that's what happened, and you didn't also remove the localizing of variables in the resetting routine, it would have exactly the effect you describe.  If the 'highlight' variable is localized  there, it will be nil for the internal purposes of that routine, regardless of whether or not the saving-variables routine had it localized.

Kent Cooper, AIA
0 Likes
Message 14 of 15

ronjonp
Mentor
Mentor

Maybe post your code where you're getting strange results with 'highlight'. I cannot reproduce what you're describing using the error handler and (mapcar 'get/set/var code above.

 

I know you have 40 routines but I'd still take the time ( maybe a couple of days ?) to define an error handler in each .. and further try to reduce command calls that require all these variable changes.

 

Do you have a common file with your functions that you are reusing in all your code?

0 Likes
Message 15 of 15

ВeekeeCZ
Consultant
Consultant

Another way to reset system variables offers the SYSVARMONITOR. Although I don't use its on-line control and notifications (found that annoying), I do use it for the quick overlook and reset changed variables. (usually changed by testing...)

 

image.png

 

BTW looking at your list of variables... Not sure how you change SDI sysvar, but if you have sdi changed to 0 with more tabs open, then reset to 1 will cause an error.

0 Likes