Passing global/public variable between forms

Wysy

Registered User.
Local time
Yesterday, 19:21
Joined
Jul 5, 2015
Messages
333
Hi,
I know old question but i would like to ask for clarification.
I have two forms:Form1 and Form2. I want to pass varible created in Form1 to Form2. If Form1 stays open it works, but if i close it it does not.
So code behind it
Form1
Option Compare Database
Option Explicit
Public strT As String
Public Sub Command0_Click()
strT = "Public Variable Test"
End Sub

Form2
Public Sub Command0_Click()
strT = Form1.strT
MsgBox strT
End Sub

What do i do wrong?
thanks
 
i have gotten it working with the following method.
Created a module:

Option Compare Database
Global strT As String
Public Sub test()
strT = "Public Variable Test"
End Sub

Then i call this module in Form1:

Option Compare Database
Global strT As String
Public Sub test()
strT = "Public Variable Test"
End Sub

Is there any more efficient or "elegant" coding i could use?
thanks
 
Use Tempvars(), but the method is pretty much the same?
Normally I would use OpenArgs() if I just wanted to pass a variable to another form.?

Tempvars/Global would be if I needed access to them anywhere in code.
 
Form2
Public Sub Command0_Click()
strT = Form1.strT
MsgBox strT
End Sub
Form1.strT is not a resolveable expression.
Use: Forms("Form1").strT

[Edit]
If Form1 stays open it works, but if i close it it does not.
I missed this bit. If you close a form, you cannot reference it anymore. But, actually, I'm very surprised you say your code works when the form is open, because my above statement is still true.
[/Edit]


Global variables (inlcuding Tempvars) are a kludge to be avoided whenever possible.
 
Last edited:
use tempvars as suggested in #3.
unlike global variable, tempvars tend to persist even
when you encounter runtime error.
while global vars are destroyed when error occurs on your code.
 
. If Form1 stays open it works, but if i close it it does not.

If the value you pass is only required for use in form 2, then you can create a storage place for it in form 2. OpenArgs also provides a storage location.

The first method for creating a storage location is to create an unbound control, (usually a textbox) and set this to the value from form 1. You make this text box invisible. I call them "Yellow Perils" because convention dictates you set their back colour to yellow, to indicate the control is not part of the interface.

A variation on this method is to create your own custom property in form 2. There is a sample "Custom Property" here:-


I prefer the "Custom Property" method because it's tidier than hidden controls. Also a custom property is very similar to a function, in that you can build code into it, code to validate data passed through it.

Also, you can create a custom property to just store a string, an integer, a control, or even a form.

Another blog here might be useful:-

 
Last edited:
Global variables (inlcuding Tempvars) are a kludge to be avoided whenever possible
I felt the same way for the longest time (about TempVars)...but only because that seemed to be the accepted concept.
I have since warmed up to them, probably for the same reason you avoid them: They allow me to do powerful things without having to use advanced coding skills.
 
Form1.strT is not a resolveable expression.
Use: Forms("Form1").strT

Global variables (inlcuding Tempvars) are a kludge to be avoided whenever possible.

While it is perhaps theoretically possible to elegantly design an app that doesn't need public variables in a common area and doesn't need TempVars either, there is a limit of practicality. Access is all about RAPID app development. It takes time to scrupulously avoid those pesky little session-wide variables that let you do so much - like retain user login information. Having started my programming career with some college courses back in the late 1960s and having started my professional career in 1975, I must say that the concept of global variables is NOT a kludge. It is a way to assure that all elements are on the same page by sharing the global information that is common to multiple cooperating processes.

Having said that, it IS possible to overdo the globalization of your data. But the characterization of global variables as a "kludge" is not a widely shared viewpoint. The word "kludge" is thought to derive from the old Scottish word "kluge" meaning "clever." It has taken on the negative connotation because of clever but often unusually complex workarounds. Its origins come from a time before computing was a "thing" in the world of engineering. (See also "Rube Goldberg Device.")
 
Thank you for the digression into the etymology of "kludge". Very interesting. In German the adjective "klug" is in common use and literally means "wise" or "clever". - I never associated it with "kludge" before.

But the characterization of global variables as a "kludge" is not a widely shared viewpoint.
I agree. But not in the way you might think. In the wider software developer community beyond Access/Office/VBA, global variables are not considered a "kludge". - They are considered pure evil that should be avoided at all cost.
 
"Wider software developer community" ?? How much wider? I worked in the industry of automating oil and gas pipelines for 12 years. I worked in the maritime navigation industry for a couple of years. I worked as a contractor for the U.S. Navy for 28 1/2 years. "Globals" - no matter how they were implemented - were a fact of life. Rather than be mean-spirited about it, I will merely quote that great American philosopher Dalton (from the movie Road House) who said, "Opinions differ."
 
