Sql vba запрос: SQL запрос из Excel VBA

SQL запрос из Excel VBA

ВВЕРХ

SQL расшифровывается как Structured Query Language (структурированный язык запросов) и является языком, который используется для получения информации из баз данных (таких как Access , SQL Server from Microsoft , Oracle , Sybase , SAP и других). Вы также можете получать данные из интернета, текстовых файлов или других Excel или CSV файлов.

Итак, нам нужно соединение с базой данных (переменная varConn в макросе ниже) и SQL запрос (переменная varSQL ), чтобы автоматизировать получение данных из базы для отчета. В примере ниже есть SQL запрос , который получает данные с малой базы данных в Access.

Нажмите скачать базу данных Access . Для корректного соединения база данных должна быть в папке «Мои документы«. Файл Access будет выглядеть:

Давайте напишем свой макрос, который будет осуществлять SQL запрос .

Меню Сервис — Макрос — Редактор Visual Basic , вставьте новый модуль (меню Insert — Module ) и скопируйте туда текст макроса:

Sub SQLQuery_1()
Dim varConn As String
Dim varSQL As String
    Range("A1").CurrentRegion.ClearContents
    varConn = "ODBC;DBQ=test.mdb;Driver={Driver do Microsoft Access (*.mdb)}"
    varSQL = "SELECT Month, Product, City FROM Sumproduct"
         With ActiveSheet.QueryTables.Add(Connection:=varConn, Destination:=Range("A1"))
             .CommandText = varSQL
             .Name = "Query-39008"
             .Refresh BackgroundQuery:=False
         End With
End Sub 

Нажимаем сохранить и возвращаемся к Excel . Выбираем в меню Вид — Макросы (Alt + F8) название нашего макроса « SQLQuery_1 «.

Теперь видим, что наш макрос-запрос подтянул колонки Month , Product и City из таблицы Sumproduct из базы данных test.mdb в файл Excel.

Аналогично мы можем получать данные из обычного файла Excel, как из базы данных. Для этого код нашего макроса нужно немного переписать и изменить драйвер подключения с Access на Excel.

Экспортируем таблицу Sumproduct из Access в Excel и сохраняем файл. Далее, вставляем наш измененный код в новый модуль и запускаем макрос:

Sub SQLQuery_1()
Dim varConn As String
Dim varSQL As String
     Range("A1").CurrentRegion.ClearContents
     varConn = "ODBC;Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)}"
     varSQL = "SELECT Month, Product, City FROM Sumproduct"
          With ActiveSheet. QueryTables.Add(Connection:=varConn, Destination:=Range("A1"))
              .CommandText = varSQL
              .Refresh BackgroundQuery:=False
          End With
End Sub

Появится окно, в котором мы можем выбрать наш файл Excel (должно называться Sumproduct.xlsx или другим расширением).
Находим и выбираем его. Жмем ОК, и получаем те же данные, что и из файла Access.

Статьи по теме:

Импорт данных с Access в Excel

Используйте функции Excel и VBA в MDX-запросах

Самородов Федор Анатольевич: Используйте функции Excel и VBA в MDX-запросах

А вы знаете, что из MDX-запроса можно вызывать экселевские (и ВБА) функции? Да, это то самое чувство, когда вы легко можете добиться желаемого результата в Экселе, а вот в MDX…

Попробуйте обратиться к внешним функциям через префикс Excel! или VBA!. Вот так:

Студия подчёркивает вызов функции Format красным — это ошибка? Ведь такой функции нет в языке MDX! Верно, нет. Но зато она есть в VBA.

Обращаться к функциям VBA можно либо через приставку «VBA!», либо через «VBAMDX.», а можно и вообще без префикса:

А ещё вы можете аналогичным образом задействовать функции Excel. Вот так:

Однако, прежде чем использовать такой «ход конём», примите во внимание три вещи.

