Returning variables from external form

D

Dennis

Hi,

This is the second time I've asked this questions I this forum. I
understood the answer I received and have implemented it, but I see some
issues with it.

The question is how do I return varirables from external forms? For
example, I have a form that is called by a report. This form gets the report
parameters and returns the variables to the report using a global variable.

The global variables are set to null in the report, the form sets the values
for the global variables, and the report uses the variables.

When I asked the question, what is the "Access" way to return variables, I
was told the appropriate way was:

strLocalVariable = forms!frm_Name!txtControlName

I've written another report and parameter form using this technique and it
works fine.

Here is what botther me.

Using the global variable approach, the external form and the report are
"loosly coupled" (not sure if correct term). That is, if I changed the name
of the external form all I have to do is change one entry in the report and
everything is done. (I could get around this by storing all of the external
names in a table and have each form / report read the names from the table.)
For example, I change the name search form name from frm_Search_Cust to
frm_Cust_Search.

Using the form method it seems that I have tightly coupled the two progams.
Not only am I referencing the program name, I'm now directly accessing
variable names within that form! As I understand it, I would have to change
each varirable reference to use the new form name. In addition, if I change
the control names I now have to change all of the reference to that form
name. It seems like this adds a lot of potential maintence.

1. Is using global variables a bad thing in this specific circumstance and
use?
2. Is there a way to use the forms statement where I can indirectly access
the variables (so I can change the variable names without having to change
all of the cord in external programs that references those variables.).

I hope I phrased my question correctly and have provided enough information
for everyone.


Thanks,


Dennis
 
M

Marshall Barton

Dennis said:
This is the second time I've asked this questions I this forum. I
understood the answer I received and have implemented it, but I see some
issues with it.

The question is how do I return varirables from external forms? For
example, I have a form that is called by a report. This form gets the report
parameters and returns the variables to the report using a global variable.

The global variables are set to null in the report, the form sets the values
for the global variables, and the report uses the variables.

When I asked the question, what is the "Access" way to return variables, I
was told the appropriate way was:

strLocalVariable = forms!frm_Name!txtControlName

I've written another report and parameter form using this technique and it
works fine.

Here is what botther me.

Using the global variable approach, the external form and the report are
"loosly coupled" (not sure if correct term). That is, if I changed the name
of the external form all I have to do is change one entry in the report and
everything is done. (I could get around this by storing all of the external
names in a table and have each form / report read the names from the table.)
For example, I change the name search form name from frm_Search_Cust to
frm_Cust_Search.

Using the form method it seems that I have tightly coupled the two progams.
Not only am I referencing the program name, I'm now directly accessing
variable names within that form! As I understand it, I would have to change
each varirable reference to use the new form name. In addition, if I change
the control names I now have to change all of the reference to that form
name. It seems like this adds a lot of potential maintence.

1. Is using global variables a bad thing in this specific circumstance and
use?
2. Is there a way to use the forms statement where I can indirectly access
the variables (so I can change the variable names without having to change
all of the cord in external programs that references those variables.).

That is an excellent question and well stated.

The big problem with global variables (in a standard module)
is that they can be referenced AND CHANGED any time anywhere
in your VBA project. This means that there is no control
over the scope of the variables and it can be very difficult
to track down when you inadvertently use one of those
variables for some other purpose. In addition to that,
global variables in an MDB are reset whenever an un handled
error occurs anywhere in your project.

In terms of coupling, global variables have the potential to
be coupled to everything and you can not guarantee that you
know how tightly or loosely there use may be.

The idea of using the form controls directly is much safer
because the controls (not variables) only exist when the
form is open and they are not reset on un handled errors.

The question of changing the names of the controls need
never come up because they are no more meaningful than a VBA
variable name. To be sure their names should provide a clue
about their purpose, but once set should never need to be
changed, only the form itself and the report that uses the
form are the only entities that should even be aware of
them.

With all that said, I think it is better to avoid using a
prompt form for report information or criteria. In my
opinion, it is much, much better to put those controls
(along with a button to open the report) on a form that is
opened before the report. This way the needed information
can be entered and validated before allowing the user to
attempt to open the report. In addition, you can pass
information to the report using the OpenReport method's
OpenArgs argument so there is no need for the report to be
coupled back to the form. If the report's record source
needs to be filtered, it can be done via the WhereCondition
argument so there is little or no need to have any coupling
from the report's record source query back to the form
either.
 
T

Tom van Stiphout

On Mon, 8 Mar 2010 19:25:01 -0800, Dennis

It is good practice to minimize the use of global variables.

To answer your second question: you can certainly write code like
this:
const SEARCH_FORM as String = "frm_Search_Cust"
strLocalVariable = forms(SEARCH_FORM)!txtControlName

Now you have to change your form name only in one place.
You can even make this a Global Const in a standard module.

-Tom.
Microsoft Access MVP
 
D

Dennis

Marshall,

Thanks for the info – I did not know about the global variables being reset
if there is an error. Not good.

Your comments: The big problem with global variables (in a standard module)
is that they can be referenced AND CHANGED any time anywhere in your VBA
project. This means that there is no control over the scope of the variables
and it can be very difficult to track down when you inadvertently use one of
those variables for some other purpose.

Response: Very true. That is why I was using them for external forms.
That way I logically controlled the scope. But you are right, I could
inadvertently change them somewhere.


Your comment: In addition to that, global variables in an MDB are reset
whenever an un handled error occurs anywhere in your project.

Response: Ah – did not know that. That is not good.


