Global variables question

J

Jim Evans

This is probably a really silly question but, I have been bitten by less
silly situations so, here it is.

Is my assumption correct that all vba code, including global variables, has
scope only in the individual FE file that is running it? A global var set in
one FE cannot be affected by the same global var being set by another
operator in a different copy of the FE file?

Silly or not, thanks for your time.
Jim
 
M

Marshall Barton

Jim said:
This is probably a really silly question but, I have been bitten by less
silly situations so, here it is.

Is my assumption correct that all vba code, including global variables, has
scope only in the individual FE file that is running it? A global var set in
one FE cannot be affected by the same global var being set by another
operator in a different copy of the FE file?


You are correct.

OTOH, in general, global variables (i.e. Public variables in
a standard module) are not a good idea and should be avoided
in almost all situations.
 
J

Jim Evans

I use the Global variables in Functions which set criteria values in
queries. The variable value is assigned just before calling the query(ies).
I do not depend on them to supply values to forms or other procedures
throughout the day. There are a few situations where the global variable is
used in several queries called in succession and my concern was having the
value changed before these procedures were completed.
Jim

Hi Marshall,

They are useful for holding global settings. For instance I often have
an application settings table and at start up I will load that data into
global variables so I do not have to repeatedly query that table every time
I
need to use one of those values. Beyond that I am in agreement with you.

Clifford Bass
 
J

Jim Evans

Thanks Marshall and Clifford. I can now sleep better!

Jim

Hi Jim,

You are correct. And in fact, they have scope within a particular
instance of Access on the same machine. So if an operator opens the FE a
second time, those in the one instance are totally separate from those in
the
other. There are ways to share values between running instances of
programs,
but you as the programmer would have to implement it.

Clifford Bass
 
J

Jack Leach

Personally, I use properties rather than global variables to hold this type
of information. For some reason I seem to have an impression that a Public
Property is much more secure than a global variable, and then you can refer
to them in queries just as you would a public function.

Just a thought...

--
Jack Leach
www.tristatemachine.com

"I haven''t failed, I''ve found ten thousand ways that don''t work."
-Thomas Edison (1847-1931)
 
D

Dirk Goldgar

Jack Leach said:
Personally, I use properties rather than global variables to hold this
type
of information. For some reason I seem to have an impression that a
Public
Property is much more secure than a global variable, and then you can
refer
to them in queries just as you would a public function.


I use properties for this, too. It's not that I think they are more secure,
but that I can have the Property Get procedure check for whether the
underlying static variable has lost its value for any reason and needs to be
reloaded.
 
M

Marshall Barton

Yeah, I've done the same thing in a few extreme cases with
projects I've taken over from other programmers.

Normally, I strongly prefer to use pubic functions in a
standard module with the application settings declared as
private.

The same idea can be done using a class with the application
settings as properties. The values would be set in the
initiate event and because the properties have no Property
Set procedure, they can not be changed inadvertantly.
 
J

Jack Leach

It's not that I think they are more secure,
but that I can have the Property Get procedure check for whether the
underlying static variable has lost its value

=More Secure? <g>

while we're on the subject... I've always been curious about this "static"
variable.

Ex.

Private m_strThisVal As String
Property Let ThisVal(arg As String)
m_strThisVal = arg
End Property
Property Get ThisVal() As String
ThisVal = m_strThisVal
End Property

I've never actually seen a property member declared as Static, though static
is not the generally default... this appears to be the only case (in a
standard module) where the variable can be declared as "not" static but
retain it's value through what would otherwise put it out of scope? I can
see this wouldn't matter in a class module, being that the value will get
redefined with each instantiation, but I've always taken this for granted in
a standard module.

--
Jack Leach
www.tristatemachine.com

"I haven't failed, I've found ten thousand ways that don't work."
-Thomas Edison (1847-1931)
 
J

Jack Leach

Right after posting the last I read Marshall's post...

"
Normally, I strongly prefer to use pubic functions in a
standard module with the application settings declared as
private.
"

