SQL语句“LIKE”运算符不会find只存在一个数字的单元格
我从没有标题行的Excel XLS工作表读取数据。 列中的某些单元格具有12345,12346,12347,12348等数字列表。其他单元格只有一个数字12345。
“LIKE”运算符可以查找单元格中有多个数字时的编号,但是找不到只存在一个编号的单元格。
SQL =“SELECT * FROM [2010 VIP $]其中F9 LIKE'%”&sDealer&“%'”
我尝试更改我的连接string:“数据源=”&dS&“;扩展属性=”“Excel 8.0; HDR =否”“”
(为IMEX添加混合数据types):“Data Source =”&dS&“; Extended Properties =”“Excel 8.0; HDR = No; IMEX = 1”“”
但是当IMEX被添加时,我得到一个未知的错误。 这是我的理解,你不能使用没有HDR =没有F1,F2,F3字段名称。
我尝试使用第一个连接string,但将我的SQL更改为:SQL =“SELECT * FROM [2010 VIP $] F9 LIKE'%”&sDealer&“%'OR F9 ='”&sDealer&“'”
但它仍然没有find只有一个数字的单元格。
编辑:我结束了使用较慢的方法,但它的工作原理,仍然在2秒钟内检查1200行:
Dim cN As New ADODB.Connection Dim rS As New ADODB.Recordset Dim SQL As String Dim dDealer As Double Dim WS As Worksheet Dim sDealer As String, sAmount As String Dim bFound As Boolean Set WS = ActiveSheet cN.Provider = "Microsoft.Jet.OLEDB.4.0" cN.Open "Data Source=" & MostRecentPath & ";" & _ "Extended Properties=""Excel 8.0;IMEX=1""" For dDealer = 2 To WS.Range("a60000").End(xlUp).Row sAmount = WS.Range("c" & dDealer).Value If Len(sAmount) > 0 Then GoTo skipOne sDealer = Trim(WS.Range("i" & dDealer).Value) If Len(sDealer) <> 5 Then GoTo skipOne If IsNumeric(sDealer) = False Then GoTo skipOne SQL = "SELECT * FROM [2010 VIP$]" rS.Open SQL, cN, adOpenStatic, adLockOptimistic bFound = False Do While rS.EOF = False If InStr(1, rS.Fields(8).Value, sDealer) > 0 Then bFound = True Exit Do End If rS.MoveNext Loop rS.Close If bFound = True Then WS.Range("l" & dDealer).Value = "VIP" DoEvents skipOne: Next dDealer cN.Close
单数单元格是数字的,不会使用基于string的运算符find。 你可以尝试强制单元格作为文本单元格,在数字前加一个撇号(例如'12345
)。
你也可以试试
SELECT * FROM [2010 VIP$] WHERE F9 LIKE '%" & sDealer & "%' OR F9=" & sDealer & "
(where子句的第二部分没有单引号)
除了设置IMEX选项,还要对工作表中的数据进行sorting,以确保前8行包含将被解释为文本的单元格 – 即具有多个值的单元格,如12345,12346,12347,12348
从这篇KB文章引用:
注:设置IMEX = 1告诉驱动程序使用导入模式。 在这种状态下,registry设置ImportMixedTypes = Text将被注意到。 这迫使混合数据被转换为文本。 为了可靠地工作,您可能还必须修改registry设置,TypeGuessRows = 8。 默认情况下,ISAM驱动程序会查看前八行,并从该采样中确定数据types。 如果这八行采样都是数字,那么设置IMEX = 1不会将默认数据types转换为文本; 它将保持数字。
或者,考虑在电子表格中标准化数据,因为这是真正的问题
首先,我同意@barrowc:底层的问题是你的'数字列表'违反了第一范式(1NF),而SQL并不是用来查询非标量数据types(即没有运算符来利用多值数据)。
其次,您需要使ADO的连接string和registry设置正确,才能将该列作为文本“查看”。 本文可能对此有所帮助。
如果您必须使用非第一范式(NFNF)数据,则需要处理逗号分隔符。
这里有一些标准的SQL与testing数据来certificate这一点:
WITH Dealers (dealer_ID, delear_list) AS ( SELECT dealer_ID, delear_list FROM ( VALUES (1, '12345,12346,12347,12348'), (2, '12344,12345,12346'), (3, '12343,12344,12345'), (4, '12345'), (5, '12399,12346,12347,12348'), (6, '12344,12399,12346'), (7, '12343,12344,12399'), (8, '12399') ) AS Dealers (dealer_ID, delear_list) ) SELECT dealer_ID, delear_list FROM Dealers WHERE (',' + delear_list + ',') LIKE ('%,12345,%');
显然,你需要把这个转换成ACE / Jet方言代码
WHERE (',' & delear_list & ',') ALIKE ('%,12345,%');
Jet不使用%进行模式匹配。 它使用*来代替。 它也将数字与模式进行匹配,就好像它们是string一样。 所以我怀疑你将能够返回到你的模式匹配的方法,如果你改变你的SQLstring从"SELECT * FROM [2010 VIP$] WHERE F9 LIKE '%" & sDealer & "%'"
到"SELECT * FROM [2010 VIP$] WHERE F9 LIKE '*" & sDealer & "*'"
。