Query access with excel

  1. Что делает макрос
  2. Код макроса
  3. Как работает макрос
  4. Как использовать
  5. Скачать файл

Ссылка на это место страницы:
#zadacha

Если вы часто копируете и вставляете результаты запросов Microsoft Access в Excel вам пригодится этот макрос. В этом макросе используется DAO (Data Access Object), чтобы открыть и запустить запрос Access в фоновом режиме и вывести результаты в Excel.

В этом макросе вы указываете Excel базу данных Access и извлекаете данные из существующего запроса. Затем вы сохраняете этот запрос в Recordset объекта, который вы можете использовать для заполнения таблиц Excel. Необходимо установить ссылку на библиотеку объектов Microsoft Access. В дополнение к библиотеке объектов доступа, необходимо установить ссылку на Microsoft DAO XX библиотеки объектов, где XX это номер версии. Обратите внимание, что вы можете увидеть несколько версий этой библиотеки в диалоговом окне Reference. Как правило, нужно выбрать последнюю версию Microsoft DAO. Установите флажок рядом с записью. 

Ссылка на это место страницы:
#formula

  1. Sub VipolnitZaprosAccessIzExcel()
  2. Dim MyDatabase As DAO.Database
  3. Dim MyQueryDef As DAO.QueryDef
  4. Dim MyRecordset As DAO.Recordset
  5. Dim i As Integer
  6. Set MyDatabase = DBEngine.OpenDatabase _
  7. ("C:TempYourAccessDatabse.accdb")
  8. Set MyQueryDef = MyDatabase.QueryDefs("Ваше имя запроса")
  9. Set MyRecordset = MyQueryDef.OpenRecordset
  10. Sheets("Лист1").Select
  11. ActiveSheet.Range("A6:K10000").ClearContents
  12. ActiveSheet.Range("A7").CopyFromRecordset MyRecordset
  13. For i = 1 To MyRecordset.Fields.Count
  14. ActiveSheet.Cells(6, i).Value = MyRecordset.Fields(i - 1).Name
  15. Next i
  16. End Sub

Ссылка на это место страницы:
#kak

1. Шаг 1 объявляет необходимые переменные. Переменная объекта MyDatabase привязывает Access к приложению базы данных через библиотеку объектов DAO. MyQueryDef также является объектной переменной, которая служит контейнером памяти для целевого запроса. MyRecordset является объектом набора записей, содержащий результаты извлечения данных. В дополнение к этим переменным i целочисленная переменная используется для добавления заголовков столбцов. 

2. Шаг 2 определяет базу данных, которая содержит ваш целевой запрос, а также какой запрос будет запущен. Присвоение запроса объекту QueryDef позволяет вам открыть запрос. 

3. Шаг 3 буквально запускает запрос в памяти. Результаты запроса затем сохраняются в MyRecordset. После того как результаты помещены в переменную, вы можете вывести данные в Excel. 

4. Шаг 4 готовится к выводу набора записей путем очистки листа Excel. Это гарантирует отсутствие остатка предыдущих данных. 

5. На этом шаге используется метод CopyFromRecordset в Excel, чтобы получить набор данных в электронной таблице. В этом примере макрос копирует данные из объекта MyRecordset на Лист1 в ячейку А7. 

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

Ссылка на это место страницы:
#touse

Для реализации этого макроса, вы можете скопировать и вставить его в стандартный модуль:

1. Активируйте редактор Visual Basic, нажав ALT + F11
2. Щелкните правой кнопкой мыши имя проекта / рабочей книги в окне проекта. 
3. Выберите Insert➜Module
4. Введите или вставьте код во вновь созданном модуле. 

Ссылка на это место страницы:
#file

Файлы статей доступны только зарегистрированным пользователям.

1. Введите свою почту

2. Нажмите Зарегистрироваться

3. Обновите страницу
Вместо этого блока появится ссылка для скачивания материалов.

Привет! Меня зовут Дмитрий. С 2014 года Microsoft Cretified Trainer. Вместе с командой управляем этим сайтом. Наша цель — помочь вам эффективнее работать в Excel. 

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

Подписывайтесь на нас в соц.сетях:

Skip to content

На чтение 3 мин. Просмотров 3.2k.