Во-первых, вам доступны не все функции, а только те, использование которых в контексте MDX-запроса не противоречит здравому смыслу. Из всего богатства ВБА можете использовать вот эти девяносто функций:


  • Abs
  • Asc
  • AscW
  • Atn
  • CBool
  • CByte
  • CCur
  • CDate
  • CDbl
  • CDec
  • Choose
  • Chr
  • CInt
  • CLng
  • Cos

  • CSng
  • CStr
  • CVar
  • Date
  • DateAdd
  • DateDiff
  • DatePart
  • DateSerial
  • DateValue
  • Day
  • DDB
  • Exp
  • Fix
  • Format
  • FV

  • Hex
  • Hour
  • Iif
  • InStr
  • Int
  • IPmt
  • IRR
  • IsArray
  • IsDate
  • IsEmpty
  • IsError
  • IsMissing
  • IsNull
  • IsNumeric
  • LCase

  • Left
  • Len
  • Log
  • LTrim
  • Mid
  • Minute
  • MIRR
  • Month
  • Now
  • NPer
  • NPV
  • Oct
  • Partition
  • Pmt
  • PPmt

  • PV
  • QBColor
  • Rate
  • RGB
  • Right
  • Rnd
  • Round
  • RTrim
  • Second
  • Sgn
  • Sin
  • SLN
  • Space
  • Sqr
  • Str

  • StrComp
  • StrConv
  • String
  • Switch
  • SYD
  • Tan
  • Timer
  • TimeSerial
  • TimeValue
  • Trim
  • TypeName
  • UCase
  • Val
  • Weekday
  • Year

Во-вторых, учтите, что если вам понадобятся функции из Экселя, то вам придётся установить сам эксель на машину с аналитическим сервером (следите за совпадением битности). И, кстати, экселевские функции также доступны далеко не все.

И в-третьих, не ждите от этого механизма высокой производительности. Если требуется высокомасштабируемое решение, то применять функции VBA и Excel следует с осторожностью.

Подробнее об этом вы сможете узнать на курсе: М50578A: Язык запросов MDX для аналитических служб SQL Server (OLAP)

sql server — Использование Excel VBA для запуска SQL-запроса

Задавать вопрос

спросил

Изменено
3 года, 4 месяца назад

Просмотрено
291 тысяч раз

Я новичок в SQL и VBA. Я написал SQL-запрос, который я хотел бы вызывать и запускать из подпрограммы VBA в книге Excel, а затем переносить результаты запроса в книгу. Я нашел некоторые подпрограммы в Интернете (stackoverflow и другие места), которые утверждают, что делают это, но у меня возникли проблемы с их пониманием, поскольку они не содержат объяснений. Например, вот саб, который я нашел в Интернете:

 Sub ConnectSqlServer()
    Dim conn As ADODB.Connection
    Dim rs As ADODB.Recordset
    Dim sConnString как строка
    ' Создайте строку подключения.
    sConnString = "Provider=SQLOLEDB;Источник данных=INSTANCE\SQLEXPRESS;" & _
                  "Исходный каталог=MyDatabaseName;" & _
                  "Интегрированная безопасность=SSPI;"
    ' Создайте объекты Connection и Recordset.
    Установить conn = новый ADODB.Connection
    Установить rs = новый ADODB.Recordset
    'Открываем соединение и выполняем.
    conn.Open sConnString
    Установите rs = conn.Execute("SELECT * FROM Table1;")
    'Проверьте, у нас есть данные.
    Если Не rs.EOF Тогда
        ' Результат передачи.
        Листы(1).Range("A1").CopyFromRecordset rs
    ' Закрыть набор записей
        rs. Закрыть
    Еще
        MsgBox «Ошибка: записи не возвращены.», vbCritical
    Конец, если
    ' Очистить
    Если CBool(conn.State и adStateOpen), то conn.Close
    Установить соединение = Ничего
    Установить rs = Ничего
Конец сабвуфера
 

Прежде всего, это сработает? Во-вторых, что мне нужно заменить в подразделе (это выглядит как поставщик, источник данных, исходный каталог и т. д.) и где я могу найти информацию, чтобы заменить их?

Я надеюсь, что этот вопрос не слишком запутан, и я ценю вашу помощь!

  • sql
  • sql-сервер
  • vba
  • excel

10

Ниже приведен код, который я сейчас использую для извлечения данных из MS SQL Server 2008 в VBA. Вы должны убедиться, что у вас есть правильная ссылка на ADODB [ VBA Editor->Tools->References ] и убедитесь, что у вас отмечена Microsoft ActiveX Data Objects 2.8 Library , которая является второй снизу отмеченной строкой (я использую Excel 2010 в Windows 7; вы можете имеют немного другую версию ActiveX, но она все равно будет начинаться с Microsoft ActiveX):

Подмодуль для подключения к MS SQL с удаленным хостом и именем пользователя/паролем

 Sub Download_Standard_BOM()
