С помощью макрокоманды ОткрытьЗапрос в базах данных Access можно открывать запросы на выборку и перекрестные запросы в режиме таблицы, в Конструкторе или в режиме предварительного просмотра. Это действие запускает запрос на изменение. Вы также можете выбрать режим ввода данных для запроса.
Примечание: Данная макрокоманда доступна только в среде базы данных Access (MDB или ACCDB). Если вы используете среду проекта Access (ADP), см. макрокоманды ОткрытьПредставление , ОткрытьСохраненнуюПроцедуру и ОткрытьФункцию . Макрокоманда ОткрытьЗапрос недоступна в веб-приложениях Access.
Настройка
Макрокоманда ОткрытьЗапрос имеет следующие аргументы:
Аргумент макрокоманды | Описание |
---|---|
Имя запроса |
Имя открываемого запроса. Выберите имя в раскрывающемся списке. Это обязательный аргумент. При выполнении в базе данных библиотеки макроса, содержащего макрокоманду ОткрытьЗапрос , Access сначала ищет запрос с этим именем в базе данных библиотеки, а затем в текущей базе данных. |
Представление, в котором будет открываться запрос. Выберите в поле Вид значение Таблица , Конструктор , Предварительный просмотр , Сводная таблица или Сводная диаграмма . По умолчанию используется Таблица . Примечание: Представления "Сводная таблица" и "Сводная диаграмма" недоступны в версиях Access, начиная с Access 2013. |
|
Режим данных |
Режим ввода данных для запроса. Этот параметр относится только к запросам, открытым в режиме таблицы. Выберите Добавить (пользователи смогут добавлять новые записи, но не изменять существующие), Изменить (пользователи смогут изменять существующие записи, а также добавлять новые) или Только для чтения (пользователи смогут только просматривать записи). По умолчанию используется значение Изменить . |
Примечания
Если для аргумента Вид задано значение Таблица , Access отображает результирующий набор, если используется запрос на выборку, перекрестный запрос, запрос на объединение или запрос к серверу, свойство ReturnsRecords которого имеет значение Да . Если это запрос на изменение, запрос определения данных или запрос к серверу, для свойства ReturnsRecords которого задано значение Нет , запрос выполняется.
Макрокоманда ОткрытьЗапрос аналогична двойному щелчку запроса в области навигации или его щелчку правой кнопкой мыши в области навигации и выбору представления. При использовании макрокоманды можно выбрать дополнительные параметры.
Советы
Вы можете перетащить запрос из области навигации в окно конструктора макросов. При этом будет автоматически создана макрокоманда ОткрытьЗапрос , которая открывает запрос в режиме таблицы.
Если переключиться в Конструктор, когда открыт запрос, значение аргумента Режим данных удаляется. Этот параметр не будет действовать, даже если пользователь вернется в режим таблицы.
Если вы не хотите отображать системные сообщения, которые обычно появляются при выполнении запросов на изменение (в них говорится о том, что это запрос на изменение, и указано количество записей, на которые он влияет), вы можете отключить их с помощью макрокоманды ЗадатьПредупреждение .
Чтобы выполнить макрокоманду ОткрытьЗапрос в модуле Visual Basic для приложений (VBA), используйте метод ОткрытьЗапрос объекта DoCmd .
Эй, я только что-то узнали, как поместить мои заявления SQL в VBA (или по крайней мере их выписывать), но я не знаю, как получить возвращенные данные?
У меня есть несколько форм (диаграмма формы), основанные на запросах, которые я запускать довольно регулярные параметры против, просто изменяя временные рамки (например, топ-10 продаж за месяц своего рода вещи). Тогда у меня есть процедуры, которые автоматически передают объект диаграммы в презентации PowerPoint. Так что я все эти запросы предварительно построены (например, 63), и диаграмма формы, чтобы соответствовать (ну да.... 63... я знаю, что это плохо), а затем все эти вещи созданы на «открыто/закрыть»событие, приводящее к следующему (его, как моей самой лучшей попытка быть хаком.... или домино; в зависимости от того вы предпочитаете).
Так что я пытался узнать, как использовать операторы SQL в VBA, так что в конце концов, я могу сделать все это там (я, возможно, нужно сохранить все эти диаграммы формы, но я не знаю, потому что я, очевидно, не хватает понимания).
Так в стороне от вопроса, что я спросил наверху, кто может дать совет? Спасибо
6 ответов
10
Это немного устаревшей, так что вы можете захотеть, чтобы захватить книга на эту тему . Но, вот тонна доступ к ресурсам и немного учебники и примеры также. Но, в принципе...
Dim dbs As Database Dim rs As Recordset Dim strSQL As String Set dbs = CurrentDb strSQL = "your query here Set rs = dbs.OpenRecordset(strSQL) If Not (rs.EOF And rs.BOF) Then rs.MoveFirst "get results using rs.Fields() Else "Use results
За комментарием: возьмите взгляд на класс записей . Он содержит коллекцию под названием поля, которые являются столбцами, которые возвращаются из вашего запроса. Не зная вашу схему, то трудно сказать, но что-то вроде...
Rs.MoveFirst Do While Not rs.EOF "do something like rs("SomeFieldName") rs.MoveNext Loop
Как я уже говорил, лучше всего, чтобы захватить книгу на эту тему, у них есть тонны примеров.
Использование параметризованных QueryDef и вызывать его из VBA.
Запрос проще проектировать... легко testable..and легко доступны с помощью VBA или формы.
Dim qd as querydef set qd = currentdb.querydefs!myquerydef qd.parameters!parm1=val1
или qd.execute
Dim rs as recordset set rs = qd.openrecordset()
Вот функция, которую вы могли бы рассмотреть рефакторинг взять в строке, и вы будете иметь возможность повторно использовать в любом месте вашего кода.
Так что константный или построить строку для вашего SQL заявление, и поп-музыки в вашем продезинфицировать, NON SQL ИНЖЕКЦИЕЙ строку в качестве аргумента:)
StrSQL = "SELECT * FROM Customer WHERE ID = " & EnsureParamIsNotSQLInjection(customerID)
Затем вызвать функцию/к югу от где вам нужно, чтобы получить данные/набор записей/выполнить инструкцию. Создав несколько доступа к данным функциям/подлодки, где вы можете просто запустить оператор UPDATE или извлекаемую одно значение, или извлечь полномасштабные записи.
Ключевым моментом здесь является, чтобы эти функции все живущие в одном месте и использовать их повсюду. Вот пример в VBScript.
Sub DoStuff(strSQL) Set adoCon = Server.CreateObject("ADODB.Connection") strConnString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath("db\Database.mdb") "strConnString = "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=" & Server.MapPath("db\Database.mdb") adoCon.Open strConnString Set rsMain = Server.CreateObject("ADODB.Recordset") rsMain.Open strSQL, adoCon Do While NOT rsMain.EOF customerName = rsMain("CustomerName") "silly example RsMain.MoveNext Loop rsMain.Close Set adoCon = Nothing End Sub
Другой способ сделать это, что, кажется, никто не упомянул, чтобы связать ваш график с одной сохраненной QueryDef, а затем во время выполнения, перепишем QueryDef. Теперь, я не рекомендую изменять сохраненные QueryDefs для большинства контекстов, поскольку она вызывает фронтального раздувание и, как правило, даже не нужно (в большинстве контекстов, где вы используете сохраненный QueryDef могут быть отфильтрованы в той или иной, в том контексте, в котором они используются, например, в качестве одной из форм RecordSource, вы просто передать один аргумент в DoCmd.OpenForm).
Графики разные, так как SQL вождения графики не могут быть изменены во время выполнения.
Некоторые из них предложили параметры, но открыть форму с графиком на нем, который использует SQL строка с параметрами собирается выскочить диалоги параметров по умолчанию. Один из способов избежать этого является использование диалоговую форму для сбора критериев, а затем установить ссылки на элементы управления в диалоговом виде в качестве параметров и т.д.:
PARAMETERS !! Long;
Если вы используете ссылки формы, это важно, что вы делаете это, потому что с Access 2002 на, то Jet Expression Service не всегда корректно обрабатывает их, когда элементы управления Null. Определение их в качестве параметров выпрямляет эту проблему (которая не присутствовала перед тем Access XP).
Одна из ситуаций, в которых вы должны переписать QueryDef для графа, если вы хотите, чтобы позволить пользователю выбрать N в заявлении TOP N SQL. Другими словами, если вы хотите, чтобы иметь возможность выбрать ТОП 5 или ТОП 10 или ТОП 20, вам придется изменить сохраненный QueryDef, так как N не может быть параметризованы.
Аксесс позволяет создавать программно строки SQL-запросов, а также строки, служащие значениями свойств форм, отчетов и т.д., параметров функций и т.д., которые тоже должны соответствовать синтаксису SQL. При этом надо помнить, что входящие в такую строку константы должны быть тоже оформлены по правилам SQL, а именно:
Если это нарушить, то возможны следующие эффекты:
Ниже в каждом разделе приведен пример строки SQL, которая должна получиться при ее программном создании, а затем код VBA, который ее создает. Еще ниже дана очень полезная рекомендация.
1. Использование чисел
SELECT
*
FROM
Table
WHERE
(((Table
.Quanty)=12
.197
));
VBA v1
Dim q As
Single
q = 12
.197
strSQL = "SELECT * "
_
& "FROM Table "
_
& "WHERE (((Table.Quanty)="
& q & "));"
VBA v2
Dim q As
String
q = "12,197"
strSQL = "SELECT * "
_
& "FROM Table "
_
& "WHERE (((Table.Quanty)="
& Str
(q) & "));"
Примечание:
Function GetDecimalSeparator() As String GetDecimalSeparator = Format (0 #, "." ) End Function Также следует учесть, что в этом случае некоторые стандартные действия Access могут не работать.
2. Использование строк
SELECT
*
FROM
Table
WHERE
(((Table
.Name)="All"
));
VBA v1
Dim q As
String
q = "All"
strSQL = "SELECT * "
_
& "FROM Table "
_
& "WHERE (((Table.Quanty)="
""
& DoubleQuote(q) & ""
"));"
VBA v2
Dim q As
String
q = "All"
strSQL = "SELECT * "
_
& "FROM Table "
_
& "WHERE (((Table.Quanty)="" & DoubleApostrophe(q) & ""
));"
Примечание:
Пример:
условие выборки:
a"a"s
SQL:
WHERE
field="a""a"s
"
VBA:
strWhere = "WHERE
field=""
" & "a""""a"s
" & """
"
Пример:
условие выборки:
a"a"s
SQL:
WHERE
field="a"a""s
"
VBA:
strWhere = "WHERE
field="
" & "a""a""s
" & ""
"
Public
Function
Replace97(StrMain As
String
, StrFind As
String
, StrZam As
String
) As
String
On
Error
GoTo
err
Dim
pos As
Long
If
StrFind = ""
Then
GoTo
err
If
StrMain = ""
Then
Replace97 = StrZam: Exit
Function
Do
Until
InStr(1
, StrMain, StrFind) = 0
pos = InStr(1
, StrMain, StrFind)
StrMain = mid
(StrMain, 1
, pos - 1
) & StrZam & mid
(StrMain, pos + Len(StrFind), Len(StrMain))
Loop
Replace97 = StrMain
Exit
Function
err:
Replace97 = StrMain
End
Function
3. Использование дат
SELECT
*
FROM
Table
WHERE
(((Table
.TimeOpen)=#3
/31
/2003
11
:17
:19
#));
VBA
Dim q As
Date
q = Now
strSQL = "SELECT * "
_
& "FROM Table "
_
& "WHERE (((Table.TimeOpen)=#"
& Format
(q, "mm\/dd\/yy hh\:mm\:ss"
) & "#));"
Примечание:
Составив такой стринг, содержащий команду SQL, и отправив его на выполнение, вы можете получить ошибку. В таком случае распечатайте этот стринг в отладочное окно и посмотрите на него глазами. Возможно, ошибка сразу бросится в глаза. Если не бросится, создайте новый запрос в конструкторе запросов, переключите в режим SQL, вставьте туда текст запроса и запустите на выполнение. Если ошибка есть, то она будет показана более явным образом.
Данный урок посвящен SQL запросам к базе данных на VBA Access . Мы рассмотрим, как на VBA осуществляется запросы INSERT, UPDATE, DELETE к базе данных, а также научимся получать конкретное значение из запроса SELECT.
Те, кто программируют на VBA Access и работая при этом с базой данных SQL сервера, очень часто сталкиваются с такой простой и нужной задачей как посыл SQL запроса к базе данных, будь то INSERT, UPDATE или простой SQL запрос SELECT . А так как мы начинающие программисты мы тоже должны уметь это делать, поэтому сегодня займемся именно этим.
Мы уже затрагивали тему получения данных с SQL сервера, где как раз на VBA писали код для получения этих данных, например в статье про Выгрузку данных в текстовый файл из MSSql 2008 или также немного затрагивали в материале Выгрузка данных из Access в шаблон Word и Excel , но так или иначе там мы рассматривали это поверхностно, а сегодня предлагаю поговорить об этом чуть более подробней.
Примечание! Все примеры ниже рассмотрены с использованием ADP проекта Access 2003 и базы данных MSSql 2008. Если Вы не знаете что вообще такое ADP проект то это мы рассматривали в материале Как создать и настроить ADP проект Access
Исходные данные для примеров
Допустим, у нас есть таблица test_table, которая будет содержать номера и названия месяцев в году (запросы выполнены с использованием Management Studio )
CREATE TABLE .( NOT NULL, (50) NULL) ON GO
Как я уже сказал, мы будем использовать ADP проект, настроенный на работу с MS SQL 2008, в котором я создал тестовую форму и добавил кнопку start с подписью «Выполнить» , которая нам понадобится для тестирования нашего кода, т.е. весь код мы будем писать в обработчике события «Нажатие кнопки ».
Запросы к базе INSERT, UPDATE, DELETE на VBA
Чтобы долго не тянуть сразу приступим, допустим, нам нужно добавить строку в нашу тестовую таблицу (код прокомментирован )/
Private Sub start_Click() "Объявляем переменную для хранения строки запроса Dim sql_query As String "Записываем в нее нужный нам запрос sql_query = "INSERT INTO test_table (id, name_mon) VALUES ("6", "Июнь")" "Выполняем его DoCmd.RunSQL sql_query End Sub
В данном случае запрос выполняется с использованием текущих параметров подключения к базе данных. Можем проверить, данные добавились или нет.
Как видим, данные вставились.
Для того чтобы удалить одну строку пишем вот такой код.
Private Sub start_Click() "Объявляем переменную для хранения строки запроса Dim sql_query As String "Записываем в нее запрос на удаление sql_query = "DELETE test_table WHERE id = 6" "Выполняем его DoCmd.RunSQL sql_query End Sub
Если мы проверим, то увидим, что нужная строка удалилась.
Для обновления данных записываем в переменную sql_query запрос update, надеюсь, смысл понятен.
Запрос SELECT к базе на VBA
Здесь дела обстоят чуть интересней, чем с остальными конструкциями SQL.
Первое, допустим, нам нужно получить все данные из таблицы, и, к примеру, мы их обработаем и выведем в сообщении, а Вы, конечно же, можете использовать их для других целей, для этого мы пишем вот такой код
Private Sub start_Click() "Объявляем переменные "Для набора записей из базы Dim RS As ADODB.Recordset "Строка запроса Dim sql_query As String "Строка для вывода итоговых данных в сообщении Dim str As String "Создаем новый объект для записей set RS = New ADODB.Recordset "Строка запроса sql_query = "SELECT id, name_mon FROM test_table" "Выполняем запрос с использованием текущих настроек подключения проекта RS.open sql_query, CurrentProject.Connection, adOpenDynamic, adLockOptimistic "Циклом перебираем записи While Not (RS.EOF) "Заполняем переменную для вывода сообщения str = str & RS.Fields("id") & "-" & RS.Fields("name_mon") & vbnewline "переход к следующей записи RS.MoveNext Wend "Вывод сообщения msgbox str End Sub
Здесь мы уже используем циклы VBA Access для того чтобы перебрать все значения в нашем наборе записей.
Но, достаточно часто бывает необходимо получить не все значения из набора записей, а всего лишь одно, например, название месяца по его коду. И для этого использовать цикл как-то накладно, поэтому мы можем просто написать запрос, который вернет всего одно значение и обращаться именно к нему, например, получим название месяца по коду 5
Private Sub start_Click() "Объявляем переменные "Для набора записей из базы Dim RS As ADODB.Recordset "Строка запроса Dim sql_query As String "Строка для вывода итогового значения Dim str As String "Создаем новый объект для записей set RS = New ADODB.Recordset "Строка запроса sql_query = "SELECT name_mon FROM test_table WHERE id = 5" "Выполняем запрос с использованием текущих настроек подключения проекта RS.open sql_query, CurrentProject.Connection, adOpenDynamic, adLockOptimistic "Получаем наше значение str = RS.Fields(0) msgbox str End Sub
Для универсальности здесь мы уже обратились не по имени ячейки, а по ее индексу, т.е. 0, а это самое первое значение в Recordset , в итоге мы получили значение «Май» .
Как видите, все достаточно просто. Если Вам достаточно часто требуется получать конкретное значение из базы (как в последнем примере ), то рекомендую вывести весь код в отдельную функцию (Как написать функцию на VBA Access 2003) с одним входящим параметром, например, код месяца (если рассматривать наш пример ) и просто, где необходимо вывести это значение, вызывать нужную нам функцию с нужным параметром и все, этим мы значительно уменьшим код VBA и улучшим восприятие нашей программы.
На сегодня это все. Удачи!