Access continuous form: Add a control without modifying the underlying table?

ms-access, ms-access-2007

Solution

You could include record selection check boxes in a form based on a disconnected recordset. That's an ADO recordset you create in memory, not bound to any data source. With the primary key in the recordset, your command button's click procedure can walk the recordset to retrieve a list of primary keys of the "selected" records. If that approach sounds useful, see this article by Danny Lesandrini at Database Journal: Create In-Memory ADO Recordsets

I created this form based on code from that article. The main form includes a subform based on a disconnected recordset which is loaded during the subform's `Form_Open`.

Note you don't actually need to display the primary key (`ID`) in the form; as long as it's included in the recordset, you can retrieve it when walking the recordset.

Private Sub Form_Open(Cancel As Integer)
    Dim dbs As DAO.Database
    Dim fld As ADODB.Field
    Dim rstAdo As ADODB.Recordset
    Dim rstDao As DAO.Recordset
    Dim strSql As String

    Set rstADO = New ADODB.Recordset
    With rstAdo
        .Fields.Append "EmployeeID", adInteger, , adFldKeyColumn
        .Fields.Append "FirstName", adVarChar, 10, adFldMayBeNull
        .Fields.Append "LastName", adVarChar, 20, adFldMayBeNull
        .Fields.Append "Selected", adBoolean
        .CursorType = adOpenKeyset
        .CursorLocation = adUseClient
        .LockType = adLockPessimistic
        .Open
    End With

    Set dbs = CurrentDb
    strSql = "SELECT EmployeeID, FirstName, LastName " & _
             "FROM Employees ORDER BY LastName, FirstName"
    Set rstDao = dbs.OpenRecordset(strSql, dbOpenSnapshot)

    Do Until rstDao.EOF
        rstAdo.AddNew
        rstAdo!EmployeeID = rstDao!EmployeeID
        rstAdo!FirstName = rstDao!FirstName
        rstAdo!LastName = rstDao!LastName
        rstAdo!Selected = False
        rstAdo.Update
        rstDao.MoveNext
    Loop

    Set Me.Recordset = rstAdo
    rstDao.Close    
    Set rstDao = Nothing
    Set dbs = Nothing
End Sub

That code sample uses early binding for ADO which requires setting a reference for a version of Microsoft ActiveX Data Objects. However, it can work fine with the appropriate modifications for late binding.

This approach is not exactly light-weight. However it allows you to have selection check boxes without binding them to a Yes/No field in the actual data table. That would be a challenge in a multi-user application when users might overwrite each others selections in the shared table. The disconnected recordset neatly avoids such conflicts.

Problem

I'm making a simple Access form (continuous view). This has a checkbox in the Details section and a Command button in the footer. This way, the user can use the checkbox to "select" multiple records then click the command button at the button to run a script which updates the selected records. There's no need to permanently store these check values. Normally, I'd add a boolean field to the underlying table and associate the checkbox to that field. But is there a way to do this without modifying the table? i.e. store the checkbox values in memory?

Original source