0

The query i have at the moment works to an extent. Running the query below in access query design will display all the employees with a relevant company ID. However with VBA it will only display the first record in Link_Table.FirstName in the string Me.txtbxFirstName = rst!FirstName. Will the value of for instance, Link_Table.FirstName only ever the first record in the table? Or can it hold multiples values which can then be iterated through?

Public Function DataLookup()
Dim CompDetailSQL As String
Dim rst As DAO.Recordset
CompDetailSQL = "SELECT Companies.CompanyID, Companies.CompanyName, 
Companies.AddressNo, 
Companies.AddressLine1, Companies.AddressLine2, Companies.AddressLine3, 
Companies.AddressPostcode, Companies.AddressCounty, 
Companies.Description, 
Companies.MainTelephone, 
Companies.MainEmail, 
Companies.WebAddress, 
Link_Table.FirstName
FROM Companies 
INNER JOIN Link_Table ON Companies.CompanyID = Link_Table.CompanyID 
WHERE Companies.CompanyID = " & Me.lstBoxCompanyName.Value
Debug.Print CompDetailSQL
Set rst = CurrentDb.OpenRecordset(CompDetailSQL, dbOpenSnapshot)
Me.lblDescription.Caption = rst!Description
Me.txtbxAddressLine1.Value = rst!AddressLine1
Me.txtbxAddressLine2.Value = rst!AddressLine2
Me.txtbxAddressLine3.Value = rst!AddressLine3
Me.txtbxAddressPostcode.Value = rst!AddressPostcode
Me.txtbxAddressCounty.Value = rst!AddressCounty
Me.txtbxMainTelephone.Value = rst!MainTelephone
Me.txtbxMainEmail.Value = rst!MainEmail
Me.txtbxMainWeb.Value = rst!WebAddress
Me.txtbxFirstName = rst!FirstName    
rst.Close
Set rst = Nothing
End Function
4

1 回答 1

2

The recordset does hold all the records your query returned, but your textboxes can only show one record at a time. Because your code currently closes the recordset and sets it to Nothing, you will need to select a method for persisting your recordset.

One way would be to put your recordset in a larger scope, such as within the form itself or a global variable, rather than only within this procedure. It can complicate things like populating the recordset or closing it when done because you have to handle than in other locations. Keeping too large of a scope can overuse your memory as well. Once you do have a persistent recordset, you can navigate it like this:

If Not (rst.BOF And rst.EOF) Then
    'Do something here'
    rst.MoveNext 'Navigate to the next sequential record'
    'or rst.MovePrevious to go backward'
End If

or

Do While Not rst.EOF
    'Do something here'
    rst.MoveNext
Loop

You may also want to consider having your query insert the records into a temp table, which you could have bound to the form. This would allow you to treat it as a static table, just like you would any other table in your database. You would not have to persist the recordset itself because the records would reside in the table until you remove them.


Update

Trying to display all records from a recordset at once would require that you have one copy of each text box for each record. Given your example of 10 fields and 3 records, you would need to show 30 controls on the form to display them all. You could do this by just populating the first set, moving to the next record and populating the next set, etc.

Do While Not rst.EOF
    Me.lblDescription1.Caption = rst!Description
    rst.MoveNext
    Me.lblDescription2.Caption = rst!Description
    rst.MoveNext
    Me.lblDescription3.Caption = rst!Description
Loop

This is kind of clunky, especially because if you happen to have 2 or 4 records, instead of 3, as you would end up with errors, empty fields, or unshown data. Instead, you might want to use a continuous form. This allows you to create one set of textboxes and have them repeat as many times as necessary to cover all the records returned. I'm not sure you can do this with labels, but for textboxes it's quite simple. Just create a form and mark it as a Continuous Form in the Default View setting, then create a TextBox for each field in your recordset. Leave them unbound in the designer, and use the following code to attach them at runtime:

Set Me.Recordset = rst

Me.txtbxAddressLine1.ControlSource = "addressline1"
Me.txtbxAddressLine2.ControlSource = "addressline2"
Me.txtbxAddressLine3.ControlSource = "addressline3"

Set rst = Nothing

Typically with a continuous form, you would make it a subform of another form, allowing you to have unique data and controls on the main form, and a subform with the repeating data from the recordset.

More on binding recordsets to forms.

More on creating unbound data controls.

于 2013-09-24T16:25:00.443 回答