Что делает макрос: Вот отличный макрос для тех из вас, кто часто копирует и вставляет результаты запросов Microsoft Access в Excel. В этом макросе вы используете DAO (Data Access Object), чтобы открыть и запустить запрос Access в фоновом режиме и вывода результатов в Excel.

Содержание

  1. Как макрос работает
  2. Код макроса
  3. Как этот код работает
  4. Как использовать

Как макрос работает

В этом макросе вы указываете Excel базу данных Access и извлекаете данные из существующего запроса доступа. Затем вы сохраняете этот запрос в Recordset объекта, который вы можете использовать для заполнения таблиц Excel.
Необходимо установить ссылку на библиотеку объектов Microsoft Access.
В дополнение к библиотеке объектов доступа, необходимо установить ссылку на Microsoft DAO XX библиотеки объектов, где XX это номер версии. Обратите внимание, что вы можете увидеть несколько версий этой библиотеки в диалоговом окне Reference. Как правило, нужно выбрать последнюю версию Microsoft DAO. Установите флажок рядом с записью.

Код макроса

Sub VipolnitZaprosAccessIzExcel()
'Шаг 1: Объявляем переменные
Dim MyDatabase As DAO.Database
Dim MyQueryDef As DAO.QueryDef
Dim MyRecordset As DAO.Recordset
Dim i As Integer
'Шаг 2: Определить базу данных и запрос
Set MyDatabase = DBEngine.OpenDatabase _
("C:TempYourAccessDatabse.accdb")
Set MyQueryDef = MyDatabase.QueryDefs("Ваше имя запроса")
'Шаг 3: Откройте запрос
Set MyRecordset = MyQueryDef.OpenRecordset
'Шаг 4: Очистить предыдущее содержимое
Sheets("Лист1").Select
ActiveSheet.Range("A6:K10000").ClearContents
'Шаг 5: Скопируйте набор записей в Excel
ActiveSheet.Range("A7").CopyFromRecordset MyRecordset
'Шаг 6: Добавить имена заголовков столбцов в электронную таблицу
For i = 1 To MyRecordset.Fields.Count
ActiveSheet.Cells(6, i).Value = MyRecordset.Fields(i - 1).Name
Next i
End Sub

Как этот код работает

  1. Шаг 1 объявляет необходимые переменные. Переменная объекта MyDatabase выставляет ваш Access к приложению базы данных через библиотеку объектов DAO. MyQueryDef также является объектной переменной, которая служит контейнером памяти для целевого запроса. MyRecordset является Объект набора записей, содержащий результаты извлечения данных. В дополнение к этим, i целочисленная переменная используется для добавления заголовков столбцов.
  2. Шаг 2 определяет базу данных, которая содержит ваш целевой запрос, а также какой запрос будет запущен. Присвоение запроса объекту QueryDef позволяет вам по существу открыть запрос.
  3. Шаг 3 буквально запускает запрос в памяти. Результаты запроса затем сохраняются в MyRecordset объекте. После того, как результаты находятся в наборе записей, вы можете вывести данные в Excel.
  4. Шаг 4 готовится к выводу набора записей путем очистки области вывода. Это гарантирует отсутствие остатка предыдущих данных.
  5. На этом шаге используется метод CopyFromRecordset в Excel, чтобы получить возвращенный набор данных в электронные таблицы. В этом примере макрос копирует данные из объекта MyRecordset в Лист1 в ячейке А7.
  6. Наконец, вы перечисляете все поля в наборе записей, чтобы автоматически получить имя каждого заголовка и вводите его в Excel.

Как использовать

Для реализации этого макроса, вы можете скопировать и вставить его в стандартный модуль:

  1. Активируйте редактор Visual Basic, нажав ALT + F11.
  2. Щелкните правой кнопкой мыши имя проекта / рабочей книги в окне проекта.
  3. Выберите Insert➜Module.
  4. Введите или вставьте код.

Перейти к содержанию

На чтение 2 мин Опубликовано 19.06.2015

