473,465 Members | 1,524 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Wish List Item

I frequently use OpenArgs to pass a value to a form; it would be nice if
there was a similarly easy way to return a value from a called form.

Darryl Kerkeslager
Nov 13 '05 #1
23 1913
Put the following code in the calling form:

DoCmd.OpenForm "NameOfFormToOpen",,,,,acDialog,"OpenArgsvalue "
If IsLoaded("NameOfFormToOpen") Then
Me!MyField = Forms!NameOfFormToOpen!NameOfControlHoldingReturnV alue

< Do Whatever >

End If

--
PC Datasheet
Your Resource For Help With Access, Excel And Word Applications
re******@pcdatasheet.com
www.pcdatasheet.com
"Darryl Kerkeslager" <Ke*********@comcast.net> wrote in message
news:gO********************@comcast.com...
I frequently use OpenArgs to pass a value to a form; it would be nice if
there was a similarly easy way to return a value from a called form.

Darryl Kerkeslager

Nov 13 '05 #2
"Darryl Kerkeslager" wrote
I frequently use OpenArgs to pass a
value to a form; it would be nice if
there was a similarly easy way to
return a value from a called form.


Unless the Form is opened "Modal", the calling code will continue to
execute, and the Procedure from which the Form was opened may well be
completed when the Form is Closed. That makes it, at best, problematical to
return a value from a Form opened from code.

There are some "workarounds", such as having an always present, but
invisible, Form into a Control on which the return value could be stored, or
having a standard module with some Public variables for this purpose. None
is quite as convenient, I'll admit, as having a function that opens a form,
waits, and returns some value when that form closes.

Larry Linson
Microsoft Access MVP
Nov 13 '05 #3
Hi Larry,

A note to the last line in your response ---

<<....and returns some value when that form closes. >>

A value from the second form can not be returned if the form is closed. The
form's visible property must be set to False so the form remains open to
return a value.

Steve
PC Datasheet
"Larry Linson" <bo*****@localhost.not> wrote in message
news:UT8pd.3765$Rs2.665@trnddc03...
"Darryl Kerkeslager" wrote
> I frequently use OpenArgs to pass a
> value to a form; it would be nice if
> there was a similarly easy way to
> return a value from a called form.
Unless the Form is opened "Modal", the calling code will continue to
execute, and the Procedure from which the Form was opened may well be
completed when the Form is Closed. That makes it, at best, problematical

to return a value from a Form opened from code.

There are some "workarounds", such as having an always present, but
invisible, Form into a Control on which the return value could be stored, or having a standard module with some Public variables for this purpose. None
is quite as convenient, I'll admit, as having a function that opens a form, waits, and returns some value when that form closes.

Larry Linson
Microsoft Access MVP

Nov 13 '05 #4
"Darryl Kerkeslager" <Ke*********@comcast.net> wrote in message
news:gO********************@comcast.com...
I frequently use OpenArgs to pass a value to a form; it would be nice if
there was a similarly easy way to return a value from a called form.

Darryl Kerkeslager

I frequently use recreational drugs to brighten my life as a database
designer.
It would be nice if they were supplied for free.

Tina
Nov 13 '05 #5
As others has mentioned, if you open the form in acDialog mode, the calling
code waits..and you can thus grab any number of values from that form. The
trick invoices making the ok button set the forms visible to false..and then
the code continues...

I give a good explain here on how to do this here:

http://www.attcanada.net/~kallal.msn/Dialog/Index.html

--
Albert D. Kallal (Access MVP)
Edmonton, Alberta Canada
pl*****************@msn.com
http://www.attcanada.net/~kallal.msn
Nov 13 '05 #6
"PC Datasheet" wrote
A note to the last line in your response ---

<<....and returns some value when that form closes. >>

A value from the second form can
not be returned if the form is closed.
The form's visible property must be
set to False so the form remains open to
return a value.


A value from the second form could be returned in a number of ways, one of
which could be from the "Form Close" event "when the Form closes". It seems
reasonable that the final value of whatever would be the one Darryl would
want "returned".

Did I really leave the impression that I was saying that an already-closed
Form could return anything?

Larry Linson
Microsoft Access MVP
Nov 13 '05 #7
"Tina van Kuntenass" wrote
I frequently use recreational drugs to
brighten my life as a database
designer.


I don't doubt that for a nanosecond, Don. Happy Thanksgiving.
Nov 13 '05 #8

