Подстановочный знак фильтра VBA «Окончание с» не работает - ошибка 3001 - PullRequest
3 голосов
/ 11 апреля 2019

Я читаю файл Excel в набор записей ADO, используя Microsoft.ACE.OLEDB.12.0.В соответствии с превосходной статьей SNB об ADO я использовал несколько фильтров, которые отлично работают, все, за исключением фильтра "Заканчивается с", для которого я получаю Error 3001: "Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another".Фильтр «Заканчивается на» по сути является фильтром с подстановочными знаками, как в SQL, и его синтаксис следующий:

"[FieldName] LIKE '*searchterm'".

Сказать, что я перепробовал все комбинации подстановочных знаков (*, %), но не повезло.В документации Microsoft о свойстве Recordset Filter говорится следующее об использовании оператора LIKE:

"В предложении LIKE можно использовать подстановочный знак в начале и конце шаблонаНапример, вы можете использовать LastName Like ' mit '. Или с LIKE вы можете использовать подстановочный знак только в конце шаблона. Например, LastName Like 'Smit *'.

Вышеуказанное кажется неясным, но я полагаю, что они говорят следующее:

Начало и конец: LastName Как ' mit ' является законным Начинается с: LastName Как 'Smit *' является законным

НО

Конец: LastName Как '* t' Является ли Illegall ???

Если это так, то я знаю, что конец с фильтром невозможен какможно интуитивно подумать, и я надеюсь, что кто-то сможет предложить альтернативное решение, которое будет имитировать фильтр подстановки «Заканчивается с».

Если нет, то я надеюсь, что кто-то может указать мне на то, что мне не хватает. Все предложения, идеи или ответыМы высоко ценим.

Ниже приведен мой код:

Option Explicit
Sub SheetToRecrdset()

 Dim strSourceFile As String
 Dim Conn As New ADODB.Connection
 Dim RcrdsetSheet As ADODB.Recordset

  strSourceFile = ThisWorkbook.FullName

    Set Conn = New ADODB.Connection
        With Conn
             .Provider = "Microsoft.ACE.OLEDB.12.0"
             .ConnectionString = "Data Source=" & strSourceFile & _
             ";Extended Properties='Excel 12.0;HDR=YES;IMEX=1'"
             .Open
        End With

    Set RcrdsetSheet = New ADODB.Recordset

     RcrdsetSheet.Open "SELECT * FROM [Data$] Where Not IsNull([Row_ID])", _
     Conn, adOpenKeyset, adLockOptimistic, adCmdText

        If RcrdsetSheet.EOF = True Or RcrdsetSheet.BOF = True Then
            MsgBox "For some reason the query did not return any data. Try closing" & _
            " and and opening the file again.", vbCritical, "Error: No Results Returned"
            Exit Sub
        End If

        'Example String to filter: "MRQ"

        'CONTAINS FILTER WORKS
        RcrdsetSheet.Filter = "[LOCATION] LIKE '*M*'"

        'BEGINS WITH FILTER WORKS
        RcrdsetSheet.Filter = "[LOCATION] LIKE 'M*'"


       'ENDS WITH FILTER DOESN'T WORK
       'RcrdsetSheet.Filter = "[LOCATION] LIKE '*Q'"     'Error 3001

       '@TinMan's Suggestions
       'RcrdsetSheet.Filter = "[LOCATION] LIKE '*Q''"    'Error 2147024809
       'RcrdsetSheet.Filter = "[LOCATION] LIKE '*Q'''"   'Error 3001
       RcrdsetSheet.Filter = "[LOCATION] LIKE ""*Q'"""   'Returns no Records

       Debug.Print RcrdsetSheet.RecordCount 'Returns 0

       Dim arrayOut As Variant

       arryOut = RcrdsetSheet.GetRows       'Error 3021


End Sub

Пример данных примера:

enter image description here

Также обратите внимание, чтотип данных поля: adVarWChar, DataTypeEnum = 202, который обозначает строку символов Юникода с нулевым символом в конце.

1 Ответ

3 голосов
/ 11 апреля 2019

Новый ответ

Мой оригинальный ответ содержит некоторую ценную информацию об использовании кавычек и синглов в запросах, но не касается вопроса ОП.

Хотя это не совсем понятно, этот отрывок из ADO »Набор записей» Фильтр объясняет это

Если вы используете оператор LIKE, вы также можете использовать подстановочные знаки * или% в качестве последнего символа в строке или в качестве первого и последнего символа встрока.

При использовании оператора LIKE со свойством фильтра записей ADODB, если фильтр начинается с подстановочного знака (* или%), то он должен заканчиваться подстановочным знаком (* или%).Подстановочные знаки в середине строки фильтра не работают.

То, что мы не можем использовать подстановочный знак с оператором LIKE, используя фильтр записей ADO, не заканчивая фильтр подстановочным знаком, не означает, что мы не можемзаставить его работать!

Давайте взломать систему!

  • Добавить вычисляемое поле в запрос, который возвращает последний символ
  • Использовать% для последнего символаADO Recordset Filter
  • Фильтруйте исходное поле, используя Like * somevalue% и вычисленное поле = последний символ

Тестовый код

Sub Test()
    TestFilter "(Location Like '*Q%') AND (LOCATIONLastChar = '''')"