'Инициализирует переменные
Dim cnn As New ADODB. Connection
Dim сначала как новый ADODB.Recordset
Dim ConnectionString как строка
Dim StrQuery как строка
'Настройте строку подключения для доступа к базе данных MS SQL
   'Обязательно измените:
       '1: ПАРОЛЬ
       '2: ИМЯ ПОЛЬЗОВАТЕЛЯ
       '3: УДАЛЕННЫЙ_IP_АДРЕС
       '4: БАЗА ДАННЫХ
    ConnectionString = "Provider=SQLOLEDB.1;Password=PASSWORD;Persist Security Info=True;ID пользователя=USERNAME;Источник данных=REMOTE_IP_ADDRESS;Использовать процедуру для подготовки=1;Автоматический перевод=True;Размер пакета=4096;Использовать шифрование для данных=False;Тегировать с сопоставлением столбцов, когда это возможно=False;Исходный каталог=BASE DATABASE"
    'Открывает соединение с базой данных
    cnn.Open ConnectionString
    'Ошибка тайм-аута в секундах для выполнения всего запроса; это будет работать за 15 минут до тайм-аута VBA, но ваша база данных может истечь до истечения этого значения
    cnn.CommandTimeout = 900
    'Это ваш фактический запрос MS SQL, который вам нужно выполнить; вы должны сначала проверить этот запрос, используя более надежный редактор SQL (например, HeidiSQL), чтобы убедиться, что ваш запрос действителен. 
    StrQuery = "ВЫБЕРИТЕ ТОП-10 * ИЗ tbl_table"
    'Выполняет фактический запрос
    rst.Open StrQuery, cnn
    'Выводит все результаты StrQuery в ячейку A2 первого листа активной книги.
    Листы(1).Range("A2").CopyFromRecordset сначала
Конец сабвуфера
 

5

Зарегистрируйтесь или войдите в систему

Зарегистрируйтесь с помощью Google

Зарегистрироваться через Facebook

Зарегистрируйтесь, используя электронную почту и пароль

Опубликовать как гость

Электронная почта

Требуется, но никогда не отображается

Опубликовать как гость

Электронная почта

Требуется, но не отображается

Нажимая «Опубликовать свой ответ», вы соглашаетесь с нашими условиями обслуживания и подтверждаете, что прочитали и поняли нашу политику конфиденциальности и кодекс поведения.

Как встроить длинные и сложные sql-запросы в код Excel VBA?

спросил

Изменено
9 месяцев назад

Просмотрено
16 тысяч раз

У меня есть приведенный ниже код VBA, который успешно работает при получении данных из базы данных SQL на лист Excel, когда мне нужно встроить простой запрос (например, Выберите * из таблицы1 ), но этот код не работает и показывает

Ошибка компиляции: определяемый пользователем тип не определен.

при сложных и длинных запросах:

 Sub ConnectSqlServer()
        Dim conn As ADODB.Connection
        Dim rs As ADODB.Recordset
        Dim sConnString как строка
        ' Создайте строку подключения. 
        sConnString = "Поставщик = SQLOLEDB; Источник данных = vrsqladhoc;" & _
                      "Исходный каталог=TACT_REV;" & _
                      "Интегрированная безопасность=SSPI;"
        ' Создайте объекты Connection и Recordset.
        Установить conn = новый ADODB.Connection
        Установить rs = новый ADODB.Recordset
        'Открываем соединение и выполняем.
        conn.Open sConnString
        Установить rs = conn.Execute("выбрать отдельный столбец1 из таблицы1;")
        'Проверьте, у нас есть данные.
        Если Не rs.EOF Тогда
            ' Результат передачи.
            Листы(2).Range("A2").CopyFromRecordset rs
        ' Закрыть набор записей
            rs.Закрыть
        Еще
            MsgBox «Ошибка: записи не возвращены.», vbCritical
        Конец, если
        Конец сабвуфера
 

Длинный запрос, который я собираюсь встроить в код VBA, выглядит примерно так:

 SELECT Count(column1) as status_count, случай, когда
    missing_flag = 1, затем 'Отсутствует', иначе 'Доступно' заканчивается как статус, 'Имя' как Document_Type
    СО стола1 см
    внутреннее соединение table2 md на md. column1 = cm.column2
    ГДЕ cm.column3 = 'R'
    и см.столбец4 = 3
    группировать по случаям, когда
    missing_flag1 = 1, затем «Отсутствует», иначе «Доступно» конец
    Союз Все
      SELECT Count(column1) как status_count, случай, когда
    missing_flag = 1, затем 'Отсутствует', иначе 'Доступно' заканчивается как статус, 'Имя' как Document_Type
    СО стола2 см
    внутреннее соединение table2 md на md.column1 = cm.column2
    ГДЕ cm.column3 = 'R'
    и см.столбец4 = 3
    группировать по случаям, когда
    missing_flag1 = 1, затем «Отсутствует», иначе «Доступно» конец
