By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,106 Members | 2,474 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,106 IT Pros & Developers. It's quick & easy.

Tip for strongly typed references to sub/parent forms/

P: n/a
Yup, Steve's full of tips, but hey, it makes him feel important, right?

Ok, here goes. I've been trying to improve encapsulation by putting code
in the same object as the stuff it affects, so I rarely refer to a subform
ir parent form's controls or records from the other form. Instead, I call
a procedure in that form that does the job.

That's all fine and good, and nothing at all revolutionary, but it leaves
one with an annoying dilemma. Either, you refer to things like
Me.Parent.FooProcedure() and don't get auto-sense help or compile-time
checking, or you declare a variable of type Form_frmFooParent in each
function, set it = to Me.Parent, then use that. You can remove some of
that duplication by doing the assignment once to a private variable on the
form once during Form_Open, but then if you ever reset the code, the form
is broken until you close it and re-open it.

Here's the new habit I've devised.

In a subform that wants a strongly typed reference to its parent, add a
function as follows...

Private Function ParentInstance() As Form_frmFooParent
Set ParentInstance = Me.Parent
End Function

Now, when you want to refer to the parent, just say something like
ParentInstance().FooProcedure(). Likewise, for each subform on a master
form, create a function in the master form's module like this...

Private Function FooChildInstance() As Form_frmFooChild
Set FooChildInstance = Me!subFooChild.Form
End Function

Foo-ooo chi-iild - things are gooonna get easie-er.

Nov 12 '05 #1
Share this Question
Share on Google+
25 Replies


P: n/a
On Fri, 17 Oct 2003 07:05:28 GMT, Steve Jorgensen
<no****@nospam.nospam> wrote:

I have a habit of setting to nothing all variables I created with Set:
Set MyForm = Forms!SomeForm
....
Set MyForm = Nothing

Not sure if this is overkill, but using your syntax I couldn't do
that. It's similar to CurrentDb().OpenRecordset often debated here
(and no definitive resolution afaik).

Have you seen any detrimental effects if you call your code a million
times?

-Tom.
Yup, Steve's full of tips, but hey, it makes him feel important, right?

Ok, here goes. I've been trying to improve encapsulation by putting code
in the same object as the stuff it affects, so I rarely refer to a subform
ir parent form's controls or records from the other form. Instead, I call
a procedure in that form that does the job.

That's all fine and good, and nothing at all revolutionary, but it leaves
one with an annoying dilemma. Either, you refer to things like
Me.Parent.FooProcedure() and don't get auto-sense help or compile-time
checking, or you declare a variable of type Form_frmFooParent in each
function, set it = to Me.Parent, then use that. You can remove some of
that duplication by doing the assignment once to a private variable on the
form once during Form_Open, but then if you ever reset the code, the form
is broken until you close it and re-open it.

Here's the new habit I've devised.

In a subform that wants a strongly typed reference to its parent, add a
function as follows...

Private Function ParentInstance() As Form_frmFooParent
Set ParentInstance = Me.Parent
End Function

Now, when you want to refer to the parent, just say something like
ParentInstance().FooProcedure(). Likewise, for each subform on a master
form, create a function in the master form's module like this...

Private Function FooChildInstance() As Form_frmFooChild
Set FooChildInstance = Me!subFooChild.Form
End Function

Foo-ooo chi-iild - things are gooonna get easie-er.


Nov 12 '05 #2

P: n/a
Well, if that was a proble, then using Me.Parent withoout assigning it to a
variable and clearing it later should be a problem just as it is with the
use of CurrentDB. If it were a problem, I think we would all know about it
by now.

On Fri, 17 Oct 2003 07:24:05 -0700, Tom van Stiphout
<to*****@no.spam.cox.net> wrote:
On Fri, 17 Oct 2003 07:05:28 GMT, Steve Jorgensen
<no****@nospam.nospam> wrote:

I have a habit of setting to nothing all variables I created with Set:
Set MyForm = Forms!SomeForm
...
Set MyForm = Nothing

Not sure if this is overkill, but using your syntax I couldn't do
that. It's similar to CurrentDb().OpenRecordset often debated here
(and no definitive resolution afaik).

Have you seen any detrimental effects if you call your code a million
times?

-Tom.
Yup, Steve's full of tips, but hey, it makes him feel important, right?

Ok, here goes. I've been trying to improve encapsulation by putting code
in the same object as the stuff it affects, so I rarely refer to a subform
ir parent form's controls or records from the other form. Instead, I call
a procedure in that form that does the job.

That's all fine and good, and nothing at all revolutionary, but it leaves
one with an annoying dilemma. Either, you refer to things like
Me.Parent.FooProcedure() and don't get auto-sense help or compile-time
checking, or you declare a variable of type Form_frmFooParent in each
function, set it = to Me.Parent, then use that. You can remove some of
that duplication by doing the assignment once to a private variable on the
form once during Form_Open, but then if you ever reset the code, the form
is broken until you close it and re-open it.

Here's the new habit I've devised.

In a subform that wants a strongly typed reference to its parent, add a
function as follows...

Private Function ParentInstance() As Form_frmFooParent
Set ParentInstance = Me.Parent
End Function

Now, when you want to refer to the parent, just say something like
ParentInstance().FooProcedure(). Likewise, for each subform on a master
form, create a function in the master form's module like this...

Private Function FooChildInstance() As Form_frmFooChild
Set FooChildInstance = Me!subFooChild.Form
End Function

Foo-ooo chi-iild - things are gooonna get easie-er.


Nov 12 '05 #3

P: n/a
no****@nospam.nospam (Steve Jorgensen) wrote in
<95********************************@4ax.com>:
Well, if that was a proble, then using Me.Parent withoout
assigning it to a variable and clearing it later should be a
problem just as it is with the use of CurrentDB. If it were a
problem, I think we would all know about it by now.


Uh, Steve? Remember the bookmark bug? It wasn't found until Access
had been in use for over half a decade.

I think the solution here is something similar to MichKa's wrapper
for a global db variable to refer to the currently opened MDB. You
create a function that returns the reference, but make the function
self-initializing.

To me, changing your function to:

Module-level variable:

Private frmMyParent As Form

Private Function ParentInstance() As Form_frmFooParent
If frmMyParent Is Nothing Then Set frmMyParent = Me.Parent
ParentInstance = frmMyParent
End Function

This would get rid of the problem Tom has with it, as well as
making it more efficient. Then I'd put a Set frmMyParent = Nothing
in the UnLoad event of the child form, though it should technically
not be needed (but then, we don't depend on VBA to properly honor
object variable scope in other places, so why depend on it here?).

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

P: n/a
On Oct 17 2003, 05:12 pm, dX********@bway.net.invalid (David W. Fenton)
wrote in news:94***************************@24.168.128.90:
I think the solution here is something similar to MichKa's wrapper
for a global db variable to refer to the currently opened MDB. You
create a function that returns the reference, but make the function
self-initializing.

To me, changing your function to:

Module-level variable:

Private frmMyParent As Form

