|
|||||||
Как запускать запросы из VBA
Время создания: 16.03.2019 23:43
Раздел: Разные закладки - VBA - Access
Запись: xintrea/mytetra_db_adgaver_new/master/base/1486541653cf2kko4f2y/text.html на raw.githubusercontent.com
|
|||||||
|
|||||||
Автор: Sfagnum, участники форума по Аксессу 1. Вопросы. Перейти на использование конструкции CurrentDb.Execute Использовать вместе с DoCmd.RunSQL, DoCmd.SetWarnings False Изменить глобальные настройки с помощью конструкции Application.SetOption "Confirm Record Changes", False Application.SetOption "Confirm Document Deletions", False Application.SetOption "Confirm Action Queries", False и т.п.
Если все параметры являются ссылками на контролы форм (Forms![ИмяФормы]![ИмяКонтрола]), тогда самое простое (и красивое) решение: Dim q As DAO.QueryDef, p As DAO.Parameter Set q = CurrentDb.QueryDefs("ИмяЗапроса") 'как обычного запроса Select, 'так и INSERT/UPDATE; в запросах на удаление это не помогает For Each p In q.Parameters p.Value = Eval(p.Name)
Next q.Execute
q.close: Set q=Nothing Если вместо обращений к формам Вы используете собственные параметры (например, [Введите начальную дату:]), тогда Вам нужно задать параметры вручную: Dim q As DAO.QueryDef Set q = CurrentDb.QueryDefs("ИмяЗапроса") q.Parameters("[Введите начальную дату:]").Value=Cdate(Ваше_значение_параметра) 'и т.д. пока не переберете все параметры
q.Execute
q.close: set q=Nothing Узнать, какие параметры от Вас хочет Аксесс, можно с помощью следующего кода: Dim q As DAO.QueryDef, p As DAO.Parameter Set q = CurrentDb.QueryDefs("ИмяЗапроса") For Each p In q.Parameters debug.print p.Name
Next q.close: set q=Nothing Альтернативой может быть использование функций, которые будут брать значения либо напрямую из нужного контрола, либо из переменной. (Такая функция должна быть описана в стандартном модуле. В модуле формы можно пользоваться свойством без параметров, функцией без параметров либо публичной переменной, но на них надо ссылаться через форму и без скобок в конце.) Использование данного метода позволяет более широко контролировать подставляемое значение, а также позволяет избавиться от квадратных скобок, что иногда бывает критично. Пример: в модуле пишем функцию, которая получает значение из поля формы: Function Rep_BegDate() Rep_BegDate = Forms!frmRep!txtBegDate End Function
WHERE ... = Forms!frmRep!txtBegDate
WHERE ... = Rep_BegDate()
Еще одной альтернативой является программное формирование команды SQL, в которой все значения параметров подставлены в явном виде. Подробнее см. здесь: http://www.sql.ru/faq/faq_topic.aspx?fid=157 Если аналогичное явление происходит не при CurrentDb.Execute, а при CurrentDb.OpenRecordset, то годятся все те же решения. При этом если параметры задаются вручную, то открывать рекордсет надо так: Set rs = q.OpenRecordset(...) 'а не Set rs = CurrentDb.OpenRecordset("ИмяЗапроса"), ...) В перекрестных запросах возникает то же явление. Правда, оно возникает не при попытке запуска (ибо перекрестный запрос не является Action Query), а при любом использовании, например при открывании формы, основанной на таком запросе. В этом случае надо действовать следующим образом: PARAMETERS [Forms]![ИмяФормы]![ИмяКонтрола] Text, ... ; ...
WHERE ИмяТаблицы.ИмяПоля=[Forms]![ИмяФормы]![ИмяКонтрола] ... ...
Если все параметры являются ссылками на контролы форм (Forms![ИмяФормы]![ИмяКонтрола]), тогда самое простое (и красивое) решение: Dim cmd As ADODB.Command Dim cnn As ADODB.Connection Dim rs As ADODB.Recordset Dim p As ADODB.Parameter Set cnn = CurrentProject.Connection 'или если не используете текущее соединение: 'Set cnn = New adodb.Connection 'cnn.Open "Cтрока подключения по аналогии с CurrentProject.BaseConnectionString" Set cmd = New ADODB.Command With cmd .ActiveConnection = cnn
.CommandText = "ИмяПроцедуры" .CommandType = adCmdStoredProc
.NamedParameters = True 'начиная с ADO версии 2.6 (???) без этого свойства работать не будет - 'ADO будет заполнять коллекцию параметров не по имени, а по порядку For Each p In .Parameters 'имена параметров равны именам контролов формы, только без @ 'Имя контрола NameFIO, тогда в процедуре @NameFIO. @- убираем с помощью Replace p.Value = Eval(Forms("ИмяФормы")(Replace(p.Name, "@", "", 1, 1, vbTextCompare))) Next Set rs = .Execute(, , adExecuteNoRecords) 'adExecuteNoRecords - можно и не указывать, если в процедуре стоит Set NoCount ON 'или чтобы иметь возможность задать свойства rs (обновляемость, например): 'Set rs = New ADODB.Recordset 'rs.CursorType = adOpenDynamic 'rs.Open cmd End With Set cmd = Nothing rs.Close: Set rs = Nothing cnn.Close: Set cnn = Nothing Если вместо обращений к формам Вы используете собственные параметры, тогда Вам нужно задать параметры вручную: Dim cmd As ADODB.Command Dim cnn As ADODB.Connection Dim rs As ADODB.Recordset Set cnn = CurrentProject.Connection Set cmd = New ADODB.Command With cmd .ActiveConnection = cnn
.CommandText = "ИмяПроцедуры" .CommandType = adCmdStoredProc
.NamedParameters = True 'Cоздадим параметр nVarChar (500) .Parameters.Append .CreateParameter("@имяПарматра1", adVarWChar, adParamInput, 500, "Некая строка") 'создадим параметр типа int (SQL) - Long (VBA) .Parameters.Append .CreateParameter("@имяПараметра2", adInteger, adParamInput, , CLng(111)) 'и т.д. Set rs = .Execute(, , adExecuteNoRecords) End With Set cmd = Nothing rs.Close: Set rs = Nothing cnn.Close: Set cnn = Nothing Узнать, какие параметры от Вас хочет Аксесс, можно с помощью следующего кода: Dim cmd As ADODB.Command Dim cnn As ADODB.Connection Dim p As ADODB.Parameter Set cnn = CurrentProject.Connection Set cmd = New ADODB.Command With cmd .ActiveConnection = cnn
.CommandText = "ИмяПроцедуры" .CommandType = adCmdStoredProc
For Each p In .Parameters Debug.Print p.Name
Next End With Set cmd = Nothing cnn.Close: Set cnn = Nothing
On Error Goto mis ...
DoCmd.SetWarnings False DoCmd.RunSQL ...
DoCmd.SetWarnings True ...
Exit Sub mis:
DoCmd.SetWarnings True
Пользователь лишен права на удаление тех объектов, которые нужны для нормальной работы программы, и его устраивает отсутствие подтверждений при удалении/редактировании данных через экран. Подтверждения не отключаются, если в приложении работает сам разработчик. Public Function Test() On Error Goto Rollback_Label DBEngine(0).BeginTrans
CurrentDb.Execute "Запрос1", dbFailOnError CurrentDb.Execute "Запрос2", dbFailOnError CurrentDb.Execute "Запрос3", dbFailOnError DBEngine(0).CommitTrans
Exit_Label:
Exit Function Rollback_Label:
DBEngine(0).Rollback
Resume Exit_Label End Function
спасибо в пункте 2.2 в первом примере из кодаи комментариев к нему следует, что любой запрос , в т.ч. на выборку можно запустить с помощью q.execute. Это неверно!!!! Спасибо! Спасибо! Огромное спасибо! Смог выкинуть тучу ненужного кода, и не натворить глупых ошибок в силу своей зелености в VBA. пригодилось, спасибо RunSql Это актуально для меня спасибо Как сложить два поля. Это надо делать в таблицах или в запросах.....где писать формулу??? Спасибо, как раз то, что надо... В самый раз. Спасибо Нашел, что искал - Методы отключения сообщений на подтверждение. Спасибо! полезно и для общего развития и для конкретных задач Хорошо, когда знающие растолковывают незнающим... Информация очень полезная!Попробую использовать. Огромное спасибо! Пригодилось по поводу отмены уведомления о невозможности вставки записей в таблицу из-за нарушения ключа пригодилось, спасибо Наконец понял что такое транзакции Оччень кстати
|
|||||||
Так же в этом разделе:
|
|||||||
|
|||||||
|