Этот пример научит вас импортировать данные из базы данных Microsoft Access с помощью мастера запросов Microsoft Query. Используя Microsoft Query, вы можете выбрать нужные столбцы и импортировать в Excel только их.

  1. На вкладке Data (Данные) нажмите кнопку From Other Sources (Из других источников) и выберите From Microsoft Query (Из Microsoft Query).Microsoft Query в ExcelПоявится диалоговое окно Choose Data Source (Выбор источника данных).
  2. Выберите MS Access Database* и поставьте галочку напротив опции Use the Query Wizard to create/edit queries (Использовать мастер запросов).Microsoft Query в Excel
  3. Нажмите ОК.
  4. Выберите базу данных и кликните ОК.Microsoft Query в ExcelЭта база данных состоит из нескольких таблиц. Вы можете выбрать таблицу и столбцы, которые нужно включить в запрос.
  5. Выделите таблицу Customers и кликните по кнопке с символом «>«.Microsoft Query в Excel
  6. Нажмите Next (Далее).
  7. Чтобы импортировать только указанный набор данных, отфильтруйте их. Для этого выделите City в списке Column to filter (Столбцы для отбора). Справа в первом выпадающем списке выберите equals (равно), а во втором название города – New York.Microsoft Query в Excel
  8. Нажмите Next (Далее).

Вы можете отсортировать данные, если хотите, мы же не будем этого делать.

  1. Нажмите Next (Далее).Microsoft Query в Excel
  2. Нажмите Finish (Готово), чтобы отправить данные в Microsoft Excel.Microsoft Query в Excel
  3. Выберите тип отображения информации, куда следует поместить данные и нажмите ОК.Microsoft Query в Excel

Результат:

Microsoft Query в Excel

Примечание: Когда база данных Access изменится, можно будет нажать Refresh (Обновить), чтобы загрузить изменения в Excel.

Оцените качество статьи. Нам важно ваше мнение:

 

Ram-zes

Пользователь

Сообщений: 46
Регистрация: 18.11.2014

Есть таблица Excel, данные которой загружаются в запрос на выборку Access
В запросе можно указать разные способы загрузки данных:
1. Загружаются данные всего листа:  SELECT [Лист1$].* FROM [Лист1$] IN » [Excel 12.0;HDR=Yes;IMEX=1;DATABASE=С:База данныхФайл.xlsx];
2. Загружаются данные заданных полей:  SELECT [Лист1$].[Поле1], [Лист1$].[Поле2],[Лист1$].[Поле3]  FROM [Excel 12.0;HDR=YES;IMEX=1;DATABASE= С:База данныхФайл.xlsx].[Лист1$]

Нужен третий вариант: загрузка данных именованного диапазона или заданного диапазона, например A3:K20. Подскажите, можно ли загружать напрямую из Excel в ЗАПРОС Access данные диапазона? Если да, то как?
Знаю как загружать именованный диапазон в Access с помощью сводных таблиц, но нужна загрузка в запрос

Изменено: Ram-zes12.01.2015 17:58:10

 

B.Key

Пользователь

Сообщений: 633
Регистрация: 26.02.2014

попробуйте просто указать имя именованного диапазона …….С:База данныхФайл.xlsx].[tbl]
где tbl имя диапазона

 

Ram-zes

Пользователь

Сообщений: 46
Регистрация: 18.11.2014

B.Key, так не получается…
Сборка по теме с учетом моих экспериментов:
1. Данные всего листа
SELECT [Лист1$].* FROM [Лист1$] IN » [Excel 12.0XML;HDR=Yes;IMEX=1;DATABASE=С:База данныхФайл.xlsx];

2. Данные заданных полей (поля должны стоять в первой строке)
SELECT [Лист1$].[Поле1], [Лист1$].[Поле2],[Лист1$].[Поле3] FROM [Excel 12.0XML;HDR=YES;IMEX=1;DATABASE= С:База данныхФайл.xlsx].[Лист1$]

3. Данные по заданному диапазону
SELECT * FROM [Лист1$A6:A11] IN » [Excel 12.0XML;HDR=Yes;IMEX=1;DATABASE=С:База данныхФайл.xlsx];

4. Данные по именованному диапазону
SELECT * FROM [имя диапазона] IN » [Excel 12.0XML;HDR=Yes;IMEX=1;DATABASE=С:База данныхФайл.xlsx];

Изменено: Ram-zes15.01.2015 16:34:17

 

LVL

Пользователь