Skimmed over the results of that search. Most of the complaints are, in my opinion, caused by poor project management and poor documentation. There is not a single thing wrong with global variables where the data in question actually represents something common to the entire app.

Let's put it this way. A global variable or Tempvars item is something you can access from anywhere in your project, usually because it represents a datum of global importance to the operation of the app's parts. Well, by that standards, records in a table can have equal importance. Maybe it takes a few steps to get that datum, but you can do it from anywhere in the app.

If you use the operating system's method for identifying the username of the person who is using the app, that is something you can get from anywhere inside the app. A global variable merely assures this availability in fewer steps. Do you ever use the username in your app?

There is nothing wrong with a global variable. What is wrong is the people who don't know how to document or manage it. This is the old "guns don't kill people... people kill people" argument all over again.

On this, I feel EXTREMELY STRONGLY that globals are just another tool in the tool box. If you don't know how to manage them and limit them then perhaps you shouldn't use them. But if you understand them, then they make sense and have a place in your project. This is 50 years of computer experience talking. No, I don't know it all. But what I learned, I learned well.
 
@The_Doc_Man, I suspect our differences are for a good part caused by different use of terminology (see last paragraph below). Nevertheless, for the public audience I'm going to respond to what you literally wrote instead of what I think you meant.


Most of the complaints are, in my opinion, caused by poor project management and poor documentation.
This!👆
Project management and documentation to manage a bloody variable? - This alone is a sufficiently strong counter-argument against global variables to avoid them whenever possible.
How many people active in this forum have documentation and/or project management for their applications?

There is not a single thing wrong with global variables where the data in question actually represents something common to the entire app.
The user name example below is well suited to prove this false.