End Sub

Sub TestFilter(Filter As String)
    Const BaseConnectionString = "Data Source=@FullName;Extended Properties='Excel 12.0;HDR=YES;IMEX=1'"
    Dim Conn As New ADODB.Connection, rs As New ADODB.Recordset
    Dim SQL As String

    Set Conn = New ADODB.Connection
    With Conn
        .Provider = "Microsoft.ACE.OLEDB.12.0"
        .ConnectionString = Replace(BaseConnectionString, "@FullName", ThisWorkbook.FullName)
        .Open
    End With

    SQL = "SELECT *, Right(LOCATION,1) AS LOCATIONLastChar FROM [Data$] Where Not IsNull(Row_ID)"

    rs.Open SQL, Conn, adOpenKeyset, adLockOptimistic, adCmdText

    rs.Filter = Filter


    If Not rs.BOF Then
        Worksheets.Add
        Range("A1").CopyFromRecordset rs
    End If
    rs.Close
    Conn.Close
End Sub

Исходное сообщение

Когда у меня возникают проблемы при написании запроса, я использую Access Query Designer, чтобы помочь мне написать его.

SELECT Table1.Field1
FROM Table1
WHERE (((Table1.Field1) Like "a'*"));

Обратите внимание, что дизайнер использует кавычки вокруг строки фильтра.SQL может использовать двойные или одинарные кавычки для строк.

Если вы используете двойные кавычки для строковых значений, любые кавычки в двойных кавычках должны быть удвоены.

Вот пример:

rs.Open "SELECT Table1.Field1 FROM Table1 WHERE (((Table1.Field1) Like ""a'*""));"

Это, однако, боль в шее, чтобы получить право.Поэтому я пишу несколько вспомогательных функций, которые удваивают для меня кавычки или одинарные кавычки.

Function getClipBoardText()
    With CreateObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
        .getFromClipBoard
        getClipBoardText = .getText
    End With
End Function

Sub PrintText()
    Dim s As String
    s = getClipBoardText
    Debug.Print Replace(s, Chr(34), String(2, 34))
End Sub

Теперь все, что мне нужно сделать, - это скопировать SQL конструктора и запустить PrintText

* 1046.*enter image description here

Чтобы сделать очень длинную историю короткой, просто удвойте одинарную кавычку, заключенную в одинарные кавычки!

RcrdsetSheet.Filter = "[LOCATION] LIKE '*Q'''"

Вот как бы вы это сделалииспользуйте одинарные кавычки внутри двойных кавычек

RcrdsetSheet.Filter = "[LOCATION] LIKE ""*Q'"""
...