Сообщений: 903
Регистрация: 01.01.1970

Загрузка в запрос — не правильная постановка задачи (формулировка). Если я правильно понял, то вам нужно использовать значения из именованного диапазона в запросе на выборку в базе Access. Тогда я бы сделал так:
Сначала создаем связанную таблицу в этой базе (линкуем данные), а потом в самой базе выполняем нужный запрос с использованием этой таблицы без заморочек. После выполнения запроса связанную таблицу удаляем.

 

Ram-zes

Пользователь

Сообщений: 46
Регистрация: 18.11.2014

Да, использовать значения…

LVL, обмен данными идет постоянно — это не разовая акция. Поэтому, как я понимаю, при удалении связанной таблицы, данные перестанут загружаться в запрос.
Изначально я так и делал, как вы описали (делал связанные таблицы в Access и обращался к ним запросами), но мои эксперименты показали, что если сразу обращаться к данным в файле  Excel из запроса с помощью SQL, то скорость обмена данными выше, а заморочек меньше. Если Вы линкуете, то перегружаете базу дополнительными таблицами, мне кажется — это лишнее промежуточное звено, особенно если нужно получать данные не с одного, а с нескольких таких файлов

 

LVL

Пользователь

Сообщений: 903
Регистрация: 01.01.1970

#6

15.01.2015 14:19:58

Цитата
Ram-zes пишет: обмен данными идет постоянно — это не разовая акция

В чем проблема, не удаляйте связанную таблицу

Цитата
Ram-zes пишет: мои эксперименты показали, что если сразу обращаться к данным в файлеExcel из запроса с помощью SQL, то скорость обмена данными выше

Доля правды в этом есть, вернее даже не так… Варианта 2:
1. Работаете с таблицами посредством SQL (в данном случае прилинковывая таблицу)
2. Формируете запрос с ограничениями сразу в нем (WHERE и т.д.)

Лично я предпочту первый вариант, он более прозрачен и его проще поддерживать, что касается производительности, то да, в теории второй вариант быстрее, но это только в теории, на практике время выполнения запроса врятле будет отличаться значительно. На самом деле вопрос несколько в ином, насколько сложно сформировать запрос сразу со всеми ограничениями? + Нужно ли будет его корректировать и как часто… Поэтому, как я уже сказал, я предпочту первый вариант.

 

LVL

Пользователь

Сообщений: 903
Регистрация: 01.01.1970

Перечитал ещё раз тему… Хочу уточнить — где находятся данные и куда их нужно вернуть? Я предполагал, что данные находятся в базе Access и вы хотите получать их с помощью запроса в файл Excel, при этом в тексте запроса использовать ограничения указанные в файле Excel… Я правильно вас понял?

 

Antubas

Пользователь

Сообщений: 50
Регистрация: 22.10.2013

#8

15.01.2015 14:28:51

Цитата
Ram-zes пишет: Если Вы линкуете, то перегружаете базу дополнительными таблицами

DAO.Recordset не спасет? Если в него записать SQL запрос условием отбора, после обнулить и закрыть.

 

Ram-zes

Пользователь

Сообщений: 46
Регистрация: 18.11.2014

Вообще коммуникация очень сложная… Но если коротко то примерно так:
Есть файл Excel, куда вносится первичная информация (одно из полей Отдел). Информация поступает в Access и там идет нарезка этой информации на отделы, т.е. в Access есть запросы, которые и делают эту нарезку, скажем на 10 отделов (ну понятно, что в каждом запросе стоит свое условие — название отдела). C этих запросов информация отправляется в другие файлы Excel — по отделам. Там вносится необходимая информация. Затем в Access работают другие запросы, которые уже обращаются к этим файлам Excel и получают информацию в базу, есть консолидирующий запрос, который после, отправляет все данные в исходный файл.
При сохранении файлов Excel информация попадает в Access. При обновлении данных в Excel информация закачивается из Access. Ну вот как-то так.

Изменено: Ram-zes15.01.2015 14:36:16

 

LVL

Пользователь

Сообщений: 903
Регистрация: 01.01.1970

Задумчивая схема…
Т.е. всетаки обмен идет между Access и Excel — это я и хотел уточнить…
А теперь — в каком именно моменте возникает проблема?

 

