Question

I have a form with several data entry boxes (text, combo, check boxes, and option groups). The name of the data entry boxes match the field names of the corresponding table that the data will be appended to/ drawn from.

In this example, when the user selects a value from a combo box, a sql is executed that gathers the data meeting the criteria and auto populates a bunch of fields in the form. My real form has many fields in it and I will be running similar functions throughout (e.g. writing data to different table (table3)), I would like to create a loop to perform the field matching instead of listing each form data entry box equaling its corresponding record source.

Using this test example, how can I alter my script to a loop instead:

Private Sub txt_ID_AfterUpdate()

Dim db As Database
Dim rs As DAO.Recordset
Dim strSQL As String

    strSQL = "SELECT Table1.ID, Table1.Color, Table1.Make, Table1.Model, Table2.FName, Table2.LName FROM Table1 INNER JOIN Table2 ON Table1.ID = Table2.ID WHERE"
    strSQL = strSQL & "[Table1].ID = """ & Me.txt_ID & """"

    Set rs = Currentdb.OpenRecordset(strSQL, DB_OPEN_DYNASET)

    Me!ID = rs!ID
    Me!Color = rs!Color
    Me!Make = rs!Make
    Me!Model = rs!Model
    Me!FName = rs!FName
    Me!LName = rs!LName

    rs.Close
    Set rs = Nothing

I want it to do something like this:

Private Sub txt_ID_AfterUpdate()

Dim db As Database
Dim rs As DAO.Recordset
Dim strSQL As String

    strSQL = "SELECT Table1.ID, Table1.Color, Table1.Make, Table1.Model, Table2.FName, Table2.LName FROM Table1 INNER JOIN Table2 ON Table1.ID = Table2.ID WHERE"
    strSQL = strSQL & "[Table1].ID = """ & Me.txt_ID & """"

    Set rs = Currentdb.OpenRecordset(strSQL, DB_OPEN_DYNASET)
    For each Name in FormA
        Me!<Name> = rs!<Name>
    Next Name

    rs.Close
    Set rs = Nothing

Many thanks in advance.

Final script ended up looking like this. Simon1979 script also works.

Private Sub txt_ID_AfterUpdate()

Dim db As Database
Dim rs As DAO.Recordset
Dim strSQL As String

    strSQL = "SELECT Table1.ID, Table1.Color, Table1.Make, Table1.Model, Table2.FName, Table2.LName FROM Table1 INNER JOIN Table2 ON Table1.ID = Table2.ID WHERE"
    strSQL = strSQL & "[Table1].ID = """ & Me.txt_ID & """"

    Set rs = Currentdb.OpenRecordset(strSQL, DB_OPEN_DYNASET)

    rs.MoveFirst
    For Each fld In rs.Fields
        Me.Controls(fld.Name) = fld
    Next fld

    rs.Close
    Set rs = Nothing

End Sub
Was it helpful?

Solution

[My suggestion followed by an answer to your question, choose whichever suits your need]

Would you be better making the form bound but editing the RecordSource for the form to be your strSQL? Adds more scope/ ease to editing data, which I assume you intend to do by the use of DB_OPEN_DYNASET, though your current approach would not keep the locks on the data beyond the rs.Close.

This method would need an alternate way of gathering the ID, unless txt_ID is not bound, I would use an InputBox via a CommandButton:

Sub cmdRetrieveRecord()

Dim strSQL as String, strID as string

EnterID:
    strID = InputBox("Enter the required ID:")
    If StrPtr(strID) = 0 Then 'Cancel was pressed
        ExitSub
    ElseIf Len(strID) = 0 Then 'OK was pressed with nothing entered
        MsgBox "You must enter an ID."
        GoTo EnterID
    End If
    If Not IsNumeric(strID) Then
        MsgBox "You must enter only a numeric ID"
        GoTo EnterID
    End If

    strSQL = "SELECT Table1.ID, Table1.Color, Table1.Make, Table1.Model, Table2.FName, " _
        & "Table2.LName FROM Table1 INNER JOIN Table2 ON Table1.ID = Table2.ID WHERE"
    strSQL = strSQL & "[Table1].ID = """ & strID & """"

    Me.RecordSource = strSQL

End Sub

NOTE if there are no records for the entered ID then the form will be blank, make sure you put the cmdRetrieveRecord button in the form header or footer so it is still visible, alternatively handle such a situation in your code.

You can then control whether the data is Snapshot / Dynaset, editable etc from the form properties.

If you wish to proceed with your intended approach I think you should be able to do it something like the below by iterating through the Fields property of the recordset, though you have to be very careful in your naming of fields and controls and I imagine sooner or later it will trip you up.

Dim x As Integer

Set rs = Currentdb.OpenRecordset(strSQL, DB_OPEN_DYNASET)
If rs.EOF And rs.BOF Then 
    ' No record for this ID, handle accordingly and ExitSub
End If
rs.MoveFirst
For x = 0 To rs.Fields.Count - 1
    Me.Controls(rs(x).Name) = rs(x)
Next x

NOTE This is untested, I've just written it from memory but it should get you on the right track.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top