Excel sql запрос к листу vba: Excel VBA. SQL-запросы в подключениях — Эффективная работа в MS Office

Excel VBA. SQL-запросы в подключениях — Эффективная работа в MS Office

UPDATE 21.10.15 Добавил «обратный» макрос — VBA в SQL и макрос для доступа к строке запроса SQL

Некоторое время назад я прошел несколько курсов по SQL. И мне было очень интересно — какую часть из мощного инструмента под названием T-SQL можно применять без использования SQL-Server (не дают мне сервачек под мои нужды, хнык-хнык).

Итак… Начнем с простого — подключение через Query Table в VBA. Можно записать через макрорекордер — для этого нужно создать подключение через Microsoft Query.

Выбираем Excel Files, указываем путь к файлу (пытаясь при этом не ругать разработчиков за интерфейс из 90х годов), фильтруем как-угодно поля. Нам сейчас это не важно — главное получить код, который дальше можно будет корректировать.

Должно получится что-то вроде этого:


Sub Макрос1()
    With ActiveSheet.ListObjects.Add(SourceType:=0, Source:=Array(Array( _
        "ODBC;DSN=Excel Files;DBQ=D:\Dropbox\Excel\тест excel_SQL-2015. xlsx;DefaultDir=D:\Dropbox\Excel;DriverId=1046;MaxBufferSize=2048;Page" _
        ), Array("Timeout=5;")), Destination:=Range("$A$1")).QueryTable
        .CommandType = 0
        .CommandText = Array( _
        "SELECT Продажи.F2, Продажи.F3" & Chr(13) & "FROM `D:\Dropbox\Excel\тест excel_SQL-2015.xlsx`.Продажи Продажи" _
        )
        .RowNumbers = False
        .FillAdjacentFormulas = False
        .PreserveFormatting = True
        .RefreshOnFileOpen = False
        .BackgroundQuery = True
        .RefreshStyle = xlInsertDeleteCells
        .SavePassword = False
        .SaveData = True
        .AdjustColumnWidth = True
        .RefreshPeriod = 0
        .PreserveColumnInfo = True
        .ListObject.DisplayName = "Таблица_Запрос_из_Excel_Files"
        .Refresh BackgroundQuery:=False
    End With
End Sub

Строчка .CommandText = «SELECT…» — отвечает за SQL запрос. Если хотя бы немного почитать поисковую выдачу google по запросу QueryTable можно упростить код до следующего:


Sub CopyFromRecordset_To_Range()
  
  DBPath = "C:\InputData.xlsx"
  sconnect = "Provider=MSDASQL.1;DSN=Excel Files;DBQ=" & DBPath & ";HDR=Yes';"
  Conn.Open sconnect
  sSQLSting = "SELECT * FROM [Sheet1$]"

  rs.Open sSQLSting, Conn
  Set QT1 = ActiveSheet.QueryTables.Add(rs, Range("A1"))
  QT1.Refresh

  rs.Close
  Conn.Close

End Sub

Теперь начинаем копаться глубже — какого уровня запросы можно строить из VBA. Самые-самые базовые, основные конструкции — все работает, все ок.

Заполнение нового столбца одинаковым значением


SELECT  'YTikhonov', * 
FROM    [Sheet1$]

Переименование столбцов


SELECT  [Advertiser] AS 'Рекламодатель', [Quantity] AS 'Количество'
FROM    [Sheet1$]

Фильтрация записей


SELECT  * 
FROM    [Sheet1$]
WHERE   [Year] = 2014

Сортировка


SELECT   * 
FROM     [Sheet1$]
ORDER BY [Advertiser] DESC

Агрегация записей


SELECT   [Advertiser], Sum([Cost]) 
FROM     [Sheet1$]
GROUP BY [Advertiser]

Работа с датой

Дату можно впрямую через конструкцию


[SomeDateField] = {ts '2015-01-01 00:00:00'}

