subform isloaded within a tab

G

Guest

I can successfully check if a subform is loaded using
If CurrentProject.AllForms.Item(ABCText).IsLoaded Then
however if the master form contains tabs and the subform is on a tab, the
previous check doesn't work. I'd like to test if the subform on the tab is
loaded.

Any help is appreciated.

On a side note, I wish I understood the Object Browser better and have a
feeling that it would help me in this case. Any good websites/books which do
some good explanation/tutorial of the Object Browser. I've many books that
tell you about it, but not enough.

thanks,
James
 
A

Allen Browne

Public Function IsSubformLoaded(SF As SubForm) As Boolean
On Error Resume Next
If SF.Form.Name <> vbNullString Then
IsSubformLoaded = True
End If
End Function
 
A

Allen Browne

So you have a subform control in the page of a tab control, and you want to
know if the subform control actually contains a form.

You could do that by testing the Name of the Form in the subform control.
For example, if the form is named Form1, and the subform control is named is
named Child1, you could test it using the function below like this:
? IsSubformLoaded(Forms!Form1!Child1)

Public Function IsSubformLoaded(SF As SubForm) As Boolean
On Error Resume Next
If SF.Form.Name <> vbNullString Then
IsSubformLoaded = True
End If
End Function

Regarding the Object Browser, it works like this. Your project contains a
number of libraries (Tools | References, in the code window), and each of
these contributes objects. For example, the Access library contains the
Application object, which contains lots of the useful thing you use all the
time. Similarly the VBA library contains lots of functions for working with
strings, numbers, dates, and other data types. The Object Browser lets you
browse through the objects in each library.

As you add other objects (e.g. forms and their modules) to your project,
they expose other things as well (controls, variables, procedures, ...) The
Object Browser is an interface to drill down through these things. It is
quite useful for finding things, provided you have some idea what they are
called. Some objects are hidden, so you have to right-click it to expose
those.

I don't find the Object Browser useful as a way to stay on top of what's in
the project. It's more a way of finding out about specific stuff when you
need it.

HTH.
 
G

Guest

Allen,

thanks for the input.

I'm not trying to check if the subform is contained in the tab, but I'm
trying to see if the subform is loaded in memory. I guess since I only use
the subform on the one master form, I could look for the master form.

I tried your method but "IsSubformLoaded(Forms!Form1!Child1)"
errors when the form is not in memory.

thanks from "up and over" (or whatever US is compared to "down under")

James Deckert
 
A

Allen Browne

Hmm: so you want to know if a particular form is currently loaded into
memory anywhere?

You would need to:
1) Loop through the Forms collection, testing the Name of each one.

2) For each form in the Forms collection, loop through each control in its
Controls collection, to see if its ControlType = acsubform. If so, examine
the SourceObject of the subform control.

3) Call step 2 recursively to handle nested subforms.

Not difficult, but not trivial either.
 
A

Allen Browne

James, this is untested, but give is a spin and see how you go:

Public Function IsFormLoaded(strFormName As String) As Boolean
Dim frm As Form
Dim bFound As Boolean

For Each frm In Forms
If frm.Name = strFormName Then
bFound = True
Exit For
Else
Call SearchInForm(frm, strFormName, bFound)
If bFound Then
Exit For
End If
End If
Next

IsFormLoaded = bFound
End Function

Private Function SearchInForm(frm As Form, strDoc As String, bFound As
Boolean)
Dim ctl As Control

For Each ctl In frm.Controls
If ctl.ControlType = acSubform Then
If ctl.Form.Name = strDoc Then
bFound = True
Else
Call SearchInForm(ctl.Form, strDoc, bFound)
End If
If bFound Then
Exit For
End If
End If
Next
End Function
 
G

Guest

Allen,

I used a function similiar to your "IsFormLoaded" for years. Then, one day,
someone mentioned I could do the same thing with:

Public Function IsFormLoaded(FormName as string) as boolean