Private Function ParentInstance() As Form_frmFooParent
If frmMyParent Is Nothing Then Set frmMyParent = Me.Parent
ParentInstance = frmMyParent
End Function

This would get rid of the problem Tom has with it, as well as
making it more efficient. Then I'd put a Set frmMyParent = Nothing
in the UnLoad event of the child form


Even better, instead of a function, make it a Property Get/Property Set
pair, so that you can use the same name when referring to the instance and
setting the private variable to Nothing.

--
(remove a 9 to reply by email)
Nov 12 '05 #5

P: n/a
On Fri, 17 Oct 2003 21:12:46 GMT, dX********@bway.net.invalid (David W.
Fenton) wrote:
no****@nospam.nospam (Steve Jorgensen) wrote in
<95********************************@4ax.com>:
Well, if that was a proble, then using Me.Parent withoout
assigning it to a variable and clearing it later should be a
problem just as it is with the use of CurrentDB. If it were a
problem, I think we would all know about it by now.
Uh, Steve? Remember the bookmark bug? It wasn't found until Access
had been in use for over half a decade.


Yup, but if this one is a bug, we've all been drinking from the poisoned
well for an awfully long time. Adding a function call in between the
..Parent reference and its use as a temporary immediate variable, I just
don't see how it could have any affect on the issue if there was one.
I think the solution here is something similar to MichKa's wrapper
for a global db variable to refer to the currently opened MDB. You
create a function that returns the reference, but make the function
self-initializing.

To me, changing your function to:

Module-level variable:

Private frmMyParent As Form

Private Function ParentInstance() As Form_frmFooParent
If frmMyParent Is Nothing Then Set frmMyParent = Me.Parent
ParentInstance = frmMyParent
End Function
I thought of that, and I do this kind of optimization all the time when I
have a need to, though when I do it, I use a static variable inside the
function instead of a private variable in the module. If the idea is to
provide a safe way of accessing the reference that works even if the code
gets reset, why invite trouble by making it accessible another way? Here's
what my version would look like...

Private Function ParentInstance() As Form_frmFooParent
Static sfrmParent As Form
If sfrmParent Is Nothing Then Set sfrmParent = Me.Parent
ParentInstance = sfrmParent
End Function

I don't do that for this function, though because I decided that to do so
was not so much anal retentive as obsessive compulsive (not that I haven't
been rightly accused of this attribute myself from time to time).
This would get rid of the problem Tom has with it, as well as
making it more efficient. Then I'd put a Set frmMyParent = Nothing
in the UnLoad event of the child form, though it should technically
not be needed (but then, we don't depend on VBA to properly honor
object variable scope in other places, so why depend on it here?).


More efficient, yes, but even without the optimization, I estimate that it
should still be greatly faster than some -really- slow operations such as
strFoo = "a". Personally, I choose not to bother with the optimization.
Nov 12 '05 #6

P: n/a
On 18 Oct 2003 00:05:21 GMT, Dimitri Furman <df*****@cloud99.net> wrote:
On Oct 17 2003, 05:12 pm, dX********@bway.net.invalid (David W. Fenton)
wrote in news:94***************************@24.168.128.90:
I think the solution here is something similar to MichKa's wrapper
for a global db variable to refer to the currently opened MDB. You
create a function that returns the reference, but make the function
self-initializing.

To me, changing your function to:

Module-level variable:

Private frmMyParent As Form

Private Function ParentInstance() As Form_frmFooParent
If frmMyParent Is Nothing Then Set frmMyParent = Me.Parent
ParentInstance = frmMyParent
End Function

This would get rid of the problem Tom has with it, as well as
making it more efficient. Then I'd put a Set frmMyParent = Nothing
in the UnLoad event of the child form


Even better, instead of a function, make it a Property Get/Property Set
pair, so that you can use the same name when referring to the instance and
setting the private variable to Nothing.


I hate to be argumentative, but this takes a 3-line solution that's
extremely simple to type and maintain, and turns it into at least 8 lines
of code. Furthermore, you can't use the static variable trick for
encapsulation because Property Set and Property Get are separate functions
that can't share a static variable.
Nov 12 '05 #7

P: n/a
no****@nospam.nospam (Steve Jorgensen) wrote in
<27********************************@4ax.com>:
On Fri, 17 Oct 2003 21:12:46 GMT, dX********@bway.net.invalid
(David W. Fenton) wrote:
no****@nospam.nospam (Steve Jorgensen) wrote in
<95********************************@4ax.com>:
Well, if that was a proble, then using Me.Parent withoout
assigning it to a variable and clearing it later should be a
problem just as it is with the use of CurrentDB. If it were a
problem, I think we would all know about it by now.
Uh, Steve? Remember the bookmark bug? It wasn't found until
Access had been in use for over half a decade.


Yup, but if this one is a bug, we've all been drinking from the
poisoned well for an awfully long time. . . .


All I'm saying is that just because something has been used for a
long time without any apparent problems does not mean that it
wouldn't be a problem in the future. That was what you said, and I
was just pointing out an example where it took 5 years to discover
a really significant problem with something that had been widely
used and no one had noticed the problem.
. . . Adding a function call in
between the .Parent reference and its use as a temporary immediate
variable, I just don't see how it could have any affect on the
issue if there was one.
I have *no* idea what you're talking about here.
I think the solution here is something similar to MichKa's
wrapper for a global db variable to refer to the currently opened
MDB. You create a function that returns the reference, but make
the function self-initializing.

To me, changing your function to:

Module-level variable:

Private frmMyParent As Form

Private Function ParentInstance() As Form_frmFooParent
If frmMyParent Is Nothing Then Set frmMyParent = Me.Parent
ParentInstance = frmMyParent
End Function


I thought of that, and I do this kind of optimization all the time
when I have a need to, though when I do it, I use a static
variable inside the function instead of a private variable in the
module. . . .


I've never used static variables because they don't fit with the
model in my head of how scope should work. I know they *do* work,
but it's one of those things that bothers me, so I just don't use
them.
. . . If the idea is to provide a safe way of accessing the
reference that works even if the code gets reset, why invite
trouble by making it accessible another way? Here's what my
version would look like...

Private Function ParentInstance() As Form_frmFooParent
Static sfrmParent As Form
If sfrmParent Is Nothing Then Set sfrmParent = Me.Parent
ParentInstance = sfrmParent
End Function
That makes perfect sense to me, yes.
I don't do that for this function, though because I decided that
to do so was not so much anal retentive as obsessive compulsive
(not that I haven't been rightly accused of this attribute myself
from time to time).


You don't think the amount of time it takes to initialize the form
variable is not significant? Well, maybe it's not, but why set
something that's already been initialized? I am always bothered by
such things -- I believe you should only do it when you need to,
unless figuring out whether or not you need to takes just as much
time as doing it.

Or, in this case, if there's a potential memory leak in setting the
object variable again without having set it to Nothing.

I doubt there's a problem there, but I don't know for certain.
This would get rid of the problem Tom has with it, as well as
making it more efficient. Then I'd put a Set frmMyParent =
Nothing in the UnLoad event of the child form, though it should
technically not be needed (but then, we don't depend on VBA to
properly honor object variable scope in other places, so why
depend on it here?).


