Создание процедур обработки событий

Теперь рассмотрим, как создавать процедуры обработки событий. Для большинства элементов управления формы, а также самой формы и отчета, стандартный набор действий следующий:

  1. Откройте форму в режиме Конструктора. Если при этом окно свойств отсутствует на экране, щелкните на кнопке Свойства (Properties) на панели инструментов.
  2. Выберите нужный элемент управления (или щелкните мышью на маленьком черном квадрате в верхнем левом углу формы, тогда выберется вся форма). В окне свойств отобразятся свойства выбранного элемента.
  3. Откройте вкладку События (Events).
  4. Выберите событие, для которого будет создаваться процедура обработки, и щелкните по нему правой кнопкой мыши.
  5. Выберите из контекстного меню пункт Построить (Build). В открывшемся диалоговом окне Построитель (Choose Builder) выберите из списка элемент Программы (Code Builder) и нажмите кнопку ОК. Откроется окно редактора VBA, в котором появятся первая и последняя строки процедуры .

Если процедура обработки выбранного события имеет аргументы, они будут также присутствовать в заголовке процедуры.
Теперь нужно ввести код процедуры между этими двумя строками. Ниже приведены некоторые примеры процедур обработки событий.
 
Синхронизация данных в связанных формах
Пример синхронизации данных в двух связанных формах с помощью процедуры обработки события Текущая запись (Current) можно увидеть в модуле формы "Поставщики" (Supplier). В форме есть кнопка Просмотр товаров (Review Products), при нажатии на которую выводится форма "Список товаров" (Product List), показывающая товары данного поставщика. Естественно, что при переходе к новой записи в форме "Поставщики" (Supplier), записи в форме "Список товаров" (Product List) тоже должны быть сменены. Процедура выглядит следующим образом:
Private Sub Form_Current()
On Error GoTo Err_Form_Current
‘ Отображение товаров текущего поставщика при открытии формы "Список ‘ товаров".
Dim strDocName As String
Dim strLinkCriteria As String
strDocName = "Список товаров"
strLinkCriteria = "[КодПоставщика] = Forms![Поставщики]![КодПоставщика] "
If IsNull(Me![Название]) Then
Exit Sub
Elself IsLoaded("Список товаров") Then
DoCmd.OpenForm strDocName, , , strLinkCriteria
End if
Exit_Form_Current:
Exit Sub
Err_Form_Current:
MsgBox Err.Description
Resume
Exit_Form_Current
End Sub
Если текущая запись в форме "Поставщики" (Supplier) пустая, т. е. добавляется новая запись, то сразу выполняется выход из процедуры. Если текущая запись отображает конкретного поставщика, то проверяется, загружена ли форма "Список товаров" (Product List). Если форма загружена, то меняется набор записей в ней. Делается это с помощью макрокоманды ОткрытьФорму(OpenForm) с соответствующим условием отбора записей. При этом на самом деле форма не открывается, просто повторно запрашивается источник данных.
 
Проверка дублирования значений первичного ключа
Обычно проверка дублирования значений первичного ключа задается на уровне таблицы, т. е. когда вы определили поле в таблице как первичный ключ, значение свойства Индексированное поле (Indexed) автоматически устанавливается равным Yes (No Duplicates) — Да (Совпадения не допускаются). Однако эта проверка выполняется только тогда, когда запись сохраняется в базе данных. Если значение ключевого поля вводится в форме пользователем, как, например, в таблице "Клиенты" (Customers), то эту проверку лучше выполнить сразу после ввода данных в это поле. Наиболее подходящим событием для этого является событие До изменения (Before Update). В форме "Клиенты" (Customers) элемент управления "КодКлиента (CustomerID) содержит идентификатор клиента. Событие До изменения (Before Update) этого поля обрабатывается с помощью макроса "Клиенты" (Customers.ValidateID), который выполняет необходимую проверку. Мы покажем, как можно обработать это событие с помощью процедуры VBA. Данная процедура может глядеть следующим образом.
Private Sub КодКлиента_ВеforeUpdate (Cancel As Integer)
Dim rs As Recordset
Set rs = CurrentDB.Openrecordset("Клиенты", dbOpenTable)
rs.Index = "PrimaryKey"
rs.Seek "=", Me!КодКлиента
if Not rs.NoMatch Then
MsgBox "Клиент с таким идентификатором уже существует в базе"
Cancel = True
End If
rs .Close
End Sub

Поиск записи со значением ключа, совпадающим с введенным значением поля "КодКлиента" (CustomerlD), выполняется с помощью метода Seek объекта Recordset. Этот метод обеспечивает быстрый поиск необходимой записи. Применить его можно только к набору записей табличного типа, поэтому при создании этого набора записей используется внутренняя константа dbOpenTable. Если такая запись найдена, свойство NoMatch объекта Recordset принимает значение False. В этом случае процедура выведет сообщение, что такой пользователь уже существует и присвоит значение True аргументу Cancel. Это позволяет отменить обновление значения элемента управления. Если значение свойства NoMatch объекта Recordset равно True, процедура закрывает набор записей (рекомендуется не забывать это делать) и завершает свою работу.