"Darryl Kerkeslager" <Ke*********@comcast.net> wrote in message
news:gO********************@comcast.com...
I frequently use OpenArgs to pass a value to a form; it would be nice if
there was a similarly easy way to return a value from a called form.


I just have the form send a value back to a hidden control on the calling
form when I click the OK button (or whatever).

You can also stuff a value in a table, or change the value of a global
variable, if you have a timer running to pick it up.

Nov 13 '05 #9
I have used all three solutions you've mentioned, and have flirted with the
method that PC Datasheet mentions, and Albert Kallal describes (both use
IsLoaded and pull the variable from the called form), but each method has
drawbacks.

Pulling the data from the called form requires a fair amount of extra
coding. While this may not be a problem 1-3 times, it could get old after
5-10 times.

Global variables can be unstable if there are unhandled errors, so I try to
avoid them (errors and global variables ...).

Using a table requires extra code to put the value into the table, and then
to get it back out of the table.

My preferred method has been the one you mention first, pushing the value
back from the called form. The problem I ran into with this is that when I
want to re-use the same form by calling it from multiple forms, I have to
pass the calling form's name in the OpenArgs in order to push it back to the
proper form\control.

Darryl Kerkeslager

"Daven Thrice" <da*********@NOyahooSPAM.com> wrote:
I just have the form send a value back to a hidden control on the calling
form when I click the OK button (or whatever).

You can also stuff a value in a table, or change the value of a global
variable, if you have a timer running to pick it up.

Nov 13 '05 #10
Yes, exactly.
Darryl Kerekslager

"Larry Linson" <bo*****@localhost.not> wrote:
There are some "workarounds", such as having an always present, but
invisible, Form into a Control on which the return value could be stored, or having a standard module with some Public variables for this purpose. None
is quite as convenient, I'll admit, as having a function that opens a form, waits, and returns some value when that form closes.

Nov 13 '05 #11
rkc

"Darryl Kerkeslager" <Ke*********@comcast.net> wrote in message
news:Uf********************@comcast.com...
I have used all three solutions you've mentioned, and have flirted with the method that PC Datasheet mentions, and Albert Kallal describes (both use
IsLoaded and pull the variable from the called form), but each method has
drawbacks.

Pulling the data from the called form requires a fair amount of extra
coding. While this may not be a problem 1-3 times, it could get old after
5-10 times.

Global variables can be unstable if there are unhandled errors, so I try to avoid them (errors and global variables ...).

Using a table requires extra code to put the value into the table, and then to get it back out of the table.

My preferred method has been the one you mention first, pushing the value
back from the called form. The problem I ran into with this is that when I want to re-use the same form by calling it from multiple forms, I have to
pass the calling form's name in the OpenArgs in order to push it back to the proper form\control.


The following is an alternative that handles everything from the calling
form.
The called form has no clue it's involved in any way.

<code in calling form>
Option Compare Database
Option Explicit

Private WithEvents tb As Access.TextBox

Private Sub cmdOpenForm_Click()
On Error GoTo Err_cmdOpenForm_Click

Dim stDocName As String
Dim stLinkCriteria As String

stDocName = "CalledForm"
DoCmd.OpenForm stDocName, , , stLinkCriteria

If Not tb Is Nothing Then
Set tb = Nothing
End If

Set tb = Forms(stDocName).Text0
tb.OnExit = "[Event Procedure]"

Exit_cmdOpenForm_Click:
Exit Sub

Err_cmdOpenForm_Click:
MsgBox Err.Description
Resume Exit_cmdOpenForm_Click

End Sub

Private Sub tb_Exit(Cancel As Integer)
Me.Text0 = "" & tb.Value
End Sub

</code in calling form>

Nov 13 '05 #12
"Darryl Kerkeslager" <Ke*********@comcast.net> wrote in
news:Uf********************@comcast.com:
My preferred method has been the one you mention first, pushing
the value back from the called form. The problem I ran into with
this is that when I want to re-use the same form by calling it
from multiple forms, I have to pass the calling form's name in the
OpenArgs in order to push it back to the proper form\control.


Use a class module to store the values. In fact, you could wrap the
called form in the class module and have the calling form initialize
the class. Your class could then automatically open the called form
as dialog, and on close, would populate the properties/members of
the class. Then your calling form would simply read the values out
of the class instance and then destroy it.

There are several advantages to this approach:

1. the called form needs to nothing about who called it -- it
communicates only with its wrapper class module.

2. the calling form needs to know nothing about the called form --
it just has to utilize the interface to it provided by the class
module.