Но я люблю отталкиваться от текущей даты. За пару текущая дата-время отвечает функция SYSDATETIME() и она может вернуть в том числе текущий день. Для этого нужна еще одна функция  — CONVERT(type,value)


SELECT CONVERT(date,SYSDATETIME())

С функцией DATEFROMPARTS строка запроса в Excel почему-то не дружит, поэтому придется использовать костыли функцию DATEADD:


DATEADD(minute, 59, DATEADD(hour, 23, DATEADD(month, MONTH(SYSDATETIME())+1, DATEADD(year, YEAR(SYSDATETIME()) - 1900, 0))))-1

Эта строчка в любой день октября 2015 вернет значение — 30.11.15 23:59

А теперь — немного best practice!

Объединение + Агрегация + Join + Подзапросы. И самое интересное — подключение к нескольким источникам:


SELECT [Year], O.Numbers, SCost, SVolume, SQuantity FROM
 (
  SELECT [Year], Month, SUM([Cost RUB]) AS SCost, SUM(Volume) AS SVolume, SUM(Quantity) AS SQuantity FROM
   (
     SELECT Advertiser, 2013 as [Year], Month, [Cost RUB], Quantity, Volume
     FROM [N:\GK\Radio\Маркетинг\Служебный\2013. xlsb].[Мониторинг$]
      UNION
     SELECT Advertiser, 2014 as [Year], Month, [Cost RUB], Quantity, Volume
     FROM [N:\GK\Radio\Маркетинг\Служебный\2014.xlsb].[Мониторинг$]
       UNION
     SELECT Advertiser, 2015 as [Year], Month, [Cost RUB], Quantity, Volume
     FROM [N:\GK\Radio\Маркетинг\Служебный\2015.xlsb].[Мониторинг$]
   )
   WHERE [Advertiser] = 'METRO GROUP'
   GROUP BY [Year], Month
 ) as T INNER JOIN [C:\test\Month.xlsb].[Test$] AS O
ON T.[Month] = O.[Month]

Одна проблема — если осуществлять такого вида запрос для соединения нескольких Excel-файлов, он будет выполняться достаточно медленно. У меня вышло порядка 2 минут. Но не стоит думать что это бесполезно — если подобные запросы выполнять при подключении к SQL-серверу, то время обработки будет 1-2 секунды (само собой, все зависит от сложности запроса, базы, и прочие прочие факторы).

Бонусы

Формировать более-менее сложный запрос SQL вручную в VBA мягко говоря неудобно.  Поэтому я написал мини-макрос, который берет информацию из буфера обмена, и возвращает туда строчки для вставки в VBE.


'работа с буфером обмена http://excelvba.ru/code/clipboard
Private Function ClipboardText() ' чтение из буфера обмена
    With GetObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
        .GetFromClipboard
        ClipboardText = .GetText
    End With
End Function
 
Private Sub SetClipboardText(ByVal txt$) ' запись в буфер обмена
    With GetObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
        .SetText txt$
        .PutInClipboard
    End With
End Sub

Public Sub SQL_String_To_VBA()
  
    Dim sInput As String, sOut As String
    Dim ArrInput, i As Integer
    
    Dim cIdent As Integer: cIdent = 1 'Count of tabs
    Dim sVar As String: sVar = "strSQL" 'Name of variable
      
    sInput = ClipboardText()
    
    ArrInput = Split(sInput, Chr(13))
    
    For i = LBound(ArrInput) To UBound(ArrInput)
        sOut = sOut & sVar & " = " & sVar & " & " & Chr(34)
        sOut = sOut & String(cIdent, Chr(9))
        sOut = sOut & Replace(ArrInput(i), Chr(10), "")
        sOut = sOut & Chr(34) & "& chr(10)" & Chr(10)
    Next i
    
    SetClipboardText (sOut)

End Sub

