Or here is alternative code for this as a function:
Code:
Function IsFormLoaded(ByVal strFormName As String) As Integer
'Returns a 0 if form is not open or a -1 if Open
On Error GoTo Err_Handler
If SysCmd(acSysCmdGetObjectState, acForm, strFormName) <> 0 Then
If Forms(strFormName).CurrentView <> 0 Then
IsFormLoaded = True
End If
End If
Exit_Handler:
Exit Function
Err_Handler:
MsgBox "Error " & err & " in IsFormLoaded procedure : " & Err.Description
Resume Exit_Handler
End Function
Typical usage: IsFormLoaded("YourFormName")
Code to test whether a form is open as a subform:
Code:
Private Function IsSubform() As Boolean
Dim bHasParent As Boolean
On Error GoTo Err_Handler
' If opened not as a subform, accessing
' the Parent property raises an error:
bHasParent = Not (Me.Parent Is Nothing)
IsSubform = True
Exit Function
Err_Handler:
IsSubform = False
End Function
For example, I use that code as a check in automatic form resizing to resize when opened as a form but not when opened as a subform
Code:
Private Sub Form_Load()
If Not IsSubform Then
ReSizeForm Me
Me.NavigationButtons = True
End If
End Sub
EDIT: I've just noticed the IsSubform code in post #2. Sorry I only skimmed the thread
Not sure what you really mean. I interpret that to simply mean you want code to determine if a form is loaded as a subform not if it is loaded both as a main form and also as a subform.
Isladogs showed how to show if a form is loaded as a main form.
Code:
Function IsFormLoaded(ByVal strFormName As String) As Integer
'Returns a 0 if form is not open or a -1 if Open
On Error GoTo Err_Handler
If SysCmd(acSysCmdGetObjectState, acForm, strFormName) <> 0 Then
If Forms(strFormName).CurrentView <> 0 Then
IsFormLoaded = True
End If
End If
Exit_Handler:
Exit Function
Err_Handler:
MsgBox "Error " & err & " in IsFormLoaded procedure : " & Err.Description
Resume Exit_Handler
End Function
To see if a form is loaded as a subform
Code:
Public Function IsSubFormLoaded(ByVal strFormName As String) As Boolean
Dim sFrm As Access.Form
Dim ctrl As Access.Control
For Each sFrm In Forms
For Each ctrl In sFrm.Controls
If ctrl.ControlType = acSubform Then
If ctrl.Form.Name = strFormName Then
IsSubFormLoaded = True
Exit Function
End If
End If
Next ctrl
Next sFrm
End Function
If you really want to know if it is loaded as either a main form or a subform, then wrap those functions
Code:
Public Function isFormOrSubFormLoaded(ByVal strFormName As String) As Boolean
If IsFormLoaded(strFormName) Or IsSubFormLoaded(strFormName) Then isFormOrSubFormLoaded = True
End Function
solved?
but the title is asking if the form is "Loaded" (meaning not a subform) or a subform.
i have a sample db, but much longer than your code.
it will test (on my case, Form1 (see test sub on module1)) the form's status.
possible results:
"Not exists" (if the specified form name does not exists in the db).
"Not loaded" (the form exists but not Open (not in design view), or not a subform).
"Loaded" (if the form is open (normal view) and not a subform)
"Subform" (when the form is a subform)
"SubSubform (prefix "Sub" is repeating, when it is x many times deep embed as subform)
Perhaps I'm missing the point but discussion in this thread seems very convoluted
A form object can be opened as a form or as a subform (or it can be a subreport)
However, for a form object to be detected as e.g. a subform, it must be loaded (open).
Is there some point of significance that I'm overlooking?
I suspect a subform isn't loaded in the way a normal form is, as it is an instance of the form contained in a subform/subreport control.
However if the so-called "subform" is opened independently it is no longer a subform, it's just an ordinary form and can be detected.
To reiterate the op's question in the hope of clarifying the situation, he found some code which would tell him if a form was open. He discovered that it didn't identify subforms as being open.
He suggested that finding the subforms parent would indicate if it was subform.
Another approach would be to find all of the subform/subreport controls and see what the source object name is. Check that against the collection of forms.
I suspect a subform isn't loaded in the way a normal form is, as it is an instance of the form contained in a subform/subreport control.
However if the so-called "subform" is opened independently it is no longer a subform, it's just an ordinary form and can be detected.
To reiterate the op's question in the hope of clarifying the situation, he found some code which would tell him if a form was open. He discovered that it didn't identify subforms as being open.
He suggested that finding the subforms parent would indicate if it was subform.
Another approach would be to find all of the subform/subreport controls and see what the source object name is. Check that against the collection of forms.
Public Function IsLoaded(Search As String, Optional Scan As Object) As Boolean
Dim i As Object
Dim First As Boolean
If Scan Is Nothing Then First = True: Set Scan = Application.Forms
For Each i In Scan
If Not First Then
If i.ControlType = 112 Then
If Search = i(0).Parent.Name Then IsLoaded = True: Exit Function
IsLoaded = IsLoaded(Search, i(0).Parent)
If IsLoaded Then Exit Function
End If
Else
If Search = i.Name Then IsLoaded = True: Exit Function
IsLoaded = IsLoaded(Search, i)
If IsLoaded Then Exit Function
End If
Next
End Function
In the whole discussion and in the presented solutions it has not yet been considered that one can work with several instances of the same form at the same time - and that is anything but confusing if I already have a good and universally usable form.
There can be different design options for these different instances:
- Multiple instances as main form (input form versus data display form)
- Use as a main form and as a subform of another form
- Use as a multiple subform with different data displays in the same main form
If there are several instances, addressing the form by name is not an option. For targeted work, addressing by reference is necessary. It's also important to note that a form is a class and its instance must be able to determine for itself what it is, where it resides, and what it's called as a control, to perform specific actions or not to execute.
With that in mind, I've added something to the DB file of @arnelgp to allow for easy testing.
The simple function:
Code:
' sample call
Private Sub Form_Open(Cancel As Integer)
Dim SourceObjectName As String
Dim ParentFormName As String
Dim UFoControlName As String
Debug.Print
Debug.Print "Is SubForm: " & IsSubform(Me, SourceObjectName, ParentFormName, UFoControlName)
Debug.Print "SourceObjectName: " & SourceObjectName, _
"ParentFormName: " & ParentFormName, _
"UFoControlName: " & UFoControlName
End Sub
Code:
Public Function IsSubform(AnyForm As Access.Form, _
Optional ByRef SourceObjectName As String, _
Optional ByRef ParentFormName As String, _
Optional ByRef UFoControlName As String) As Boolean
SourceObjectName = AnyForm.Name
If SysCmd(acSysCmdGetObjectState, acForm, AnyForm.Name) = 0 Then
IsSubform = True
ParentFormName = AnyForm.Parent.Name
UFoControlName = SubformControlName(AnyForm)
Else
IsSubform = False
End If
End Function
Public Function SubformControlName(SubformOBJ As Access.Form) As String
Dim ctl As Access.Control
For Each ctl In SubformOBJ.Parent
If ctl.ControlType = acSubform Then
If ctl.SourceObject = SubformOBJ.Name Then
If ctl.Form.Hwnd = SubformOBJ.Hwnd Then
SubformControlName = ctl.Name
Exit For
End If
End If
End If
Next
End Function
In the whole discussion and in the presented solutions it has not yet been considered that one can work with several instances of the same form at the same time - and that is anything but confusing if I already have a good and universally usable form.
There can be different design options for these different instances:
- Multiple instances as main form (input form versus data display form)
- Use as a main form and as a subform of another form
- Use as a multiple subform with different data displays in the same main form
If there are several instances, addressing the form by name is not an option. For targeted work, addressing by reference is necessary. It's also important to note that a form is a class and its instance must be able to determine for itself what it is, where it resides, and what it's called as a control, to perform specific actions or not to execute.
With that in mind, I've added something to the DB file of @arnelgp to allow for easy testing.
The simple function:
Code:
' sample call
Private Sub Form_Open(Cancel As Integer)
Dim SourceObjectName As String
Dim ParentFormName As String
Dim UFoControlName As String
Debug.Print
Debug.Print "Is SubForm: " & IsSubform(Me, SourceObjectName, ParentFormName, UFoControlName)
Debug.Print "SourceObjectName: " & SourceObjectName, _
"ParentFormName: " & ParentFormName, _
"UFoControlName: " & UFoControlName
End Sub
Code:
Public Function IsSubform(AnyForm As Access.Form, _
Optional ByRef SourceObjectName As String, _
Optional ByRef ParentFormName As String, _
Optional ByRef UFoControlName As String) As Boolean
SourceObjectName = AnyForm.Name
If SysCmd(acSysCmdGetObjectState, acForm, AnyForm.Name) = 0 Then
IsSubform = True
ParentFormName = AnyForm.Parent.Name
UFoControlName = SubformControlName(AnyForm)
Else
IsSubform = False
End If
End Function
Public Function SubformControlName(SubformOBJ As Access.Form) As String
Dim ctl As Access.Control
For Each ctl In SubformOBJ.Parent
If ctl.ControlType = acSubform Then
If ctl.SourceObject = SubformOBJ.Name Then
If ctl.Form.Hwnd = SubformOBJ.Hwnd Then
SubformControlName = ctl.Name
Exit For
End If
End If
End If
Next
End Function
Public Function IsLoaded(Search As String, Optional Scan As Object) As Boolean
Dim i As Object
Dim First As Boolean
If Scan Is Nothing Then First = True: Set Scan = Application.Forms
For Each i In Scan
If Not First Then
If i.ControlType = 112 Then
If Search = i(0).Parent.Name Then IsLoaded = True: Exit Function
IsLoaded = IsLoaded(Search, i(0).Parent)
If IsLoaded Then Exit Function
End If
Else
If Search = i.Name Then IsLoaded = True: Exit Function
IsLoaded = IsLoaded(Search, i)
If IsLoaded Then Exit Function
End If
Next
End Function
How many versions of code to detect a subform do we really need in this thread?
I gave code to detect if a form is open as a subform in post #20, then realised @cheekybuddha had given similar code in post #2
It seems to me that we are going around in circles...or am I still missing something?
@Efer and @isladogs, I have introduced and formulated an extension of requirements, which is also relevant to practice, at least in a better practice.
If a form instance is to check and recognize itself, questions as to whether the instance is loaded or whether the form even exists have long been answered and therefore do not need to be asked again.
So my answer is quite different from yours or any previous one. Let's see if anyone recognizes this on their own.
Now we are offering puzzles instead of solving problems.
It's at least your second try to offer a code and say go figure yourself what it does.
It was your answer to @Pat Hartmanhere
Do I have to be surprised if a description as text plus a complete open code plus a demo DB appears as a puzzle to a viewer who perceives this as a whole?
The video of Alan Cossey's excellent presentation to last week's Access Europe meeting is now available on YouTube: The Standard Module Object Generation (SMOG) add-in and supporting files are also now available free to all Access Europe subscribers from...
www.access-programmers.co.uk
The simultaneous use of multiple instances of the same form is familiar to some.
Do I have to be surprised if a description as text plus a complete open code plus a demo DB appears as a puzzle to a viewer who perceives this as a whole?
The video of Alan Cossey's excellent presentation to last week's Access Europe meeting is now available on YouTube: The Standard Module Object Generation (SMOG) add-in and supporting files are also now available free to all Access Europe subscribers from...
www.access-programmers.co.uk
The simultaneous use of multiple instances of the same form is familiar to some.
@ebs17 My English is not that good, so I really can't understand what you mean by that. Maybe if I watch the video and read the linked you sent I can find a relation between my comment, your reply and the contents, but for now, I'm terribly busy with my job.