Ram-zes

Пользователь

Сообщений: 46
Регистрация: 18.11.2014

Antubas, может DAO.Recordset и спасет… Но мне об этом не ведомо. Я не профессиональный IT и к сожалению об DAO.Recordset пока ничего не знаю. Можете показать пример кода, я попробую

 

Ram-zes

Пользователь

Сообщений: 46
Регистрация: 18.11.2014

LVL, ну сейчас с запросами и получением (обменом) информации между файлами проблем нет. Есть другая проблема:

Почему при обновлении данных в файле Excel открывается другой файл, связанный с ним через запрос Access?

Есть файл данные_1.xlsx. Он связан с файлом данные_2.xlsx через запрос Access. Все файлы находятся в локальной сети. Подключение к базе данных Access в Excel идет по ссылке на сетевой диск Data Source=P:База…
При обновлении файла данные_1.xlsx на компьютере_1 происходит запуск на этом же компьютере файла данные_2.xlsx (в режиме для чтения), если он одновременно открыт на компьютере_2.
Если файл данные_2.xlsx закрыт, то обновление в файле данные_1.xlsx происходит без открытия связанного файла
Из-за чего так происходит и что сделать, что бы при обновлении файла данные_1.xlsx не запускался файл данные_2.xlsx

Можно ли решить эту проблему через настройку свойств подключения в Excel? В частности в настройке прав доступа:
Права доступа (Read — только чтение; ReadWrite — чтение и запись; Share Deny None — никому не отказывать ни в чтении, ни в записи; Share Deny Read — запретить всем работу в режиме чтения; Share Deny Write — запретить всем работу в режиме записи; Share Exclusive — запретить всем работу в режиме чтения/записи; Write — только запись).

Изменено: Ram-zes15.01.2015 14:43:28

 

Ram-zes

Пользователь

Сообщений: 46
Регистрация: 18.11.2014

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

 

Antubas

Пользователь

Сообщений: 50
Регистрация: 22.10.2013

#14

15.01.2015 14:51:53

Цитата
Ram-zes пишет: пример кода
Код
Function status()
   Dim db As Database
   Dim rst As DAO.Recordset
   Dim strSQL As String
   Set db = CurrentDb
   strSQL = "SELECT [Лист1$].* FROM [Лист1$] IN '' [Excel 12.0;HDR=Yes;IMEX=1;DATABASE=С:База данныхФайл.xlsx];"
   Set rst = db.OpenRecordset(strSQL)
   rst.MoveFirst
   While Not rst.EOF
      rst.Fields("Столбец").Value
      rst.MoveNext
   Wend
   Set rst = Nothing
   rst.Close
End Function

Примерно так

 

Ram-zes

Пользователь

Сообщений: 46
Регистрация: 18.11.2014

Да, совсем забыл, есть еще одно огромное преимущество у SQL запросов перед связанными таблицами. Вы знаете, что Access не берет более 255 столбцов…
В моем случае в файлах ведется учет рабочего времени и там создана шкала времени на весь год, т.е. более 360 столбцов. Если вы делаете связанную таблицу, то она возьмет в Access только первы 255 столбцов. Даже если вы создадите именованный диапазон на столбцы после 255 и попытаетесь создать связанную таблицу в Access на этот диапазон, то он ее не подцепит. А вот SQL запрос берет с этого листа любые диапазоны. В начале мне приходилось дублировать вторую половину года на отдельный лист и с него делать связанную таблицу, сейчас же все на одном листе

 

Ram-zes

Пользователь

Сообщений: 46
Регистрация: 18.11.2014

Antubas, а вставляем этот код в SQL запрос? Я правильно понимаю, что вместо моего кода нужно вставить ваш?

 

Antubas

Пользователь

Сообщений: 50
Регистрация: 22.10.2013

Может выложите примерчик с Excel и Access файлом, или сходите на

http://www.cyberforum.ru/ms-access/

там помогут с Access.

 

Antubas

Пользователь

Сообщений: 50
Регистрация: 22.10.2013

#18

15.01.2015 15:03:51

Цитата
Ram-zes пишет: вставляем этот код в SQL запрос?

В VBA, лучше всего дайте файлы с примерами )

 

LVL