Союз Все
      SELECT Count(column1) как status_count, случай, когда
    missing_flag = 1, затем 'Отсутствует', иначе 'Доступно' заканчивается как статус, 'Имя' как Document_Type
    СО стола3 см
    внутреннее соединение table2 md на md.column1 = cm.column2
    ГДЕ cm.column3 = 'R'
    и см.столбец4 = 3
    группировать по случаям, когда
    missing_flag1 = 1, затем «Отсутствует», иначе «Доступно» конец
Союз Все
      SELECT Count(column1) как status_count, случай, когда
    missing_flag = 1, затем 'Отсутствует', иначе 'Доступно' заканчивается как статус, 'Имя' как Document_Type
    СО стола4 см
    внутреннее соединение table2 md на md. column1 = cm.column2
    ГДЕ cm.column3 = 'R'
    и см.столбец4 = 3
    группировать по случаям, когда
    missing_flag1 = 1, затем «Отсутствует», иначе «Доступно» конец
Союз Все
      SELECT Count(column1) как status_count, случай, когда
    missing_flag = 1, затем 'Отсутствует', иначе 'Доступно' заканчивается как статус, 'Имя' как Document_Type
    СО стола5 см
    внутреннее соединение table2 md на md.column1 = cm.column2
    ГДЕ cm.column3 = 'R'
    и см.столбец4 = 3
    группировать по случаям, когда
    missing_flag1 = 1, затем «Отсутствует», иначе «Доступно» конец
Союз Все
      SELECT Count(column1) как status_count, случай, когда
    missing_flag = 1, затем 'Отсутствует', иначе 'Доступно' заканчивается как статус, 'Имя' как Document_Type
    СО стола6 см
    внутреннее соединение table2 md на md.column1 = cm.column2
    ГДЕ cm.column3 = 'R'
    и см.столбец4 = 3
    группировать по случаям, когда
    missing_flag1 = 1, затем «Отсутствует», иначе «Доступно» конец
Союз Все
      SELECT Count(column1) как status_count, случай, когда
    missing_flag = 1, затем 'Отсутствует', иначе 'Доступно' заканчивается как статус, 'Имя' как Document_Type
    ОТ стола7 см
    внутреннее соединение table2 md на md. column1 = cm.column2
    ГДЕ cm.column3 = 'R'
    и см.столбец4 = 3
    группировать по случаям, когда
    missing_flag1 = 1, затем «Отсутствует», иначе «Доступно» конец
Союз Все
      SELECT Count(column1) как status_count, случай, когда
    missing_flag = 1, затем 'Отсутствует', иначе 'Доступно' заканчивается как статус, 'Имя' как Document_Type
    ОТ стола8 см
    внутреннее соединение table2 md на md.column1 = cm.column2
    ГДЕ cm.column3 = 'R'
    и см.столбец4 = 3
    группировать по случаям, когда
    missing_flag1 = 1, затем «Отсутствует», иначе «Доступно» конец
 

Подскажите, пожалуйста, как можно без ошибок внедрить длинные SQL-запросы в код VBA.

  • Excel
  • ВБА

11

Как именно вы строите строку подключения:

 sConnString = "Provider=SQLOLEDB;Источник данных=vrsqladhoc;" & _
                  "Исходный каталог=TACT_REV;" & _
                  "Интегрированная безопасность=SSPI;"
 

Путем объединения строковых литералов.

Одна из проблем, с которой вы столкнетесь при таком длинном запросе, заключается в том, что VBA не позволит вам создать логических строк кода, которые охватывают гораздо больше, чем 10-15 физических строк кода. Видите ли, приведенный выше оператор представляет собой одну единственную логическую строку кода, но он охватывает 3 физических строк, которые включают 2 токенов продолжения строки .

Итак, вы просто делаете это:

 Dim sql As String
sql = "SELECT Count (column1) как status_count, случай, когда " & _
      "..." и _
      "..." и _
      "..." и _
      "и так далее"
 

И когда компилятор начинает жаловаться, что слишком много продолжений строки, вы просто конкатенируете его с собой:

 sql = sql & "остальные" & _
      " ...запрос"
 