You could also make a generic wrapper class module and use an array
in your class module to hold the property/value pairs that are
needed. Obviously, the calling context would need to know exactly
what properties are needed/supplied by the form, but that's the case
with a class module dedicated to a single form, as well.

Steve Jorgensen: comments on this? Have you done this kind of thing?
Any ideas on making it more foolproof with tricks to generate
compile-time errors?

--
David W. Fenton http://www.bway.net/~dfenton
dfenton at bway dot net http://www.bway.net/~dfassoc
Nov 13 '05 #13
David W. Fenton wrote:
Steve Jorgensen: comments on this? Have you done this kind of thing?
Any ideas on making it more foolproof with tricks to generate
compile-time errors?


Although I'm not Steve :-) I have indeed applied this technique and
wondered about an opportunity to get early binding. When I find
something browsing through my application remains, I will let you know.
--
Bas Cost Budde, Holland
http://www.heuveltop.nl/BasCB/msac_index.html
I prefer human mail above automated so in my address
replace the queue with a tea
Nov 13 '05 #14
This does sound like the best way to go, short of MS creating an OpenForm()
function.

Unfortunately for me, it would probably take me longer to write a truly
robust class module for this than it would take me to work around it several
times. Still, I may try my hand at it during Prolonged Periods of
Procrastination. However, if one of the many contributors to the newsgroup
with more skill than I should create such a module, I wouldn't spurn it ...
Darryl Kerkeslager

"David W. Fenton" <dX********@bway.net.invalid> wrote:
Use a class module to store the values. In fact, you could wrap the
called form in the class module and have the calling form initialize
the class. Your class could then automatically open the called form
as dialog, and on close, would populate the properties/members of
the class. Then your calling form would simply read the values out
of the class instance and then destroy it.

There are several advantages to this approach:

1. the called form needs to nothing about who called it -- it
communicates only with its wrapper class module.

2. the calling form needs to know nothing about the called form --
it just has to utilize the interface to it provided by the class
module.

Nov 13 '05 #15
Thanks. I'll have to give this a try. It sounds promising. Definitely not
something I had considered before, and it offers less extra coding than my
current method.

Darryl Kerkeslager
"rkc" <rk*@yabba.dabba.do.rochester.rr.bomb> wrote:

[compressed]
Option Compare Database
Option Explicit

Private WithEvents tb As Access.TextBox

Private Sub cmdOpenForm_Click()
On Error GoTo Err_cmdOpenForm_Click
DoCmd.OpenForm "CalledForm"
If Not tb Is Nothing Then Set tb = Nothing
Set tb = Forms("CalledForm").Text0
tb.OnExit = "[Event Procedure]"
Exit Sub
Err_cmdOpenForm_Click:
MsgBox Err.Description
End Sub

Private Sub tb_Exit(Cancel As Integer)
Me.Text0 = "" & tb.Value
End Sub

Nov 13 '05 #16
"Darryl Kerkeslager" <Ke*********@comcast.net> wrote in
news:I9********************@comcast.com:
Unfortunately for me, it would probably take me longer to write a
truly robust class module for this than it would take me to work
around it several times.


That is almost always the case with this kind of functionality.

But you've got to bite the bullet at some point and do it, or you're
forever rewriting the same code, with all the potential for error
that exposes you to.

--
David W. Fenton http://www.bway.net/~dfenton
dfenton at bway dot net http://www.bway.net/~dfassoc
Nov 13 '05 #17
rkc

"David W. Fenton" <dX********@bway.net.invalid> wrote in message
news:Xn**********************************@24.168.1 28.78...

<snip>
Use a class module to store the values. In fact, you could wrap the
called form in the class module and have the calling form initialize
the class. Your class could then automatically open the called form
as dialog, and on close, would populate the properties/members of
the class. Then your calling form would simply read the values out
of the class instance and then destroy it.

There are several advantages to this approach:

1. the called form needs to nothing about who called it -- it
communicates only with its wrapper class module.

2. the calling form needs to know nothing about the called form --
it just has to utilize the interface to it provided by the class
module.

You could also make a generic wrapper class module and use an array
in your class module to hold the property/value pairs that are
needed. Obviously, the calling context would need to know exactly
what properties are needed/supplied by the form, but that's the case
with a class module dedicated to a single form, as well.


Sort of a data access object that retrieves a simple 'recordset' from a
form's controls. Knowing the controls involved is no different than
knowing the columns you ask for when querying a table.


Nov 13 '05 #18
On Wed, 24 Nov 2004 23:29:24 GMT, "PC Datasheet" <no****@nospam.spam> wrote:
Put the following code in the calling form:

