MS Access VBA - display dynamically built SQL results in datasheet subform

后端 未结 4 1574
长情又很酷
长情又很酷 2021-01-17 18:45

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

相关标签:
4条回答
  • 2021-01-17 19:23

    Use a CreateQueryDef and then
    Me.dataDisplaySubform.SourceObject = "Query.NewqueryName"
    NewQueryName is the name given when created using createQueryDef

    0 讨论(0)
  • 2021-01-17 19:24

    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).

    0 讨论(0)
  • 2021-01-17 19:27

    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

    0 讨论(0)
  • 2021-01-17 19:40

    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
    
    0 讨论(0)
提交回复
热议问题