Excel VBA 和 SQL :指定 Where 子句时没有返回行
Excel VBA with SQL : No row returned when Where clause specified
下面是我的代码摘录。
这是 SQL 命令:
vSQL = "SELECT OLIN.fk_cCUST as CustomerKey, Sum(nOLINselTota) AS ResultSumV "
vSQL = vSQL & " FROM (OLIN Inner Join TYOR on OLIN.fk_cTYOR = TYOR.cTYOR) INNER Join MTYP On TYOR.fk_cMTYP = MTYP.cMTYP "
vSQL = vSQL & " Where OLIN.fk_cOHEAkey Like 'T180*' "
vSQL = vSQL & " GROUP BY OLIN.fk_cCUST "
vSQL = vSQL & ";"
数据库所在位置:
vDataSRC = "C:\_projCuTOPs\bdd\GSF_dataWHouse.accdb"
包含数据库字符串连接的变量:
vArrSRC = "OLEDB;Provider=Microsoft.ACE.OLEDB.12.0;Password="""";User ID=Admin;"
vArrSRC = vArrSRC & "Data Source= " & vDataSRC & ";"
vArrSRC = vArrSRC & "Mode=Share Deny Write;Extended Properties="""";Jet OLEDB:System database="""";Jet OLEDB:Registry Path="""";Jet OLEDB:Database Password="""";"
vArrSRC = vArrSRC & "Jet OLEDB:Engine Type=6;Jet OLEDB:Database Locking Mode=0;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;"
vArrSRC = vArrSRC & "Jet OLEDB:New Database Password="""";Jet OLEDB:Create System Database=False;Jet OLEDB:Encrypt Database=False;Jet OLEDB:Don't Copy Locale on Compact=False;"
vArrSRC = vArrSRC & "Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False;Jet OLEDB:Support Complex Data=False;Jet OLEDB:Bypass UserInfo Validation=False;"
vArrSRC = vArrSRC & "Jet OLEDB:Limited DB Caching=False;Jet OLEDB:Bypass ChoiceField Validation=False"
结果的 wrkSheet :
ActiveWorkbook.Sheets.Add After:=Worksheets(Worksheets.Count)
ActiveWorkbook.Sheets(Worksheets.Count).Name = "RawDatas"
此命令将 QueryTable 添加为 ListObject returns 由于 Where 子句而零出现,而 SQL 正常。
如果删除 Where 子句,它可以工作,但我需要添加对行的限制。
With ActiveSheet.ListObjects.Add(SourceType:=xlSrcExternal, Source:=vArrSRC, Destination:=Range("$A")).QueryTable
'>>
.CommandType = xlCmdSql
.CommandText = vSQL
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.PreserveColumnInfo = True
'**
.SourceDataFile = vDataSRC
'**
.ListObject.DisplayName = "tbl_SQL_SumTYOR"
.Refresh BackgroundQuery:=False
'>>
End With
怎么了?我绝对需要使用 Where 子句。
当 运行 在 MS Access GUI(前端)和任何 ODBC/OLDEB 连接到 MS Access(后端)之间查询时,LIKE
通配符的行为不同。在 MSDN docs.
中查看 ANSI-89 和 ANSI-92 之间的区别
对于您在 Excel 中所做的 ODBC/OLEDB 连接,LIKE
需要 ANSI-92 通配符 %
:
vSQL = vSQL & " Where OLIN.fk_cOHEAkey Like 'T180%' "
或者,为了兼容在 GUI 中使用 ALIKE
(类 ANSI)和 ODBC/OLEDB:
vSQL = vSQL & " Where OLIN.fk_cOHEAkey ALike 'T180%' "
更好的是,将查询保存在 MS Access 中(这更有效,因为引擎缓存统计信息和最佳执行计划):
SELECT OLIN.fk_cCUST as CustomerKey,
SUM(nOLINselTota) AS ResultSumV
FROM (OLIN INNER JOIN TYOR ON OLIN.fk_cTYOR = TYOR.cTYOR)
INNER Join MTYP On TYOR.fk_cMTYP = MTYP.cMTYP
WHERE OLIN.fk_cOHEAkey LIKE 'T180*'
GROUP BY OLIN.fk_cCUST
然后,在 Excel 中引用其名称(避免 VBA 连接):
vSQL = "SELECT * FROM mySavedQuery"
下面是我的代码摘录。
这是 SQL 命令:
vSQL = "SELECT OLIN.fk_cCUST as CustomerKey, Sum(nOLINselTota) AS ResultSumV "
vSQL = vSQL & " FROM (OLIN Inner Join TYOR on OLIN.fk_cTYOR = TYOR.cTYOR) INNER Join MTYP On TYOR.fk_cMTYP = MTYP.cMTYP "
vSQL = vSQL & " Where OLIN.fk_cOHEAkey Like 'T180*' "
vSQL = vSQL & " GROUP BY OLIN.fk_cCUST "
vSQL = vSQL & ";"
数据库所在位置:
vDataSRC = "C:\_projCuTOPs\bdd\GSF_dataWHouse.accdb"
包含数据库字符串连接的变量:
vArrSRC = "OLEDB;Provider=Microsoft.ACE.OLEDB.12.0;Password="""";User ID=Admin;"
vArrSRC = vArrSRC & "Data Source= " & vDataSRC & ";"
vArrSRC = vArrSRC & "Mode=Share Deny Write;Extended Properties="""";Jet OLEDB:System database="""";Jet OLEDB:Registry Path="""";Jet OLEDB:Database Password="""";"
vArrSRC = vArrSRC & "Jet OLEDB:Engine Type=6;Jet OLEDB:Database Locking Mode=0;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;"
vArrSRC = vArrSRC & "Jet OLEDB:New Database Password="""";Jet OLEDB:Create System Database=False;Jet OLEDB:Encrypt Database=False;Jet OLEDB:Don't Copy Locale on Compact=False;"
vArrSRC = vArrSRC & "Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False;Jet OLEDB:Support Complex Data=False;Jet OLEDB:Bypass UserInfo Validation=False;"
vArrSRC = vArrSRC & "Jet OLEDB:Limited DB Caching=False;Jet OLEDB:Bypass ChoiceField Validation=False"
结果的 wrkSheet :
ActiveWorkbook.Sheets.Add After:=Worksheets(Worksheets.Count)
ActiveWorkbook.Sheets(Worksheets.Count).Name = "RawDatas"
此命令将 QueryTable 添加为 ListObject returns 由于 Where 子句而零出现,而 SQL 正常。
如果删除 Where 子句,它可以工作,但我需要添加对行的限制。
With ActiveSheet.ListObjects.Add(SourceType:=xlSrcExternal, Source:=vArrSRC, Destination:=Range("$A")).QueryTable
'>>
.CommandType = xlCmdSql
.CommandText = vSQL
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.PreserveColumnInfo = True
'**
.SourceDataFile = vDataSRC
'**
.ListObject.DisplayName = "tbl_SQL_SumTYOR"
.Refresh BackgroundQuery:=False
'>>
End With
怎么了?我绝对需要使用 Where 子句。
当 运行 在 MS Access GUI(前端)和任何 ODBC/OLDEB 连接到 MS Access(后端)之间查询时,LIKE
通配符的行为不同。在 MSDN docs.
对于您在 Excel 中所做的 ODBC/OLEDB 连接,LIKE
需要 ANSI-92 通配符 %
:
vSQL = vSQL & " Where OLIN.fk_cOHEAkey Like 'T180%' "
或者,为了兼容在 GUI 中使用 ALIKE
(类 ANSI)和 ODBC/OLEDB:
vSQL = vSQL & " Where OLIN.fk_cOHEAkey ALike 'T180%' "
更好的是,将查询保存在 MS Access 中(这更有效,因为引擎缓存统计信息和最佳执行计划):
SELECT OLIN.fk_cCUST as CustomerKey,
SUM(nOLINselTota) AS ResultSumV
FROM (OLIN INNER JOIN TYOR ON OLIN.fk_cTYOR = TYOR.cTYOR)
INNER Join MTYP On TYOR.fk_cMTYP = MTYP.cMTYP
WHERE OLIN.fk_cOHEAkey LIKE 'T180*'
GROUP BY OLIN.fk_cCUST
然后,在 Excel 中引用其名称(避免 VBA 连接):
vSQL = "SELECT * FROM mySavedQuery"