DoCmd.OpenForm "NameOfFormToOpen",,,,,acDialog,"OpenArgsvalue "
If IsLoaded("NameOfFormToOpen") Then
Me!MyField = Forms!NameOfFormToOpen!NameOfControlHoldingReturnV alue

< Do Whatever >

End If


You forgot to mention that the form must hide itself by setting me.Visible =
False so the calling code can continue, and that the calling code should close
the form after reading data from it, so it can be properly opened in dialog
mode again next time. Finally, you forgot to mention that you'll need to
write an IsLoaded function because there is no built-in function like that to
check whether an Access form is open.
Nov 13 '05 #19
On Wed, 24 Nov 2004 23:34:12 GMT, "Larry Linson" <bo*****@localhost.not>
wrote:
"Darryl Kerkeslager" wrote
I frequently use OpenArgs to pass a
value to a form; it would be nice if
there was a similarly easy way to
return a value from a called form.


Unless the Form is opened "Modal", the calling code will continue to
execute, and the Procedure from which the Form was opened may well be

....

Actually, the form must be opened using acDialog to prevent the calling code
from continuing to execute. Simply opening a modal form will not cause the
calling code to wait.
Nov 13 '05 #20
I just tried to apply this to my current sutuation. Unfortunately, the
requirements are too complex - I still need that 'return value'. For
instance, right now, I'm calling a form for the user to "Select an item from
the list or click the New button". While the OnExit would cover a
selection, clicking the New button can't be covered that way - I need a
return value of 0.
Darryl Kerkeslager

"rkc" <rk*@yabba.dabba.do.rochester.rr.bomb> wrote:
<code in calling form>
Option Compare Database
Option Explicit

Private WithEvents tb As Access.TextBox

Private Sub cmdOpenForm_Click()
On Error GoTo Err_cmdOpenForm_Click

Dim stDocName As String
Dim stLinkCriteria As String

stDocName = "CalledForm"
DoCmd.OpenForm stDocName, , , stLinkCriteria

If Not tb Is Nothing Then
Set tb = Nothing
End If

Set tb = Forms(stDocName).Text0
tb.OnExit = "[Event Procedure]"

Exit_cmdOpenForm_Click:
Exit Sub

Err_cmdOpenForm_Click:
MsgBox Err.Description
Resume Exit_cmdOpenForm_Click

End Sub

Private Sub tb_Exit(Cancel As Integer)
Me.Text0 = "" & tb.Value
End Sub

</code in calling form>

Nov 13 '05 #21
rkc

"Darryl Kerkeslager" <Ke*********@comcast.net> wrote in message
news:o7********************@comcast.com...
I just tried to apply this to my current sutuation. Unfortunately, the
requirements are too complex - I still need that 'return value'. For
instance, right now, I'm calling a form for the user to "Select an item from the list or click the New button". While the OnExit would cover a
selection, clicking the New button can't be covered that way - I need a
return value of 0.


You can catch any event of any control on the called form in the same
way the simple example I posted catches the textbox OnExit event.
The point was that the called form does not have to communicate
with, or even know the calling form exists. It can live in it's own
little world.

Catch the New button's OnClick event and do what ever you would
do with a return value of 0.


Nov 13 '05 #22
On Thu, 25 Nov 2004 19:21:49 GMT, "David W. Fenton"
<dX********@bway.net.invalid> wrote:
"Darryl Kerkeslager" <Ke*********@comcast.net> wrote in
news:Uf********************@comcast.com:
My preferred method has been the one you mention first, pushing
the value back from the called form. The problem I ran into with
this is that when I want to re-use the same form by calling it
from multiple forms, I have to pass the calling form's name in the
OpenArgs in order to push it back to the proper form\control.


Use a class module to store the values. In fact, you could wrap the
called form in the class module and have the calling form initialize
the class. Your class could then automatically open the called form
as dialog, and on close, would populate the properties/members of
the class. Then your calling form would simply read the values out
of the class instance and then destroy it.

There are several advantages to this approach:

1. the called form needs to nothing about who called it -- it
communicates only with its wrapper class module.

2. the calling form needs to know nothing about the called form --
it just has to utilize the interface to it provided by the class
module.

You could also make a generic wrapper class module and use an array
in your class module to hold the property/value pairs that are
needed. Obviously, the calling context would need to know exactly
what properties are needed/supplied by the form, but that's the case
with a class module dedicated to a single form, as well.