More efficient, yes, but even without the optimization, I estimate
that it should still be greatly faster than some -really- slow
operations such as strFoo = "a". Personally, I choose not to
bother with the optimization.


This is a case where we'll have to agree to disagree.

To me, your code looks sloppy, because it doesn't consider the
context in which it's running. I believe that you should initialize
such variables once, rather than each time you call them. Your
function repeatedly does unnecessary work, and my version (or your
static variable variation) are much more efficient and just as
reliable.

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

P: n/a
On Sat, 18 Oct 2003 21:06:05 GMT, dX********@bway.net.invalid (David W.
Fenton) wrote:
no****@nospam.nospam (Steve Jorgensen) wrote in
<27********************************@4ax.com>:
On Fri, 17 Oct 2003 21:12:46 GMT, dX********@bway.net.invalid
(David W. Fenton) wrote:
no****@nospam.nospam (Steve Jorgensen) wrote in
<95********************************@4ax.com>:

Well, if that was a proble, then using Me.Parent withoout
assigning it to a variable and clearing it later should be a
problem just as it is with the use of CurrentDB. If it were a
problem, I think we would all know about it by now.

Uh, Steve? Remember the bookmark bug? It wasn't found until
Access had been in use for over half a decade.
Yup, but if this one is a bug, we've all been drinking from the
poisoned well for an awfully long time. . . .


All I'm saying is that just because something has been used for a
long time without any apparent problems does not mean that it
wouldn't be a problem in the future. That was what you said, and I
was just pointing out an example where it took 5 years to discover
a really significant problem with something that had been widely
used and no one had noticed the problem.


OK, sure, but it appears to me that if there's a problem with calling a
function that indirectly resolves and returns a reference to Me.Parent,
that has precisely the same reliability issues, no more, and no less, than
simply referring to M.Parent in the calling code. A hidden problem?
Hypothetically, but I never was worried about it before, so I wasn't
planning to start worrying about it because I'm now inserting a function
call between part A and part B of the expression.
. . . Adding a function call in
between the .Parent reference and its use as a temporary immediate
variable, I just don't see how it could have any affect on the
issue if there was one.


I have *no* idea what you're talking about here.


OK, when I refer to Me.Parent, that's a property reference that gives me
back an object reference to the parent control. In my code, if I make a
reference to Me.Parent!txtValue, I expect that, behind the scenes, VB is
creating a temporary reference to the parent form, then creating a
temporary reference to its default collection which is Controls (not
precisely, but close enough for this discussion), then looks up the control
with the name , "txtValue" in the colleciton, then finally looks up the
default value property (Value) and returns a variant from that. Finally,
all these temporary references fall out of scope.

Inserting a function call in the mix where the function call gets the
Me.Parent reference, and returns it to the calling function where it
remains temporarily until the rest of the chain is resolves makes very
little difference to the sequence of events, and I don't see how it could
insert any new issues, though it's true it won't solve any issues if they
already existed.
I think the solution here is something similar to MichKa's
wrapper for a global db variable to refer to the currently opened
MDB. You create a function that returns the reference, but make
the function self-initializing.

To me, changing your function to:

Module-level variable:

Private frmMyParent As Form

Private Function ParentInstance() As Form_frmFooParent
If frmMyParent Is Nothing Then Set frmMyParent = Me.Parent
ParentInstance = frmMyParent
End Function


I thought of that, and I do this kind of optimization all the time
when I have a need to, though when I do it, I use a static
variable inside the function instead of a private variable in the
module. . . .


I've never used static variables because they don't fit with the
model in my head of how scope should work. I know they *do* work,
but it's one of those things that bothers me, so I just don't use
them.


I use that same reasoning often. In this case, though, I've used static
variables for encapsulation enough now to trust the technique.
. . . If the idea is to provide a safe way of accessing the
reference that works even if the code gets reset, why invite
trouble by making it accessible another way? Here's what my
version would look like...

Private Function ParentInstance() As Form_frmFooParent
Static sfrmParent As Form
If sfrmParent Is Nothing Then Set sfrmParent = Me.Parent
ParentInstance = sfrmParent
End Function


That makes perfect sense to me, yes.
I don't do that for this function, though because I decided that
to do so was not so much anal retentive as obsessive compulsive
(not that I haven't been rightly accused of this attribute myself
from time to time).


You don't think the amount of time it takes to initialize the form
variable is not significant? Well, maybe it's not, but why set
something that's already been initialized? I am always bothered by
such things -- I believe you should only do it when you need to,
unless figuring out whether or not you need to takes just as much
time as doing it.


It may in fact be significant overhead for certain values of significant.
By percentage, the private or static variable reference is sure to be
faster by a significant amount. Still, the cost of allocating space on the
heap for a string would be higher in my estimation, but we all willingly do
that repeatedly in many functions without worrying about the cost
until/unless we see a performance problem - then we optimize. So, I could
see doing making the change for optimizaiton reasons in a form or 2 where a
performance issue came up, but otherwise, simple is good.
Or, in this case, if there's a potential memory leak in setting the
object variable again without having set it to Nothing.
Again, it is possible such an issue exists, but I'd decide to account for
that at the same time I decide I should never refer to Me.Parent without
assigning it to a variable, then setting it to Nothing when I was done with
it. If I didn't think I needed that before, then I don't think I need it
now. Of course, once the function is there and used, it's a convenient
place to put the fix later as you describe if an issue did prove to exist,
particularly in the case of subform references where search/replace can't
easily find all cases.
I doubt there's a problem there, but I don't know for certain.
This would get rid of the problem Tom has with it, as well as
making it more efficient. Then I'd put a Set frmMyParent =
Nothing in the UnLoad event of the child form, though it should
technically not be needed (but then, we don't depend on VBA to
properly honor object variable scope in other places, so why
depend on it here?).


More efficient, yes, but even without the optimization, I estimate
that it should still be greatly faster than some -really- slow
operations such as strFoo = "a". Personally, I choose not to
bother with the optimization.


This is a case where we'll have to agree to disagree.

To me, your code looks sloppy, because it doesn't consider the
context in which it's running. I believe that you should initialize
such variables once, rather than each time you call them. Your
function repeatedly does unnecessary work, and my version (or your
static variable variation) are much more efficient and just as
reliable.


I'm deciding that sloppy is sometimes OK, so long as it is consciously
chosen and considered, not simply due to thoughtlessness or ignorance. In
this case, I'm fine with choosing sloppy for the benefit of simplicity.

Here's another consideration. In the case of subform references from the
parent, it is actually possible that the subform reference could refer to
different subform objects at different times. If you keep a reference to
the subform so long as it's not Nothing, and the subform is changed, you
now have a non-Nothing reference to a closed form (the object still exists
because a reference remains even though the form is now closed).

So, if one was really committed to keeping a cached reference to the
subform, and assuming all errors not specifically handled in the function
should be raised to the calling code, I suppose one could write code like
this...

