A Microsoft Office (Excel, Word) forum. OfficeFrustration

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

Go Back   Home » OfficeFrustration forum » Microsoft Access » Using Forms
Site Map Home Register Authors List Search Today's Posts Mark Forums Read  

Calling a Function on a subform from the Main Form (Round II)



 
 
Thread Tools Display Modes
  #1  
Old May 7th, 2008, 09:29 PM posted to microsoft.public.access.forms
Max Moor
external usenet poster
 
Posts: 148
Default Calling a Function on a subform from the Main Form (Round II)

Hi All,

I asked how to do this some time back, and got a response from Allen
Browne, explaining (in part):

If the subform is name Sub1, and the procedure is named Text0_AfterUpdate,
you can then call it like this:

Call Form_Sub1.Text0_AfterUpdate


I 've been doing this and everything works fine. Every so often, I
get a sick desire to understand what's happening under all the comfy layers
I usually stay above.

In this case, when I make a call like the one above, how would Access
know that I wanted the instance of Form_Sub1 that is a child on the main
form making the call? I think this has worked so far because I never have
more than one instance of any given form open at a time.

Allen also suggested that the function being called be moved into a
standard module, then passed a reference to the form I want to work done
by. I can see how that would fix things.

In search of a calling convention that would properly resolve to the
child form's function, I tried, "Call Forms!frmMain!
fsub_Child.Form.FuncCall", where fsub_Child is the subform's control name.
It didn't work, but I'm sure those of you in the know could have told me
that it wouldn't.

Is there a syntax that I could use to call the child form's function
specifically?

Regards,
Max
  #2  
Old May 7th, 2008, 11:30 PM posted to microsoft.public.access.forms
Albert D. Kallal
external usenet poster
 
Posts: 2,874
Default Calling a Function on a subform from the Main Form (Round II)

"Max Moor" wrote in message
. 16...
Hi All,

I asked how to do this some time back, and got a response from Allen
Browne, explaining (in part):

If the subform is name Sub1, and the procedure is named Text0_AfterUpdate,
you can then call it like this:

Call Form_Sub1.Text0_AfterUpdate


Actually, the above syntax is wrong, because you using the forms "base"
class object, and you NEVER EVER want to do that.

The reason why you never want to do this, is if the form is not loaded, the
above syntax will actually create an instance of that form, and all the
forms events such as on load, on open etc. will in fact fire, and that is
completely unexpected behavior.

Furthermore, you are confusing the concept of a sub form, and that of a sub
form control. In the access world, in a sense, there's no such thing as a
true sub form, but only a control called sub form "control" that you place
into a regular existing form. Keep in mind that most of the time you usually
give that sub form control the same name as the form, but it does not have
to be so.

For example, many developers to reduce confusion always use a different name
for the text box controls that they place on a form, as opposed to the
underlying fields that the control is bound to. By doing this, they
never get confused if they're referencing a control in their code, or the
actual direct underlying record set in their code. And of course the worst
thing to do is to have a text control box that's not bound, but has the same
name as the underlying field in the form, then things get really confusing
fast.

So, first and foremost I can't stress enough that when you place a sub form
into a form, you are placing a control on the form, not a real sub form.
Furthermore, what this means is that if you have five sub form controls on
your form named F1 to f5, you're now free have these five sub form controls
set or point to any instance of any form you have in your application.
Furthermore, those sub form controls can all point to the same form. If you
take a look at the following screen shot you'll see to create a calendar I
simply placed a grid of sub form controls laid out in a calendar fashion.

The result is in a small amount of time, I've created a very functional
outlook style calendar with almost no code:

http://www.kallal.ca/ridestutorialp/setdriver.htm

(Take a look at the third screen shot the above, you'll see it's a grid of 7
x 6 sub forms. That means the actual form (frmDay) used by the sub-form
control is repeated 42 times!!!)

So the question then becomes, when we have 42 instances of the same form
active here, how are you going to know which form you're actually
referencing?

