如何在 VBA 中复制和过滤 DAO 记录集?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7101127/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 13:50:02  来源:igfitidea点击:

How do I copy and filter a DAO recordset in VBA?

excelms-accessvbadaorecordset

提问by sigil

Due to problems with DAO (see my previous question), I need to create an Excel VBA Recordset from an Access query and filter its results using a user-defined function.

由于 DAO 的问题(请参阅我之前的问题),我需要从 Access 查询创建 Excel VBA 记录集并使用用户定义的函数过滤其结果。

I thought I could use the following code to accomplish this:

我以为我可以使用以下代码来完成此操作:

Sub test()

Dim db As Database
Dim rs As Recordset
Dim rs_clone As Recordset

Set db = OpenDatabase(dbPath)
Set rs = db.OpenRecordset("select testVal from dataTable")
Set rs_clone = rs.Clone
rs_clone.MoveLast
rs_clone.MoveFirst
while not rs_clone.eof
 if myUDF(rs_clone!testVal) then
    rs_clone.delete
 end if
 rs_clone.moveNext
wend

End Sub

But that actually deletes values from my source table, so the clone isn't a new recordset that I can freely alter, it's just another pointer to the original one. How can I use my UDF to filter out the records I don't want, while leaving the original data untouched, if putting the UDF in the query itself is not an option?

但这实际上会从我的源表中删除值,因此克隆不是我可以自由更改的新记录集,它只是另一个指向原始记录集的指针。如果将 UDF 放入查询本身不是一种选择,我如何使用我的 UDF 过滤掉我不想要的记录,同时保持原始数据不变?

采纳答案by Lance Roberts

Use the .getrows method:

使用 .getrows 方法:

Dim rs_clone As Variant

...

rs_clone = rs.getrows(numrows)

then process the resulting 2-d array.

然后处理生成的二维数组。

回答by David-W-Fenton

In Access with DAO, this is how you'd do it:

在 Access with DAO 中,您可以这样做:

  Dim db As DAO.Database
  Dim rs As DAO.Recordset
  Dim rsFiltered As DAO.Recordset

  Set db = CurrentDb
  Set rs = db.OpenRecordset("SELECT tblInventory.* FROM tblInventory;")
  rs.MoveLast
  Debug.Print "Unfiltered: " & rs.RecordCount

  rs.filter = "[LastUpdated]>=#1/1/2011#"
  Set rsFiltered = rs.OpenRecordset
  rsFiltered.MoveLast
  Debug.Print "Filtered: " & rsFiltered.RecordCount

  rsFiltered.Close
  Set rsFiltered = Nothing
  rs.Close
  Set rs = Nothing
  Set db = Nothing

However, note that (as mentioned in the help file), it may be just as fast to simply reopen the recordset with new criteria, instead of filtering the existing recordset.

但是,请注意(如帮助文件中所述),使用新条件重新打开记录集而不是过滤现有记录集可能同样快。

回答by user1934049

Option Compare Database

Private Sub Command0_Click()
Sub Export_Click()

Dim db As Database, rs As Recordset, sql As String, r As Variant

Dim appExcel As Excel.Application
Dim excelWbk As Excel.Workbook
Dim excelSht As Object
Dim rng As Excel.Range

Set appExcel = New Excel.Application
On Error Resume Next
Set excelWbk = appExcel.Workbooks.Open("Folder Name(Template)")

Set db = CurrentDb()
sql1 = "Select * from Query_New"
sql2 = "Select * from Query_Expired"
Set rs1 = db.OpenRecordset(sql1, dbReadOnly)
Set rs2 = db.OpenRecordset(sql2, dbReadOnly)

Dim SheetName1 As String
Dim SheetName2 As String

SheetName1 = "New"
SheetName2 = "Expired"

'For first sheet
On Error Resume Next
excelWbk.Sheets(SheetName1).Select

If Err.Number <> 0 Then
MsgBox Err.Number
excelWbk.Close False
appExcel.Quit
Exit Sub
End If

With excelWbk.Activesheet
    .Cells(5, 1).CopyFromRecordset rs1
    On Error GoTo 0
End With

'For second sheet
On Error Resume Next
excelWbk.Sheets(SheetName2).Select

If Err.Number <> 0 Then
MsgBox Err.Number
excelWbk.Close False
appExcel.Quit
Exit Sub
End If

With excelWbk.Activesheet
    .Cells(5, 1).CopyFromRecordset rs2
    On Error GoTo 0
End With


rs1.Close
Set rs1 = Nothing
rs2.Close
Set rs2 = Nothing
db.Close
Set db = Nothing

On Error Resume Next

excelWbk.SaveAs "C:\Documents and settings\" & Environ("UserName") & "\Desktop\Decision.xlsx"

If Err.Number <> 0 Then
MsgBox Err.Number
End If

excelWbk.Close False
appExcel.Quit
Set appExcel = Nothing
MsgBox "The report has been saved"
End Sub




End Sub