Очевидно, это станет очень уродливым, очень быстро. Исправление ошибки в этом запросе будет кошмаром. Поддержание этого запроса будет кошмаром. Просто , глядя на в этом запросе, вызовет у вас кошмары.

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

Если нет абсолютно никакого способа избежать этого, то я настоятельно рекомендую вам использовать StringBuilder для объединения строк. Результат, по крайней мере, будет намного чище, чем беспорядок чередующихся конкатенаций, продолжающихся строкой, и будет работать лучше.

 Dim sql как строка
С новым StringBuilder
    .Добавить "ВЫБРАТЬ..."
    .Добавить "..."
    .Добавить "..."
    .Добавить "..."
    .Добавить "..."
    .Добавить "..."
    SQL = .ToString
Конец с
 

Примечание: что бы вы ни делали, никогда не объединяйте пользовательский ввод в SQL-запрос. Вместо этого параметризируйте его.

0

Чтобы преобразовать SQL в VBA, сделайте следующее:

 Dim sql As String
sql = "SELECT Count (column1) как status_count, случай, когда " & _
        «missing_flag = 1, затем «Отсутствует», иначе «Доступно» заканчивается как статус, «Имя» как Document_Type» и _
        "ИЗ таблицы1 см" &_
        "внутреннее соединение table2 md на md.column1 = cm.column2" & _
        "ГДЕ cm.column3 = 'R'" & _
        "и cm.column4 = 3" & _
        "группировать по регистру, когда" & _
        "missing_flag1 = 1, затем "Отсутствует", иначе "Доступно" конец "
sql = sql & "ОБЪЕДИНИТЬ ВСЕ"
sql = sql & "продолжайте в том же духе..."
 

Вы можете сделать это в одном операторе, если это короткий SQL и легко читаемый, но с длинными операторами вы столкнетесь с проблемами строки продолжения ( _ ) в VBA. Именно поэтому я разбил его на несколько настроек sql .

Это грубая сила, а не идеальное решение, кошмар для отладки и обслуживания!

Лучше всего хранить в БД непосредственно как хранимую процедуру и вызывать ее в excel vba.

1

Обычно я пишу SQL-запросы для встраивания в Excel/VBA в Notepad++, а затем сохраняю их в виде простого (текстового) файла .sql. У меня есть скрипт, который с помощью .fso(FileSystemObject) считывает содержимое файла и использует его для формирования запроса (все соединения с моими БД стандартные).

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

 strSQL = ThisWorkbook.Sheets("SQL_Query").TextBoxes( "SQL_Text").Текст
 

Преимущество этого в том, что все отступы из Notepad++ остаются на месте.

На последнем этапе необходимо убедиться, что для свойства Visible рабочего листа задано значение .xlSheetVeryHidden и, конечно же, код защищен паролем.

1

Это должно быть довольно просто. Просто следите за переносом слов!

 Sub ADOExcelSQLServer()
    Dim Cn As ADODB.Connection
    Dim Server_Name как строка
    Dim Database_Name как строка
    Dim User_ID как строку
    Dim Пароль как строка
    Dim SQLStr как строка
    Dim rs As ADODB. Recordset
    Установить rs = новый ADODB.Recordset
    Server_Name = "Your_Server_Name" ' Введите здесь имя вашего сервера
    Database_Name = "Northwnd" ' Введите здесь имя вашей базы данных
    User_ID = "" ' введите здесь свой ID пользователя
    Пароль = "" 'Введите свой пароль здесь
    SQLStr = "ВЫБЕРИТЕ Поле1, Поле2, Поле3, Поле4"
    SQLStr = SQLStr & " FROM Orders Where Order ID = 100 " ' Введите здесь свой SQL
    Установите Cn = Новый ADODB.Connection
    Cn.Open "Driver={SQL Server};Server=" & Server_Name & ";Database=" & Database_Name & _
    ";Uid=" & User_ID & ";Pwd=" & Password & ";"
    rs.Open SQLStr, Cn, adOpenStatic
    С рабочими листами («Лист1»). Диапазон («A1: Z500»)
        .ClearContents
        .CopyFromRecordset rs
    Конец с
    rs.Закрыть
    Установить rs = Ничего
    Сп.Закрыть
    Установите Cn = Ничего