IsFormLoaded = Currentproject.Allforms(FormName).IsLoaded

End Function

For simplicity, this sure does beat running through the entire forms
collection, although I don't know how much faster it is, if any.

Dale
 
D

Dale Fye

Dirk,

I was commenting about Allen's IsFormLoaded function, not about the subforms
issue.

For subforms, I just check to see of the SourceObject is populated.

Public Function IsSubformLoaded(FormName as string, SubControlName as
String) as boolean

If IsFormLoaded(FormName) then
IsSubFormLoaded =
(Forms(FormName).Controls(SubControlName).SourceObject <> "")
Else
IsSubFormLoaded = False
end if

End function

Dale
 
A

Allen Browne

Dale, there's a couple of problems with that approach:

a) Subforms can be nested to 7 levels deep, so you need recursive code to
test for subsubforms, subsubsubforms, etc.

b) The SourceObject doesn't actually guarantee the form is actually loaded.
In some of the databases I write, some users have permission to see a
subform and others don't. So in Form_Open, we test if the user has
permission, and cancel the event if they don't. When this happens, the
SourceObject indicates the subform that should be there, but the form is not
loaded. That's why I'm suggesting [Child1].Form.Name (with error handling if
there is no Form in the subform control.)

Of course, the name of the subform control may not be the same as the name
of the form either.
 
D

Dale Fye

Allen, Different techniques I guess.

I guess I didn't read the OP very closely, because I thought he was only
concerned with the subform on his main form.

I usually set my subform SourceObject to "" (and visible = False) at design
time, then perform the tests you mention and set the source object and
Visible = True if the user passes the permissions test. This also speeds up
the loading of the form on those forms with multiple subforms, because I
don't set the source object until I need to display the subform.

I know you can nest subforms to 7 deep, but I honestly cannot say I have
ever gone more than two.

Dale.

Allen Browne said:
Dale, there's a couple of problems with that approach:

a) Subforms can be nested to 7 levels deep, so you need recursive code to
test for subsubforms, subsubsubforms, etc.

b) The SourceObject doesn't actually guarantee the form is actually
loaded. In some of the databases I write, some users have permission to
see a subform and others don't. So in Form_Open, we test if the user has
permission, and cancel the event if they don't. When this happens, the
SourceObject indicates the subform that should be there, but the form is
not loaded. That's why I'm suggesting [Child1].Form.Name (with error
handling if there is no Form in the subform control.)

Of course, the name of the subform control may not be the same as the name
of the form either.

--
Allen Browne - Microsoft MVP. Perth, Western Australia

Reply to group, rather than allenbrowne at mvps dot org.

Dale Fye said:
Dirk,

I was commenting about Allen's IsFormLoaded function, not about the
subforms issue.

For subforms, I just check to see of the SourceObject is populated.

Public Function IsSubformLoaded(FormName as string, SubControlName as
String) as boolean

If IsFormLoaded(FormName) then
IsSubFormLoaded =
(Forms(FormName).Controls(SubControlName).SourceObject <> "")
Else
IsSubFormLoaded = False
end if

End function

Dale
 
G

Guest

but give is a spin
Wow, it spun real well. No changes necessary.
I was out of town for a few days, so just tried it.

I understand what's going on, but I don't understand how bFound gets passed
back out of the functions. Isn't the default for arguments byVal (not byRef)
which does not pass values back to the calling function?

thanks Allen,
James Deckert
 
A

Allen Browne

The default VBA behavior is to pass the actual variable so another routine
can change it (not merely a copy of the variable), so it's like passing a
pointer in C. You have to specify ByVal if you want to pass an independent
copy.

When the function calls itself recursively, it passes the actual variable it
is using to the child instance. If the new recursive instance changes the
variable, the prior instance is able to test the result and pull out,
continuing to pass the result up the recursive chain until it finally passes
the value back to the separate top-level function IsFormLoaded().
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top