Private Function FooChildInstance() As Form_frmFooChild
Static sfrmFooChild As Form_frmFooChild
Dim blnDummy As Boolean
Proc_Start:
If sfrmFooChild Is Nothing Then
Set sfrmFooChild = Me!subFooChild.Form
Else
On Error Goto Proc_Err
blnDummy = Form.Modal
End If
Fn_Return:
Set FooChildInstance = sfrmFooChild
Proc_Err:
If Err.Number = constAccErrObjectClosedOrNotExist Then ' = 2467
Set sfrmFooChild = Nothing
Resume Proc_Start
Else
Err.Raise Err.Number, , Err.Description
End If
End Function

So, I'm going to paste -this- all over my form modules? And we've lost
some of the performance gain we had. If I did decide this approach was
worth it (and I won't), then I would probably want to refactor most of this
into another class that I can set up with a subform control reference, then
ask it at any time for the Form reference, and have it do the above
gyrations. I could go on about what this could lead to - or I can keep
doing...

Private Function FooChildInstance() As Form_frmFooChild
Set FooChildInstance = Me!subFooChild.Form
End Function

Granted, this line of reasoning does not apply to the Parent form case,
since the parent form reference can never change during the lifespan of the
subform.
Nov 12 '05 #9

P: n/a
no****@nospam.nospam (Steve Jorgensen) wrote in
<4a********************************@4ax.com>:
Here's another consideration. In the case of subform references
from the parent, it is actually possible that the subform
reference could refer to different subform objects at different
times. If you keep a reference to the subform so long as it's not
Nothing, and the subform is changed, you now have a non-Nothing
reference to a closed form (the object still exists because a
reference remains even though the form is now closed).


I thought the code was running from the child form and was a public
function of the child form?

Therefore, as long as you have the same function in all the child
forms, it really doesn't matter.

Didn't you start this thread out by talking about putting all the
code close to where it operates? If so, why are you now talking
about a problem that exists only if you're breaking that principle?

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

P: n/a
On Sun, 19 Oct 2003 19:12:23 GMT, dX********@bway.net.invalid (David W.
Fenton) wrote:
no****@nospam.nospam (Steve Jorgensen) wrote in
<4a********************************@4ax.com>:
Here's another consideration. In the case of subform references
from the parent, it is actually possible that the subform
reference could refer to different subform objects at different
times. If you keep a reference to the subform so long as it's not
Nothing, and the subform is changed, you now have a non-Nothing
reference to a closed form (the object still exists because a
reference remains even though the form is now closed).
I thought the code was running from the child form and was a public
function of the child form?

Therefore, as long as you have the same function in all the child
forms, it really doesn't matter.


No, it -wouldn't- really matter if we -weren't- talking about caching a
reference to the subform's Form object. If you change the subform
control's source, then the old, cached Form reference is closed, and there
is a new Form reference in the Subform control that is not what's cached.
To fix that, the function has to check for a closed form reference, and go
fetch the .Form reference from the subform control again.
Didn't you start this thread out by talking about putting all the
code close to where it operates? If so, why are you now talking
about a problem that exists only if you're breaking that principle?


See above. I can have 2 subforms with the same interface, and switch from
one to the other by changing the Source object string, and that works fine
with either Me!subFooChild.Form.FooProcedure or
FooChildInstance().FooProcedure when FooChildInstance is not caching the
reference, but it breaks with the simple cached reference version. To fix
it, FooChildInstance must check for a closd form reference and refresh its
cached reference - leading to the vastly more complex version of the cached
reference code.
Nov 12 '05 #11

P: n/a
On Sun, 19 Oct 2003 20:54:23 GMT, Steve Jorgensen <no****@nospam.nospam>
wrote:

....
See above. I can have 2 subforms with the same interface, and switch from
one to the other by changing the Source object string, and that works fine
with either Me!subFooChild.Form.FooProcedure or
FooChildInstance().FooProcedure when FooChildInstance is not caching the
reference, but it breaks with the simple cached reference version. To fix
it, FooChildInstance must check for a closd form reference and refresh its
cached reference - leading to the vastly more complex version of the cached
reference code.


A similar real-world situation in one of my apps - I have correlated
subforms on several tabs in a C/S application. For performance reasons, I
wait to set the subform sources until the tabs are selected, and clear the
hidden ones on Current of the main form. Here, I'm loading and re-loading
the same subform, but I get a separate instance each time, so a cached Form
reference would need to be refreshed.
Nov 12 '05 #12

P: n/a
no****@nospam.nospam (Steve Jorgensen) wrote in
<93********************************@4ax.com>:
On Sun, 19 Oct 2003 19:12:23 GMT, dX********@bway.net.invalid
(David W. Fenton) wrote:
no****@nospam.nospam (Steve Jorgensen) wrote in
<4a********************************@4ax.com>:
Here's another consideration. In the case of subform references
from the parent, it is actually possible that the subform
reference could refer to different subform objects at different
times. If you keep a reference to the subform so long as it's
not Nothing, and the subform is changed, you now have a
non-Nothing reference to a closed form (the object still exists
because a reference remains even though the form is now closed).


I thought the code was running from the child form and was a
public function of the child form?

Therefore, as long as you have the same function in all the child
forms, it really doesn't matter.


No, it -wouldn't- really matter if we -weren't- talking about
caching a reference to the subform's Form object. If you change
the subform control's source, then the old, cached Form reference
is closed, and there is a new Form reference in the Subform
control that is not what's cached. To fix that, the function has
to check for a closed form reference, and go fetch the .Form
reference from the subform control again.


I don't see the issue here.
Didn't you start this thread out by talking about putting all the
code close to where it operates? If so, why are you now talking
about a problem that exists only if you're breaking that
principle?


See above. I can have 2 subforms with the same interface, and
switch from one to the other by changing the Source object string,
and that works fine with either Me!subFooChild.Form.FooProcedure
or FooChildInstance().FooProcedure when FooChildInstance is not
caching the reference, but it breaks with the simple cached
reference version. To fix it, FooChildInstance must check for a
closd form reference and refresh its cached reference - leading to
the vastly more complex version of the cached reference code.


Then the subform's unload event needs to reset the reference in the
parent form, and the function in the parent form that returns the
reference to the child form needs to be self-healing, checking for
Nothing and resetting if necessary.

At this point, I've apparently completely lost track of what the
hell I'm talking about, so I'll just leave it at that!

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

P: n/a
no****@nospam.nospam (Steve Jorgensen) wrote in
<d4********************************@4ax.com>:
On Sun, 19 Oct 2003 20:54:23 GMT, Steve Jorgensen
<no****@nospam.nospam> wrote:
See above. I can have 2 subforms with the same interface, and
switch from one to the other by changing the Source object
string, and that works fine with either
Me!subFooChild.Form.FooProcedure or
FooChildInstance().FooProcedure when FooChildInstance is not
caching the reference, but it breaks with the simple cached
reference version. To fix it, FooChildInstance must check for a
closd form reference and refresh its cached reference - leading
to the vastly more complex version of the cached reference code.


A similar real-world situation in one of my apps - I have
correlated subforms on several tabs in a C/S application. For
performance reasons, I wait to set the subform sources until the
tabs are selected, and clear the hidden ones on Current of the
main form. Here, I'm loading and re-loading the same subform, but
I get a separate instance each time, so a cached Form reference
would need to be refreshed.


And with a wrapper around it that checks for validity, you wouldn't
have to worry about it, because you're acting on a function rather
than directly on a variable, and the function can be self-healing.

Which seems to me to be where I came in on this in the first place.

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

P: n/a
On Tue, 21 Oct 2003 02:16:35 GMT, dX********@bway.net.invalid (David W.
Fenton) wrote:
....
A similar real-world situation in one of my apps - I have
correlated subforms on several tabs in a C/S application. For
performance reasons, I wait to set the subform sources until the
tabs are selected, and clear the hidden ones on Current of the
main form. Here, I'm loading and re-loading the same subform, but
I get a separate instance each time, so a cached Form reference
would need to be refreshed.


And with a wrapper around it that checks for validity, you wouldn't
have to worry about it, because you're acting on a function rather
than directly on a variable, and the function can be self-healing.

Which seems to me to be where I came in on this in the first place.


Respectfully,

I know you were. And my point was that, the amount of code it would take
to make this work makes the whole idea no longer a simple, elegant
solution. If you go ahead and resolve the reference every call, you don't
have to worry about code for self-healing. Futhermore, the minimum
necessary amount of code that must be present in every case of the function
that does the self-healing is a mainenance issue, and the code is complex
enough that it has a reasonable probability of needing maintenance.

At this point, to me, the longer code starts to seem just as sloppy as the
short version, but is now also complicated and time consuming. And, if
your worried about tripping over unknown bugs, now you can also worry about
if there are resource leaks with repeatedly trying to access properties of
closed form references, whether closed forms still maintain module-private
variables for the form module leading to circular reference issues, etc.
Nov 12 '05 #15

P: n/a
On Tue, 21 Oct 2003 02:14:55 GMT, dX********@bway.net.invalid (David W.
Fenton) wrote:

....
No, it -wouldn't- really matter if we -weren't- talking about
caching a reference to the subform's Form object. If you change
the subform control's source, then the old, cached Form reference
is closed, and there is a new Form reference in the Subform
control that is not what's cached. To fix that, the function has
to check for a closed form reference, and go fetch the .Form
reference from the subform control again.
I don't see the issue here.


Cache a reference to a subform's Form object, now clear the subform
control's Control Source property, now set it again, now try
MyFooChildInstance().FooProcedure. The reference is not Nothing, but it
refers to the previous closed Form instance in the subform, so the call
fails. To fix that, you need more code in the MyFooChildInstance()
function to test whether the Form instance is closed, and attempt to
re-load it if so.
Didn't you start this thread out by talking about putting all the
code close to where it operates? If so, why are you now talking
about a problem that exists only if you're breaking that
principle?


See above. I can have 2 subforms with the same interface, and
switch from one to the other by changing the Source object string,
and that works fine with either Me!subFooChild.Form.FooProcedure
or FooChildInstance().FooProcedure when FooChildInstance is not
caching the reference, but it breaks with the simple cached
reference version. To fix it, FooChildInstance must check for a
closd form reference and refresh its cached reference - leading to
the vastly more complex version of the cached reference code.


Then the subform's unload event needs to reset the reference in the
parent form, and the function in the parent form that returns the
reference to the child form needs to be self-healing, checking for
Nothing and resetting if necessary.


I try to avoid having the subform need to know how the parent form is
handling it (principle of orthogonality). The subform should not have to
tell the parent form what it is doing. I would sooner make the mess in the
parent form checking for a closed form reference than that.
At this point, I've apparently completely lost track of what the
hell I'm talking about, so I'll just leave it at that!


Oh, you're no fun <g>.
Nov 12 '05 #16

P: n/a
no****@nospam.nospam (Steve Jorgensen) wrote in
<ep********************************@4ax.com>:
On Tue, 21 Oct 2003 02:14:55 GMT, dX********@bway.net.invalid
(David W. Fenton) wrote:

...
No, it -wouldn't- really matter if we -weren't- talking about
caching a reference to the subform's Form object. If you change
the subform control's source, then the old, cached Form
reference is closed, and there is a new Form reference in the
Subform control that is not what's cached. To fix that, the
function has to check for a closed form reference, and go fetch
the .Form reference from the subform control again.
I don't see the issue here.


Cache a reference to a subform's Form object, . . .


I've never suggested that.

I suggested wrapping the cached reference in a function and using
the function. When the cached reference becomes invalid, the
function can repair it.
. . . now clear the
subform control's Control Source property, now set it again, now
try MyFooChildInstance().FooProcedure. The reference is not
Nothing, but it refers to the previous closed Form instance in the
subform, so the call fails. . . .
Then you didn't write the code correctly. The subform's UnLoad
event should clear the reference.
. . . To fix that, you need more code in
the MyFooChildInstance() function to test whether the Form
instance is closed, and attempt to re-load it if so.


I am confused as to where the code is.

I thought you had spoken about putting the code in the child form.
And at some point we were talking about Me.Parent, which, of
course, means code running in the child form.

Now you've changed the subject to child forms being unloaded from
the parent form and that invalidating cached form references. If
the form reference were created by Me.Parent, it would be in the
child form. Since you've switched subforms, that's not going to
even exist any more.

We had some code in this thread that looked like this:

Private Function ParentInstance() As Form_frmFooParent
If frmMyParent Is Nothing Then Set frmMyParent = Me.Parent
ParentInstance = frmMyParent
End Function

That function in the child form would work just fine regardless of
whether or not you swapped child forms, unless you're talking about
a situation where you have cascading child forms, where you used
the lowest-level form to create a reference to the mid-level form
in the module of the top-level form.

Dim frm As Form

Set frm = Me!Child1.Form!Child2.Form.ParentInstance()

That makes no sense to me as a viable strategy, so I just don't see
what your point is here.

If you're swapping subforms, then have the code that swaps the
subform manage the cached reference. I don't see the problem, nor
what the hell it has to do with the beginning of this thread!
Didn't you start this thread out by talking about putting all
the code close to where it operates? If so, why are you now
talking about a problem that exists only if you're breaking
that principle?

See above. I can have 2 subforms with the same interface, and
switch from one to the other by changing the Source object
string, and that works fine with either
Me!subFooChild.Form.FooProcedure or
FooChildInstance().FooProcedure when FooChildInstance is not
caching the reference, but it breaks with the simple cached
reference version. To fix it, FooChildInstance must check for a
closd form reference and refresh its cached reference - leading
to the vastly more complex version of the cached reference code.


Then the subform's unload event needs to reset the reference in
the parent form, and the function in the parent form that returns
the reference to the child form needs to be self-healing,
checking for Nothing and resetting if necessary.


I try to avoid having the subform need to know how the parent form
is handling it (principle of orthogonality). The subform should
not have to tell the parent form what it is doing. I would sooner
make the mess in the parent form checking for a closed form
reference than that.


The code that swaps the child forms is the correct place for
managing cached form references.
At this point, I've apparently completely lost track of what the
hell I'm talking about, so I'll just leave it at that!


Oh, you're no fun <g>.


Well, it's no fun having an argument when you actually disagree --
it's much more fun to do it when you've just confused each other
and just talking past each other.

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

P: n/a
no****@nospam.nospam (Steve Jorgensen) wrote in
<ua********************************@4ax.com>:
On Tue, 21 Oct 2003 02:16:35 GMT, dX********@bway.net.invalid
(David W. Fenton) wrote:
...
A similar real-world situation in one of my apps - I have
correlated subforms on several tabs in a C/S application. For
performance reasons, I wait to set the subform sources until the
tabs are selected, and clear the hidden ones on Current of the
main form. Here, I'm loading and re-loading the same subform,
but I get a separate instance each time, so a cached Form
reference would need to be refreshed.
And with a wrapper around it that checks for validity, you
wouldn't have to worry about it, because you're acting on a
function rather than directly on a variable, and the function can
be self-healing.

Which seems to me to be where I came in on this in the first
place.


Respectfully,

I know you were. And my point was that, the amount of code it
would take to make this work makes the whole idea no longer a
simple, elegant solution. . ..


Simple and elegant to implement or simple and elegant to use?

Here's what I use for my global db variable these days:

Public Function dbWB(Optional ysnInitialize As Boolean = True) _
As DAO.Database
On Error GoTo errHandler
Dim strTest As String

If Not ysnInitialize Then GoTo closeDB

retryDB:
If dbCurrent Is Nothing Then
Set dbCurrent = CurrentDb()
End If
' now that we know the db variable is not Nothing,
' test if it's Open
strTest = dbCurrent.Name

exitRoutine:
Set dbWB = dbCurrent
Exit Function

closeDB:
If Not (dbCurrent Is Nothing) Then
Set dbCurrent = Nothing
End If
GoTo exitRoutine

errHandler:
Select Case Err.Number
Case 3420 ' Object invalid or no longer set.
Set dbCurrent = Nothing
If ysnInitialize Then
Resume retryDB
Else
Resume closeDB
End If
Case Else
MsgBox Err.Number & ": " & Err.Description, _
vbExclamation, "Error in Global Code.dbWB()"
Resume exitRoutine
End Select
End Function

I wouldn't call that simple or elegant code at all.

But, boy, is it sure as hell easy to use, simple and elegant to
implement! I never have to worry about whether I've set the
variable at all. I never have to worry about code resets. I never
have to worry about those rare cases where the db has been closed
but is not set to Nothing. The code takes care of all of it, and I
can just use dbWB as though it were a public variable.
. . . If you go ahead and resolve the
reference every call, you don't have to worry about code for
self-healing. Futhermore, the minimum necessary amount of code
that must be present in every case of the function that does the
self-healing is a mainenance issue, and the code is complex enough
that it has a reasonable probability of needing maintenance.
Perhaps this kind of thing could be wrapped in code that would not
have to be in every subform. I don't know if that's possible or
not, but it would be a solution that would be simple and elegant to
use, though internally it might be very complex.
At this point, to me, the longer code starts to seem just as
sloppy as the short version, but is now also complicated and time
consuming. And, if your worried about tripping over unknown bugs,
now you can also worry about if there are resource leaks with
repeatedly trying to access properties of closed form references,
whether closed forms still maintain module-private variables for
the form module leading to circular reference issues, etc.


Well, given that so far as I can see the code would have to be
pasted into every subform in order to be of use, yes, I see that
this might be an issue.

Maybe this is a case for a class module solution. Have your parent
form use a class module to set the subform references. Then you'd
use the class to work with the subform. That would put the code in
one place, rather than in every subform.

Yes, you'd have to manage the class modules just like the cached
subform references, but, as I suggested in the other reply I made
earlier, that should be handled in the code that manages swapping
the subforms.

And in this case, you could operate on the class instances and have
the classes be self-healing.

Now, I'm not saying this is what you should do. But it would solve
the problem you were trying to address and solve it in a way that
is elegant and simple to use, and does not proliferate code in the
subform. Nor does it require the parent form to know about the
child form or vice versa.

I suspect that given your current orientation, you'll reject this
solution, but I think that's a mistake. I avoided implementing
MichKa's db variable function because I needed to do a lot of
search and replacing, but once I did it in one app, I realized what
a huge productivity helper it was (as well as increasing
robustness), so I have gradually converted all my apps to use that
approach. I didn't see it until I implemented it, and I didn't
implement it until I had fully researched the issue.

Chicken and egg, I guess.

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

P: n/a
On Tue, 21 Oct 2003 19:27:21 GMT, dX********@bway.net.invalid (David W.
Fenton) wrote:
no****@nospam.nospam (Steve Jorgensen) wrote in
<ua********************************@4ax.com>:
On Tue, 21 Oct 2003 02:16:35 GMT, dX********@bway.net.invalid
(David W. Fenton) wrote:
...
A similar real-world situation in one of my apps - I have
correlated subforms on several tabs in a C/S application. For
performance reasons, I wait to set the subform sources until the
tabs are selected, and clear the hidden ones on Current of the
main form. Here, I'm loading and re-loading the same subform,
but I get a separate instance each time, so a cached Form
reference would need to be refreshed.

And with a wrapper around it that checks for validity, you
wouldn't have to worry about it, because you're acting on a
function rather than directly on a variable, and the function can
be self-healing.

Which seems to me to be where I came in on this in the first
place.
Respectfully,

I know you were. And my point was that, the amount of code it
would take to make this work makes the whole idea no longer a
simple, elegant solution. . ..


Simple and elegant to implement or simple and elegant to use?

Here's what I use for my global db variable these days:

.... code omitted for brevity
I wouldn't call that simple or elegant code at all.

But, boy, is it sure as hell easy to use, simple and elegant to
implement! I never have to worry about whether I've set the
variable at all. I never have to worry about code resets. I never
have to worry about those rare cases where the db has been closed
but is not set to Nothing. The code takes care of all of it, and I
can just use dbWB as though it were a public variable.
This I agree with. You eliminate the duplication, then make the common
function as advanced as it needs to be to make the calls that use it
simpler.
. . . If you go ahead and resolve the
reference every call, you don't have to worry about code for
self-healing. Futhermore, the minimum necessary amount of code
that must be present in every case of the function that does the
self-healing is a mainenance issue, and the code is complex enough
that it has a reasonable probability of needing maintenance.
Perhaps this kind of thing could be wrapped in code that would not
have to be in every subform. I don't know if that's possible or
not, but it would be a solution that would be simple and elegant to
use, though internally it might be very complex.


And that, I would also agree with. In my previous replies, though, I was
thinking that the code could not be factored out because the point was that
each call should return a value of the specific object type desired, and
that means one function per use case. -- I am seeing that this was not
correct --. Actually, it's just the call that casts the return type that
must be duplicated for each use case, so that topples msot of my previous
arguments.
At this point, to me, the longer code starts to seem just as
sloppy as the short version, but is now also complicated and time
consuming. And, if your worried about tripping over unknown bugs,
now you can also worry about if there are resource leaks with
repeatedly trying to access properties of closed form references,
whether closed forms still maintain module-private variables for
the form module leading to circular reference issues, etc.


Well, given that so far as I can see the code would have to be
pasted into every subform in order to be of use, yes, I see that
this might be an issue.

Maybe this is a case for a class module solution. Have your parent
form use a class module to set the subform references. Then you'd
use the class to work with the subform. That would put the code in
one place, rather than in every subform.


It funny, but I didn't make the connection the whole time we've been having
this discussion, but I just finished implementing a clsFormManager class
that is essentially solution you are describing! I just didn't think of
employing that class wrapped in functions that get the form reference from
the clsFormManager instance and casts it to the specific form type needed
in context.
Yes, you'd have to manage the class modules just like the cached
subform references, but, as I suggested in the other reply I made
earlier, that should be handled in the code that manages swapping
the subforms.
Which is in a class module - yes, I see the light.
And in this case, you could operate on the class instances and have
the classes be self-healing.
Again, the self-healing aspect of is as likely to run afoul of unknown bugs
as employing transitory references to the parent or subform. I think you
would probably say, though, that at least, now, there's a single likely
place to pur the work-around if there is such a bug, and there is a
work-around - and then I would have to agree.
Now, I'm not saying this is what you should do. But it would solve
the problem you were trying to address and solve it in a way that
is elegant and simple to use, and does not proliferate code in the
subform. Nor does it require the parent form to know about the
child form or vice versa.
Yop - I'm with you now.
I suspect that given your current orientation, you'll reject this
solution, but I think that's a mistake. I avoided implementing
No. I was rejecting it because I did not think it through thoroughly
enough. I was thinking that the code that casts to a specific type had to
be the same code that manages cached form references. I see, now, that it
doesn't.
MichKa's db variable function because I needed to do a lot of
search and replacing, but once I did it in one app, I realized what
a huge productivity helper it was (as well as increasing
robustness), so I have gradually converted all my apps to use that
approach. I didn't see it until I implemented it, and I didn't
implement it until I had fully researched the issue.

Chicken and egg, I guess.


Yes, the chicken and egg thing happens a lot in the evolution of
programming technique. I'm seeing the same thing with things like being
agressive about removing duplication early (a point you were actually
making better than me in this thread).

Tomorrow, I'll to seeing if it works to wrap my form manager class in a
function that returns a properly casted object reference as I believe it
should.
Nov 12 '05 #19

P: n/a
On Tue, 21 Oct 2003 19:14:20 GMT, dX********@bway.net.invalid (David W.
Fenton) wrote:
no****@nospam.nospam (Steve Jorgensen) wrote in
<ep********************************@4ax.com>:
On Tue, 21 Oct 2003 02:14:55 GMT, dX********@bway.net.invalid
(David W. Fenton) wrote:

...
No, it -wouldn't- really matter if we -weren't- talking about
caching a reference to the subform's Form object. If you change
the subform control's source, then the old, cached Form
reference is closed, and there is a new Form reference in the
Subform control that is not what's cached. To fix that, the
function has to check for a closed form reference, and go fetch
the .Form reference from the subform control again.

I don't see the issue here.
Cache a reference to a subform's Form object, . . .


I've never suggested that.

I suggested wrapping the cached reference in a function and using
the function. When the cached reference becomes invalid, the
function can repair it.
. . . now clear the
subform control's Control Source property, now set it again, now
try MyFooChildInstance().FooProcedure. The reference is not
Nothing, but it refers to the previous closed Form instance in the
subform, so the call fails. . . .


Then you didn't write the code correctly. The subform's UnLoad
event should clear the reference.
. . . To fix that, you need more code in
the MyFooChildInstance() function to test whether the Form
instance is closed, and attempt to re-load it if so.


I am confused as to where the code is.

I thought you had spoken about putting the code in the child form.
And at some point we were talking about Me.Parent, which, of
course, means code running in the child form.


Yes, I did switch because it's the case where the parent form uses a
function to get a typed reference to the subform that has the potential
breakage problem. In this case, I don't think the subform should tell the
parent form that it is unloading because it shouldn't have to know how the
parent is handling its reference. I see we are probably not disagreeing on
this.

....We had some code in this thread that looked like this:

Private Function ParentInstance() As Form_frmFooParent
If frmMyParent Is Nothing Then Set frmMyParent = Me.Parent
ParentInstance = frmMyParent
End Function

That function in the child form would work just fine regardless of
whether or not you swapped child forms, unless you're talking about
a situation where you have cascading child forms, where you used
the lowest-level form to create a reference to the mid-level form
in the module of the top-level form.
Yes, I'm on the same wavelength with you on this.
Dim frm As Form

Set frm = Me!Child1.Form!Child2.Form.ParentInstance()

That makes no sense to me as a viable strategy, so I just don't see
what your point is here.
I hope I successfully cleared this up above.
If you're swapping subforms, then have the code that swaps the
subform manage the cached reference. I don't see the problem, nor
what the hell it has to do with the beginning of this thread!


I had my wires crossed with you, and did not see what you were really
getting at with this. The only problem, then with having the same code
that returns the subform reference swap the subform is that the code that
returns the reference is returning a reference to the specific form object
type, and that's not the form manager object that you're suggesting should
do the swapping. Perhaps, this could be solved with an optional ByRef
parameter to return the form manager to code that needs to talk to it.
That means at least 2 more lines of code in each function that has to talk
to the manager, but that's not too bad, or perhaps, there's a more elegant
idea I haven't thought of yet.

OK, we could go with your idea of not trying to use statics for
encapsulation, and leave the managed form and form manager references in
private, form variables. I'd rather try to encapsulate for better safety,
and to not spread the code around so many parts of the module if there's a
way to do it. If only VBA allowed declaring at least private, local
classes within modules instead of -as- modules, this would all be easier to
do properly.

....
Oh, you're no fun <g>.


Well, it's no fun having an argument when you actually disagree --
it's much more fun to do it when you've just confused each other
and just talking past each other.


Well, we were really disagreeing partially and talking past each other
partially, but I actually do agree with you now.
Nov 12 '05 #20

P: n/a
rkc

"Steve Jorgensen" <no****@nospam.nospam> wrote in message
news:1k********************************@4ax.com...
Well, we were really disagreeing partially and talking past each other
partially, but I actually do agree with you now.


Do you have time to summerize what it is you two have agreed on?

This discussion has gone from a simple function that returns a
reference to a form instance, to talk of a form management class.
All based on the fear that calling the simple function a million times
might possibly under unknown conditions cause a memory leak.
A fear you rejected from the outset.
Nov 12 '05 #21

P: n/a
On Wed, 22 Oct 2003 11:09:27 GMT, "rkc"
<rk*@yabba.dabba.do.rochester.rr.bomb> wrote:

"Steve Jorgensen" <no****@nospam.nospam> wrote in message
news:1k********************************@4ax.com.. .
Well, we were really disagreeing partially and talking past each other
partially, but I actually do agree with you now.


Do you have time to summerize what it is you two have agreed on?

This discussion has gone from a simple function that returns a
reference to a form instance, to talk of a form management class.
All based on the fear that calling the simple function a million times
might possibly under unknown conditions cause a memory leak.
A fear you rejected from the outset.


Well, a simple function often evolves to handle more cases. Personally, my
fear level is very low here, but since there's a small performance benefit
to caching the form reference, and since other highly useful functions can
and would be added to the form manager, why not use it. I still think my
original idea is fine, but extending it with a reusable manager class is
better.

I do, in fact, have a form manager class, but I didn't think of combining
this with the original idea for sprinkling around 3 or 4 line functions
that return strongly typed form references. Among other things my form
manager class allows, you can...

1. check the form's dirty status (drilling down into subforms to see if any
one of them is Dirty)
2. Commit any unsaved changes in the form (or the dirty subform), returning
False if the commit failed due to errors, and not reporting to the user,
errors due to cancelling the BeforeUpdate since the user should have
already been alerted.
3. Undo changes...
4. Resize/rescale the form and all the objects it contains.

