我有一个包含 107,141 条记录的 Excel 工作表。
我正在使用此页面中的基本代码。
Public Function RecordSetFromSheet(sheetName As String)
Dim rst As New ADODB.Recordset
Dim cnx As New ADODB.Connection
Dim cmd As New ADODB.Command
'setup the connection
'[HDR=Yes] means the Field names are in the first row
With cnx
.Provider = "Microsoft.Jet.OLEDB.4.0"
.ConnectionString = "Data Source='" & ThisWorkbook.FullName & "'; " & "Extended Properties='Excel 8.0;HDR=Yes;IMEX=1'"
.Open
End With
str_SQL = "SELECT * From [" & sheetName & "$]" & _
"WHERE [Profession] = 'Veterinary Medicine' " & _
"AND [Type] = 'Veterinarian' Or [Type] = 'Veterinarian Cln Ac Ltd' Or [Type] = 'Veterinarian Ed Ltd' Or [Type] = 'Veterinarian Nonaprv Prgm Ltd' " & _
"AND [County] = 'Livingston' Or [County] = 'Macomb' Or [County] = 'Monroe' Or [County] = 'Oakland' Or [County] = 'Washtenaw' Or [County] = 'Wayne'"
'setup the command
Set cmd.ActiveConnection = cnx
cmd.CommandType = adCmdText
' cmd.CommandText = "SELECT * FROM [" & sheetName & "$]"
cmd.CommandText = str_SQL
rst.CursorLocation = adUseClient
rst.CursorType = adOpenDynamic
rst.LockType = adLockOptimistic
'open the connection
rst.Open cmd
'disconnect the recordset
Set rst.ActiveConnection = Nothing
'cleanup
If CBool(cmd.State And adStateOpen) = True Then
Set cmd = Nothing
End If
If CBool(cnx.State And adStateOpen) = True Then cnx.Close
Set cnx = Nothing
'"return" the recordset object
Set RecordSetFromSheet = rst
End Function
Public Sub Test()
Dim rstData As ADODB.Recordset
Set rstData = RecordSetFromSheet("Sheet2")
rstData.MoveFirst
rstData.MoveLast
MsgBox rstData.RecordCount
rstData.Filter = "County = 'Macomb'"
rstData.MoveFirst
rstData.MoveLast
MsgBox rstData.RecordCount
rstData.Close
Set rstData = Nothing
End Sub
创建对象和记录集时没有错误。
我需要的记录(至少最初)都位于数据的底部。
当我使用以下 SQL 时:
str_SQL = "SELECT * From [" & sheetName & "$]"
ADODB 是否有一些内置限制?
这是系统资源限制吗?
如果是这样,在不添加更多内存的情况下,是否可以应用任何设置来获取所有(或至少更多)记录?
为了执行更多测试,我将底部 14,592 条记录复制到另一个工作表(还更新了代码中的工作表名称参考)。
现在,当我重新运行上述 SQL 时,我得到了正确的记录数:14,592。
但我需要进一步缩小记录范围,因此我添加了更多 SQL,如下所示:
str_SQL = "SELECT * From [" & sheetName & "$]" & _
"WHERE [Profession] = 'Veterinary Medicine' " & _
"AND [Type] = 'Veterinarian' Or [Type] = 'Veterinarian Cln Ac Ltd' Or [Type] = 'Veterinarian Ed Ltd' Or [Type] = 'Veterinarian Nonaprv Prgm Ltd'"
实际上,为了节省空间,从技术上讲,我首先添加了最初的
WHERE
子句,当记录计数正确时,我添加了以下 AND
子句。但是如果我运行下面的 SQL:
str_SQL = "SELECT * From [" & sheetName & "$]" & _
"WHERE [Profession] = 'Veterinary Medicine' " & _
"AND [Type] = 'Veterinarian' Or [Type] = 'Veterinarian Cln Ac Ltd' Or [Type] = 'Veterinarian Ed Ltd' Or [Type] = 'Veterinarian Nonaprv Prgm Ltd' " & _
"AND [County] = 'Livingston' Or [County] = 'Macomb' Or [County] = 'Monroe' Or [County] = 'Oakland' Or [County] = 'Washtenaw' Or [County] = 'Wayne'"
我收到 8,741 记录。
作为进一步的测试,如果我在生成的记录集上使用以下行:
rstData.Filter = "County = 'Macomb'"
我得到 1,099 条记录,而不是正确的记录数 184 条。
很明显
.Filter
正在过滤记录集,尽管没有达到正确的记录计数。.Filter
导致错误的记录计数,因为初始记录集的记录太多。我知道这是真的,因为如果我在具有“正确记录数”的*最后一个 SQL 化身上使用过滤器 rstData.Filter = "County = 'Macomb'"
,过滤器将按预期生成 184 条记录。
但是最后一条 SQL 发生了什么?
结果记录集如何比不包含最后一个 AND
子句的 SQL 获得*更多*记录?
...AND A or B or c
AND C or D or E
应该是
...AND (A or B or c)
AND (C or D or E)
这个(例如):
AND [County] = 'Livingston' Or [County] = 'Macomb' Or [County] = 'Monroe' Or [County] = 'Oakland' Or [County] = 'Washtenaw' Or [County] = 'Wayne'"
也可以写成:
AND [County] IN ('Livingston','Macomb','Monroe','Oakland','Washtenaw', 'Wayne')
...这也可以帮助解决 AND/OR 问题。