Конец сабвуфера
Вспомогательная рабочая2 ()
Dim con As Connection
Dim сначала как набор записей
Dim strConn как строка
Установить con = новое соединение
strConn = "EXCEL-PC\SQLEXPRESS;база данных=Борей;Trusted_Connection=True"
con. Open strConn
'Поместите название страны в ячейку E1
Установите rst = con.Execute("Exec dbo.MyOrders '" & ActiveSheet.Range("E1").Text & "'" & ActiveSheet.Range("E2").Text & "'")
'Общее количество записей возвращается в ячейку A5
ActiveSheet.Range("A5").CopyFromRecordset сначала
рст.Закрыть
кон.Закрыть
Конец сабвуфера
 

Оставляйте пробел перед и после каждой двойной кавычки.

Итак, для вас, я думаю, это должно быть примерно так…

 SQLStr = " SELECT Count(column1) as status_count, случай, когда
    missing_flag = 1, затем 'Отсутствует', иначе 'Доступно' заканчивается как статус, 'Имя' как Document_Type
    СО стола1 см
    внутреннее соединение table2 md на md.column1 = cm.column2
    ГДЕ cm.column3 = 'R'
    и см.столбец4 = 3
    группировать по случаям, когда
    missing_flag1 = 1, затем 'Отсутствует', иначе 'Доступно' end "
SQLStr = SQLStr & "Объединить все
    SELECT Count(column1) как status_count, случай, когда
    missing_flag = 1, затем 'Отсутствует', иначе 'Доступно' заканчивается как статус, 'Имя' как Document_Type
    СО стола2 см
    внутреннее соединение table2 md на md. column1 = cm.column2
    ГДЕ cm.column3 = 'R'
    и см.столбец4 = 3
    группировать по случаям, когда
    missing_flag1 = 1, затем 'Отсутствует', иначе 'Доступно' end "
SQLStr = SQLStr & "Объединить все
    SELECT Count(column1) как status_count, случай, когда
    missing_flag = 1, затем 'Отсутствует', иначе 'Доступно' заканчивается как статус, 'Имя' как Document_Type
    СО стола3 см
    внутреннее соединение table2 md на md.column1 = cm.column2
    ГДЕ cm.column3 = 'R'
    и см.столбец4 = 3
    группировать по случаям, когда
    missing_flag1 = 1, затем 'Отсутствует', иначе 'Доступно' end "
 

Я наткнулся на эту тему, но решил добавить решение, которое нашел удобным.

Решение, которое я нашел полезным для этого, заключается в сохранении запросов на рабочем листе и последующем обращении к значениям (например, sQuery = Sheets("Queries").Range("A1").Value ). В завершенных проектах электронная таблица, содержащая сохраненные запросы, скрыта от обычного просмотра.

Используя стандартный текстовый редактор, вы можете написать запрос, а затем вырезать и вставить его в ячейку, и он будет отображаться так же, как в текстовом редакторе. Это облегчает чтение, не загромождает ваш код и позволяет легко изменить/обновить позже, если это необходимо.

Вот пример, который я вырезал и вставил из одного из моих рабочих листов в этот редактор:

 ВЫБРАТЬ
       инвойс_идентификатор,
       temp.invoice_number,
       temp.open_date,
       temp.close_date,
       Код товара,
       описание,
       линия_итого,
       облагаемый налогом
   ОТ
       позиции
           ВНУТРЕННЕЕ СОЕДИНЕНИЕ
       (ВЫБИРАТЬ
           invoice_id, invoice_number, open_date, close_date
       ОТ
           счета-фактуры
       ГДЕ
           close_date МЕЖДУ [дата_начала] И [дата_окончания]) AS temp USING (invoice_id)
   ГДЕ
     taxable=1 ИЛИ product_id LIKE '%TAX%';
 

В приведенном выше примере я использую функцию replace() для замены параметров [start_date] и [end_date] правильными значениями до выполнения запроса.

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

Использование некоторых творческих функций ( GetStoredQuery() , PutStoredQuery() , ExecuteStoredQuery() и т. д.) это очень похоже на использование хранимых процедур в SQL, за исключением того, что ваши хранимые процедуры хранятся в вашем проекте VB, а не на сервере SQL.

Мое решение состоит в том, чтобы обернуть длинный код sql в процедуру на части сервера sql. Следовательно, вам не нужно писать длинный код sql в vba. Процедура может иметь параметры, поэтому вам не нужно ничего менять в коде sql. Просто вызовите процедуру из vba с помощью sqlcommand и все.

3

Я бился головой о стену с той же проблемой. Самый простой способ решить эту проблему — сохранить сложный код как хранимую процедуру в самой базе данных.