Оператор SQL «LIKE» не находит ячейки, в которых существует только одно число - PullRequest
1 голос
/ 12 октября 2010

Я читаю с листа Excel XLS без строк заголовка.Некоторые ячейки в столбце имеют список чисел, таких как 12345, 12346, 12347, 12348. Другие ячейки имеют только одно число 12345.

Оператор «LIKE» находит число, когда в ячейке несколько чисел,но не находит ячейки, в которых существует только одно число.

SQL = "SELECT * FROM [2010 VIP $], ГДЕ F9 НРАВИТСЯ '%" & sDealer & "%'"

Iпопытался изменить строку подключения с: "Источник данных =" & dS & "; Расширенные свойства =" "Excel 8.0; HDR = Нет" ""

Кому (добавление IMEX для смешанных типов данных): "Источник данных= "& dS &"; Расширенные свойства = "" Excel 8.0; HDR = Нет; IMEX = 1 "" "

Но я получаю неизвестную ошибку при добавлении IMEX.Насколько я понимаю, вы не можете использовать имена полей F1, F2, F3 без HDR = No.

Я попытался использовать первую строку подключения, но изменил свой SQL на: SQL = "SELECT * FROM [2010 VIP $] ГДЕ F9 НРАВИТСЯ '% "& sDealer &"%' ИЛИ ​​F9 = '"& sDealer &"' "

Но он по-прежнему не находит ячейки только с одним номером.

РЕДАКТИРОВАТЬ: я закончил с использованием более медленного метода, но он работает и все еще проверяет 1200 строк в течение 2 секунд:

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 голосов
/ 25 ноября 2010

Jet не использует% для сопоставления с образцом. Вместо этого он использует *. Он также сопоставляет шаблоны с числами, как если бы они были строками. Поэтому я подозреваю, что вы сможете вернуться к подходу сопоставления с образцом, если вы изменили строку SQL с "SELECT * FROM [2010 VIP$] WHERE F9 LIKE '%" & sDealer & "%'" на "SELECT * FROM [2010 VIP$] WHERE F9 LIKE '*" & sDealer & "*'".

0 голосов
/ 12 октября 2010

Помимо установки параметра IMEX, сортируйте данные в рабочем листе, чтобы убедиться, что первые восемь строк содержат ячейки, которые будут интерпретироваться как текст - то есть с несколькими значениями, такими как 12345,12346,12347,12348

Цитата из этой статьи базы знаний :

ПРИМЕЧАНИЕ. Установка IMEX = 1 указывает драйверу использовать режим импорта.В этом состоянии будет замечен параметр реестра ImportMixedTypes = Text.Это заставляет смешанные данные быть преобразованы в текст.Чтобы это работало надежно, вам также может потребоваться изменить параметр реестра, TypeGuessRows = 8.Драйвер ISAM по умолчанию просматривает первые восемь строк и по этой выборке определяет тип данных.Если выборка из восьми строк полностью числовая, то установка IMEX = 1 не преобразует тип данных по умолчанию в текстовый;он останется числовым.

В качестве альтернативы рассмотрите возможность нормализации ваших данных в электронной таблице, поскольку это реальная проблема здесь

0 голосов
/ 12 октября 2010

Во-первых, я согласен с @barrowc: основная проблема заключается в том, что ваши «списки чисел» нарушают первую нормальную форму (1NF), а SQL не предназначен для запроса нескалярных типов данных (т. Е. Не хватает операторов для эксплуатации многозначных). данные).

Во-вторых, вам нужно правильно настроить строку подключения и параметры реестра, чтобы ADO «видел» столбец в виде текста. Эта статья может помочь с этим.

Если вам необходимо работать с данными не первой нормальной формы (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,%');
0 голосов
/ 12 октября 2010

Ячейки с одним номером являются числовыми и не могут быть найдены с помощью строкового оператора like. Вы можете попытаться сделать так, чтобы ячейки были текстовыми ячейками, добавив перед апострофом число (например, '12345).

Вы также можете попробовать

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

(без одинарных кавычек во второй части предложения where)

...