Public Sub VBA_String_To_SQL()
 
    Dim sInput As String, sOut As String
    Dim ArrInput, i As Integer, sTemp
 
    sInput = ClipboardText()
 
    ArrInput = Split(sInput, Chr(10))
 
    For i = LBound(ArrInput) To UBound(ArrInput)
      sTemp = Replace(ArrInput(i), "& chr(10)", "")
      If Right(sTemp, 1) = " " Then sTemp = Left(sTemp, Len(sTemp) - 1)
      If Right(sTemp, 1) = Chr(34) Then sTemp = Left(sTemp, Len(sTemp) - 1)
 
      If Len(sTemp) > 0 Then
        sTemp = Right(sTemp, Len(sTemp) - InStr(1, sTemp, Chr(34)))
        sOut = sOut & Chr(10) & sTemp
      End If
    Next i
 
    SetClipboardText (sOut)

End Sub

Сами запросы просто и удобно создавать, например, используя Notepad++. Создали многострочный запрос SQL, копируете его в буфер обмена, запускаете макрос и вуаля — в буфере обмена строчки кода, готовые для вставки в ваши макросы. При желании вы можете настроить название переменной и количество табуляций.

И еще один небольшой бонус. Если у вас есть отчет по менеджерам/руководителям, построенный на запросах, то вам наверняка потребуется получать доступ к строке запроса через VBA. Сделать это можно через замечательную команду .CommandText — работает на чтение и запись. Мне для формирования отчета на 25 человек очень пригодился.


Public Sub ReplaceCommandText()
 
Dim con As WorkbookConnection
Dim sTemp As String
 
  For Each con In ActiveWorkbook.Connections
    sTemp = con.ODBCConnection.CommandText
    con.ODBCConnection.CommandText = sTemp
    con.Refresh
  Next con
 
End Sub

PS Ссылка с ответом на вопрос — как вставить данные из Excel в SQL
https://www.simple-talk. com/sql/t-sql-programming/questions-about-using-tsql-to-import-excel-data-you-were-too-shy-to-ask/

 

Приятного использования!

Понравилось это:

Нравится Загрузка…

SQL VBA Excel



Работа с внешними источниками данных

Материалы по работе с внешними источниками данных на примере Excel и SQL.

Рассмотрим способы передачи данных между Excel и внешней базой данной на SQL сервере с помощью ADO.

Задача первая. Подключаемся к внешней базе данных.


Для начала надо подключиться к внешней базе данных. Подключение возможно если на компьютере установлен драйвер. Список установленных драйверов для подключения к базам данных на компьютере под управлением Windows:

Панель управления\Все элементы панели управления\Администрирование\Источники данных (ODBC)


Проверить подключение к базе данных можно простым способом. Создаем пустой файл (например, «текстовый документ.txt»), затем изменяем имя и расширение на .udl (например, «connect.udl»). Двойной клик мышкой по новому файлу, далее приступаете к настройке и проверке подключения к базе данных. После того, как удалось настроить корректное подключение к базе данных, сохраняем файл «connect.udl». Открываем файл «connect.udl» обычным текстовым редактором (например, блокнотом), и видим в строке подключения все необходимые параметры. Про подключение к внешним базам данных можно посмотреть на ресурсе ConnectionStrings .

Теперь возвращаемся к нашему VBA для Excel. В редакторе VBA подключаем последнюю версию библиотеки:

 Microsoft ActiveX Data Objects Library


Пример кода:

Sub TestConnection()
Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
cn.ConnectionString = "" 'Параметры строки подключения
cn.Open   'Открываем подключение
cn.Close   'Закрываем подключение
Set cn = Nothing   'Стираем объект из памяти
End Sub
Задача вторая.

Загружаем данные из внешней базы данных на SQL сервере в Excel.


После того, как мы установили подключение к внешней базе данных можно приступать к чтению данных и выводу в Excel. Здесь потребуется знание языка запросов SQL. В результате выполнения SQL запроса к нам возвращается некая таблица с данными в объект RecordSet. Далее из объекта RecordSet можно выгружать данные непосредственно на лист или в сводную таблицу.

Пример кода простой процедуры:

Sub LoadData()