So it seems as though you can do this with regular old public functions and
private module-scope variables as well? I was always of the impression that
the variable was required to be declared as Static to retain it's value. Can
someone please explain?

Thanks!

--
Jack Leach
www.tristatemachine.com

"I haven''t failed, I''ve found ten thousand ways that don''t work."
-Thomas Edison (1847-1931)
 
D

Dirk Goldgar

Jack Leach said:
=More Secure? <g>

Fair enough, if that's what you meant.
while we're on the subject... I've always been curious about this "static"
variable.

Ex.

Private m_strThisVal As String
Property Let ThisVal(arg As String)
m_strThisVal = arg
End Property
Property Get ThisVal() As String
ThisVal = m_strThisVal
End Property

I've never actually seen a property member declared as Static, though
static
is not the generally default... this appears to be the only case (in a
standard module) where the variable can be declared as "not" static but
retain it's value through what would otherwise put it out of scope? I can
see this wouldn't matter in a class module, being that the value will get
redefined with each instantiation, but I've always taken this for granted
in
a standard module.

In the above, the variable m_strThisVal is declared at the module level, and
so has no need to be declared Static. Module-level variables never go out
of scope, and so they never lose their values unless the VB project is
reset. The Static keyword is only useful when applied to a procedure-level
variable, since it makes the variable retain its value between executions of
the procedure -- even though the variable is out of scope.
 
B

Banana

Jack said:
I was never aware of this. Thanks Dirk

FWIW, for me, a common use of static variable is to create a read-only
property without going through the expense of instantiating of the
object everytime.

Here's an example of what I commonly do when I need an ADO connection
object. In the project, I only need one connection object for the
application's lifetime, and I don't want to litter my code with orphaned
connection objects or worse, create more than one and have them step on
each other, raising bogus 'read/write conflict' or 'lock conflict' or
similar erros. Thus, I get my ADO connection from a read-only property:

Property Get Conn() As ADODB.Connection

Static con As ADODB.Connection

If con Is Nothing Then
Set con = New ADODB.Connection
'Other settings for the connections...
End If

Conn = con

End Property



With this procedure, I have hid my connection object to the procedure so
there's no need for a module-level variable to hold the connection (and
thus exposing it to other procedures in the same module... I may be able
to discipline myself to not use it but there is no guarantee I'll
remember to do so or that other programmer who replace me will
understand that it is not to be touched. Static, thus, helps with
documenting "Do not try to change this connection object outside of the
property procedure".

Furthermore, notice that I have a If/Then testing whether the static
variable has been instantiated and in case it's not, instantiate it.
This is useful in cases where the object may have been inadvertently
destroyed so the procedure self-heals and I always get a valid
connection object without need to be concerned that I've destroyed it
somewhere else or an error re-initialized it or whatever. It'll always
work when I need it and I won't have more than one connection object
(providing that my code consistently call this property instead of
creating its own connection object).


Note: I fudged a bit in the paragraph above previous paragraph -
Technically, static variable will not protect the connection object from
being modified when it has been called and placed in another variable
for the calling procedure, but that's generally OK because I usually
don't do that. Furthermore, I think the intention is more clear to other
programmers reading my code regarding my intention with the object.
Besides, the self-healing feature is really what make it useful.

If I really wanted to enforce all setting on an object, I could put the
connection settings outside the If/Then block so it always get set
everytime it's called but that would add a bit of overhead. YMMV.
 
J

Jack Leach

Thanks for the insight Banana. I can see how putting the variable as Static
within the procedure itself is yet another step towards cleaning things up
some.

To couple this with Marshall's suggestion of public functions and private
variables, one can further disambiguate their intentions behind the use of
those variables by making them private to the procedure rather than the
module. One of those "not when there is nothing left to add, but when
there's nothing left to take away" situations. If the procedure itself is
the only place it's needed, why not store it there instead of private to the
module?

I like it, thanks for the tip.

--
Jack Leach
www.tristatemachine.com

"I haven't failed, I've found ten thousand ways that don't work."
-Thomas Edison (1847-1931)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top