Пользователь

Сообщений: 903
Регистрация: 01.01.1970

#19

15.01.2015 15:04:20

Цитата
Ram-zes пишет: Access не берет более 255 столбцов…

Вы создаете таблицы в Access с таким количеством полей?

 

Ram-zes

Пользователь

Сообщений: 46
Регистрация: 18.11.2014

LVL, а куда деваться? Если нужно такое количество полей: 01.01 | 02.01 | 03.01 и т.д.

Antubas, с VBA не работаю, к сожалению…

Изменено: Ram-zes15.01.2015 15:08:07

 

Antubas

Пользователь

Сообщений: 50
Регистрация: 22.10.2013

У Вас база Access типа «Клиент»-«Сервер», или же Вы Access используете просто для операции БД?

Изменено: Antubas15.01.2015 15:08:14

 

Ram-zes

Пользователь

Сообщений: 46
Регистрация: 18.11.2014

видимо просто для операции БД

 

Ram-zes

Пользователь

Сообщений: 46
Регистрация: 18.11.2014

В принципе, выложить можно, но мне нужно ее подготовить для этого, только завтра

 

Antubas

Пользователь

Сообщений: 50
Регистрация: 22.10.2013

#24

15.01.2015 15:11:44

Цитата
Ram-zes пишет: операции БД

А почему бы тогда Вам не тратить время на Access и сделать все эти деления и обновления в самом Excel?

Цитата
только завтра

no problem

Изменено: Antubas15.01.2015 15:21:55

 

Ram-zes

Пользователь

Сообщений: 46
Регистрация: 18.11.2014

Вопрос в совместном доступе в Excel — не просто это сделать (ну мне не просто). Потребуется VBA. Ну или я не знаю адекватного способа

Изменено: Ram-zes15.01.2015 15:21:11

 

Ram-zes

Пользователь

Сообщений: 46
Регистрация: 18.11.2014

В общем решение оказалось простым. Нужен офис 2010 на всех компах и в свойствах подключения в правах доступа нужно указать: Share Deny None

 

zin-renat

Пользователь

Сообщений: 1
Регистрация: 24.07.2015

#27

24.07.2015 11:37:14

Добрый день. Ситуация такая. Имеется запрос из внешней базы данных MS SQL Server 2012, результат которого выводится в книгу Excel.

Код
select * from packs where packs.prday = 10

Как вместо цифры 10 подставить значение из ячейки листа Excel без использования VBA?

 

JeyCi

Пользователь

Сообщений: 3357
Регистрация: 27.11.2013

#28

24.07.2015 12:05:22

попробуйте так — при обновлении запроса должно выскочить окно — там и указать ячейку или др (см вроде бы в свойствах выходной таблицы — параметры)…

Код
select * from packs where packs.prday = [?]

или заново сформируйте параметрический (!) запрос через ms query…

см пост№23 здесь

p.s. и все запросы сваливать в эту ветку, наверно, не надо — лучше см.

Правила форума

— чуть что, я вас предупредила…

Изменено: JeyCi24.07.2015 12:10:08

чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок — обратитесь к собеседнику на ВЫ — ответ на ваш вопрос получите — а остальное вас не касается (п.п.п. на форумах)

Running Access Queries From Excel Using VBA


Introduction


Two weeks ago, I published a VBA code for retrieving values from DBF (database) files. Some days after that post, I received some e-mail requests about doing the same, but for Access databases. More precisely, two readers (Josh and Maria) asked me to write two different VBA codes for running Access queries directly from Excel. I decided to “answer” both requests by writing this post since both are related to the same subject: Access queries.

In the next section, you will find two Excel VBA code snippets that show you how to retrieve data from an Access database. The idea behind both macros is the same:

  • Create and open a connection to the Access database.
  • Create a recordset that will contain the query results.
  • Create the necessary SQL select statement or set the query name.
  • Open the recordset.
  • If the recordset has data, write them into Excel.
  • Finally, close the recordset and the connection.

Both codes have many similarities and share a lot of code lines. Their main difference, however, is in the query part. The first code (CreateAndRunQuery) creates the query on the fly, while the second one (RunExistingQuery) uses an existing database query.


VBA code for running access queries