Dim cn As ADODB.Connection
Dim rst As ADODB.Recordset

Set cn = New ADODB.Connection
Set rst = New ADODB.Recordset

cn.ConnectionString = "" 'Параметры строки подключения
cn.Open

rst.Open "SELECT TOP 10 * FROM <таблица>", cn 'SQL-запрос, подключение

ActiveSheet.Range("A1").CopyFromRecordset rst 'Извлекаем данные на лист

rst.Close
cn.Close

Set rst = Nothing
Set cn = Nothing

End Sub


Для удобства работы. Предлагаю создать собственный класс «tSQL» для работы с базой данных.  У класса будет одно свойство:

Public ConnectionSring As String


Для чтения данных напишем метод SelectFrom с параметрами TableName и ws. TableName — это имя таблицы, откуда будем считывать данные и ws — лист Excel, куда будем записывать данные.

Public Sub SelectFrom(TableName As String, ws As Worksheet)

Dim cn As ADODB.Connection
Dim rst As ADODB.Recordset
Dim SQLstring As String
Dim i As Long

Set cn = New ADODB.Connection
Set rst = New ADODB.Recordset
SQLstring = "SELECT * FROM " & TableName
ws.Cells.Clear

cn.ConnectionString = ConnectionSring
cn.Open

rst.Open SQLstring, cn

For i = 1 To rst.Fields.Count
 ws.Cells(1, i) = rst.Fields(i - 1).Name
Next i
ws.Range("A2").CopyFromRecordset rst

rst.Close
cn.Close

Set rst = Nothing
Set cn = Nothing
SQLstring = Empty
i = Empty

End Sub


Пример использования класса tSQL в процедуре

Sub mySQL()
Dim ts As tSQL
Set ts = New tSQL

ts. ConnectionSring = '<Строка подключения>
ts.SelectFrom "Название таблицы", ActiveSheet

Set ts = Nothing
End Sub
Задача третья. Загружаем данные из Excel во внешнюю базу данных.


Для записи данных напишем метод InsertInto с параметрами TableName. rHead и rData. TableName — это имя таблицы, куда будем добавлять данные;  rHead — диапазон ячеек, с указанием полей; rData — диапазон ячеек с данными, которые будем добавлять.

Public Sub InsertInto(TableName As String, rHead As Range, rData As Range)

Dim cn As ADODB.Connection
Dim SQLstring As String
Dim SQLstringH As String
Dim SQLstringV As String
Dim i As Long
Dim j As Long

Dim arrHead()
Dim arrData()

arrHead = rHead.Value
arrData = rData.Value
Set cn = New ADODB.Connection
cn.ConnectionString = ConnectionSring
cn.Open

SQLstringH = "INSERT INTO " & TableName & "("
For j = LBound(arrHead, 2) To UBound(arrHead, 2)
 SQLstringH = SQLstringH & " " & arrHead(1, j)
 If j < UBound(arrHead, 2) Then
 SQLstringH = SQLstringH & ","
 Else
 SQLstringH = SQLstringH & ")"
 End If
Next j
SQLstringH = SQLstringH & " VALUES("

For i = LBound(arrData, 1) To UBound(arrData, 1)
 For j = LBound(arrData, 2) To UBound(arrData, 2)
 SQLstringV = SQLstringV & " " & arrData(i, j)
 If j < UBound(arrHead, 2) Then
 SQLstringV = SQLstringV & ","
 Else
 SQLstringV = SQLstringV & ") "
 End If
 Next j
 SQLstring = SQLstringH & SQLstringV
 SQLstringV = Empty
 cn. Execute SQLstring
Next i
cn.Close

Set cn = Nothing
SQLstring = Empty
i = Empty
j = Empty
SQLstring = Empty
SQLstringH = Empty
SQLstringV = Empty
Erase arrHead
Erase arrData

End Sub


Пример использования класса tSQL в процедуре

Sub mySQL()
Dim ts As tSQL
Set ts = New tSQL