Your comment: In terms of coupling, global variables have the potential to
be coupled to everything and you can not guarantee that you know how tightly
or loosely there use may be.

Response: I was going to disagree with you right up until I got to the word
“guaranteeâ€. You are correct.



Your comment: The question of changing the names of the controls need never
come up because they are no more meaningful than a VBA variable name. To be
sure their names should provide a clue about their purpose, but once set
should never need to be changed, only the form itself and the report that
uses the form are the only entities that should even be aware of them.

Response: This is true, but I still find myself going back and changing
stuff once in a while.

The form and the report are not the only place I use an “external†form. I
just created a customer lookup form where the user can select was field they
want to search on (address, phone, comment) and for what text they want to
search. I was planning on putting this form in quite a few places.

The languages I have used in the passed allowed me to call an “external
form†and pass parameters to and receive parameters back from the “external
formâ€. I’m just very uncomfortable having to “reach into†a form to get a
variable value. I guess I will just have to learn the Access way. I don’t
have to like it though.


Your comment: With all that said, I think it is better to avoid using a
prompt form for report information or criteria. In my opinion, it is much,
much better to put those controls (along with a button to open the report) on
a form that is opened before the report. This way the needed information can
be entered and validated before allowing the user to attempt to open the
report. In addition, you can pass information to the report using the
OpenReport method's OpenArgs argument so there is no need for the report to
be coupled back to the form. If the report's record source needs to be
filtered, it can be done via the WhereCondition argument so there is little
or no need to have any coupling from the report's record source query back to
the form either.

My Response: Ah, I guess I should have stopped and though about it. Very
good point! Much better way to do this.


Dennis
 
D

Dennis

Tom,


Your comment: To answer your second question: you can certainly write code
like this:
const SEARCH_FORM as String = "frm_Search_Cust"
strLocalVariable = forms(SEARCH_FORM)!txtControlName


Response: Ah, I learn a little more each day. Thanks.

Is there anyway that I can have the control name in a constant?


Ideally, I would like to have a section at the top of the form what I would
declare a public constant for the form such as:

const SEARCH_FORM as String = "frm_Search_Cust"
const CONTROL_NAME as String = “txtControlNameâ€


and in my code I would like something like you had:

strLocalVariable = forms(SEARCH_FORM)!(CONTROL_NAME)


I realize that this might be a bit of overkill, it would just make me feel
more comfortable with my code. That way if I do have to change a variable
name, I know that I only have to change it one place in the code.

My question is:
1. Can I do this?
2. If so, what is the syntax for it?


I’m still climbing the Access learning cliff and I’ve lost a lot of blood
from hitting my head against the rocks to many times.


Thanks you for you assistance.



Dennis
 
M

Marshall Barton

Dennis wrote:
[]
Your comment: The question of changing the names of the controls need never
come up because they are no more meaningful than a VBA variable name. To be
sure their names should provide a clue about their purpose, but once set
should never need to be changed, only the form itself and the report that
uses the form are the only entities that should even be aware of them.

Response: This is true, but I still find myself going back and changing
stuff once in a while.

That may happen, but then it generally means that the
programmer changed the purpose of the variable/control and
the name becomes misleading. In these hopefully rare
occasions, the programmer would already be changing all
sorts of things and should expect having to check back to
all original uses of the variable.

If that's not why a name was changed, then I propose that
the programmer did not put sufficient effort into choosing
the original name.

The form and the report are not the only place I use an “external” form. I
just created a customer lookup form where the user can select was field they
want to search on (address, phone, comment) and for what text they want to
search. I was planning on putting this form in quite a few places.

The languages I have used in the passed allowed me to call an “external
form” and pass parameters to and receive parameters back from the “external
form”. I’m just very uncomfortable having to “reach into” a form to get a
variable value. I guess I will just have to learn the Access way. I don’t
have to like it though.
[]

If you want to encapsulate references to a popup form that
return a value. then think about using a function that opens
the form (in Dialog mode), retrieves the value from the form
and returns the value to the calling procedure.

If the form needs to stay open, then there is no way to
guarantee there is a value to return and the references can
not be encapsulated. In this case, it is a far more complex
issue that should probably be event driven.
 
J

Jack Leach

const SEARCH_FORM as String = "frm_Search_Cust"
const CONTROL_NAME as String = “txtControlNameâ€


and in my code I would like something like you had:

strLocalVariable = forms(SEARCH_FORM)!(CONTROL_NAME)


strLocalVar = Forms(SEARCH_FORM).Controls(CONTROL_NAME)


Unfortunately with the Bang (!) operator you cannot substitute the name of
the control with a variable, and therefore must explicitly reference the
Controls collection of the form to provide the index for it.

I'm not sure I would call this overkill... I have a template form with a
common header section for my general form use, and all of the names of the
headers are stored as constants for this same reason.

hth
--
Jack Leach
www.tristatemachine.com

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

Dennis

Jack,

Thanks for the information. I will be coding my forms this way.


I guess I'm just lazy. This "strange idea" of coding in such a way that you
only have to change it once will never catch on. :)


Dennis
 
J

Jack Leach

Just in case:

http://www.skrol29.com/dev/en_vtools.htm

I month or two ago I asked about this because I had to change a table name
that was referenced througout various portions of the project, and MVP
Crystal Long (strive4peace) was nice enough to point me to this quite handy
utility.

--
Jack Leach
www.tristatemachine.com

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

Dennis

Jack, Crystal,

Thanks. VERY COOL. I will be downloading that software this weekend!


Dennis
 

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