I have several years experience with VBA in MS Office applications (for automation and ETL processes) but have not had the need to mess with Forms in MS Access until recentl
Use a CreateQueryDef
and then
Me.dataDisplaySubform.SourceObject = "Query.NewqueryName"
NewQueryName
is the name given when created using createQueryDef
Some clarifying points for other readers:
A detail view subform's sourceObject property determines which columns/fields are displayed. So, you could set it to a table or query, then optionally use a filter to return no records (if you want the recordset to be initially blank) or as an alternative to using the recordSource for custom SQL.
The recordSource can be any table, query, or SQL, but the subform will only display fields with names matching the sourceObject's fields. This can be confusing if, for example, you set the sourceObject to a table, then the recordSource to a query with partially overlapping field names (Access will display all columns, but only the overlapping ones will have data in them).
To have a form which displays an arbitrary SELECT statement or allows the user to choose what table(s) to SELECT on, one could save their input as a new query (or have an existing named one to overwrite), then set the sourceObject to that (the form would have to be closed then re-opened for the new columns to be displayed, so you might want to open a pop-up or new tab to display the results).
If the "object that is closed or doesn't exist" error occurs on the Me.dataDisplaySubform.Form.RecordSource
line, chances are your subform control is not named dataDisplaySubform.
You can examine the names of all your form's subform controls with this temporary change to your code ...
'Me.dataDisplaySubform.Form.RecordSource = pSQL
Dim ctl As Control
For Each ctl In Me.Controls
If TypeName(ctl) = "SubForm" Then
Debug.Print ctl.Name, TypeName(ctl)
End If
Next
Stop
The Stop
statement will trigger debug (break) mode and take you to the Immediate window where you can view the names of your form's subform control(s).
The screenshot you added to the question confirms you're using the correct name for the subform control. However, that subform has nothing in its Source Object property. Since there is no form there, the second part of the error message, "doesn't exist", applies. There is no form to be referenced by Me.dataDisplaySubform.Form
short and sweet. Here is the code for a button that creates dynamic sql string, closes the current object (just in case its open), deletes a temporary query definition (because we need one), creates a new query definition with the new sql, changes the recordsource and Bob's your uncle.
Private Sub btnRunSQL_Click()
'my subform is called datasheet, i know -- dumb name.
'a dynamic sql needs to be saved in a temporoary query. I called my qtemp
Dim sql As String
sql = "select * from client order by casename asc"
'in case there is something kicking around, remove it first, otherwise we can't delete the temp query if it is still open
Me!Datasheet.SourceObject = ""
'delete our temporary query. Note, add some err checking in case it doesn't exist, you can do that on your own.
DoCmd.DeleteObject acQuery, "qtemp"
'lets create a new temporary query
Dim qdf As QueryDef
Set qdf = CurrentDb.CreateQueryDef("qtemp", sql)
'set the subform source object
Me!Datasheet.SourceObject = "query.qtemp"
'and it should work.
End Sub