ts.ConnectionSring = '<Строка подключения>
ts.InsertInto "Название таблицы", Range("B1:D1"), Range("B8:D300")

Set ts = Nothing
End Sub


 

Задача четвертая. Управляем внешней базой данных из Excel


Рекомендую использовать запросы в основном для чтения данных из внешней БД. Можно записывать данные в таблицы внешней БД.
Но крайне не желательно использовать Excel для управления внешней базой данных, лучше использовать стандартные средства разработки.


Полезные ссылки:

Data from Excel to SQL 

 http://www.excel-sql-server.com/excel-sql-server-import-export-using-vba.htm

Как SQL запросить данные Excel в VBA?

Существует множество способов получить данные из листа Excel. Это может быть не так очевидно на первый взгляд. В этой статье я собираюсь показать вам, как запрашивать данные Excel с помощью SQL в VBA.

Да, я собираюсь смешать немного SQL с VBA! И это лучше, чем Вы думаете! Но перед этим давайте начнем с приятного и приятного напоминания о подходе ListObject. Действительно крутая и довольно простая альтернатива таким методам, как диапазон таблиц Excel или массивы.

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

Ссылки на проект

Теперь давайте напомним о соединении с Microsoft SQL Server, потому что здесь нужные ссылки будут одинаковыми: одна из Microsoft ActiveX Data Object Library , в моем случае это 6.1 версия.

Демонстрационные данные

Чтобы получить воспроизводимые результаты, мы снова возьмем данные финансовой выборки с сайта документации Microsoft, как и в предыдущей статье.

Упражнение

Для возможности сравнения результатов подходов (имею в виду, что результаты должны быть такими же, как в методе ListObject) примите тот же порядок, что и в прошлый раз – отфильтруйте данные выборки по указанным Страна и указан Цена изготовления .

Функция

Предполагая, что мы уже знаем, что нам нужно будет проверить количество строк для 2 наборов заданных параметров, давайте создадим для этого функцию. Создание этой функции можно разбить на 3 части:
— запрос строки SQL
— запрос соединения
— набор записей ADODB

запрос строки SQL

Проще говоря — просто напишите запрос SELECT, как вы делаете в SQL, как строку переменная.

 Константа COUNTRY_COL_NAME = "Страна"
Const MAN_PRICE_COL_NAME = "Производственная цена"
    
Dim mySQL как строка
mySQL = "ВЫБЕРИТЕ СЧЕТ([Страна])" & _
    "FROM [" & myFile & "].[Sheet1$] " & _
    "ГДЕ [" & MAN_PRICE_COL_NAME & "] > " & минимальная цена производства & _
    "И [" & COUNTRY_COL_NAME & "] = '" & страна & "'" 

На этот раз все вычисления выполняются на стороне SQL. VBA получит окончательный результат, что мне в итоге и нужно.

Строка подключения

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

 Dim myConnection как строка
myConnection = "Provider=Microsoft.ACE.OLEDB.16.0;" & _
    "Источник данных=" & myFile & ";Расширенные свойства=""Excel 12.0 Xml;HDR=YES;IMEX=1"";"
 

Набор записей ADODB

Теперь некоторые константы, установите набор записей ADODB и создайте запрос, используя функцию Open с параметрами: запрос строки SQL, строка подключения и константы.

 Константа adOpenStatic = 3
Константа adLockOptimistic = 3
Константа adCmdText = &h2
    
Dim rs As ADODB.Recordset
Установить rs = новый ADODB.Recordset
    
rs.Open mySQL, myConnection, adOpenStatic, adLockOptimistic, adCmdText 

Возврат функции

Результат будет одномерным — 1 столбец — и только 1 строка. Вот почему Вам не нужно перейти к первой записи и может просто взять значение из первого (0) поля — rs.Fields(0).Value .

 countRowsForGivenParamsSQLExcel = "Страна: " & страна & "; Минимальная цена производства: " & ManufacturingMinimumPrice & "; Сумма: " & rs.Fields(0).Value 