Both macros below use the Sample.accdb database, located in the same folder as the workbook. First, the CreateAndRunQuery macro is presented, which runs a query on the Customers table of the database, retrieving information (names, addresses, etc.) from all the customers from Canada.

Create and run Access queries on the fly

Option Explicit

Sub CreateAndRunQuery()
    
    '------------------------------------------------------------------------------------------
    'This macro opens the Sample.accdb database, creates and runs a SQL query (filtering
    'all the customers from Canada). Then, it copies selected fields back in the Excel sheet.
    'The code uses late binding, so no reference to an external library is required.
    
    'Written By:    Christos Samaras
    'Date:          05/10/2013
    'Last Updated:  29/11/2014
    'E-mail:        [email protected]
    'Site:          https://www.myengineeringworld.net
    '------------------------------------------------------------------------------------------

    'Declaring the necessary variables.
    Dim con         As Object
    Dim rs          As Object
    Dim AccessFile  As String
    Dim strTable    As String
    Dim SQL         As String
    Dim i           As Integer
            
    'Disable screen flickering.
    Application.ScreenUpdating = False
    
    'Specify the file path of the accdb file. You can also use the full path of the file like:
    'AccessFile = "C:UsersChristosDesktopSample.accdb"
    AccessFile = ThisWorkbook.Path & "" & "Sample.accdb"
    
    'Set the name of the table you want to retrieve the data.
    strTable = "Customers"
    
    On Error Resume Next
    'Create the ADODB connection object.
    Set con = CreateObject("ADODB.connection")
    'Check if the object was created.
    If Err.Number <> 0 Then
        MsgBox "Connection was not created!", vbCritical, "Connection Error"
        Exit Sub
    End If
    On Error GoTo 0
    
    'Open the connection.
    con.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & AccessFile
    
    'Create the SQL statement to retrieve the data from the table.
    'Get the necessary information (first name etc.) for all the Canadian customers.
    SQL = "SELECT FirstName, LastName, Address, City, Phone FROM " & strTable & " WHERE COUNTRY='Canada'"
    
    On Error Resume Next
    'Create the ADODB recordset object.
    Set rs = CreateObject("ADODB.Recordset")
    'Check if the object was created.
    If Err.Number <> 0 Then
        'Error! Release the objects and exit.
        Set rs = Nothing
        Set con = Nothing
        'Display an error message to the user.
        MsgBox "Recordset was not created!", vbCritical, "Recordset Error"
        Exit Sub
    End If
    On Error GoTo 0
         
    'Set thee cursor location.
    rs.CursorLocation = 3 'adUseClient on early  binding
    rs.CursorType = 1 'adOpenKeyset on early  binding
    
    'Open the recordset.
    rs.Open SQL, con
    
    'Check if the recordset is empty.
    If rs.EOF And rs.BOF Then
        'Close the recordset and the connection.
        rs.Close
        con.Close
        'Release the objects.
        Set rs = Nothing
        Set con = Nothing
        'Enable the screen.
        Application.ScreenUpdating = True
        'In case of an empty recordset display an error.
        MsgBox "There are no records in the recordset!", vbCritical, "No Records"
        Exit Sub
    End If
    
    'Copy the recordset headers.
    For i = 0 To rs.Fields.Count - 1
        Sheets("New Query").Cells(1, i + 1) = rs.Fields(i).Name
    Next i
    
    'Write the query values in the sheet.
    Sheets("New Query").Range("A2").CopyFromRecordset rs
    
    'Close the recordset and the connection.
    rs.Close
    con.Close
    
    'Release the objects.
    Set rs = Nothing
    Set con = Nothing
    
    'Adjust the columns' width.
    Sheets("New Query").Columns("A:E").AutoFit
    
    'Enable the screen.
    Application.ScreenUpdating = True

    'Inform the user that the macro was executed successfully.
    MsgBox "The Canadian customers were successfully retrieved from the '" & strTable & "' table!", vbInformation, "Done"

End Sub 

Here is the RunExistingQuery macro, which runs the existing qrRegions query. The particular query counts the number of customers from each region on the Customers table.

Run existing Access queries

Option Explicit

