【问题标题】:Code to loop through all records in MS Access循环访问 MS Access 中所有记录的代码
【发布时间】:2011-08-17 09:00:24
【问题描述】:

我需要一个代码来循环遍历表中的所有记录,以便提取一些数据。除此之外,是否还可以遍历过滤记录​​并再次提取数据?谢谢!

【问题讨论】:

    标签: ms-access vba


    【解决方案1】:

    您应该能够使用非常标准的 DAO 记录集循环来执行此操作。您可以在以下链接中查看一些示例:
    http://msdn.microsoft.com/en-us/library/bb243789%28v=office.12%29.aspx
    http://www.granite.ab.ca/access/email/recordsetloop.htm

    我自己的标准循环看起来像这样:

    Dim rs As DAO.Recordset
    Set rs = CurrentDb.OpenRecordset("SELECT * FROM Contacts")
    
    'Check to see if the recordset actually contains rows
    If Not (rs.EOF And rs.BOF) Then
        rs.MoveFirst 'Unnecessary in this case, but still a good habit
        Do Until rs.EOF = True
            'Perform an edit
            rs.Edit
            rs!VendorYN = True
            rs("VendorYN") = True 'The other way to refer to a field
            rs.Update
    
            'Save contact name into a variable
            sContactName = rs!FirstName & " " & rs!LastName
    
            'Move to the next record. Don't ever forget to do this.
            rs.MoveNext
        Loop
    Else
        MsgBox "There are no records in the recordset."
    End If
    
    MsgBox "Finished looping through records."
    
    rs.Close 'Close the recordset
    Set rs = Nothing 'Clean up
    

    【讨论】:

    • 仅供参考,您应该将您的rs.Close 封装为If Not rs = Nothing Then Set rs.Close。如果由于某种原因,您的 Set 语句失败,您的代码将在此处出错。我的 0.02c。
    【解决方案2】:

    在“引用”中,导入 DAO 3.6 对象引用。

    private sub showTableData
    
    dim db as dao.database
    dim rs as dao.recordset
    
    set db = currentDb
    set rs = db.OpenRecordSet("myTable") 'myTable is a MS-Access table created previously
    
    'populate the table
    rs.movelast
    rs.movefirst
    
    do while not rs.EOF
       debug.print(rs!myField) 'myField is a field name in table myTable
       rs.movenext             'press Ctrl+G to see debuG window beneath
    loop
    
    msgbox("End of Table")
    
    end sub
    

    您可以通过不同方式交互查询和过滤表等数据对象:

    通过查询:

    private sub showQueryData
    
    dim db as dao.database
    dim rs as dao.recordset
    dim sqlStr as string
    
    sqlStr = "SELECT * FROM customers as c WHERE c.country='Brazil'"
    
    set db = currentDb
    set rs = db.openRecordset(sqlStr)
    
    rs.movefirst
    
    do while not rs.EOF
      debug.print("cust ID: " & rs!id & " cust name: " & rs!name)
      rs.movenext
    loop
    
    msgbox("End of customers from Brazil")
    
    end sub
    

    您还应该寻找记录集对象的“过滤器”属性以仅过滤所需的记录,然后以相同的方式与它们交互(参见 MS-Access 代码窗口中的 VB6 帮助),或创建一个“QueryDef”对象运行查询并将其也用作记录集(有点棘手)。如果你想要另一种方法,请告诉我。

    我希望我有所帮助。

    【讨论】:

    • 一些 cmets:在 .MoveFirst 之前执行 .MoveLast 没有任何好处,除非您需要准确的记录集记录数。否则,您只是在浪费资源遍历记录集的末尾并再次回到开头,没有任何目的。
    • 我看不出过滤现有记录集有什么用处。该过程的昂贵部分是打开记录集。如果您需要记录子集,请从该过滤器开始。否则,过滤记录集然后对结果进行处理没有多大意义。
    • 您好 David-W-Fenton,感谢您的建议。我只是认为,对于小型表,填充记录集值得将数据加载到内存中并提高 seek 等方法的速度。 Access 帮助中也会显示将记录集移动到其末尾然后再到其开头。
    • 我认为你已经把它弄反了——记录集越小,将它加载到记录集中的价值就越小,因为 Jet 会将整个小表缓存在内存中。应该避免 SEEK,因为它实际上没有任何用处,除非在非常特殊的情况下非常小。
    • 当你用完rs.close记录集和db.close数据库是个好主意。
    【解决方案3】:

    找到了一个用 cmets 解释每个语句的好代码。 代码位于 -accessallinone

    Sub DAOLooping()
    On Error GoTo ErrorHandler
    
    Dim strSQL As String
    Dim rs As DAO.Recordset
    
    strSQL = "tblTeachers"
    'For the purposes of this post, we are simply going to make 
    'strSQL equal to tblTeachers.
    'You could use a full SELECT statement such as:
    'SELECT * FROM tblTeachers (this would produce the same result in fact).
    'You could also add a Where clause to filter which records are returned:
    'SELECT * FROM tblTeachers Where ZIPPostal = '98052'
    ' (this would return 5 records)
    
    Set rs = CurrentDb.OpenRecordset(strSQL)
    'This line of code instantiates the recordset object!!! 
    'In English, this means that we have opened up a recordset 
    'and can access its values using the rs variable.
    
    With rs
    
    
        If Not .BOF And Not .EOF Then
        'We don’t know if the recordset has any records, 
        'so we use this line of code to check. If there are no records 
        'we won’t execute any code in the if..end if statement.    
    
            .MoveLast
            .MoveFirst
            'It is not necessary to move to the last record and then back 
            'to the first one but it is good practice to do so.
    
            While (Not .EOF)
            'With this code, we are using a while loop to loop 
            'through the records. If we reach the end of the recordset, .EOF 
            'will return true and we will exit the while loop.
    
                Debug.Print rs.Fields("teacherID") & " " & rs.Fields("FirstName")
                'prints info from fields to the immediate window
    
                .MoveNext
                'We need to ensure that we use .MoveNext, 
                'otherwise we will be stuck in a loop forever… 
                '(or at least until you press CTRL+Break)
            Wend
    
        End If
    
        .close
        'Make sure you close the recordset...
    End With
    
    ExitSub:
        Set rs = Nothing
        '..and set it to nothing
        Exit Sub
    ErrorHandler:
        Resume ExitSub
    End Sub
    

    记录集在循环数据时有两个重要的属性,EOF(文件结束)和 BOF(文件开始)。记录集就像表格,当您遍历一个表格时,您实际上是按顺序从一个记录移动到另一个记录。在您浏览记录时,EOF 属性设置为 false,但在您尝试越过最后一条记录后,EOF 属性变为 true。对于 BOF 属性,这同样适用。

    这些属性让我们知道何时达到记录集的限制。

    【讨论】:

      猜你喜欢
      • 2014-04-09
      • 1970-01-01
      • 1970-01-01
      • 2015-11-11
      • 1970-01-01
      • 2014-08-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多