Form Dim Strings (1 Viewer)

MattBaldry

Self Taught, Learn from the Forums
Local time
Today, 08:42
Joined
Feb 5, 2019
Messages
293
Hi all,

If I have repeated Dim Strings, can I declare them as public once on a form then just refer back to them anywhere else on the form code?

Example as the below code. This is used on a few different command buttons.

Code:
    Dim strLoggedUser As String
        strLoggedUser = DLookup("EmployeeID", "tblEmployees", "EmployeeNetworkUserName = GetUserName()")

If I have a Public Sub at the start of my form code and all my Dim str values there, can I just call them anywhere else on the form code?

Or can I do this on a module?

~Matt
 

MattBaldry

Self Taught, Learn from the Forums
Local time
Today, 08:42
Joined
Feb 5, 2019
Messages
293
Update.

Quick search and I have changed the Dim for Public, but the below now does not work. Says invalid outside procedure.

But when it has Dim, is works. Do I need to add something else?

Code:
Public strLoggedUser As String
        strLoggedUser = DLookup("EmployeeID", "tblEmployee", "EmployeeUserName = GetUserName()")
 

Minty

AWF VIP
Local time
Today, 08:42
Joined
Jul 26, 2013
Messages
10,371
At the top of a form module anything you declare outside of a normal event procedure is persistent for the whole time the form is open.
However, you can't assign a dynamic value to it at that point as that involves running a process.

For value such as a UserID that won't change in the course of normal use I would create that as a self healing property in a globals module.
have a read here:
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Today, 15:42
Joined
May 7, 2009
Messages
19,243
you can declare Public Variables in a Module.
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 02:42
Joined
Feb 28, 2001
Messages
27,186
If I have a Public Sub at the start of my form code and all my Dim str values there, can I just call them anywhere else on the form code?

Here is how declarations work.

You can declare a variable in a function or subroutine. You can declare a variable in the declarations area (before the first sub or function declaration) of a class or general module. This includes examples of ReDim for arrays. Variable persistence is simple. You need to know WHERE it was created to know its lifetime.

A variable defined in a function or subroutine exists ONLY for as long as the function or subroutine is active, because with one exception, all such variables are declared on the call stack (in something called a Call Frame.) This call frame is the localized keeper of the routine's current execution context - including all "local" variables, the address of the current error handler, the address to which your code returns on routine exit, and some traceback information that you can see using the View >> Call Stack operation from the VBA Window's menu bar. Once you exit a sub or function, its call frame is dissolved and all of its locally declared variables cease to exist. At the next call to that same sub or function, new instances of the variables come into existence on the stack. The one exception is any variable declared as STATIC, which persists and can retain values across multiple activations of the sub/function declaring it.

The question you asked about variables declared in a sub/function is directly answer by the above paragraph. Here are the rest of the rules for variable existence/persistence.

A variable declared in a class module comes into existence when the class object (a form, usually) comes into actual existence, i.e. opens. (The fact that it has POTENTIAL existence doesn't usually matter.) For the duration of its existence, the variable is however you declared it. It ceases to exist if the class object (that supports the class module) closes. If you open the same class object a second time after it was opened and closed, the variables are new instances of themselves and are re-initialized to their default values.

A variable declared in a general module theoretically comes into existence when the app opens and that variable exists until the app closes. It retains any value for the duration of the app UNLESS there is an unhandled error and the only way out of the error is the RESET option. Its scope of PUBLIC or PRIVATE or something else is however you declared it.

Depending on exactly how function/sub variables were defined, it is POSSIBLE for you to recursively activate the routines (i.e. routines CAN call themselves) and thus have more than one active copy of the routine's variables. When that happens, any local variables are local to the currently active instance of the function/sub call and are separate from other instances, each of which has its own call frame. In this case, I believe the STATIC variables are still visible and do NOT get re-initialized in the case of recursion. The one recent time I used that feature, that is the way it appeared to me.

All simple variables declared as noted above lose their value after a RESET operation. However, certain structures such as Dictionaries, TempVars, and user Collections can retain values across a reset. None of them survive an Application.Quit operation.
 

Gasman

Enthusiastic Amateur
Local time
Today, 08:42
Joined
Sep 21, 2011
Messages
14,299
Update.

Quick search and I have changed the Dim for Public, but the below now does not work. Says invalid outside procedure.

But when it has Dim, is works. Do I need to add something else?

Code:
Public strLoggedUser As String
        strLoggedUser = DLookup("EmployeeID", "tblEmployee", "EmployeeUserName = GetUserName()")
You could also use TempVars?
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 03:42
Joined
Feb 19, 2002
Messages
43,275
If you find yourself having to use the same variable over and over again in code, you should probably rethink your structure. Look for articles that define coupling and cohesion.

Coupling is how tightly bound separate procedures are and cohesion is the connection within a procedure. in general, procedures should be loosely coupled but highly cohesive. You don't want a procedure that produces pay checks and a monthly sales report only because they both happen on the same day. If the manager decides he needs to run the report on a different day, how do you not also run the payroll? If you find you have to define variables outside of procedures, you have broken up your code illogically or combined pieces that shouldn't have been combined.

 

MajP

You've got your good things, and you've got mine.
Local time
Today, 03:42
Joined
May 21, 2018
Messages
8,529
One thing I do a lot for information I pull from a table often if make Public functions in a standard module

Not that it is going to matter, but at the top of the form you should declare any variables as Private or Public. I always declare as Private unless I plan to call that value from outside of the form. But to call from outside the form you have to go through and instance of the form. Which in your case I doubt you plan to do. But if you wanted to call that variable from outside of the current form you would need to do something like
Like

dim frm as access.form
set frm =forms("yourFormName")
msgbox frm.strLoggedUser

at the top of your form

Code:
private StrLoggedUser as string

Private Sub Form_Load()
  strLoggedUser = GetLoggedUser()
End Sub

Now you can use strLoggedUser anywher in the form's code. But maybe you do not even want to do that. Simply build the Public function in a standard module.

Code:
Public Function GetLoggedUser() as string
  GetLoggedUser = nz(DLookup("EmployeeID", "tblEmployees", "EmployeeNetworkUserName = GetUserName()"),"")
end Function

Now in your form it is just as easy to replace any call to strLoggedUser to simply getLoggedUser
 

Isaac

Lifelong Learner
Local time
Today, 00:42
Joined
Mar 14, 2017
Messages
8,777
Create a public function, don't keep declaring them
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 03:42
Joined
May 21, 2018
Messages
8,529
@MattBaldry,

If you create a public function, there is really no need for a module level private variable. The only reason there might be a need if the public function call was resource intensive and you do not want to call it more than once. That is pretty uncommon, but I have examples where I have to churn through a calculation and only want to do that once for a form.

However, in a procedure you might want a local variable to save a little bit of resources instead of multiple calls to the funciton.
Instead of
Code:
Private sub SomeProcedure ()
  if getLoggedUser() = "Some User" or getLoggedUser() = "Some other User" or  getLoggedUser() = "Someone Else" then
....
end sub

Code:
Private sub SomeProcedure ()
dim strLoggedUser as string
  strLoggedUser = getLoggedUser()
  if strLoggedUser = "Some User" or strLoggedUser = "Some other User" or  strLoggedUser = "Someone Else" then
....
end sub

In truth the amount of resources is miniscule, but I always prefer if I call something more than once to store a variable. It can save typing to.
 

Users who are viewing this thread

Top Bottom