If you use the operating system's method for identifying the username of the person who is using the app, that is something you can get from anywhere inside the app. A global variable merely assures this availability in fewer steps. Do you ever use the username in your app?
If you use the Windows user name it is impossible that this will change during the run time of the current instance of your application. For that reason, using a global variable to store it is in itself a design fault.
Write a function (or property) to retrieve the user name (you need that anyway) and use this function instead of a global variable to access it anywhere. (You can use a static, local(!) variable in the function to cache the value, as it won't change.)

If you use your own authentication method, use a private variable in the authentication module to store the user name after authentication and make it available globally, but read-only, with a function as with the Windows user name above.

On this, I feel EXTREMELY STRONGLY that globals are just another tool in the tool box. If you don't know how to manage them and limit them then perhaps you shouldn't use them.
The term "Globals" is not identical to global variables!
Every global variable is a "global". But not every "global" is a (global) variable! Other globals, like constants, functions, and properties also induce dependencies and tight coupling, which is not ideal, but they do not bring the horrible error proneness and burden of managing and debugging global writable state (=global variables). My strong advice against global variables does not extend to other globals. The latter are also problematic from a general software design perspective, but Microsoft Access forces us to still use them a lot. So, there is little choice for us Access developers other than to swallow this pill.
 
You aren't forced to use public global variables. There are various techniques to limit the scope of any variable.
Nowadays I put all my public variables in type wrappers, so even though they are global, from the type name I can recall the intended use.
 
Project management and documentation to manage a bloody variable? - This alone is a sufficiently strong counter-argument against global variables to avoid them whenever possible.
How many people active in this forum have documentation and/or project management for their applications?

Putting words where they were not.... You use project management and documentation to manage the project that CONTAINS global-scope variables. Your document will enumerate functions, subroutines, logic flow, data structures, ... and any wide-scope variables. To answer your question, I surely had documentation to enumerate all of the things I listed. The U.S. Navy required it. They acknowledged the existence of that particular bird. They have had documentation guidelines for at least the 28 1/2 years I worked as a Navy contractor. Their guidance, if I recall correctly, and this is paraphrased, was "rare but used when necessary." I also had that level of project documentation for my oil-and-gas pipeline projects from the 1970s and 1980s. Back then, Yourdon and Boehm wrote books about project management and concluded that good project documentation was a sine qua non for successful projects. It is not my fault if you learned programming in a vacuum of guidance.

If you use the Windows user name it is impossible that this will change during the run time of the current instance of your application. For that reason, using a global variable to store it is in itself a design fault.

Given the structural constraints of VBA, I have two choices - make a function or subroutine call every time I need the username, or put it somewhere convenient for later use. BUT since it is only available after the app launches, I cannot put it in a constant. So I have to put it somewhere convenient. My choices now become either a TempVars slot or a public variable - both of which have raised your hackles. Multiply that by the need to recall the user's security profile, privileges, and other flow-controlling variables that applied security to each of over 30 forms, and putting those variables behind a function was just that much more complex. That's where the KISS principle says "not so many layers, please."

By just slightly extending the logic of "avoiding global variables" you would quickly come to the conclusion that storing variables in a module declaration area - even for class modules - is ALSO bad.

The truth is that other languages have different scoping rules. I have worked in languages where the variables of your subroutine's caller are also visible to the called subroutine, on up the line regarding (essentially) "what's on the call stack?" They had context-specific global visibility. The whole problem comes down to engineering - the art of making it work in the least breakable way you can manage.
 
Putting words where they were not.... You use project management and documentation to manage the project that CONTAINS global-scope variables.
I might have a vague idea about documentation and project management. Nevertheless, I prefer code that can be maintained without consulting the documentation for each variable encountered.

It might be my learning programming in a vacuum of guidance that makes me value general principles of making things work in the least breakable way I can manage higher than project specific ones, which need to be created, learned, and maintained.

Don’t get me wrong, I support global variables being properly documented. Still, I would rather forgo them altogether.

BTW: My question was not whether you got project management and documentation. – I assumed you did, from your previous comments in that regard.

I have two choices - make a function or subroutine call every time I need the username, or put it somewhere convenient for later use.
I don’t see any reason why a function call would be less convenient than accessing a variable directly.

If your KISS principle values raw global variables, an inexhaustible source of unexpected and undesired behavior, more than wrapping those variables in 3 lines of code, I would say it is in urgent need of replacement.

By just slightly extending the logic of "avoiding global variables" you would quickly come to the conclusion that storing variables in a module declaration area - even for class modules - is ALSO bad.
Actually, I came to that conclusion already and try to avoid module scoped variables as well. – That’s why I recommended a static one for the first username example. – However, module scoped variables are much less problematic because of their clearly limited scope. So, they are a huge improvement over global ones and their existence is justified by their benefits in most cases.
 
I think we will have to agree to disagree. However, I will add this comment:

I don’t see any reason why a function call would be less convenient than accessing a variable directly.

That is because you don't see the behind-the-scenes overhead involved in making system calls that require you to change contexts from user mode to non-user mode. That is because user information in a domain setting is kept in a separate memory area. If a purely user-mode function would do it, that is a totally different question. The earlier suggestion (Dave/Gemma the Husky) of making a home-grown class module to record user info and keeping it protected behind the class object is a better choice because the relatively low overhead of using a class module (which stays in User mode AND in your user memory as opposed to system memory) is preferable.

Nevertheless, I prefer code that can be maintained without consulting the documentation for each variable encountered.

For lone-wolf programming, that works. The MOMENT you have a development team, even only a couple of people, that attitude totally fails. No, you don't develop where you reference the "book" for every variable every time you use it. Having been a project leader and a department head, I can tell you that your first lesson would be the "corporate standards" book. Your second lesson would be the "project architecture" book. I do not disrespect you as a person, but I must point out that if you don't understand my position, it is because you have a parochial viewpoint.

Quoth the bard: "There are more things in heaven and earth, Horatio, Than are dreamt of in your philosophy."
 
I think we will have to agree to disagree.
Finally something to agree on. :)
That is because you don't see the behind-the-scenes overhead involved in making system calls that require you to change contexts from user mode to non-user mode. That is because user information in a domain setting is kept in a separate memory area. If a purely user-mode function would do it, that is a totally different question.
Windows distinguishes between User Mode and Kernel Mode. I don't think retrieving the Windows username requires code to run in Kernel mode. - I've to admit though: I do not know for sure.

In any case, my suggestion of caching the username in a static variable will definitely only run in User mode except for the very first call, where your code to initially retrieve the value of the global variable would also need to call the Windows API.

Your case here is for caching the results of expensive calculations. To that I absolutely agree. Whether you store the cached results in a globally writable location or not is an entirely different matter.

I can tell you that your first lesson would be the "corporate standards" book. Your second lesson would be the "project architecture" book. I do not disrespect you as a person, but I must point out that if you don't understand my position, it is because you have a parochial viewpoint.
I still struggle for breath...
I'm usually the person writing and maintaining these documents. From this parochial viewpoint, it's so much easier to write "Don't use global variables!" instead of documenting any number of them. - Yes, sure, global functions of significance require a similar amount of documentation, but at least my mind is at ease knowing that I will not spend hours debugging obscure errors caused by unintended global variable changes.
 

Users who are viewing this thread

Back
Top Bottom