....and more
Nov 12 '05 #22

P: n/a
no****@nospam.nospam (Steve Jorgensen) wrote in
<ik********************************@4ax.com>:
Yes, the chicken and egg thing happens a lot in the evolution of
programming technique. I'm seeing the same thing with things like
being agressive about removing duplication early (a point you were
actually making better than me in this thread).


Ha ha! I WIN!!!!

;)

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

P: n/a
rk*@yabba.dabba.do.rochester.rr.bomb (rkc) wrote in
<Hz******************@twister.nyroc.rr.com>:
"Steve Jorgensen" <no****@nospam.nospam> wrote in message
news:1k********************************@4ax.com.. .
Well, we were really disagreeing partially and talking past each
other partially, but I actually do agree with you now.


Do you have time to summerize what it is you two have agreed on?

This discussion has gone from a simple function that returns a
reference to a form instance, to talk of a form management class.
All based on the fear that calling the simple function a million
times might possibly under unknown conditions cause a memory leak.
A fear you rejected from the outset.


That was actually only one of my objections, but Steve's addressing
it was what caused us to go off the rails.

I'm delighted to find that Steve and I do look at the situation in
the same fashion, as I so greatly respect his expertise and points
of view on these kinds of issues.

My issues are:

1. re-use of code.

2. minimal need for any form/subform to know about the internals of
objects outside itself.

