Выполнить список SQL-запросов, используя условия из диапазона значений ячеек - PullRequest
0 голосов
/ 26 января 2019

Я пытаюсь запустить список SQL-запросов, где существует условие для «кода», а значения располагаются в диапазоне ячеек на другом листе (от ячеек A2 до A385).

У меня естьоднако в приведенном ниже коде я получаю недопустимое имя объекта для SQLQueries! $ A2: A385

Итак, я понимаю, что синтаксис неправильный, но я изо всех сил пытаюсь найти правильный, несмотря на чтение многочисленных статей.

Sub RunSQLQueries()

'Select SQLQueries sheet
    Sheets("SQLQueries").Activate

'Initializes variables
    Dim cnn As New ADODB.Connection
    Dim rst As New ADODB.Recordset
    Dim ConnectionString As String
    Dim StrQuery As String

'Setup the connection string for accessing MS SQL database
    ConnectionString = "Provider=SQLOLEDB; Data Source=HOSTNAME; Initial Catalog=DBNAME; UID=domain\user; Integrated Security=SSPI"

'Opens connection to the database
    cnn.Open ConnectionString

'Timeout
    cnn.CommandTimeout = 900

'Build SQK queries
    StrQuery = "SELECT * FROM table WHERE code IN (SELECT * FROM [SQLQueries!$A2:A385])"

'Performs the queries
    rst.Open StrQuery, cnn

'Select Results sheet
    Sheets("Results").Activate

'Dumps all the results from the StrQuery into cell A2 of the active sheet
    Range("A2").CopyFromRecordset rst

End Sub

Результат, который я ожидаю, состоит в том, что SQL-запрос будет выполняться с использованием каждого условия из диапазона значений, а результаты заполняются на листе «Результаты» из ячеек A2 вниз

Ответы [ 2 ]

0 голосов
/ 27 января 2019

Вот предложение:

StrQuery = "SELECT * FROM table WHERE code IN (" & _
             InList(Sheets("SQLQueries").Range("A2:A385"),True) & ")"

Функция для создания списка SQL "in" в заданном диапазоне:

Function InList(rng As Range, quoted As Boolean)
    Dim qt, a, r As Long, c As Long, rv As String, v, sep As String
    a = rng.Value
    qt = IIf(quoted, "'", "")
    For r = 1 To UBound(a, 1)
    For c = 1 To UBound(a, 2)
        v = Trim(a(r, c))
        If Len(v) > 0 Then
            rv = rv & sep & qt & v & qt
            sep = ","
        End If
    Next c
    Next r
    InList = rv
End Function

Примечания:

  • PassFalse в качестве второго аргумента, если у вас есть числовые значения
  • Я бы не использовал это для очень больших списков
  • Убедитесь, что вы не подвержены риску возможных проблем с внедрением SQL: параметризованныйзапросы всегда предпочтительнее, но не работают со списками «in»
0 голосов
/ 26 января 2019

Строка запроса буквально отправляется на сервер базы данных, и поскольку ваш sql пытается обратиться к списку Excel, к которому сервер не может получить доступ, он возвращает ошибку. Сервер ищет таблицу с именем [SQLQueries! $ A2: A385]

Чтобы придерживаться текущего плана, вам нужно будет передать предложение IN () буквально или с помощью переменной vba, отформатированной так: IN ('item1', 'item2' ...)

Примечание: Вы можете удалить одинарные кавычки, если элементы являются числовыми

Я советую переосмыслить план либо 1) если возможно настроить вещи на стороне базы данных: можете ли вы создать новую справочную таблицу, чтобы присоединиться к фактической таблице или создать представление, которое возвращает только нужные строки? Тогда вам понадобится задание, которое настраивает представление / таблицу фильтрации перед выполнением запроса. Идея в том, что вам не нужно корректировать запрос каждый раз, когда bc постоянная строка sql будет возвращать нужные вам строки Или же 2) если исходная таблица имеет, скажем, 100 тыс. Строк или меньше, а данные не слишком широки, просто выделите все строки в Excel на новом листе, затем отфильтруйте этот лист (добавьте новый столбец в Excel, который возвращает true, используя vlookup против вашего справочный лист) или используйте vlookup на справочном листе, чтобы вытянуть нужные столбцы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...