Результаты

Собрав все вместе, функция будет выглядеть так: это:

 Функция countRowsForGivenParamsSQLExcel (ByVal myFile As String, country As String, ManufacturingMinimumPrice As Integer) As String
Константа COUNTRY_COL_NAME = "Страна"
Const MAN_PRICE_COL_NAME = "Производственная цена"
Dim mySQL как строка
mySQL = "ВЫБЕРИТЕ СЧЕТ([Страна])" & _
    "FROM [" & myFile & "].[Sheet1$] " & _
    "ГДЕ [" & MAN_PRICE_COL_NAME & "] > " & производствоМинимальная цена & " " & _
    "И [" & COUNTRY_COL_NAME & "] = '" & страна & "'"
Dim myConnection как строка
myConnection = "Provider=Microsoft.ACE.OLEDB.16.0;" & _
    "Источник данных=" & myFile & ";Расширенные свойства=""Excel 12.0 Xml;HDR=YES;IMEX=1"";"
Константа adOpenStatic = 3
Константа adLockOptimistic = 3
Константа adCmdText = &h2
Dim rs As ADODB. Recordset
Установить rs = новый ADODB.Recordset
rs.Open mySQL, myConnection, adOpenStatic, adLockOptimistic, adCmdText
countRowsForGivenParamsSQLExcel = "Страна: " & country & "; Минимальная цена производства: " & ManufacturingMinimumPrice & "; Сумма: " & rs.Fields(0).Value
Завершить функцию 

Вызов функции:

 Sub getDataUsingSQL()
Dim myFile как строка
myFile = "...\Финансовый образец.xlsx"
Debug.Print countRowsForGivenParamsSQLExcel (myFile, "Канада", 100)
Debug.Print countRowsForGivenParamsSQLExcel (myFile, "Германия", 200)
End Sub 

Окончательные результаты вызова такие же, как и в предыдущей статье ListObject:

 Страна: Канада; Минимальная цена производства: 100; Количество: 60
Страна: Германия; Минимальная цена производства: 200; Сумма: 40 

Получить данные Excel с помощью SQL в VBA?

А вот как запросить данные из Excel с помощью SQL в VBA. Это действительно просто, не так ли? И очень быстро, особенно в случае больших данных.
На этот раз это была сложная строка SQL-запроса, в следующих статьях я покажу Вам, как манипулировать циклами данных по наборам записей и получать нужные данные.

Создание приложения SQL Query Executor в MS Excel и VBA

Поиск

7 мин.

Дата изменения:

В этом посте мы узнаем Как создать приложение-исполнитель запросов SQL в MS Excel и VBA для запроса данных из книги Excel ?

Никакой другой инструмент не может заменить использование и гибкость SQL. Оператор SQL обеспечивает вывод любых простых или сложных запросов очень быстро. Вам не нужно щелкать где-либо или выполнять какие-либо шаги для запроса данных. Вам просто нужно написать SQL-запрос, и он предоставит результат за доли секунды.

Только представьте, если мы сможем использовать оператор SQL для запроса данных из книги Excel, это сэкономит много времени, а также мы сможем выполнять сложные запросы, которые было бы практически сложно обработать в Excel со встроенными функциями/шагами запросов. .

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

Давайте начнем создавать это интересное приложение с нуля!

Откройте новую книгу Excel и сохраните файл с именем «SQL Query Executor» с расширением .XLSM, так как мы собираемся писать код VBA.

Если вы не выберете .XLSM, Excel не сохранит ваш код VBA после закрытия файла.

Сохранение файла

Теперь давайте переименуем sheet1 в Query Executor .

Переименовать

Перейдите на вкладку «Вид» и снимите флажок «Сетка» в группе «Показать», чтобы скрыть линии сетки

Удаление линий сетки

Создайте пользовательский интерфейс на листе исполнителя запросов, как показано на рисунке ниже.

Пользовательский интерфейс

Теперь нам нужно написать код приложения на Visual Basic.