3. self-healing code that won't error out on a reset, and in some
cases, that doesn't even need to be initialized (it's
self-initializing).

Steve's solution of just resetting the variable each time was, to
my way of thinking, too brute force simple and also had the slight
risk of causing memory leaks. Fixing that aspect of it added one
line of code and a variable (either static within the sub or at the
form level). I don't see that as too bad in terms of making the
code more reliable.

But Steve then changed to the subform swapping issue, and then he
completely lost me!

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

P: n/a
rkc

"David W. Fenton" <dX********@bway.net.invalid> wrote in message
news:94***************************@24.168.128.78.. .
rk*@yabba.dabba.do.rochester.rr.bomb (rkc) wrote in
<Hz******************@twister.nyroc.rr.com>:
"Steve Jorgensen" <no****@nospam.nospam> wrote in message
news:1k********************************@4ax.com.. .
Well, we were really disagreeing partially and talking past each
other partially, but I actually do agree with you now.


Do you have time to summerize what it is you two have agreed on?

This discussion has gone from a simple function that returns a
reference to a form instance, to talk of a form management class.
All based on the fear that calling the simple function a million
times might possibly under unknown conditions cause a memory leak.
A fear you rejected from the outset.


That was actually only one of my objections, but Steve's addressing
it was what caused us to go off the rails.

