Misbehaving Global Variable

TheSearcher

Registered User.
Local time
Today, 06:05
Joined
Jul 21, 2011
Messages
383
I have a module called "Globals" in which I declare all of my global variables in the General Declarations section. I have one called glb_FullName that is declared as:

Public glb_FullName As String

I initialize this variable in my login form assigning to it the full name of the person who logs into the program. Whenever anyone updates a record a log is kept (in the form of a table) which holds the person's full name (glb_FullName) and a timestamp. This works successfully about 95% of the time. However, sometimes when a record is updated the log will show an empty string where the full name is supposed to be. Since the variable is assigned a value immediately after a successful login how could my log table contain an empty string?

Any ideas will be greatly appreciated. I'm using Access 2016.

Thanks,
TS
 
An unhandled error can reset global variables. Might that be happening? You can try using a TempVar, which I don't think get reset.
 
As Paul says - if you get any unhandled run time error (you will see the debug window) and you have to stop the code - then all your variables are reset to their "base" value - 0 or a blank string.

You need to add error handling everywhere this is possible to guard against it.
 
Also, since we're dealing with 'full names,' have you noticed this happening with any particular users? Names containing apostrophes, such as O'Hara or O'Conner, can cause no end of problems with code that 'usually' works correctly!

Linq ;0)>
 
I recall being on the losing end of this discussion a couple of years ago with someone about an unhandled error resetting variables. The statement about resetting variables is true but not complete, so I'm tossing in a clarification to be sure everyone understands what happens and what to do about it.

When you have an unhandled error, global variables are NOT reset. But since you don't have an error handler (i.e. it IS an "unhandled error"), Access takes over because it ALWAYS has an error handler - the "Last Chance" error handler - which leaves you hanging at a dialog box to let you debug the code and see what happened, or you could decide to give up and start over. At that point that you take the Debug option and the code window opens, you still have data in the variables. You can poke around and look at things.

You have to click on the Code window menu bar >> Debug sub-menu drop-down >> Reset button to proceed from an app that is hung up and cannot resume what it is doing. THAT is when the variables get reset. And the reason that you need that button is because you can't manually issue a "Resume xxxx.Module.Label" and the "Resume label" target from the last-chance handler isn't in your code. It is in Access GUI code.

Which is why even a minimal Form_Error routine that does nothing except a Resume Next would protect you from this condition. Even if it causes the form to close, the global module WON'T necessarily close and should preserve the variables. (In theory.) Of course, it still might leave some items "dangling" and in bad states, but re-opening a form (if the app is well-designed) would reset things that could be in bad states.

I knew that I had good handlers copiously placed in my app including the switchboard, and these handlers kept me from losing track of the globals. But I was a belt-and-suspenders man for the Navy so I always had my Form_Load code reset anything about which there was the slightest doubt. That was a matter of personal preference on practicing "safe hex" so didn't screw up stuff due to neglect.

Just a question about the login. Do you have a domain-based environment? Because if you do and your users have unique domain names, you can just ask Access via the Environ("Username") function who logged in. Even if the variable got hosed, the Environ function is so fast it ALMOST costs nothing to just re-initialize the appropriate variable when the form opens again.
 
I recall being on the losing end of this discussion a couple of years ago with someone about an unhandled error resetting variables.

Sounds like maybe you ran into ChrisO. ;)
 
And the reason that you need [the reset button] is because you can't manually issue a "Resume xxxx.Module.Label" and the "Resume label" target from the last-chance handler isn't in your code.

Actually there is a way to resume a procedure at a designated location. I often recover from an error induced Break by commenting out the lines causing the error and hitting the Go button to resume.

Another alternative is to comment out the line and replace it with an Exit command or place an exit command as the first line so the procedure Exits immediately after being called.

These techniques are particularly useful when the error is in a Function being called hundreds of times from a query. Hitting reset will only terminate the running instance of the function, only to have it called again for the next record.
 
That's true... VBA CAN be made to dynamically recompile. But that is a feature I rarely used since I never allowed code that did that to make it to the public. I always stopped, examined variables and the stack, and then reset so that I could fix it. So I didn't often modify the code and then let it dynamically recompile.

Of course, if you have code known to need debugging, you might just want to have some minimum error handlers sprinkled around so that you don't ever HAVE an unhandled error in the first place.
 
One would hope that if the application was going into debug the user would let the OP know about it. I wonder if in one of the clients this Global variable is actually an empty string. I suggest adding a field or two to the log table and start tracking Environ("Computername") and/or Environ("Username") to find out which client application is causing this.

Where does the person's full name come from?
 
sometimes you get a non-repairable error though - or just as bad, an error that even though it's handled leaves you with a partly updated dataset, etc.

I just had an imperfectly coded msgbox. It wouldn't let me change the msgbox structure and I had to crash the code. Thinking about it now, I probably could have commented out the msgbox.

And it certainly sounds like ChrisO.....

And furthermore, as you generally don't want users in code windows, so they tend to get .mde/.accde files which they can't then modify/fix at run time.
 
I have a module called "Globals" in which I declare all of my global variables in the General Declarations section. I have one called glb_FullName that is declared as:

Public glb_FullName As String

I initialize this variable in my login form assigning to it the full name of the person who logs into the program. Whenever anyone updates a record a log is kept (in the form of a table) which holds the person's full name (glb_FullName) and a timestamp. This works successfully about 95% of the time. However, sometimes when a record is updated the log will show an empty string where the full name is supposed to be. Since the variable is assigned a value immediately after a successful login how could my log table contain an empty string?

Any ideas will be greatly appreciated. I'm using Access 2016.

Thanks,
TS


I would highly recommend that you switch to using TempVars as your global variables. The don't get lost when the VBA code is reset do to errors.

You can even use them in Macros and queries.

This works in Access 2007/2010/2013/2016.

See this Microsoft Access Team Pwer Tip: https://blogs.office.com/2010/09/27/power-tip-maximize-the-use-of-tempvars-in-access-2007-and-2010/

FWIW: I have started using then all teh time with great success.

If you want to stick with using a global variable then hat I do is every time I use glb_FullName I check to see if it is set. If glb_FullName is not set then I open the logon form.
 

Users who are viewing this thread

Back
Top Bottom