Steve Jorgensen: comments on this? Have you done this kind of thing?
Any ideas on making it more foolproof with tricks to generate
compile-time errors?


In one application, I had to do an awful lot of opening dialog forms and
getting user responses back, and I ended up with a scheme that combines a
generic helper function with specific wrapper functions for each case. The
call stack looks something like this...

1. Code calls specific wrapper function with parameters.
2. Wrapper function creates a collection, and adds the parameters using
parameter names as keys, and calls helper function, passing a form name and
the parameter collection.
3. Helper function adds the parameters collection to a global collection
variable using the form name as the collection key, and opens the indicated
form in dialog mode.
4. The form calls another helper function, passing Me as an argument.
5. The helper function grabs the parameters collection from the global
collection using <form>.name as the key, deletes that item from the global
collection to prevent collisions next time, and returns the parameters
collection to the form.

6. Now, the user interacts with the form, and selects an option telling the
form to close.

7. The form creates a return values collection, adds return values to the
collection, and calls a generic helper function for returning values, passing
Me and the collection as parameters.
8. The helper function again adds the parameters collection to a global
collection using the form's name as a key.
9. The form closes, and the generic helper function started in step 3
continues running.
10. The helper function that opened the form now gets the return values
collection from the global collection using the form name as a key, and
deletes the item from the global collection.
11. The helper function returns the return values collection to the specific
wrapper function.
12. The specific wrapper function reads the values from the return values
collection, and returns them to the caller either as a function return value,
via ByRef parameters, or both.

This combination of specific and generic layers provides a high degree of code
reuse, and a pretty high level of safety as well. Since the dialog form is
always called via a specific wrapper function with specific parameters and a
specific return type, everything is type-safe at that interface boundary.
Inside the boundary, there is no name or type safety, but if there is a
problem, the code will generally fail early and in obvious ways.

Notes and variations:
1. When I refer to the global collection variables above, that's just a
shorthand to make the explanation simpler. They are really private variables
at the head of the module that contains the helper functions.
2. The specific wrapper function can just as well be a wrapper class. In some
cases, that's helpful, and in other cases, it's way overkill.
3. You can actually pass any kind of an object to/from the form using this
code, not just a collection, so if you'd rather create a class for passing the
values back-and-forth, you can. Usually, this is overkill unless you'll be
passing the same parameters for multiple forms or unless you already have a
wrapper class - see #4 below.
4. Combination of 2 and 3 - If you have a wrapper class, you can have that
class pass itself as the parameter object to the form via the helper function,
and the form can hold a reference to it, and return values directly to members
of the wrapper class. The form does not need to call a helper function to
return values in this case.
Nov 13 '05 #23
"Steve Jorgensen" <no****@nospam.nospam> wrote
Actually, the form must be opened using
acDialog to prevent the calling code
from continuing to execute. Simply opening
a modal form will not cause the
calling code to wait.


Thanks for the catch, Steve.
Nov 13 '05 #24

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Joe Cox | last post by:
I appologize for the novice question. I believe in am using standard ECMA. Can someone explain to me why the following script works in IE but does not work in Firefox, Mozila, or Opera? ...
13
by: na1paj | last post by:
here's a simple linked list program. the DeleteNode function is producing an infinit loop i think, but i can't figure out where.. #include <stdio.h> typedef struct { char *str; //str is a...
24
by: Robin Cole | last post by:
I'd like a code review if anyone has the time. The code implements a basic skip list library for generic use. I use the following header for debug macros: /* public.h - Public declarations and...
10
by: Ryan Graham | last post by:
I totally bombed this question in an interview so I'm posting my answer here for comments and suggestions... perhaps (god help me) I'm just not that bright, but this works and seems to be fairly...
6
by: Rylios | last post by:
I am trying to make a very basic text editor using a linked list, fstream, sorting... This is what i have so far...
9
by: zacks | last post by:
I have written a serialized class that has several properties that are typed as a list of type class. When I deserialize an XML file, the list is populated just fine. But I am having trouble...
5
by: ibiza | last post by:
Hi all, I have a question which I have no ideal of the answer...I am currently working on a web application and at some time, I have a string representing a short text. This could be a simple...
6
by: ahart | last post by:
I'm pretty new to python and am trying to write a fairly small application to learn more about the language. I'm noticing some unexpected behavior in using lists in some classes to hold child...
1
by: jmartmem | last post by:
Greetings, I have a nagging problem with client-side dynamic dependent list boxes that perhaps someone can help me troubleshoot. I have a form with a series of dynamic dependent list boxes....
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.