I'm delighted to find that Steve and I do look at the situation in
the same fashion, as I so greatly respect his expertise and points
of view on these kinds of issues.

My issues are:

1. re-use of code.


Re-use of code wasn't an issue in the original post. Not only was
the name of the parent form built in to the function, knowledge of a
function in the parent form was also necessary. That was the problem
I had with it. But that had nothing to do with the point of his original
post.

Like you, I lost track of what was being discussed after that.

I also had trouble seeing why anyone would liken his original function
to the CurrentDB function. His function did nothing but return a
reference to a form set using me.parent. CurrentDB obviously does
much more than that and more than likely causes it's own problems
doing what it does before it returns a reference to the current database
object.

Nov 12 '05 #25

P: n/a
rk*@yabba.dabba.do.rochester.rr.bomb (rkc) wrote in
<fh******************@twister.nyroc.rr.com>:

"David W. Fenton" <dX********@bway.net.invalid> wrote in message
news:94***************************@24.168.128.78. ..
rk*@yabba.dabba.do.rochester.rr.bomb (rkc) wrote in
<Hz******************@twister.nyroc.rr.com>:
>"Steve Jorgensen" <no****@nospam.nospam> wrote in message
>news:1k********************************@4ax.com.. .
>
>> Well, we were really disagreeing partially and talking past
>> each other partially, but I actually do agree with you now.
>
>Do you have time to summerize what it is you two have agreed
>on?
>
>This discussion has gone from a simple function that returns a
>reference to a form instance, to talk of a form management
>class. All based on the fear that calling the simple function a
>million times might possibly under unknown conditions cause a
>memory leak. A fear you rejected from the outset.
That was actually only one of my objections, but Steve's
addressing it was what caused us to go off the rails.