Sub RunExistingQuery()
    
    '------------------------------------------------------------------------------------
    'This macro opens the Sample.accdb database and runs the (existing) qrRegions query
    '(counting the number of customers from each region, based on table Customers).
    'Then, it copies all the query results back in the Excel sheet.
    'The code uses late binding, so no reference to an external library is required.
    
    'Written By:    Christos Samaras
    'Date:          05/10/2013
    'Last Updated:  29/11/2014
    'E-mail:        [email protected]
    'Site:          https://www.myengineeringworld.net
    '------------------------------------------------------------------------------------

    'Declaring the necessary variables.
    Dim con         As Object
    Dim rs          As Object
    Dim AccessFile  As String
    Dim strQuery    As String
    Dim i           As Integer
            
    'Disable screen flickering.
    Application.ScreenUpdating = False
    
    'Specify the file path of the accdb file. You can also use the full path of the file like:
    'AccessFile = "C:UsersChristosDesktopSample.accdb"
    AccessFile = ThisWorkbook.Path & "" & "Sample.accdb"
    
    'Set the name of the query you want to run and retrieve the data.
    strQuery = "qrRegions"
    
    On Error Resume Next
    'Create the ADODB connection object.
    Set con = CreateObject("ADODB.connection")
    'Check if the object was created.
    If Err.Number <> 0 Then
        MsgBox "Connection was not created!", vbCritical, "Connection Error"
        Exit Sub
    End If
    On Error GoTo 0
    
    'Open the connection.
    con.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & AccessFile
    
    On Error Resume Next
    'Create the ADODB recordset object.
    Set rs = CreateObject("ADODB.Recordset")
    'Check if the object was created.
    If Err.Number <> 0 Then
        'Error! Release the objects and exit.
        Set rs = Nothing
        Set con = Nothing
        'Display an error message to the user.
        MsgBox "Recordset was not created!", vbCritical, "Recordset Error"
        Exit Sub
    End If
    On Error GoTo 0
         
    'Set thee cursor location.
    rs.CursorLocation = 3 'adUseClient on early  binding
    rs.CursorType = 1 'adOpenKeyset on early  binding
    
    'Open the recordset.
    rs.Open strQuery, con
    
    'Check if the recordset is empty.
    If rs.EOF And rs.BOF Then
        'Close the recordset and the connection.
        rs.Close
        con.Close
        'Release the objects.
        Set rs = Nothing
        Set con = Nothing
        'Enable the screen.
        Application.ScreenUpdating = True
        'In case of an empty recordset display an error.
        MsgBox "There are no records in the recordset!", vbCritical, "No Records"
        Exit Sub
    End If
    
    'Copy the recordset headers.
    For i = 0 To rs.Fields.Count - 1
        Sheets("Existing Access Query").Cells(1, i + 1) = rs.Fields(i).Name
    Next i
    
    'Write the query values in the sheet.
     Sheets("Existing Access Query").Range("A2").CopyFromRecordset rs
    
    'Close the recordset and the connection.
    rs.Close
    con.Close
    
    'Release the objects.
    Set rs = Nothing
    Set con = Nothing
    
    'Adjust the columns' width.
    Columns("A:B").AutoFit
    
    'Enable the screen.
    Application.ScreenUpdating = True

    'Inform the user that the macro was executed successfully.
    MsgBox "All data were  successfully retrieved from the '" & strQuery & "' query!", vbInformation, "Done"

End Sub 

Both codes use late binding, so no reference to an external library is required. The Access queries that were used here were relatively simple to demonstrate the macros. Of course, you can use more complicated ones.


Downloads


Download

The zip file contains an Excel workbook containing the two macros presented above and a sample Access database. The workbook can be opened with Excel 2007 or newer.


Read also 


Read DBF Files Using VBA
Export A Large Access Table/Query To Excel
Add Records Into Existing Access Table From Excel Using VBA

Page last modified: May 16, 2021

Author Image

Hi, I am Christos, a Mechanical Engineer by profession (Ph.D.) and a Software Developer by obsession (10+ years of experience)! I founded this site back in 2011 intending to provide solutions to various engineering and programming problems.

Add Content Block

Like this post? Please share to your friends:
  • Queries in microsoft excel
  • Queries in excel sheet
  • Queries in excel 2016
  • Queries in excel 2013
  • Queries in excel 2010