Судя по ответам, я не понимаю вопроса. Похоже, что OP имеет запрос DML (или «запрос действия» в терминах Access), который изменяет данные и хочет отобразить результаты в форме. В текущих ответах объясняется, как отображать результаты, а не как выполнять запрос.
Итак, вот ответ, основанный на моей интерпретации вопроса.
Сначала создайте непрерывную форму или таблицу данных, которая привязана к результатам.
Это легкая часть. «Трудная» часть - выполнение SQL для обновления, результаты которого вы собираетесь отобразить. Вы не предоставляете никакого контекста для того, откуда вы это запускаете, и как вы определяете, какие именно записи нужно обновить, поэтому я дам два довольно общих ответа.
Способ 1. создать макрос из двух частей:
первая команда - OpenQuery, в качестве аргумента вы должны указать имя сохраненного запроса.
вторая команда OpenForm, которая открывает форму, созданную вами для отображения результатов.
Теперь я не предоставил никакого метода для выполнения макроса, но это потому, что вы не предоставили никакого контекста.
Способ 2. в форме, из которой уместно инициировать этот процесс:
создать кнопку команды.
используйте событие OnClick для выполнения желаемого действия.
а. используйте макрос, который вы написали с методом 1, в качестве аргумента для события OnClick командной кнопки.
б. написать код VBA для выполнения обеих задач:
CurrentDB.Execute "MySaveQueryThatUpdatesData", dbFailOneError
DoCmd.OpenForm "MyFormThatDisplaysTheResults"
Но все это действительно напрашивается на вопросы, поскольку это все чертовски элементарно. Сложная часть такого рода вещей возникает, когда обновление SQL работает с подмножеством записей, и вам нужно отображать только это подмножество записей.
Весьма вероятно, что ваш исходный запрос будет привязан к исходному контексту. Скажем, например, что вы хотите запустить весь процесс из формы, отображающей «Компании», а ваш SQL работает с «Сотрудниками» отображаемой в данный момент записи «Компании». В этом случае вы захотите обновить таблицу сотрудников только для той компании, которую вы просматриваете. Есть два способа сделать это:
используйте ссылку на CompanyID в форме компании в предложении WHERE сохраненного QueryDef:
UPDATE Employees
SET [blah, blah, blah]
WHERE Employees.CompanyID = Forms!Company!CompanyID
вместо того, чтобы использовать сохраненный аппаратный код QueryDef, чтобы требовать, чтобы форма вашей компании была открыта для его работы, напишите SQL на лету в коде за вашей командной кнопкой:
Dim strSQL As String
strSQL = "UPDATE Employees "
strSQL = strSQL & "SET [blah, blah, blah] "
strSQL = strSQL & "WHERE Employees.CompanyID = "
strSQL = strSQL & Me!CompanyID
CurrentDB.Execute strSQL, dbFailOneError
Теперь для второй части вам нужно открыть форму результатов, чтобы отобразить только те записи, которые были обновлены. Это означает, что вы хотите, чтобы форма открывалась с тем же предложением WHERE, которое использовалось для обновления. Для этого тоже есть два метода.
первый очень похож на первый метод выполнения обновления, т. Е. Жесткую привязку ссылки на форму компании в предложении WHERE предложения WHERE в форме записей результатов. Итак, источник записей для вашей формы результатов будет выглядеть так:
SELECT Employees.*
FROM Employees
WHERE Employees.CompanyID = Forms!Company!CompanyID
Тогда вы откроете форму так же, как было указано ранее:
DoCmd.OpenForm "MyFormThatDisplaysTheResults"
второй подход позволяет избежать жесткого соединения источника записей формы результатов с требованием, чтобы форма Company была открытой, и вместо этого вы просто предоставляете предложение WHERE (без ключевого слова WHERE) в соответствующем параметре команды OpenForm:
DoCmd.OpenForm "MyFormThatDisplaysTheResults", , , "[CompanyID] = " & Me!CompanyID
Научиться делать это - один из самых мощных и простых аспектов использования Access, поскольку вы можете создать форму, которая возвращает все записи в таблице, а затем открыть эту форму и отобразить подмножества данных, указав соответствующий ГДЕ параметр в команде OpenForm. Имейте в виду, что Access применяет их очень эффективно, то есть он не открывает форму и не загружает весь набор записей, а затем применяет к ней аргумент WHERE, но применяет параметр WHERE к источнику записей до любой записи загружаются в виде.
Теперь рассмотрим, каков наилучший выход из всех альтернатив:
Я бы написал SQL на лету для обновления и использовал бы параметр WHERE команды OpenForm для выполнения фильтрации. Итак, в одном из моих приложений код, стоящий за событием OnClick вашей командной кнопки в форме компании, будет выглядеть так:
Dim strSQL As String
strSQL = "UPDATE Employees "
strSQL = strSQL & "SET [blah, blah, blah] "
strSQL = strSQL & "WHERE Employees.CompanyID = "
strSQL = strSQL & Me!CompanyID
CurrentDB.Execute strSQL, dbFailOneError
DoCmd.OpenForm "MyFormThatDisplaysTheResults", , , "[CompanyID] = " & Me!CompanyID
Теперь из-за аргумента dbFailOnError для CurrentDB.Execute вам понадобится обработчик ошибок. И если вы хотите узнать, сколько записей было изменено, вам нужно будет использовать объект базы данных, отличный от CurrentDB, поэтому, скорее всего, я бы сделал это так:
On Error GoTo errHandler
Dim strSQL As String
Dim db As DAO.Database
strSQL = "UPDATE Employees "
strSQL = strSQL & "SET [blah, blah, blah] "
strSQL = strSQL & "WHERE Employees.CompanyID = "
strSQL = strSQL & Me!CompanyID
Set db = CurrentDB
db.Execute strSQL, dbFailOneError
Debug.Print "Updated " & db.RecordsAffect & " Employee records."
DoCmd.OpenForm "MyFormThatDisplaysTheResults", , , "[CompanyID] = " & Me!CompanyID
exitRoutine:
Set db = Nothing
Exit Sub
errHandler:
MsgBox Err.Number & ": " & Err.Description, _
vbExclamation, "Error in Forms!Company!cmdMyButton.OnClick()"
Resume exitRoutine
Моя причина для создания SQL на лету в событии OnClick командной кнопки заключается в том, что очень легко добавить дополнительные критерии, если они станут необходимыми. Мне нравится избегать перегрузки моих сохраненных QueryDef с зависимостями от объектов пользовательского интерфейса, поэтому я буду стремиться писать SQL на лету в том месте, где он используется.
Некоторые люди беспокоятся о том, что это снижает производительность, поскольку SQL на лету не оптимизируется оптимизатором запросов вашего ядра СУБД. Это может или не может быть правдой. Многие серверные базы данных кэшируют планы оптимизации команд SQL на лету, и из-за способа, которым Jet / ACE анализирует подобную команду SQL и передает ее на сервер, она, вероятно, будет отправлена как общая хранимая процедура. Из-за этого сервер, такой как SQL Server, будет кэшировать этот план запросов и сможет использовать его каждый раз, когда вы выполняете SQL на лету, даже если каждый раз он имеет другое значение CompanyID.
При использовании серверной части Jet / ACE такое кэширование отсутствует, но разница во времени выполнения оптимизированного и неоптимизированного SQL будет очень мала во всех случаях, когда вы не работаете с действительно большими наборами данных. И даже обновление, скажем, 1000 записей о сотрудниках - это не то, что считается большим набором данных для Jet / ACE. Поэтому я думаю, что при написании SQL на лету редко бывает достаточно снижения производительности, чтобы оправдать перемещение его в сохраненный QueryDef. Однако в каждом конкретном случае я вполне мог бы сделать это - это не будет моим первым выбором.
Тем не менее, более существенное возражение заключается в том, что у вас в коде будет куча строк SQL, и это может стать кошмаром обслуживания. Я не знаю, что сказать по этому поводу, за исключением того, что есть способы справиться с этим, чтобы вы исключили как можно больше дублирования, либо сохранив базовый запрос SELECT в качестве сохраненного QueryDef, и используя его так, чтобы SQL-код, который вы создаете в код уникален только теми частями, которые относятся к действию, выполняемому в данном конкретном случае, или с использованием определенных констант в вашем коде, которые содержат базовые операторы SQL, которые вы используете (так что вам нужно только изменить определение константы, чтобы изменить результаты везде, где он используется).
Это довольно слабо, но с Access я не вижу альтернативы. Если вы сохраняете каждый оператор SQL как QueryDef, вы получаете неуправляемый беспорядок другого типа со слишком большим количеством сохраненных запросов, каждый из которых немного отличается от другого, и он может быть таким же дублирующим, как SQL, повторяемый в коде.
Но это еще одна проблема, и я, вероятно, не должен больше делать это, пытаясь решить ее здесь!