I was recently needing to breakdown a very complex form and amongst other things, I needed to extract a list of the subforms contained within it for further analysis. Below is a simple function I wrote which will return to the immediate pane a listing of the subform names.
Function ListSubFrms(sFrm As String)
On Error GoTo Error_Handler
Dim ctl As Access.Control
Dim frm As Access.Form
DoCmd.OpenForm sFrm, acDesign
Set frm = Forms(sFrm).Form
For Each ctl In frm.Controls
Select Case ctl.Properties("ControlType")
Case acSubform ', acListBox
' ctl.Name 'Will return the given name of the control, not necessarily the actual object name
' ctl.Properties("SourceObject") 'Will return the object name
If ctl.Properties("SourceObject") = "" Then
Debug.Print ctl.name
Else
Debug.Print ctl.Properties("SourceObject")
End If
End Select
Next ctl
Error_Handler_Exit:
On Error Resume Next
DoCmd.Close acForm, sFrm, acSaveNo
Set frm = Nothing
Set ctl = Nothing
Exit Function
Error_Handler:
MsgBox "The following error has occurred." & vbCrLf & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: ListSubFrms" & vbCrLf & _
"Error Description: " & Err.Description, _
vbCritical, "An Error has Occurred!"
Resume Error_Handler_Exit
End Function
Thank you for your routine ListSubFrms. I’ve not been able to crack this issue before but now I’ve adapted it to list ALL the sub-forms AND the sub-sub-forms – see below:
‘List ALL sub forms in the parent – SOLVED
Private Function ListSubFrms1(frm As Access.Form) As String
‘Thanks to Daniel Pineault at https://www.devhut.net/2014/03/13/list-subforms-within-another-form-ms-access-vba/
’11 Mar 2020: Made re-iterative to check sub subforms
Dim sCtrl As String, sFormsList As String
Dim ctl As Access.Control
Dim sf As Access.Form
‘On Error GoTo Error_Handler
‘sFrm = “frmSettings”
‘DoCmd.OpenForm sFrm, acDesign
‘Set frm = Forms(sFrm).Form
If frm Is Nothing Then GoTo Error_Handler_Exit
temp = frm.Name
For Each ctl In frm.Controls
Select Case ctl.Properties(“ControlType”)
Case acSubform ‘, acListBox
‘ ctl.Name ‘Will return the given name of the control, not necessarily the actual object name
‘ ctl.Properties(“SourceObject”) ‘Will return the object name
If ctl.Properties(“SourceObject”) = “” Then ‘Never gets here
Debug.Print ctl.Name
Else
sCtrl = ctl.Properties(“SourceObject”)
‘Debug.Print sCtrl
On Error Resume Next
Set sf = ctl.Form
If Err.Number = 0 Then
sFormsList = sFormsList & sCtrl & “;”
sFormsList = sFormsList & ListSubFrms1(sf)
Else
sFormsList = sFormsList & sCtrl & ” – has no subform” & “;”
End If
On Error GoTo Error_Handler
End If
End Select
Next ctl
Error_Handler_Exit:
On Error Resume Next
‘DoCmd.Close acForm, sFrm, acSaveNo
Set frm = Nothing
Set sf = Nothing
Set ctl = Nothing
ListSubFrms1 = sFormsList
Exit Function
Error_Handler:
MsgBox “The following error has occurred.” & vbCrLf & vbCrLf & _
“Error Number: ” & Err.Number & vbCrLf & _
“Error Source: ListSubFrms” & vbCrLf & _
“Error Description: ” & Err.Description, _
vbCritical, “An Error has Occurred!”
Resume Error_Handler_Exit
End Function
Private Sub ListSubFrms1_TEST()
Dim sList As String
Dim frm As Access.Form
Const conFrm As String = “frmSettings”
DoCmd.OpenForm conFrm
Set frm = Forms(conFrm)
sList = ListSubFrms1(frm)
sList = VBA.Replace(sList, “;”, vbCrLf, 2, , vbTextCompare)
Debug.Print sList
DoCmd.Close acForm, conFrm, acSaveNo
Set frm = Nothing
End Sub
I forgot the calling routine for my modification of your routine, ListSubFrms1:
Private Sub ListSubFrms1_TEST()
Dim sList As String
Dim frm As Access.Form
Const conFrm As String = “frmSettings”
DoCmd.OpenForm conFrm
Set frm = Forms(conFrm)
sList = ListSubFrms1(frm)
sList = VBA.Replace(sList, “;”, vbCrLf, 2, , vbTextCompare)
Debug.Print sList
DoCmd.Close acForm, conFrm, acSaveNo
Set frm = Nothing
End Sub