I'm delighted to find that Steve and I do look at the situation
in the same fashion, as I so greatly respect his expertise and
points of view on these kinds of issues.

My issues are:

1. re-use of code.


Re-use of code wasn't an issue in the original post. . .


No, but that was one of the problems with my solution that Steve
objected to -- it meant to much code of too high a level of
complexity duplicated in too many different places.
. . . Not only was
the name of the parent form built in to the function, knowledge of
a function in the parent form was also necessary. . . .
I'm not sure I remember that part of the thread. Me.Parent is, by
definition, a method of removing references to particular forms.
. . . That was the
problem I had with it. But that had nothing to do with the point
of his original post.

Like you, I lost track of what was being discussed after that.

I also had trouble seeing why anyone would liken his original
function to the CurrentDB function. His function did nothing but
return a reference to a form set using me.parent. CurrentDB
obviously does much more than that and more than likely causes
it's own problems doing what it does before it returns a reference
to the current database object.


I wasn't comparing to CurrentDB. I was comparing this cached
reference to a form to the practice of caching a reference to the
currently opened MDB (so as to avoid repeated calls to either
CurrentDB() or DBEngine(0)(0)). Steve's original code did not have a
cached reference, but returned the reference afresh each time it was
called, and I objected to that, proposing caching the reference.

And then the wheels came off the wagon. . . ;)

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

This discussion thread is closed

Replies have been disabled for this discussion.