【问题标题】:Access 2010 VBA query a table and iterate through resultsAccess 2010 VBA 查询表并遍历结果
【发布时间】:2011-06-15 05:58:36
【问题描述】:

我有一个要对表执行的查询。有了结果,我想做点什么。在我的脑海中,伪代码是:

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

我怎么会与 vba 如此相似?

【问题讨论】:

    标签: ms-access vba ms-access-2010


    【解决方案1】:

    DAO 是 Access 原生的,迄今为止最适合一般用途。 ADO 有它的位置,但不太可能就是这样。

     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
    

    【讨论】:

    • 只是一个评论,我也更喜欢 DAO 而不是 ADO,除非你需要从 SQL Server 或类似的东西运行存储过程。
    • 我只想说,一般来说,遍历记录集并不是您为了更新数据而经常做的事情。在许多只读场景中,您正在组装数据以供以某种格式使用(例如输出到 HTML),但更新通常最好使用 SQL UPDATE 命令完成(如果可能的话)。跨度>
    【解决方案2】:

    啊。因为我错过了你最初发帖的重点,所以这里有一个同样迭代的例子。第一个例子没有。在这种情况下,我检索一个 ADODB 记录集,然后将数据加载到一个集合中,该集合由函数返回给客户端代码:

    编辑:不确定我在粘贴代码时搞砸了什么,但格式有点乱。对不起!

    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
    

    结束函数

    【讨论】:

    • ADO 不是最适合与 Access 一起使用的东西。在特殊情况下它很有用,但对于普通的记录集来说,DAO 是原生的并且是最好的。
    • @XIVSolutions ADO 的“较新”参数并不是真正有用。 ADO 的开发已经停止,取而代之的是 Access 不使用的 ADO.Net。然而,DAO 的发展仍在继续。您还忽略了 DAO 的“次要”性能优势,但 DAO 可以比 ADO 快一个数量级......这对我来说并不小。
    • @XIVSolutions 在这个 StackOverflow 问题中,DAO 花了大约 2 秒。与 ADO 大约一分钟相比:stackoverflow.com/questions/2986831/… 我没有检查过网络上表源的差异,但我不知道这种情况有利于 ADO 的任何原因......但我不知道。对于 Jet/ACE 数据而言,DAO 可以更快地处理似乎总是合理的,因为这就是它的设计目的。
    • ADO 提供了灵活性,因为它可以容纳其他数据源,但可能会降低 Jet/ACE 的性能。有时我仍然使用 ADO,但仅用于 DAO 根本不能做或不能方便做的事情。
    • 如果您没有使用链接表,那么您就没有按照设计使用的方式使用 Access。 Microsoft 已弃用 ADP 5 年,转而支持带有 SQL Server 的 ODBC 链接表的 MDB/ACCDB。这也适用于其他数据库。当您说“跨网络”时,如果您的意思是 WAN、WiFi 或 Internet,那么您肯定不想要绑定的 Access 应用程序。事实上,我认为您根本不需要 Jet/ACE 后端。但即使使用带有链接表的 ODBC 到 SQL Server,DAO 也是最好的接口,因为 ODBC 连接是通过 ODBC 提供的。
    【解决方案3】:

    我知道在 AC 2010 中发生了一些变化。但是,据我所知,老式的 ADODB 是 VBA 的最佳方式。一个例子:

    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
    

    【讨论】:

    • 如果 AC 2010 中有任何变化导致上述内容无效,我很想听听。我还没有从 AC 2003 升级(不要再使用 Access 了……)。
    • 我应该在这里注意,我的示例是将查询结果加载到在类模块中声明的一组变量中(以可怕的伪匈牙利表示法,不少于)。然而,你可以很容易地加载到一个数组中,填充一个表单,你有什么。
    • 我不确定您为什么不编辑此答案而不是发布新答案,但如果新答案是您想要使用的答案,则应删除此答案。
    • 哈!因为我还在在这里学习礼仪。我还觉得第一个答案提供了从记录集进行分配的信息量更大的视图,而第二个答案则演示了迭代。道歉 。 . .
    猜你喜欢
    • 2012-02-06
    • 1970-01-01
    • 2016-01-29
    • 1970-01-01
    • 2020-01-06
    • 1970-01-01
    • 2015-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多