ADODB 在 Excel 中的限制是什么?

问题描述 投票:0回答:1

我有一个包含 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 & "$]"

我只得到上面的 41,604 条记录。

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
子句。
此查询返回正确的记录数,4,584

但是如果我运行下面的 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 获得*更多*记录?

    

sql excel vba adodb
1个回答
0
投票

...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 问题。

© www.soinside.com 2019 - 2024. All rights reserved.