17

I have a query that I want to execute against a table. With the results I want to do something. In my head the pseudo code is:

var q = "select * from table where some condition";
var results = db.getResults(q);
foreach (row r in results )
    do something with result

How would I so something similar with vba?

Fionnuala
  • 90,370
  • 7
  • 114
  • 152
Sally
  • 1,749
  • 7
  • 31
  • 39

3 Answers3

33

DAO is native to Access and by far the best for general use. ADO has its place, but it is unlikely that this is it.

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

 Set db=CurrentDB

 strSQL = "select * from table where some condition"

 Set rs = db.OpenRecordset(strSQL)

 Do While Not rs.EOF

    rs.Edit
    rs!SomeField = "Abc"
    rs!OtherField = 2
    rs!ADate = Date()
    rs.Update

    rs.MoveNext
Loop
Fionnuala
  • 90,370
  • 7
  • 114
  • 152
  • Just a comment that I also prefer DAO over ADO unless you need to run stored procedures from SQL Server or something like that. – HK1 Jan 26 '11 at 04:25
  • 4
    Let me just say that in general, walking a recordset is not something you'll do that often to update data. There are any number of read-only scenarios where you're assembling data for use in some format (such as outputting to HTML), but updating is something that is generally best done with a SQL UPDATE command (where that's possible). – David-W-Fenton Jan 26 '11 at 23:29
2

Ahh. Because I missed the point of you initial post, here is an example which also ITERATES. The first example did not. In this case, I retreive an ADODB recordset, then load the data into a collection, which is returned by the function to client code:

EDIT: Not sure what I screwed up in pasting the code, but the formatting is a little screwball. Sorry!

Public Function StatesCollection() As Collection
Dim cn As ADODB.Connection
Dim cmd As ADODB.Command
Dim rs As ADODB.Recordset
Dim colReturn As New Collection

Set colReturn = New Collection

Dim SQL As String
SQL = _
    "SELECT tblState.State, tblState.StateName " & _
    "FROM tblState"

Set cn = New ADODB.Connection
Set cmd = New ADODB.Command

With cn
    .Provider = DataConnection.MyADOProvider
    .ConnectionString = DataConnection.MyADOConnectionString
    .Open
End With

With cmd
    .CommandText = SQL
    .ActiveConnection = cn
End With

Set rs = cmd.Execute

With rs
    If Not .EOF Then
    Do Until .EOF
        colReturn.Add Nz(!State, "")
        .MoveNext
    Loop
    End If
    .Close
End With
cn.Close

Set rs = Nothing
Set cn = Nothing

Set StatesCollection = colReturn

End Function

XIVSolutions
  • 4,442
  • 19
  • 24
  • 1
    ADO is not the most suitable thing to use with Access. There are special circumstances where it is useful, but for an ordinary recordset DAO is native and best. – Fionnuala Jan 25 '11 at 15:10
  • I respectfully disagree. Obviously DAO IS native, which may have had a minor performance advantage under the more limited machines of a few years ago. However, the clumsy syntax, arcane connection mechanism, and limited feature set (as compared with ADODB) make it more attractive. Of course, this is only my opinion, and you know what they say . . . – XIVSolutions Jan 25 '11 at 15:47
  • @Remou - Note: emphasis on the "respectfully" in my post above. Obviously, I prefer ADO, but on reflection, it is also what I "grew up with", therefore most familiar with, therefore in favor of. Point taken aboutht enative technology vs. the newer. – XIVSolutions Jan 25 '11 at 15:56
  • 1
    @XIVSolutions The "newer" argument for ADO is not really useful. Development of ADO has stopped in favor of ADO.Net, which Access doesn't use. However development continues for DAO. Also you dismissed a "minor" performance advantage for DAO, but DAO can be an order of magnitude faster than ADO ... which is not minor to me. – HansUp Jan 25 '11 at 17:11
  • @HansUp - Duly noted, and comments like yours are part of why I am here! My best (mis)information was contrary to what you are telling me and from what I (at the time) considered a reliable source. I did NOT know that development continues on DAO, nor the degree it might outperform ADO. Is this true over a netwrok as well? Most of my experience using ADO has been creating client-side .mdb or .exe's targeting a back-end on our server at work (and avaioding linked tables). I also moved to ADO.net a few years ago. Anyway, thanks for the feedback! – XIVSolutions Jan 26 '11 at 02:13
  • 2
    @XIVSolutions In this StackOverflow question, DAO took about 2 sec. vs. about a minute for ADO: http://stackoverflow.com/questions/2986831/ms-access-why-is-adodb-recordset-batchupdate-so-much-slower-than-application-imp/2987017#2987017 I haven't examined differences with table sources across a network, but I'm not aware of any reasons why that situation would favor ADO ... but I dunno. It's always seemed reasonable that DAO could be faster for Jet/ACE data because that's what it's designed for. – HansUp Jan 26 '11 at 03:20
  • 1
    ADO offers flexibility in that it can accommodate other data sources, but with perhaps a performance penalty for Jet/ACE. I still use ADO sometimes, but only for stuff which DAO can't do at all or can't do as conveniently. – HansUp Jan 26 '11 at 03:22
  • Nicely done, and color me humbled. Also, I was stunned when I saw Remou's example, and went back to see how I could have been led so far astray (way back in the day). Then I understood - I had an IT guy at work show me my ADODB basics. When I went to MS Access "help (this is 2005 or so, and we were using ac 2000 at the time), the DAO example was much, MUCH less clear, and unnecessarily complicated for the beginner I was at that time. So I never went back to it. Ooops. – XIVSolutions Jan 26 '11 at 05:01
  • @XIVSolutions: I was going to ask that you provide 3 important features that DAO lacks and ADO provides, but I see you've changed your tune in comments. ADO is useful with non-Jet/ACE data sources, but if you're using Access as the front end, you're likely working with those via ODBC linked tables, in which case you're using Jet/ACE as your data intermediary so that DAO is the superior interface. That doesn't mean ADO has no role in that scenario, just that it's the SECONDARY data interface, used when you need to do something DAO can't (or doesn't do efficiently). – David-W-Fenton Jan 26 '11 at 23:27
  • @David Fenton - When I was learning all this we were using .mdb or .exe "front-ends" at work, pointed at a back-end on the other end of the network pipe. Also, Much of what our IT guys do is point Access Front-ends at SQL Server Back-ends, so the ADODB thing made sense in that context. However, I AM still curious if the DAO superiority holds up in the Scenario I describe: an Access front end against an Access Back-end over a network (and NOT using Linked Tables). If so, you will find me changing my tune even more. I am happy to be wrong, if it results in furthering my knowledge . . . – XIVSolutions Jan 27 '11 at 02:51
  • 1
    If you're not using linked tables, you're not using Access the way it was designed to be used. Microsoft has deprecated ADPs for 5 years now in favor of MDB/ACCDB with ODBC linked tables with SQL Server. That would also apply to other databases. When you say "across a network" if you mean a WAN or WiFi or Internet, then you definitely don't want a bound Access app. Indeed, I don't think you want a Jet/ACE back end at all. But even with ODBC to SQL Server with linked tables, DAO is the best interface because the ODBC connection is provided via ODBC. – David-W-Fenton Jan 29 '11 at 02:14
  • @David-W-Fenton - The network is LAN. Due to, well, just the way things have evolvedover the years, I landed with a mess of Access Back-ends for my department (I am not IT, they have just "put up" with me over the years. So (for the moment) it is mostly .mdb Fornt-end, pulling from .mdb Back-end. I would love to consolidate it all into SQL Server, but I.T. WON'T let me do that (for valid reasons, butstill . . .). For the moment I am stuck with it, but you have made a solid case for checking out linking the tables instead of using code connection via ADODB. THanks for the feedback! – XIVSolutions Jan 29 '11 at 06:01
1

I know some things have changed in AC 2010. However, the old-fashioned ADODB is, as far as I know, the best way to go in VBA. An Example:

Dim cn As ADODB.Connection
Dim cmd As ADODB.Command
Dim prm As ADODB.Parameter
Dim rs As ADODB.Recordset
Dim colReturn As New Collection

Dim SQL As String
SQL = _
    "SELECT c.ClientID, c.LastName, c.FirstName, c.MI, c.DOB, c.SSN, " & _
    "c.RaceID, c.EthnicityID, c.GenderID, c.Deleted, c.RecordDate " & _
    "FROM tblClient AS c " & _
    "WHERE c.ClientID = @ClientID"

Set cn = New ADODB.Connection
Set cmd = New ADODB.Command

With cn
    .Provider = DataConnection.MyADOProvider
    .ConnectionString = DataConnection.MyADOConnectionString
    .Open
End With

With cmd
    .CommandText = SQL
    .ActiveConnection = cn
    Set prm = .CreateParameter("@ClientID", adInteger, adParamInput, , mlngClientID)
    .Parameters.Append prm
End With

Set rs = cmd.Execute

With rs
    If Not .EOF Then
        Do Until .EOF
            mstrLastName = Nz(!LastName, "")
            mstrFirstName = Nz(!FirstName, "")
            mstrMI = Nz(!MI, "")
            mdDOB = !DOB
            mstrSSN = Nz(!SSN, "")
            mlngRaceID = Nz(!RaceID, -1)
            mlngEthnicityID = Nz(!EthnicityID, -1)
            mlngGenderID = Nz(!GenderID, -1)
            mbooDeleted = Deleted
            mdRecordDate = Nz(!RecordDate, "")

            .MoveNext
        Loop
    End If
    .Close
End With

cn.Close

Set rs = Nothing
Set cn = Nothing
XIVSolutions
  • 4,442
  • 19
  • 24
  • If anything has changed in AC 2010 which makes the above invalid, I would love to hear about it. I have not upgraded yet from AC 2003 (don't use Access as much anymore . . .). – XIVSolutions Jan 25 '11 at 14:43
  • I should note here that my example is loading the results of the query into a set of variables (in horrible, pseudo-hungarian notation, no less) declared within a class module. However, one could just as easily load into an array, populate a form, what have you. – XIVSolutions Jan 25 '11 at 14:51
  • 1
    I am not sure why you did not edit this answer instead of posting a new answer, but if the new answer is the one you want to go with, you should delete this one. – Fionnuala Jan 25 '11 at 15:11
  • Ha! Because I am still learning ettiquette on here. I also felt that the first answer provided a slightly more informative view of making assignments from the recordset, while the second demonstrated iteration. Apologies . . . – XIVSolutions Jan 25 '11 at 15:51