Чтобы открыть окно VBA, просто щелкните вкладку «Разработчик», а затем нажмите кнопку VBA, доступную в группе «Код». Вы также можете нажать сочетание клавиш как Alt + F11, чтобы открыть окно VBA.

Кнопка VBA

Теперь вы можете видеть, что окно приложения Visual Basic открыто.

VBA для Excel

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

Давайте щелкнем меню «Вставка», а затем щелкните «Модуль». Он добавит пустой модуль в этот проект.

Пустой модуль

Перед написанием кода нам нужно добавить в этот проект ссылку на библиотеку Microsoft ActiveX Data Object 6.1 . Эта библиотека поможет нам в выполнении SQL-запроса.

Чтобы добавить ссылку, просто нажмите «Меню инструментов», затем нажмите «Ссылка» и выберите Microsoft ActiveX Data Object 6.1 из ссылки на доступные библиотеки.

Справочное окно

Давайте напишем код события нажатия кнопки Обзор.

 Частная подпрограмма cmdBrowse_Click()
     Дим txtFullPath
    'Отображает стандартное диалоговое окно "Открыть" и получает имя файла от пользователя, фактически не открывая никаких файлов. 
     txtFullPath = Application.GetOpenFilename(_
               FileFilter:="Файлы Excel (*.xls; *.xlsx; *.xlsm), *.xls; *.xlsx; *.xlsm", _
               Заголовок:="Выберите файл Excel")
      Если txtFullPath = False, то выйдите из Sub
      txtWorkbookPath. Значение = txtFullPath
 Конец сабвуфера
 

Напишите приведенный ниже код при событии двойного щелчка txtWorkbookPath

 Private Sub txtWorkbookPath_DblClick (ByVal Cancel As MSForms.ReturnBoolean)
   Дим txtFullPath
    'Отображает стандартное диалоговое окно "Открыть" и получает имя файла от пользователя, фактически не открывая никаких файлов.
     txtFullPath = Application.GetOpenFilename(_
               FileFilter:="Файлы Excel (*.xls; *.xlsx; *.xlsm), *.xls; *.xlsx; *.xlsm", _
               Заголовок:="Выберите файл Excel")
      Если txtFullPath = False, то выйдите из Sub
      txtWorkbookPath. Значение = txtFullPath
 Конец сабвуфера
 

Напишите приведенный ниже код в событии щелчка cmdReset

 Private Sub cmdReset_Click()
   Dim iConfirmation As VbMsgBoxResult
   iconfimration = MsgBox("Вы хотите сбросить исполнителя запросов?", vbYesNo + vbQuestion, "Подтверждение")
   Если iConfirmation = vbNo, тогда выйдите из Sub
   'Удаление предыдущего результата запроса
   ThisWorkbook. Sheets("Исполнитель запросов").Rows("24:" & Rows.Count).Clear
    ThisWorkbook.Sheets("Исполнитель запросов").txtWorkbookPath.Value = ""
    ThisWorkbook.Sheets("Исполнитель запросов").txtSQLQuery.Value = ""
  MsgBox "Готово"
Конец сабвуфера
 

Давайте перейдем в окно модуля и начнем писать код для запуска кода SQL.

Напишите подпроцедуру в окне модуля.

 Подпрограмма Run_SQL_Query()
При ошибке Перейти к err_handler

Dim MyConnect как строка

Dim MyRecordset As ADODB.Recordset
Dim MySQL как строка
ExcelFile = ThisWorkbook.Sheets("Исполнитель запросов").txtWorkbookPath.Value
MySQL = ThisWorkbook.Sheets("Исполнитель запросов").txtSQLQuery.Value

MyConnect = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Источник данных = " & ExcelFile & ";" & _
«Расширенные свойства = Excel 12.0»

Установить MyRecordset = новый ADODB.Recordset

MyRecordset.Open MySQL, MyConnect, adOpenStatic, adLockReadOnly
Для i = 0 To MyRecordset.