To make a long story short, you're original syntax don't know what form it
going to reference when that form is used several places in your application
as a sub form (which one will it call).

Furthermore if you used more advanced coding techniques, often you will
allow multiple instances of one form to be opened at the **same** time.
Often a developer will "enable/allow" this feature in applications,
especially
when they're doing entry of a customer, the phone rings, and they have to
inquire and deal with another customer, but are halfway through entering a
whole bunch of data in the current existing form. If you don't want to lose
your place in the current form, it is perfectly legal in MS access to write
your code that supports multiple instances of the same form opened more then
once. I should point out that having multiple instances of forms also works
well when those forms have many sub forms inside of them.

So, you never want to access the base class object of a form in code,
because it causes an instance of that form to be created in code at that
point in time (unless, there's *already* one instance of that form created,
then MS uses that instance! I believe this **why your** above coding
practice has been working up to this point in time. While most developers
don't do extra coding to allow multiple instances of the same form open, it
is quite common that a sub form will be used more in one place in your
application.

Because you have no control over what instance of the base class object of
the form is being used, and when where and how it is being used, then you
really have to avoid that syntax altogether.


In this case, when I make a call like the one above, how would Access
know that I wanted the instance of Form_Sub1 that is a child on the main
form making the call?


As I said, in your case it simply takes the first instance of that form that
was created, and as I mentioned you only been *very* lucky up to this point.
Furthermore, your syntax will actually launch a copy of that form, if it's
currently not in use, and all of the forms events such as on load, open etc
will fire, and that is unexpected behavior.

I think this has worked so far because I never have
more than one instance of any given form open at a time.


Golly, I should have read your post BEFORE I started typing! You are 100%
right on the money here!


In search of a calling convention that would properly resolve to the
child form's function, I tried, "Call Forms!frmMain!
fsub_Child.Form.FuncCall", where fsub_Child is the subform's control name.
It didn't work, but I'm sure those of you in the know could have told me
that it wouldn't.

Is there a syntax that I could use to call the child form's function
specifically?


If you inside of the "main" form, then you can go:

call me.subFormContorl.Form.NameOfSub

or in your example:

Call me.fsubContorl.Form.FuncCall

Note that in the above I've changed your syntax slightly, because I really
want is stressed that you're referencing the control name + the .form
property of that control. the ".form" property is what gets you a reference
to the instance of a form that you want.

I haven't checked, but I also notice in the above you have "FuncCall", and
were actually calling the code, then that should be declared as a
subroutine, not a function. However all public functions of that form
actually become a method of the form, and if it *really* is a function, then
you can use it like in the standard property like any other object

eg:

me.fsubContorl.Form.FuncCall

Once again I can't stress how in the above your specifying the name of the
sub form control, which is not necessarily the same name of the form that
the sub form "control" points to.

If I had five sub form controls all with the same sub form action specified,
then you could go

call me.day1.Form.SetToblue
call me.day2.Form.SetToblue
call me.day3.Form.SetToblue
call me.day4.Form.SetToblue

The above syntax would call a subroutine called set SetToBlue in each of the
4 subforms (in my hypothetical example, I'm assuming sub forms day1 to day4
all specify the exact same form).

And of course is the code is to be called from outside of the form, then you
can not use "me", you would go:

Call Forms("frmMain").fsubContorl.Form.FuncCall

perhaps as a slight inconsistency, but when you use the "call", you can
*NOT*
reference the form as

forms!frmMain

You *have* TO USE for call

forms("frmMain")

Not also in the above you use the "dot", not the bang to get to the forms
contorl(s).

I suggest you get in the habit of *always* using the dot when you're
referencing a control on a form

eg:
use
forms!frmCustomer.compayName

However if there might not be a company name control on the form, but you
want a reference the underlying record set, then in all cases, then use

forms!frmCustomer!compayName

The above syntax will work and function regardless if you actually have the
CompanyName control on the form.

Hope this helps....

Also don't forget to make the function or sub declared of public in that sub
form or form, else external callers will not be able to see it.

--
Albert D. Kallal (Access MVP)
Edmonton, Alberta Canada



  #3  
Old May 8th, 2008, 05:47 AM posted to microsoft.public.access.forms
Max Moor
external usenet poster
 
Posts: 148
Default Calling a Function on a subform from the Main Form (Round II)

"Albert D. Kallal" wrote in
:


Wow, Albert, what a great reply! Thank you so much.

I have a follow up question, if you're game...

As agreed, if I have multiple instances of a form open at one time, and make
a call like Form_frmMain.Func, Access calls the function from the first
instance. How does one tell Access to call the function on the second, or
third, or Nth instance of a form?

Now that I've asked, I understand that this could be a big question, and I
appreciate all the time you already put into my education. If you know of a
reference you could point me toward to learn more, I'd be more than happy to
go do some reading.

Thanks Again,
Max
  #4  
Old May 10th, 2008, 12:36 AM posted to microsoft.public.access.forms
Albert D. Kallal
external usenet poster
 
Posts: 2,874
Default Calling a Function on a subform from the Main Form (Round II)

"Max Moor" wrote in message
. 16...
"Albert D. Kallal" wrote in
:


Wow, Albert, what a great reply! Thank you so much.

I have a follow up question, if you're game...

As agreed, if I have multiple instances of a form open at one time, and
make
a call like Form_frmMain.Func, Access calls the function from the first
instance. How does one tell Access to call the function on the second, or
third, or Nth instance of a form?


Great question.

In the case of a sub-form, there is never a problem, since you always
reference the sub-form "control".

In the case in which you have *several* copies of the *same* form opened,
then you have to reference that form via the variable that ***holds*** the
form in memory. While I just That said you should never use the base class
object to reference a form, when you have multiple instances of that same
form opened, the only way to do this is in fact the Clair multiple instances
all that form.


eg:

dim f1 as New form_frmContacts
dim f2 as New from_frmContacts
dim f3 as New form_frmContacts

f1.Visible = true
f2.Visible = true
f3.Visible = true

to call code, we then go:

Call f1.MyPublicSubName

And, you can reference any variable declared as public in that form like:

f1.bolNoNameEdit = False
f2.bolNoNameEdit = True

So, each "form" is a separate class object.

Also, keep in mind that when f1, f2, f3 goes out of scope (the above sub
exits and ends, then all 3 forms will magically disappear, because the three
variables that hold the forms will in fact go out of scope (they will no
longer exist in memory). What this means is either you have a form that
launches these additional forms and holds these variables (for really cool
trick, if you close that parent form, then all of the forms launched from
that form will magically close at the same time because the variables no
longer exist).

If you need the forms to stay open in dependins of one particular form, then
you'll have to declare the form variables as global in a standard code
module.

Often, if you don't know how many copies of the one form be opened at the
same time, then we often declare a global collection, and add forms to that
collection as they are needed.

colMyFormsCol.Add f1

Keep in mind in the case that you're not using multiple instances of a form,
you always want to use the forms() collection to reference and use your
forms, and furthermore you always want to the docmd.OpenForm to open the
form, so it is correctly added to the general forms() collection.

Note that if you do have multiple instances of a formal opened, I believe in
fact they do get added to the forms() collection, but you have no way of
identifying which form you want to reference.


--
Albert D. Kallal (Access MVP)
Edmonton, Alberta Canada



  #5  
Old May 10th, 2008, 04:00 AM posted to microsoft.public.access.forms
Max Moor
external usenet poster
 
Posts: 148
Default Calling a Function on a subform from the Main Form (Round II)

"Albert D. Kallal" wrote in
:

Great question.


And a great answer! I appreciate all the time you put in on this. It makes
good sense to me now. So much to know, so much to learn...

Regards,
Max
 




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Forum Jump


All times are GMT +1. The time now is 11:22 PM.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Copyright ©2004-2024 OfficeFrustration.
The comments are property of their posters.