SQL语句“LIKE”运算符找不到只存在一个数字的单元格

时间:2010-10-11 23:41:36

标签: sql excel ms-access vba ado

我正在阅读没有标题行的Excel XLS工作表。列中的一些单元格有一个数字列表,如12345,12346,12347,12348。其他单元格只有一个数字12345。

“LIKE”运算符在单元格中有多个数字时查找数字,但找不到只存在一个数字的单元格。

SQL =“SELECT * FROM [2010 VIP $] WHERE F9 LIKE'%”& sDealer& “%'”

我尝试更改我的连接字符串: “数据来源=”& dS& “;扩展属性=”“Excel 8.0; HDR =否”“”

To(为混合数据类型添加IMEX): “数据来源=”& dS& “;扩展属性=”“Excel 8.0; HDR =否; IMEX = 1”“”

但是在添加IMEX时出现未知错误。据我了解,如果没有HDR = No。

,你不能使用F1,F2,F3字段名称

我尝试使用第一个连接字符串,但将SQL更改为: SQL =“SELECT * FROM [2010 VIP $] WHERE F9 LIKE'%”& sDealer& “%'或F9 ='”& sDealer& “'”

但它仍然没有找到只有一个数字的单元格。

编辑:我最终使用了一个较慢的方法,但它仍然可以工作,并且仍然在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

4 个答案:

答案 0 :(得分:0)

单数字格是数字,使用基于字符串的like运算符将无法找到。您可以尝试通过在数字前加上撇号(例如'12345)来强制单元格成为文本单元格。

您也可以尝试

SELECT * FROM [2010 VIP$] WHERE F9 LIKE '%" & sDealer & "%' OR F9=" & sDealer & "

(where子句的第二部分没有单引号)

答案 1 :(得分:0)

除了设置IMEX选项外,还要对工作表中的数据进行排序,以确保前八行包含将被解释为文本的单元格 - 即具有多个值的单元格,如12345,12346,12347,12348

引自this KB article

  

注意:设置IMEX = 1会告诉驱动程序   使用导入模式。在这种状态下,   注册表设置ImportMixedTypes = Text   会被注意到。这种力量混合了   要转换为文本的数据。为了这   为了可靠地工作,你可能也必须这样做   修改注册表设置,   TypeGuessRows = 8。 ISAM驱动程序   默认查看前八行   从那个抽样决定了   数据类型。如果这八行采样   全部是数字,然后设置IMEX = 1   不会转换默认数据类型   到文本;它将保持数字。

或者,考虑在电子表格中规范化您的数据,因为这是真正的问题

答案 2 :(得分:0)

首先,我同意@barrowc:潜在的问题是你的'数字列表'违反了第一范式(1NF)而SQL并不是为了查询非标量数据类型(即缺乏运算符来利用多值数据)数据)。

其次,您需要让ADO的连接字符串和注册表设置正确,以便将列“视为”文本。 This article可能有助于此。

如果必须使用非第一范式(NFNF)数据,则需要处理逗号分隔符。

这是一些带有测试数据的标准SQL,用于演示这一点:

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,%');

答案 3 :(得分:0)

Jet不使用%进行模式匹配。它使用*代替。它还将模式与数字匹配,就好像它们是字符串一样。因此,如果您将SQL字符串从"SELECT * FROM [2010 VIP$] WHERE F9 LIKE '%" & sDealer & "%'"更改为"SELECT * FROM [2010 VIP$] WHERE F9 LIKE '*" & sDealer & "*'",我怀疑您将能够返回到模式匹配方法。