Full Version: SubForm ... IsLoaded()
UtterAccess Forums > Microsoft® Access > Access Forms
Hello folk.
I've been looking around for some time but haven't spotted anyone discussing this.
You are probably aware of the Northwind VBA function to check if a form is loaded.
<snip> ...
Const conObjStateClosed = 0
Const conDesignView = 0
If SysCmd(acSysCmdGetObjectState, acForm, strFormName) <> conObjStateClosed Then
If Forms(strFormName).CurrentView <> conDesignView Then
IsLoaded = True
Exit Function
End If
End If
... </SNIP>
Has anyone figured out how to check if a SUBForm is open ?
Because I find the loaded property in Access is not set.
The subform is loaded when the main form is loaded, unless the subform's SourceObject property Is Null.
Dear Sagus.
Yes, you are quite correct about the subform being loaded.
In stepping through code, I find that subform events fire before the main. (e.g. Form_Current)
My question concerns the coding of a generic IsLoaded routine that will always return the correct value ... and one which takes sub-forms into account.
(Becase I don't know how to determine the parent name of the subform I'm interested in)

Yes, I could always try to loop through all the controls in each of the defined forms in the system ...
... searching for a subform definition (expect via a naming convention) and then checking if it has a value ...
... but I was hoping there was an existing, easier and quicker way .... something more elegant than that.
... such as a known (system) value to test for.
At Design time, Access knows if a form is loaded - it will complain if you try going into design mode on a subform when you already have it's parent form open in design mode.
But whether this is known at runtime is another question.
Any other takers on this one ?
Subforms are not really open like a main form. That is to say that they are not part of the Forms collection.
better approach to test whether you are in a subform vs. a main form is to use the Parent property of Screen.ActiveControl. If you are in a main form, Screen.ActiveControl.Parent.Parent will throw an error, while in a subform, Screen.ActiveControl.Parent.Parent will return the main form object.
Hope this helps,
That goal do you have in mind for checking if the subform is open?
It's an interesting question you've put forth . . . and I want to understand what you're trying to do in case I need to do it later.
HAs a off topic remark, I use subreports a lot and found that while you can reference them in code to get totals and what have you, if the first subreport doesn't have any records, the 2nd report if it's looking for a result produces an #Error.
The way I get around this is to do a dcount on the first subreport qry to see if it has any records in the Format event.
It's not perhaps the best way to do a test for a subreport but it works!
I am going to merge the two threads.
The other thread concerned what I was trying to achieve - context-awareness ... for custom context Help and auto-issue logging - based on right-click menu.
That thread is here: Screen.ActiveForm
Ygoing to merge the two threads.
The other thread concerned what I was trying to achieve - context-awareness ... for custom context Help and auto-issue logging - based on right-click menu.
That thread is here: Screen.ActiveForm
Your valued input got me thinking, providing clues to experiment some more.
Ohaven't yet reworked the IsLoaded routine, maybe one day !
(So still cannot call from "other" form to see whether a subform is active/ loaded.)
Allow me to share my answer anyway.
Querying values "up the tree", while running under Resume Next, I can figure it out.
Custom context-sensitive-help now possible. ;-))
Setup and Code example if someone would like to play :-
( Not the most efficient of code, just functional enough to prove the point )
1. Build Public Function showHelp()
On Error Resume Next
Dim sSubFormName As String
sSubFormName = Screen.ActiveForm.ActiveControl.Form.Name

Dim sMsg As String
sMsg = sMsg & "Active Control : " & Screen.ActiveControl.Name & vbCrLf
sMsg = sMsg & " Container : " & Screen.ActiveForm.ActiveControl.Name & vbCrLf
sMsg = sMsg & vbCrLf

If Len(sSubFormName & "") > 0 Then
sMsg = sMsg & " In SubForm : " & sSubFormName & vbCrLf
sMsg = sMsg & " Parent 1 : " & Screen.ActiveControl.Parent.Name & vbCrLf
sMsg = sMsg & " Parent 2 : " & Screen.ActiveControl.Parent.Parent.Name & vbCrLf
sMsg = sMsg & " Parent 3 : " & Screen.ActiveControl.Parent.Parent.Parent.Name & vbCrLf
sMsg = sMsg & " Parent 4 : " & Screen.ActiveControl.Parent.Parent.Parent.Parent.Name & vbCrLf
sMsg = sMsg & vbCrLf
'== Normal / Main form
sMsg = sMsg & " Is MainForm : " & Screen.ActiveControl.Parent.Name & vbCrLf
sMsg = sMsg & " Parent ? : " & Screen.ActiveControl.Form.Parent.Name & vbCrLf
sMsg = sMsg & vbCrLf

End If

MsgBox sMsg, , "Where are we now ?"
End Function
2. Create a Macro: RunCode showHelp ()
3. Build a custom shortcut menu (e.g myToolbar)
Add the showHelp macro to it.
4. On ALL forms you want to enable the funtion on (main, sub1,sub2 etc)
1. set ShortCutMenu=Yes
2. set ShortcutMenubar = myToolbar (assuming this is the name you're going to use)
Run. Right-click in various sections down the line ands choose showHelp.
The display returns the active control and up to four parent levels back .
Thanx to all for their help and suggestions.
I hope this will be useful to some other poor soul fighting to figure it out ;-))
This is a "lo-fi" version of UA. To view the full version with more information, formatting and images, please click here.