Как сделать диапазон в access?

Содержание

В простейшем случае запрос реализует выбор из одной таблицы нужных полей, записей, соответствующих заданным условиям отбора, и просмотр результатов выполнения запроса.

Конструирование запросов на выборку с условиями отбора

Рассмотрим запросы на выборку в Access на примере получения информации из таблицы ТОВАР базы данных Поставка товаров.

Задача 1. Пусть необходимо выбрать ряд характеристик товара по его наименованию.

  1. Для создания запроса в окне базы данных выберите вкладку ленты — Создание (Create) и в группе Запросы (Queries) нажмите кнопку Конструктор запросов (Query Design). Откроется пустое окно запроса на выборку в режиме конструктора — ЗапросN (QueryN) и диалоговое окно Добавление таблицы (Show Table) (рис. 4.2).
  2. В окне Добавление таблицы (Show Table) выберите таблицу ТОВАР и нажмите кнопку Добавить (Add). Выбранная таблица будет отображена в области схемы данных запроса. Закройте окно Добавление таблицы (Show Table), нажав кнопку Закрыть (Close).

В результате выполненных действий в окне конструктора запросов (рис. 4.1) в верхней панели появится схема данных запроса, которая включает выбранные для данного запроса таблицы. В данном случае одну таблицу ТОВАР. Таблица представлена списком полей. Первая строка в списке полей таблицы, отмеченная звездочкой (*), обозначает все множество полей таблицы. Нижняя панель является бланком запроса, который нужно заполнить.

как сделать диапазон в access

Кроме того, на ленте появляется и автоматически активизируется новая вкладка Работа с запросами | Конструктор (Query Tools | Design) (на рис. 4.3 представлена на часть этой вкладки), на которой цветом выделен тип созданного запроса — Выборка (Select). Таким образом, по умолчанию всегда создается запрос на выборку. Команды этой вкладки представляют инструментарий для выполнения необходимых действий при создании запроса. Эта вкладка открывается, когда в режиме конструктора создается новый запрос или редактируется существующий.

  1. Для удаления любой таблицы из схемы данных запроса установите на нее курсор мыши и нажмите клавишу . Для добавления ― нажмите кнопку Отобразить таблицу ( Show Table) в группе Настройка запроса (Query Setup) на вкладке Работа с запросами | Конструктор (Query Tools | Design) или выполните команду Добавить таблицу (Show Table) в контекстном меню, вызываемом на схеме данных запроса.
  2. В окне конструктора (рис. 4.4) последовательно перетащите из списка полей таблицы ТОВАР поля НАИМ_ТОВ, ЦЕНА, НАЛИЧИЕ_ТОВ в столбцы бланка запроса в строку Поле (Field).
  3. Для включения нужных полей из таблицы в соответствующие столбцы запроса можно воспользоваться следующими приемами:
    • в первой строке бланка запроса Поле (Field) щелчком мыши вызвать появление кнопки списка и выбрать из списка нужное поле. Список содержит поля таблиц, представленных в схеме данных запроса;
    • дважды щелкнуть на имени поля таблицы в схеме данных запроса;
    • для включения всех полей таблицы можно перетащить или дважды щелкнуть на символе * (звездочка) в списке полей таблицы в схеме данных запроса.
  4. Если вы по ошибке перетащили в бланке запроса ненужное поле, удалите его. Для этого переместите курсор в область маркировки столбца сверху, где он примет вид черной стрелки, направленной вниз, и щелкните кнопкой мыши. Столбец выделится. Нажмите клавишу или выполните команду Удалить столбцы (Delete Columns) в группе Настройка запроса (Query Setup).
  5. В строке Вывод на экран (Show) отметьте поля, иначе они не будут включены в таблицу запроса.
  6. Запишите в строке Условия отбора (Criteria) наименование товара, как показа-но в бланке запроса на рис. 4.4. Так как выражение в условии отбора не содержит оператора, то по умолчанию используется оператор =. Используемое в выражении текстовое значение вводится в двойных кавычках, которые добавляются автоматически.
  7. Выполните запрос, щелкнув на кнопке Выполнить (Run) или на кнопке Режим (View) в группе Результаты (Results). На экране появится окно запроса в режиме таблицы с записью из таблицы ТОВАР, отвечающей заданным условиям отбора.

ЗАМЕЧАНИЕ
Окно запроса в режиме таблицы аналогично окну просмотра таблицы базы данных. Через некоторые таблицы запроса может производиться изменение данных базовой таблицы, лежащей в основе запроса. Запрос, просматриваемый в режиме таблицы, в отличие от таблицы базы данных Access 2010, не имеет столбца Щелкнуть для добавления (Click to Add), предназначенного для изменения структуры таблицы. В этом режиме на вкладке ленты Главная (Home) доступны те же кнопки, что и при открытии таблицы базы данных.

  1. Если при вводе сложного наименования товара вы допустили неточность, товар не будет найден в таблице. Использование операторов шаблона — звездочка (*) и вопросительный знак (?) (стандарт ANSI-89, используемый для запросов по умолчанию) или знак процента (%) и подчеркивания (_) (ANSI-92, рекомендуемый как стандарт для SQL Server), упрощает поиск нужных строк и позволяет избежать многих ошибок. Введите вместо полного имени товара Корпус* или Корпус%. Выполните запрос. Если в поле наименования товара одно значение начинается со слова «Корпус», результат выполнения запроса будет таким же, как в предыдущем случае. После выполнения запроса введенное выражение будет дополнено оператором Like «Корпус*». Этот оператор позволяет использовать символы шаблона при поиске в текстовых полях.
  2. Если необходимо найти несколько товаров, используйте оператор In. Он позволяет выполнить проверку на равенство любому значению из списка, который задается в круглых скобках. Запишите в строке условий отбора In («Корпуc MiniTower»;»HDD Maxtor 20GB»;»FDD 3,5″). В таблице запроса будет выведено три строки. В операторе In не допускается использование символов шаблона.
  3. Сохраните запрос, щелкнув на вкладке Файл (File) и выполнив команду Сохранить (Save). В окне Сохранение (Save As) введите имя запроса Пример1. Заметим, что имя запроса не должно совпадать не только с именами имеющихся запросов, но и с именами таблиц в базе данных.
  4. Закройте текущий запрос по команде контекстного меню Закрыть (Close) или нажав кнопку окна запроса Закрыть (Close).
  5. Выполните сохраненный запрос, выделив запрос в области навигации и выбрав в контекстном меню команду Открыть (Open).
  6. Для редактирования запроса выделите его в области навигации и выполните в контекстном меню команду Конструктор (Design View).

Задача 2. Пусть надо выбрать товары, цена которых не более 1000 руб., и НДС не более 10%, а также выбрать товары, цена которых более 2500 руб. Результат должен содержать наименование товара (НАИМ_ТОВ), его цену (ЦЕНА) и НДС (СТАВКА_НДС).

  1. Создайте новый запрос в режиме конструктора, добавьте таблицу ТОВАР. В окне конструктора (рис. 4.5) последовательно перетащите из списка полей таблицы ТОВАР в бланк запроса поля НАИМ_ТОВ, ЦЕНА, СТАВКА_НДС.
  2. Запишите Условия отбора (Criteria), как показано в бланке запроса на рис. 4.5. Между условиями, записанными в одной строке, выполняется логическая операция AND. Между условиями, записанными в разных строках, выполняется логическая операция OR.
  3. Выполните запрос, щелкните на кнопке Выполнить (Run) в группе Результаты (Results). На экране появится окно запроса в режиме таблицы с записями из таблицы ТОВАР, отвечающими заданным условиям отбора.
  4. Сохраните запрос, выполнив соответствующую команду в контекстном меню запроса, которое вызывается при установке курсора на заголовок запроса. Дайте ему имя Пример2.

Задача 3. Пусть надо выбрать все накладные за заданный период. Результат должен содержать номер накладной (НОМ_НАК), код склада (КОД_СК), дату отгрузки (ДАТА_ОТГР) и общую стоимость отгруженного товара (СУММА_НАКЛ).

  1. Создайте новый запрос в режиме конструктора, добавьте таблицу НАКЛАДНАЯ. В окне конструктора последовательно перетащите из списка полей таблицы НАКЛАДНАЯ в бланк запроса все необходимые поля.
  2. Для поля ДАТА_ОТГР в строке Условия отбора (Criteria) запишите Between #11.01.2008# And #31.03.2008#. Оператор Between задает интервал дат (в ANSI-92 вместо знака # используются одинарные кавычки ‘). Кроме того, этот оператор позволяет задать интервал для числового значения.

Для закрепления смотрим видеоурок:

Вычисляемые поля в запросах Access далее.

В данном разделе мы хотим рассказать о настройке параметров среды Access. При установке Microsoft Access они получают значения, определенные по умолчанию, однако в процессе разработки приложения вы можете переустановить их таким образом, чтобы они соответствовали особенностям конкретного приложения и были удобны для его пользователей.

Большинство параметров Access настраивается с помощью диалогового окна Параметры (Options), которое отображается при выборе команды Сервис, Параметры (Tools, Options). Все эти параметры сгруппированы по своему назначению и размещены на нескольких вкладках. На некоторые из этих параметров и вкладок мы ссылались в предыдущих главах книги (например, в гл. 11).

На рис. 14.1 представлена вкладка Вид (View) окна Параметры (Options) со значениями параметров, установленными по умолчанию.

Рис. 14.1. Диалоговое окно Параметры

Эта вкладка содержит следующие группы параметров.

  • Группа параметров Отображать (Show) задает внешний вид среды Access. Флажки в этой группе позволяют скрыть или показать строку состояния (Status bar), область задач при запуске (Startup Task Pane ), ярлыки для создания новых объектов в окне База данных (New object shortcart), системные объекты и скрытые объекты. При установленном флажке окна в панели задач (Use taskbar for each document) на панели задач в нижней части экрана отображаются значки открытых объектов базы данных: форм, отчетов, запросов. Если вы не хотите загромождать панель задач, сбросьте этот флажок.
  • Группа параметров Конструктор макросов (Show in macro design) позволяет показать дополнительные столбцы в окне Конструктора макросов: имена макросов и условия (см. разд. «Создание групп макросов»гл. 11).
  • В группу Открывать объекты в окне базы данных (Click options in database window) входит очень полезный на наш взгляд переключатель, который позволяет открывать объекты из окна базы данных не только по двойному щелчку мыши, но и по одинарному — это гораздо удобнее.

Следующая вкладка Общие (General) (рис. 14.2) содержит ряд действительно общих параметров.

  • Группа Границы печатного поля (Print Margins) позволяет установить значения полей, применяемые по умолчанию при печати любого объекта базы данных. Их можно изменить для конкретного объекта с помощью команды Файл, Параметры страницы (File, Page Setup) (см. разд. «Печать таблицы»гл. 2).

Рис. 14.2. Вкладка Общие диалогового окна Параметры

  • Два флажка в группе Формат года из четырех цифр (Use four-year digit formatting) позволяют задать формат отображения дат в текущей базе данных и во всех базах данных, работающий под управлением Access. По умолчанию во всех датах показываются две цифры года.
  • Группа флажков Автозамена имен (Name AutoCorrect) обеспечивает возможность при изменении пользователем имени таблицы или поля корректно изменить все ссылки на эту таблицу или поле во всех связанных объектах — очень полезная функция, не забудьте о ней, т. к. изменить имя таблицы или поля иногда нужно, а самим исправить все ссылки на него — задача не из легких.
  • Несколько независимых флажков определяют следующие параметры:
    • указать, какое количество последних имен файлов MDB будет сохраняться и отображаться в списке в меню Файл (File);
    • выполнять или не выполнять звуковое сопровождение событий в приложении;
    • нужно ли сжимать базу данных при закрытии. Известно, что при интенсивной работе базы данных MDB-файлы имеют очень неприятную тенденцию быстро увеличиваться в размере. Вы можете установить флажок Сжимать при закрытии (Compact on close), и тогда файл будет сжиматься каждый раз при выходе из приложения;
    • флажок Удалить личные сведения из файла (Remove Personal Information), будучи установленным, позволяет прятать персональную информацию на вкладке Документ (Summery) диалогового окна свойств базы данных (меню Файл, Свойства (File, Properties)).
  • Поле Рабочий каталог (Default Database Folder) определяет папку, которая отображается по умолчанию в диалоговых окнах при открытии и сохранении файлов баз данных. Обычно это папка Мои документы (My documents) в Windows 98 или Личная (Personal) в Windows NT.
  • Поле со списком Порядок сортировки базы данных (New database sort order) имеет по умолчанию значение General (Универсальный). Это означает, что порядок сортировки в создаваемых базах данных будет определяться региональными стандартами, установленными с помощью Панели управления (Control Panel) в операционной системе компьютера, на котором была создана база данных (Windows NT или Windows 95/98). Вы можете изменить порядок сортировки, изменив значение в этом поле. Но обращаем ваше внимание, что значение этого поля определяет порядок сортировки в новой базе, т. е. оно должно быть установлено перед тем, как создается новая база. Изменение этого поля не меняет порядок сортировки в уже созданной базе данных. Для того чтобы изменить порядок сортировки в уже существующей базе данных, нужно выполнить ее сжатие.
  • На этой же вкладке есть кнопка, которая позволяет открыть диалоговое окно, в котором можно изменить цвет и вид гиперссылок (рис.14.3).

Рис. 14.3. Окно Параметры веб-документа

Вкладка Правка и поиск (Edit/Find) содержит параметры, которые используются при поиске, фильтрации и редактировании записей (рис. 14.4).

  • Группа флажков Поиск и замена по умолчанию (Default Find/Replace Behavior) определяет стратегию поиска данных в таблицах Access, которая принята по умолчанию:
    • флажок поле — целиком (Fast search) означает, что поиск будет вестись в текущем поле и на полное совпадение значения поля с образцом;
    • флажок везде — любая часть (General search) обеспечивает поиск по всем полям и поиск вхождения искомой строки в значение поля;
    • флажок поле — с начала (Start of field search) означает поиск в текущем поле на совпадение образца с первыми символами значения поля.

Рис. 14.4. Вкладка Правка и поиск диалогового окна Параметры

  • Группа флажков Подтверждение (Confirm) позволяет отключить при необходимости вывод на экран предупреждающих сообщений при изменении и удалении объектов и данных. Это эквивалент макрокоманды Установить Сообщения (SetWarnings) со значением аргумента Ложь (False). Однако будьте внимательны, т. к. забыв их потом снова включить, можно случайно испортить готовые формы, отчеты или изменить данные нежелательным образом.
  • Группа параметров Параметры фильтра по умолчанию (Filter By Form Defaults) определяет поведение системы при установке фильтра. Флажки в группе Отображать список значений (Show list of values in) позволяют определить, когда в окне задания фильтра будут появляться списки для выбора критериев. Они могут появляться в индексированных полях локальной таблицы, в неиндексированных полях локальной таблицы и в полях внешней таблицы. Специальное поле ввода позволяет указать максимальное количество элементов, которые могут содержать отображаемые списки значений. Если количество элементов в списке превышает указанный предел, такой список отображаться не будет (см. разд. «Сортировка, поиск и фильтрация данных»гл. 2).

На вкладке Клавиатура (Keyboard) расположены параметры, которые определяют возможные перемещения курсора при вводе и редактировании данных в формах (рис. 14.5). По умолчанию определены следующие перемещения:

  • переход при нажатии клавиши — следующее поле;
  • переход по клавише со стрелкой вправо — следующее поле;
  • поведение при входе в поле — выделить все поле; .
  • останов на первом/последнем поле — нет (флажок сброшен). Вы можете настроить эти параметры удобным для вас образом.

Рис. 14.5. Вкладка Клавиатура диалогового окна Параметры

На вкладке Режим таблицы (Datasheet) (рис. 14.6) находятся параметры, которые определяют вид таблиц: тип и размер шрифта, цвета символов и фона, наличие, отсутствие и цвет сетки, специальные эффекты оформления сетки, ширину столбцов. Это те параметры, которые заданы по умолчанию для всех таблиц. При желании их можно изменить для конкретной таблицы с помощью команд меню Формат (Format).

Параметры на вкладке Формы и отчеты (Forms/Reports) позволяют задать некоторые общие для форм и отчетов значения (рис. 14.7).

  • Можно задать шаблоны, которые используются по умолчанию для форм и отчетов. В качестве шаблона может быть использовано имя формы или отчета, которые оформлены в нужном стиле. Тогда все вновь создаваемые формы и отчеты будут сразу создаваться в вашем стиле, что позволит существенно сократить время разработки интерфейса. Правда, эти параметры относятся только к формам и отчетам, создаваемым без помощи мастеров.
  • Группа Выделение объектов (Selection Behavior) определяет, как выполняется операция выделения объектов в режиме Конструктора форм и отчетов. По умолчанию выделяются все объекты, которые даже частично попадают в область выделения. Если выбрать переключатель охват (Fully enclosed), то будут выделены только те объекты, которые попадут в эту область целиком. Когда элементы управления в форме или отчете расположены очень плотно, лучше использовать первый переключатель — пересечение (Partially enclosed).

Рис. 14.6. Вкладка Режим таблицы диалогового окна Параметры

Рис. 14.7. Вкладка Формы и отчеты диалогового окна Параметры

  • Флажок Всегда использовать процедуры обработки событий (Always use event procedures) позволяет избежать появления диалогового окна Построитель (Choose Builder). Обычно это окно появляется, когда пользователь назначает обработчик события в окне свойств формы, отчета или элемента управления. По умолчанию этот флажок сброшен. Если вы для обработки событий не используете макросов, можно его установить.

Следующая вкладка Страницы (Pages) содержит параметры, касающиеся страниц доступа к данным (рис. 14.8).

  • Первая группа параметров Стандартные свойства конструктора (Default Designer Properties) касается Конструктора (Designer). Вы можете задать расстояние между разделом и полями страницы, цвет текущей строки, стили для заголовков и примечаний разделов.
  • Вторая группа — Стандартные свойства БД или проекта (Default Database/Project. Properties). Вы можете установить флажок и определить папку, в которой по умолчанию будут сохраняться файлы страниц, и файл, содержащий параметры подключения страницы к базе данных (см. гл. 12).

Рис. 14.8. Вкладка Страницы диалогового окна Параметры

Вкладка Другие (Advanced) объединяет параметры, определяющие функционирование приложения в многопользовательском режиме или в режиме «клиент-сервер» (рис. 14.9). Назначение этих параметров будет объяснено ниже (см. гл. 16 и 17).

Кроме того, вы можете определить используемый по умолчанию формат файла базы данных: Access 2000 или Access 2002. По умолчанию создаваемые файлы базы данных будут иметь формат Access 2000. Это позволяет использовать их как в Access 2000, так и в Access 2002. Файлы, имеющие новый формат (Access 2002), доступны только в Access 2002.

  • Параметр Аргументы командной строки (Command-line Arguments) позволяет задать параметры командной строки, которые будут переданы приложению Microsoft Access при запуске.
  • Группа переключателей Режим открытия по умолчанию (Default open mode) позволяет задать режим доступа к открываемой базе данных — монопольный (Exclusive) или многопользовательский (Shared).

Рис. 14.9. Вкладка Другие диалогового окна Параметры

Специальная вкладка Международные (International) (рис. 14.10) позволяет задать параметры, учитывающие использование языков, в которых текст пишется не слева направо, как мы привыкли, а справа налево, и календарь не григорианский, а юлианский. Можно, например, установить эти параметры таким образом, что если в одном предложении содержатся и арабский и европейский тексты, то при перемещении по арабскому тексту курсор будет перемещаться справа налево, а при перемещении по европейскому (русскому, английскому и т. д.) тексту — слева направо. Изменение же календаря рекомендуется делать сразу, как только создан новый файл базы данных, и потом этот параметр не менять.

Параметры, связанные с проверкой орфографии и автозамены, теперь тоже вынесены на отдельную вкладку Орфография (Spelling) (рис. 14.11). Это те же параметры, которые используются функцией проверки орфографии в Microsoft Word. Вы можете вызвать эту функцию, нажав кнопку в текстовом поле таблицы, запроса или формы.

  • По умолчанию в поле Язык словаря (Dictionary Language) установлен словарь, соответствующий региональным установкам на вашем компьютере. Нужный словарь вы можете выбрать из списка в этом поле.

Рис. 14.10. Вкладка Международные диалогового окна Параметры

Рис. 14.11. Вкладка Орфография диалогового окна Параметры

  • В поле Добавлять слова в (Add Words to) можно определить файл, который будет содержать ваш собственный словарь.
  • Несколько флажков позволяют указать, какие слова нужно игнорировать в процессе проверки правописания.

Кнопка Параметры автозамены (AutoCorrect Options) открывает диалоговое окно, в котором задаются параметры автозамены (рис. 14.12).

Рис. 14.12. Диалоговое окно Автозамена

Назначение параметров Автозамены ясно из их названий. Автозамена используется в данном случае для выполнения следующих функций.

  • Автоматическое исправление опечаток при вводе данных в текстовые поля. Исправление производится путем замены слова в левом столбце списка словом в правом столбце. По умолчанию этот список достаточно длинный. Данная функция будет эффективно использоваться, если вы настроите список таким образом, чтобы он включал в себя типичные опечатки для конкретного пользователя.
  • Автоматическая замена при вводе определенных сочетаний обычных символов специальными символами.
  • Автоматическое исправление типичных ошибок ввода, связанных с неправильным нажатием клавиш и

    Данная глава посвящена основному средству программирования в Access 2002 — языку программирования Visual Basic for Applications (VBA). Язык программирования VBA является общим инструментом для всех приложений Microsoft Office, позволяющим решать любые задачи программирования, начиная от автоматизации действий конкретного пользователя и кончая разработкой полномасштабных приложений, использующих Microsoft Office в качестве среды разработки.

    Цель этой главы — дать читателю основные сведения как о самом языке, так и о тех инструментальных средствах, которые предоставляет разработчику приложений среда Access 2002.

    Поскольку Visual Basic for Applications является объектно-ориентированным языком программирования, будут описаны объектные модели, которые могут использоваться в Access 2002. Это не только собственная объектная модель Access, но и объектные модели Visual Basic for Applications и Microsoft Office, которые являются общими для всех приложений семейства. Основная работа в приложениях Access — это работа с данными, поэтому будут рассмотрены также библиотеки управления данными: DАО (Data Access Objects), ADO (ActiveX Data Objects), JRO (Jet and Replication Objects).

    Модель программирования в Access является событийно-управляемой, т. е. в процессе работы приложения возникают события, которые запускают специальные программы — обработчики событий. Большое количество разнообразных событий определено в таких объектах Access, как формы, отчеты и элементы управления в них. Мы подробно описываем эти события и последовательности их возникновения, т. к. искусство программирования в формах и отчетах включает в себя правильное определение того события, которое требуется обработать специальной программой.

    Итак, в данной главе будут рассмотрены следующие вопросы:

    • Синтаксис языка Visual Basic for Applications
    • Интегрированная среда VBA, которая включает в себя как редактор кода программных модулей, так и большое количество средств отладки этого кода
    • Объектные модели, применяемые в приложениях Access
    • События форм, отчетов и элементов управления и последовательности их возникновения
    • Примеры применения процедур обработки событий в формах и отчетах

    Следующие ниже подразделы данного раздела описывают синтаксис языка программирования VBA.

    Основными компонентами программы на VBA являются процедуры и функции, Они представляют собой фрагменты программного кода, заключенные между операторами Sub и End Sub или между операторами Function и End Function. Вот как может выглядеть процедура VBA:

     Sub  (, , ... )   End Sub

    Функция отличается от процедуры тем, что ее имя выступает также в качестве переменной и используется для возвращения значения в точку вызова функции. Вот как может выглядеть функция:

     Function  (, , ... )    =  End Function

    Для того чтобы использовать написанную вами процедуру или функцию, необходимо вызвать ее. Как же осуществляется вызов процедур и функций? Процедуру с непустым списком аргументов можно вызвать только из другой процедуры или функции, использовав ее имя со списком фактических значений аргументов в качестве одного из операторов VBA. Функцию же можно вызвать не только с помощью отдельного оператора VBA, но и поместив ее имя со списком фактических значений аргументов прямо в формулу или выражение в программе на VBA или, например, прямо в формулу в вычисляемых полях запросов, форм и отчетов Access. Процедура с пустым списком аргументов (так называемый командный макрос) может быть вызвана не только из другой процедуры или функции, но и с помощью комбинации клавиш быстрого вызова, команд раскрывающихся меню или кнопок панелей инструментов. Можно также связать такую процедуру с выполнением самых различных событий: например, с открытием формы или отчета, со щелчком мышью по кнопке в форме, с воздействием на элементы управления форм, в частности элементы управления ActiveX. Такие процедуры называют процедурами обработки событий. Понятно, что функции или процедуры, нуждающиеся в передаче им аргументов, таким способом вызвать нельзя. Подробнее о том, как создаются процедуры обработки событий, будет рассказано в разд. «Программирование в формах и отчетах» данной главы.

    Если вызываемая процедура имеет уникальное имя и находится в том же модуле, что и вызывающая процедура, то для ее вызова достаточно указать это имя и задать список фактических значений аргументов, не заключая его в скобки. Второй способ вызова процедуры состоит в использовании оператора Call. Сначала идет оператор Call, затем имя процедуры и список параметров, в этом случае обязательно заключенный в скобки. Функцию можно вызывать точно так же, как и процедуру, но гораздо чаще используется другой, специфический способ вызова функций: использованием ее имени с заключенным в скобки списком параметров в правой части оператора присваивания.

    Вот примеры вызова процедуры под именем CrossRC с передачей ей двух аргументов (константы и выражения):

     CrossRC 7, i + 2

    ИЛИ

     Call CrossRC(7, i + 2)

    А вот пример вызова двух функций — Left и Mid, и использования возвращаемого ими значения в выражении:

     yStr = Left(y, 1) & Mid(у, 2, 1)

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

    Способ передачи параметров процедуре или функции указывается при описании ее аргументов: имени аргумента может предшествовать явный описатель способа передачи. Описатель ByRef задает передачу по ссылке, a ByVal — по значению. Если же явное указание способа передачи параметра отсутствует, то по умолчанию подразумевается передача по ссылке.

    Поясним сказанное на примере. Пусть имеются следующие описания двух процедур:

     Sub Main() а = 10 b = 20 с = 30 Call Examplel(a, b, с) Call MsgBox(a) Call MsgBox(b) Call MsgBox(c) End Sub Sub Example1(x, ByVal y, ByRef z) x = x + 1 у = у + 1 z = z + 1 Call MsgBox(x) Call MsgBox(y) Call MsgBox(z) End Sub

    Вспомогательная процедура Examplel использует в качестве формальных аргументов три переменные, описанные по-разному. Далее в теле этой процедуры каждый из них увеличивается на единицу, а затем их значения выводятся на экран с помощью функции MsgBox. Основная процедура Main устанавливает значения переменных a, b и с, а затем передает их в качестве (фактических) аргументов процедуре Examplel. При этом первый аргумент передается по ссылке (действует умолчание), второй — по значению, а третий — снова по ссылке. После возврата из процедуры Examplel основная процедура также выводит на экран значения трех переменных, передававшихся в качестве аргументов. Всего на экран выводится шесть значений:

    • сначала это числа 11, 21 и 31 (все полученные значения увеличены на 1 и выводятся процедурой Examplel);
    • затем это числа 11, 20 и 31 (эти значения выводятся процедурой Main, причем переменные, переданные по ссылке, увеличились, а переменная, переданная по значению — нет).

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

    Каждая из процедур, находящихся в одном модуле, должна иметь уникальное имя, однако в проекте может содержаться несколько различных модулей. Обычно рекомендуется использовать только уникальные имена процедур в одном проекте, но допустимы и исключения. В том случае, если в проекте содержится несколько различных процедур с одним и тем же именем, необходимо для уточнения имени использовать при вызове процедуры следующий синтаксис:

    .

    Если при этом имя модуля состоит из нескольких слов, следует заключить это имя в квадратные скобки. Например, если модуль называется «Графические процедуры», а процедура — «Крестик», вызов может выглядеть следующим образом:

    .Крестик

    Допускается также использование процедур, расположенных и в других проектах. При этом может потребоваться еще один уровень уточнения имени:

    ..

    Как и в других языках программирования, в VBA для хранения временных значений, передачи параметров и проведения вычислений используются переменные. Кратко остановимся на основных особенностях описания и использования переменных в VBA.

    Обычно перед тем, как использовать переменную, производится ее объявление, т. е. вы заранее сообщаете Visual Basic, какие именно имена переменных вы будете использовать в своей программе, при этом объявляется также тип данных, для хранения которых предназначена эта переменная. В VBA, как и в обычном языке Basic, для этого используется оператор Dim. Вот синтаксис этого оператора:

     Dim  

    В VBA действуют следующие правила именования переменных. Имя не может быть длиннее 255 символов, оно должно начинаться с буквы, за которой могут следовать буквы, цифры или символ подчеркивания. Оно не должно содержать пробелов, знаков препинания или специальных символов, за исключением самого последнего знака. В конце к имени переменной может быть добавлен еще один из следующих шести специальных символов — описателей типа данных:

     ! # $ % & @

    Эти символы не являются частью имени переменной: если в программе используются одновременно имена stringl$ и stringl, то они ссылаются на одну и ту же строковую переменную. Нельзя использовать одно и то же имя переменной с разными символами определения типа данных или одновременно явное описание типа данных и не соответствующий этому типу данных специальный символ. Мы еще остановимся на этом подробнее при обсуждении типов данных.

    Кроме того, не допускается использование в качестве имен переменных ключевых слов VBA и имен стандартных объектов. Именно поэтому рекомендуется начинать имена переменных со строчной, а не с прописной буквы. Поскольку у ключевых слов VBA и имен стандартных объектов первая буква при вводе автоматически преобразуется в прописную, вы будете избавлены от риска нечаянно использовать запрещенное имя переменной.

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

    Во многих языках программирования, например в Pascal, переменные должны быть объявлены обязательно, и эти объявления используются компилятором, чтобы зарезервировать память для переменных. В то же время в VBA объявление переменных не яаляется обязательным. Как и в его предшественнике, обычном языке Basic, допускается использование неописанных переменных. Выделение памяти переменным может выполняться динамически, а тип данных, хранящихся в переменной, может определяться по последнему символу имени переменной.

    В свое время велись длительные баталии между сторонниками сокращения записи процедур за счет отказа от объявлений переменных и сторонниками обязательного описания всех переменных. Аргументы обеих сторон были достаточно серьезны — действительно, зачастую обязательное описание всех переменных требует изрядной доли занудства при методичном выписывании объявлений типа

     Dim i As Integer, j As Integer Dim x As Double

    С другой стороны, трудно что-нибудь возразить и против того, что одним из самых опасных источников труднообнаружимых ошибок в языках программирования, допускающих применение неописанных переменных, служат опечатки в написании имен переменных. Такие опечатки истолковываются транслятором как появление еще одной, новой переменной, отличной от ранее использовавшейся, и не воспринимаются как ошибки. Порой для обнаружения такой опечатки требуется время, во много раз превосходящее то, которое потребовааось бы на явное описание всех используемых в программе переменных.

    В VBA принято поистине соломоново решение — предоставить разрешение этой дилеммы самому программисту. В этом языке имеется оператор

     Option Explicit

    Если вы начнете свой модуль с этого оператора (он должен быть расположен в самом начале модуля, до того, как начнется первая процедура этого модуля), то VBA будет требовать обязательного объявления переменных в этом модуле и генерировать сообщения об ошибке всякий раз, как встретит необъявленную переменную. Кроме того, если вы строгий пуританин и хотели бы, чтобы это требование стало обязательным для всех ваших модулей без исключения, вы можете установить параметр Require Variable Declaration (Явное описание переменных) на вкладке Editor (Редактор) диалогового окна Options (Параметры) редактора VBA. (Подробнее об установке параметров редактора VBA будет рассказано в разд. «Среда программирования Access 2002» ниже в данной главе.)

    Установка этого параметра приведет к тому, что редактор Visual Basic будет автоматически добавлять оператор Option Explicit в начало каждого вновь создаваемого модуля. Учтите, однако, что этот флажок не влияет на все ранее созданные модули — если вы хотите добавить этот оператор к уже существующим модулям, вам придется проделать это вручную.

    Приведем теперь краткую сводку используемых типов данных VBA (табл. 13.1).

    Тип данных  Описание 
    Array Массив переменных, для ссылки на конкретный элемент массива используется индекс.
    Boolean Требуемая память: зависит от размеров массива Принимает одно из двух логических значений: True или False. Требуемая память: 2 байта
    Byte Число без знака от 0 до 255 Требуемая память: как нетрудно догадаться, 1 байт
    Currency Используется для произведения денежных вычислений с фиксированным количеством знаков после десятичной запятой, в тех случаях, когда важно избежать возможных ошибок округления. Диапазон возможных значений: от -922 337 203 685 477,5808 до 922 337 203 685 477,5807. Требуемая память: 8 байтов. Символ определения типа по умолчанию: @
    Date Используется для хранения дат. Диапазон возможных значений: от 1 января 0100 г. до 31 декабря 9999 г. Требуемая память: 8 байтов
    Double Числовые значения с плавающей точкой двойной точности. Диапазон возможных значений для отрицательных чисел: от -1 ,797693 13486232Е308 до -4,94065645841 247Е-324. Диапазон возможных значений для положительных чисел: от 4,94065645841 247Е-324 до 1, 7976931 3486232Е308. Требуемая память: 8 байтов. Символ определения типа по умолчанию: #
    Integer Короткие целые числовые значения. Диапазон возможных значений: от -32 768 до 32 767. Требуемая память: 2 байта. Символ определения типа по умолчанию: %
    Long Длинные целые числовые значения. Диапазон возможных значений: от -2 147 483 648 до 2 147 483 647. Требуемая память: 4 байта. Символ определения типа по умолчанию: &
    Object Используется только для хранения ссылок на объекты. Требуемая память: 4 байта
    Single Числовые значения с плавающей точкой обычной точности. Диапазон возможных значений для отрицательных чисел: от -3.402823Е38 до -1 ,401 298Е-45. Диапазон возможных значений для положительных чисел: от 1 ,401 298Е-45 до 3.402823Е38. Требуемая память: 4 байта. Символ определения типа по умолчанию: !
    String Используется для хранения строковых значений. Длина строки: от 0 до 64 Кбайтов. Требуемая память: 1 байт на символ. Символ определения типа по умолчанию: $
    Variant Может использоваться для хранения различных типов данных: даты/времени, чисел с плавающей точкой, целых чисел, строк, объектов. Требуемая память: 16 байтов, плюс 1 байт на каждый символ строковых значений. Символ определения типа по умолчанию: отсутствует
    Определяемый пользователем тип Определяемые пользователем типы данных, назначение и размер выделяемой памяти зависят от определения. Используется для описания структур данных. Позволяет хранить в переменной такого типа множество различных значений разного типа

    Таблица 13.1. Типы данных VBA

    При описании переменной указание типа данных может быть опущено. Тип переменной в таком случае определяется последним символом имени переменной: @, #, %, &, ! или $ (Currency, Double, Integer, Long, Single или String соответственно). Например, поскольку символ «$» является символом определения типа для строковых данных, то переменная под именем text$ автоматически становится переменной типа «строка символов». В дальнейшем этот специальный символ указания типа данных может быть опущен, однако постоянное присутствие в имени переменной символа определения типа будет напоминать о том, к какому типу данных относится эта переменная, что поможет избежать ошибок использования несовместных типов данных.

    Если же последний символ не является ни одним из вышеперечисленных и явное указание типа тоже не используется, в этом случае переменной будет назначен по умолчанию тип данных Variant, который позволяет хранить в ней данные любого типа.

    Учтите также, что нельзя использовать в одной и той же процедуре имена переменных, отличающиеся друг от друга только специальным символом определения типа в конце переменной. Например, не допускается одновременное использование переменных var$ и var%. He допускается и явное объявление переменной, уже содержащей символ определения типа в конце имени, с помощью описателя As (даже если такое определение не противоречит обычному применению символа определения типа). Так, например, вы получите сообщение об ошибке, попытавшись ввести любое из следующих определений:

     Dim var1% As String Dim var2% As Integer

    Для определения типа данных аргументов процедуры или функции используется описание типа данных непосредственно в заглавной строке процедуры или функции. Например, следующая заглавная строка процедуры описывает ее параметры как переменные строкового типа:

     Sub SplitStr(str1 As String, str2 As String, str3 As String)

    Определение типа данных возвращаемого функцией значения завершает заглавную строку функции, например:

     Function FindSplitSpace (strl As String) As Integer

    описывает возвращаемое функцией значение как переменную короткого целого типа.

    Чтобы программа работала быстрее и занимала меньше памяти, рекомендуется использовать, когда это возможно, конкретные типы переменных, а не универсальный тип Variant. На обработку переменных типа Variant требуется не только дополнительная память (сравните размеры, приведенные в табл. 13.1), но и дополнительное время: требуется выяснить, к какому конкретному типу данных принадлежит такая переменная в момент обработки, а также при необходимости выполнить преобразование данных к нужному типу. Может показаться, что в таком случае лучше вообще не использовать подобные переменные. Это не так. Часто подобные переменные просто необходимы: например, в том случае, когда вы точно не уверены, какие именно данные будут присвоены переменной.

    Приведем здесь лишь один пример. Если вы хотите, чтобы пользователь программы ввел некоторое целое значение, необходимое для дальнейшей работы программы, и описали для этого переменную целого типа, то рекомендуется использовать для ввода данных промежуточную переменную, описанную как Variant, а затем выполнить присваивание введенного значения нужной переменной (или же описать переменную, в которую вы хотите поместить это значение как Variant, несмотря на то, что ввести предполагается именно целое число). Дело в том, что пользователь может ошибиться и ввести, например, вещественное число или вообще нечаянно нажать не на ту клавишу и ввести строковое значение. В таком случае при присваивании введенного значения переменной целого типа произойдет ошибка во время выполнения программы. Если же переменная для ввода будет объявлена как Variant, ничего страшного не случится: введенное значение будет благополучно присвоено этой переменной, а вы получите возможность проанализировать введенное значение и попросить пользователя повторить ввод, если введенное им значение не отвечает нужным условиям.

    И в завершение этого раздела обсудим использование именованных констант. Для их описания применяется оператор Const, схожий с оператором описания переменных Dim. Вот синтаксис этого оператора:

     Const   = 

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

     Const maxLen% = 30

    Как и переменные, константы могут содержать значения различных типов данных, но при этом они не меняют своих значений во время выполнения программы.

    Совет

    Если вы собираетесь использовать в вашей программе какие-либо константы, то рекомендуется дать этим константам осмысленные имена и описать их в самом начале модуля, а затем использовать всюду только именованные константы. Это не только делает программу понятнее, но и проще в сопровождении и отладке. Зачастую значение той или иной константы требуется изменить (хотя бы на время отладки), и тогда достаточно поменять лишь одно значение в описании именованной константы. Если же непосредственное значение использовалось прямо в тексте кода программы, то изменить все вхождения этого значения намного сложнее.

    Кроме описываемых пользователем констант, существуют еще предопределенные встроенные константы, которые включаются в тексты программ без предварительного описания. Сведения о предопределенных встроенных константах, используемых для различных объектов приложений Microsoft Office и Visual Basic, можно найти в справке—в разделах описания свойств объектов (реже — в разделах описания методов). При именовании встроенных констант используется стандартное соглашение, позволяющее определить, к объектам какого приложения относится эта константа. Например, встроенные константы, относящиеся к объектам Access, начинаются с префикса ас, относящиеся к объектам Excel — с префикса xl, относящиеся к объектам Word — с префикса wd, а относящиеся к объектам VBA — с префикса vb. Например, в команде

     DoCmd.OpenForm "Orders", acNormal, , stLinkCriteria

    используется встроенная константа Access acNormal.

    Кроме обычных переменных, в Visual Basic часто встречаются неременные, представляющие собой ссылку на объект. Оказывается, зачастую использование переменных для ссылок на объекты позволяет не только сократить и упростить текст программы, но и существенно ускорить ее работу.

    Применение переменной-объекта отличается от использования обычных переменных: нужно не только объявить такую переменную, но и назначить ей соответствующий объект с помощью специального оператора Set. Вот синтаксис этого объявления и назначения:

     Dim  As Object Set  = 

    Иногда при объявлении такой переменной удобно заранее указать конкретный тип объекта — можно использовать любой конкретный объект из объектной модели Office. Приведем пример упомянутого объявления и назначения:

     Dim MyBase As Database Set MyBase = CurrentDb( )

    После такого объявления и назначения вы можете применять переменную MyBase для обращения к текущей открытой базе данных. Мало того, что такая ссылка короче: она еще и быстрее обрабатывается, и программа, использующая переменные для прямых ссылок на объекты вместо сложных иерархических ссылок, включающих в себя большое количество операторов уточнения (точек), работает быстрее. Время, которое уходит у программы на разрешение ссылок, пропорционально количеству операторов уточнения, которые приходится обрабатывать программе.

    Совет

    Еще одно замечание о быстродействии. Если вы всерьез озабочены быстродействием вашей программы, то рекомендуется при описании переменных типа «объект» использовать конкретные объекты модели Office, а не универсальное описание Object. В оправдание можно привести примерно те же соображения, что и по поводу применения универсального типа Variant при описании обычных переменных: обработка такого типа переменных требует дополнительного времени и места в памяти.

    Объектная переменная будет указывать на объект до тех пор, пока мы другим оператором Set не присвоим ей ссылку на другой объект этого же типа или не присвоим ей значение Nothing, что означает, что переменная не содержит никакой ссылки. Например:

     Set txt = Nothing

    После такого действия переменная продолжает существовать, хотя и не ссылается ни на какой объект. Другим оператором Set ей можно снова присвоить ссылку на объект.

    Замечание

    Обратите внимание, что объектные переменные, в отличие от обычных переменных, содержащих значения, включают в себя только ссылки на объекты, а не сами объекты или их копии.

    Массив это переменная, в которой хранится одновременно несколько значений одинакового типа. Формальное определение массива таково: он представляет собой совокупность однотипных индексированных переменных.

    Количество используемых индексов массива также может быть различным. Чаще всего применяются массивы с одним или двумя индексами, реже — с тремя, еще большее количество индексов встречается крайне редко. В VBA допускается использовать до 60 индексов. О количестве индексов массива обычно говорят как о размерности массива. Массивы с одним индексом называют одномерным, с двумя — двумерными и т. д. Массивы с большим количеством измерений могут занимать очень большие объемы памяти, так что следует быть осторожным в их применении.

    Прежде чем использовать массив, нужно обязательно объявить его с помощью оператора Dim и указать при этом тип хранящихся в массиве значений. Все значения в массиве обязаны принадлежать к одному типу данных. Это ограничение на практике можно обойти, использовав при объявлении массива тип Variant — в этом случае элементы массива смогут принимать значения разных типов. Вот синтаксис оператора объявления массива:

     Dim  (, , ...) As 

    где указанные в скобках величины , и т.д. задают размеры массива — количество индексов и максимально допустимое значение для каждого. конкретного индекса. При этом индексирование элементов массива по умолчанию начинается с нуля. Так, объявление

     Dim Array1 (9) As Integer

    определяет одномерный массив из 10 элементов, являющихся переменными целого типа, а объявление

     Dim Array2 (4, 9) As Variant

    определяет двумерный массив из пятидесяти (5×10) элементов, являющихся переменными универсального типа variant.

    ЗамечаниеВ качестве стандартного значения нижней границы для допустимых значений индекса может использоваться не только ноль. Можно изменить это стандартное значение с помощью оператора Option Base. Например, если поместить в начало вашего модуля оператор Option Base 1, то индексирование элементов массивов по умолчанию будет начинаться не с нуля, а с единицы.

    При объявлении массива можно указать не только верхнюю границу индекса, но и его нижнюю границу, т. е. явно задать диапазон изменения конкретного индекса массива, причем нижняя граница может быть любым целым числом, необязательно неотрицательным. Вот синтаксис такого определения:

     Dim  ( То , ...) As 

    Например, если вы собираетесь работать с массивом метеорологических данных, представляющих собой средние дневные температуры за последние две недели, то может оказаться весьма удобным дать следующее определение массива:

     Dim Temperature (-14 То 0) As Single

    При этом, например, Temperature (-2) будет соответствовать позавчерашней температуре, а для определения нужного индекса для интересующего вас дня будет достаточно использовать разность дат.

    В приведенных выше примерах речь шла о массивах фиксированного размера, количество элементов в которых явно указано во время описания массива в операторе Dim. Такие массивы называются статическими. В VBA допускается использование и динамических массивов, размеры которых при описании не фиксируются. Определение размера динамического массива может быть сделано непосредственно во время выполнения программы.

    При определении динамического массива в операторе Dim после имени массива стоят лишь пустые скобки и описание типа переменных. Количество индексов и диапазон их изменения не задаются. Однако перед тем, как использовать массив, нужно выполнить оператор ReDim, который задаст размерность и диапазоны изменения индексов динамического массива.

    Синтаксис объявления и определения размеров динамического массива таков:

     Dim  ( ) As  ReDim  (, , . . . )

    Вот как может выглядеть объявление, определение размеров и использование динамического массива, а затем последующее изменение размерности и размеров этого же массива:

     Dim dArray ( ) As Variant ReDim dArray ( 1 , 2 ) dArray (0, 0) = 2 dArray (0, 1) = 3 k = dArray (0, 0) + dArray (0, 1) ReDim dArray (k) dArray (0) = "Строка1"

    В этом примере массив dArray сначала определяется как двумерный массив из шести элементов, а затем переопределяется как одномерный массив, причем верхняя граница индекса задается значением переменной k.

    Замечание

    Чтобы определить текущую нижнюю или верхнюю границу массива, можно использовать функции LBound и Ubound соответственно.

    Учтите, что по умолчанию при изменении размеров массива ему заново выделяется память и текущие значения его элементов теряются. Чтобы не потерять текущие значения массива при изменении его размеров, используется ключевое слово Preserve. Например, чтобы увеличить размер массива dArray на один элемент, не потеряв значений существующих элементов, можно поступить следующим образом:

    ReDim Preserve dArray (UBound( dArray) + 1)

    Все процедуры, функции, переменные и константы в VBA имеют свою область действия. Это означает, что они могут использоваться только в определенном месте программного кода — именно там, где они описаны. Например, если переменная А описана с помощью оператора Dim в теле процедуры с именем Prod, именно эта процедура и является ее областью действия. Таким образом, если имеется другая процедура Ргос2, вы не можете использовать в ней эту же переменную. Если вы попытаетесь сделать это, то либо получите сообщение об ошибке из-за использования неописанной переменной (в том случае, если используется упоминавшийся выше оператор Option Explicit) либо просто получите другую переменную — с тем же самым именем, но никак не связанную с одноименной переменной из первой процедуры.

    Начнем с определения области действия переменных. То, в каком месте программы и как именно описана переменная, определяет область ее действия и то, как долго она «живет» в памяти и сохраняет присвоенное ей значение. Имеются три различных уровня при определении области действия переменных:

    • уровень процедуры;
    • уровень модуля;
    • уровень проекта.

    Чтобы определить переменную на уровне процедуры, ее описание помещается в тело данной процедуры, и тогда это будет локальная переменная этой процедуры.

    Чтобы определить процедуру на уровне модуля и сделать её тем самым доступной для совместного применения во всех процедурах данного модуля, следует поместить ее описание в секции объявлений модуля — перед текстом каких-либо процедур или функций. При этом может использоваться и явное описание области действия: ключевое слово Dim в этом случае заменяется на ключевое слово Private. Нет никакой разницы в том, какой из этих описателей вы используете.

    Наконец, чтобы описать переменную на уровне проекта, необходимо расположить ее описание в секции объявлений одного из модулей проекта и при этом обязательно должно использоваться ключевое слово Public. Описанные таким образом переменные могут применяться в любом модуле проекта.

    Замечание

    Все вышесказанное относится и к описанию и определению области действия констант и массивов.

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

    Тем не менее статистическая переменная не может быть использована в других процедурах. Изменяется лишь время ее жизни, но не область действия. Если произойдет повторный вызов той же самой процедуры, в которой была описана статистическая переменная, то эта переменная сохранит свое прежнее значение, которое она имела в момент завершения работы этой процедуры при предыдущем вызове. Обыкновенные, не статистические, переменные всякий раз инициализируются заново и получают при входе в процедуру пустые значения.

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

    Если требуется описать процедуру, используемую только на уровне модуля, то для этого применяется ключевое слово Private. Учтите, что такое описание не только сужает область действия для процедуры, но и запрещает ее использование как самостоятельной процедуры — ее можно вызвать только из другой процедуры.

    Наконец, при описании процедур или функций может использоваться и ключевое слово static. Оно никак не влияет на область действия процедуры, но воздействует на все переменные, описанные внутри этой процедуры или функции. В этом случае все локальные переменные получают статус Static и тем самым остаются в памяти после завершения такой процедуры и при повторном ее вызове сохраняют свои прежние значения.

    Рассмотрим пример модуля, начинающегося следующим образом:

    Public Al As String Private A2 As Integer Dim A3 As Single Sub Prod () Dim A4 As Integer Static A5 As Integer Al = "Текстовая строка 1" A2= 2 A3 = 3.14 A4 = A4 + 4 A5 = A5 + 5 MsgBox A4 MsgBox A5 End Sub Sub Proc2 () Procl MsgBox Al MsgBox A2 MsgBox A3 MsgBox A4 MsgBox A5 Procl End Sub

    В этом примере переменная А1 определена на уровне всего проекта (использовано ключевое слово Public), переменные А2 и A3 определены на уровне модуля, переменная А4 — только на уровне процедуры Prod, а переменная А5 хотя и определена в теле процедуры Procl, но описана как статическая переменная.

    При вызове процедуры Рrос2 произойдет следующее: из этой процедуры будет в свою очередь вызвана процедура Procl, которая присвоит значения всем пяти переменным А1, А2, A3, А4 и А5, а затем покажет текущие значения переменных А4 и А5 в диалоговом окне.

    После завершения этой процедуры будут выведены текущие значения переменных А1—А5 из процедуры Ргос2. При этом окажется, что переменные А1—A3 сохранили свои значения, поскольку они описаны на уровне модуля, а переменные А4 и А5 принимают пустые значения, поскольку областью действия этих переменных являются процедуры, в которых они используются. Никакие изменения этих переменных внутри одной из процедур не имеют отношения к аналогичным переменным из другой процедуры — на самом деле это разные переменные, просто для них используются совпадающие имена.

    Затем происходит еще один вызов процедуры Procl, и она вновь начинает изменять и выводить на экран значения переменных А4 и А5. При этом переменная А4 вновь получит значение 4, поскольку при новом вызове процедуры для этой переменной будет заново выделена память и она будет инициализирована пустым значением. В отличие от А4, переменная А5, описанная как статическая переменная, сохранит свое прежнее значение от предыдущего вызова этой процедуры, в результате ее значение при повторном вызове окажется равным 10.

    Как и во всех других языках программирования, в VBA имеются различные управляющие конструкции, позволяющие изменять порядок выполнения программы. Если управляющие конструкции не используются, происходит последовательное выполнение операторов языка программирования, начиная с самого первого и кончая последним. Хотя в некоторых самых простых случаях этого и бывает достаточно, обычно все-таки требуется изменять порядок исполнения операторов при выполнении определенных условий, либо пропуская выполнение некоторых операторов, либо, наоборот, многократно повторяя их. Оказывается, для реализации любых алгоритмов достаточно иметь только два вида конструкций управления: ветвления и циклы.

    Управляющие конструкции ветвления позволяют проверить некоторое условие и, в зависимости от результатов этой проверки, выполнить ту или иную группу операторов. Для организации ветвлений в VBA используются различные формы оператора ветвления If и-оператор выбора Select Case.

    Простейшая, краткая форма оператора if используется для проверки одного условия, а затем либо выполнения, либо пропуска одного оператора или блока из не скольких операторов. Краткая форма оператора ветвления if может иметь как однострочную, так и блочную форму. В одну строку краткая форма If может быть записана так:

     If  Then 

    В блочной форме краткое ветвление выглядит следующим образом:

     If  Then   End If

    В качестве условия можно использовать логическое выражение, возвращающее значение True или False, или любое арифметическое выражение. Если применяется арифметическое выражение, то нулевое значение этого выражения эквивалентно логическому значению False, а любое ненулевое выражение эквивалентно True. В том случае, когда условие возвращает значение False, оператор или блок операторов, заключенных между ключевыми словами Then и End if и составляющих тело краткого оператора ветвления, не будет выполняться.

    Замечание

    Обратите внимание, что при записи краткого оператора ветвления в одну строку ключевые слова End I f не используются.

    Полная форма оператора if используется в тех случаях, когда имеются два различных блока операторов и по результатам проверки условия нужно выполнить один из них. Такая форма if не может записываться в одну строку и всегда имеет блочную форму записи:

     If  Then  Else  End If

    Если условие истинно, выполняется первый блок операторов, заключенный между ключевыми словами Then и Else, а в противном случае — второй блок, заключенный между ключевыми словами Else и End If.

    Совет

    Для того чтобы текст вашей процедуры был понятным и удобным для восприятия, рекомендуется делать отступы для групп операторов так, как это указано при описании их синтаксиса. В VBA предусмотрено удобное средство изменения отступов — нажатие на клавишу увеличивает отступ вправо, нажатие комбинации клавиш + уменьшает этот отступ.

    Иногда приходится делать выбор одного действия из целой группы действий на основе проверки нескольких различных условий. Для этого можно использовать цепочку операторов ветвления If. . .Then. . . Elseif:

     If  Then  Elseif  Then  Elseif  Then  Elseif  Then  Else  End If

    Такие цепочки операторов If.. .Then. . .Elseif обладают большой гибкостью и позволяют решить все проблемы, однако если выбор одной из нескольких возможностей все время основан на различных значениях одного и того же выражения, гораздо удобнее использовать специально предназначенный для этого оператор выбора Select Case, имеющий следующий синтаксис:

     Select Case  Case   Case   Case   Case Else  End Select

    Проверяемое выражение вычисляется в начале работы оператора Select Case. Это выражение может возвращать значение любого типа, например логическое, числовое или строковое.

    Список выражений представляет собой одно или несколько выражений, разделенных запятой. При выполнении оператора проверяется, соответствует ли хотя бы один из элементов этого списка проверяемому выражению.

    Эти элементы списка выражений могут иметь одну из следующих форм:

    • в данном случае проверяется, совпадает ли значение проверяемого выражения с этим выражением;
    • То в этом случае проверяется, находится ли значение проверяемого выражения в указанном диапазоне значений;
    • Is в третьем случае проверяемое выражение сравнивается с указанным значением с помощью заданного логического оператора; например, условие is >= 10 считается выполненным, если проверяемое значение не меньше 10.

    Если хотя бы один из элементов списка соответствует проверяемому выражению, то выполняется соответствующая группа операторов и на этом выполнение оператора Select Case заканчивается, а остальные списки выражений не проверяются, т. е. отыскивается только первый подходящий элемент списков выражений. Если же ни один из элементов всех этих списков не соответствует значению проверяемого выражения, выполняются операторы группы Else, если таковая присутствует.

    В VBA имеется богатый выбор средств организации циклов, которые можно разделить на две основные группы — циклы с условием Do… Loop и циклы с перечислением For…Next.

    Циклы типа Do … Loop используются в тех случаях, когда заранее неизвестно, сколько раз должно быть повторено выполнение блока операторов, составляющего тело цикла. Такой цикл продолжает свою работу до тех пор, пока не будет выполнено определенное условие. Существуют четыре вида циклов Do…Loop, которые различаются типом проверяемого условия и временем выполнения этой проверки. В табл. 13.2 приводится синтаксис этих четырех конструкций.

    Конструкция  Описание 
    Do While Loop Условие проверяется до того, как выполняется группа операторов, образующих тело цикла. Цикл продолжает свою работу, пока это условие выполняется (то есть имеет значение True), иными словами, в этой конструкции указывается условие продолжения работы цикла
    Do Until Loop Условие проверяется до того, как выполняется группа операторов, образующих тело цикла. Цикл продолжает свою работу, если это условие еще не выполнено, и прекращает работу, когда оно станет истинным, иными словами, в этой конструкции указывается условие прекращения работы цикла
    Do Loop Until Условие проверяется после того, как операторы, составляющие тело цикла, будут выполнены хотя бы один раз. Цикл продолжает свою работу, если это условие еще не выполнено, а когда оно станет истинным, цикл прекращает работу, иными словами, в этой конструкции указывается условие прекращения работы цикла
    Do Loop While Условие проверяется после того, как операторы, составляющие тело цикла, будут выполнены хотя бы один раз. Цикл продолжает свою работу, пока это условие остается истинным, иными словами, в этой конструкции указывается условие продолжения работы цикла

    Таблица 13.2. Синтаксис операторов цикла Do

    Имеется также две разновидности оператора цикла с перечислением For. . .Next. Очень часто при обработке массивов, а также в тех случаях, когда требуется повторить выполнение некоторой группы операторов заданное число раз, используется цикл For. . .Next со счетчиком. В отличие от циклов Do. . .Loop, данный тип цикла использует специальную переменную, называемую счетчиком, значение которой увеличивается или уменьшается при каждом выполнении тела цикла на определенную величину. Когда значение этой переменной достигает заданного значения, выполнение цикла заканчивается.

    Синтаксис этого вида цикла выглядит, следующим образом (в квадратные скобки заключены необязательные элементы синтаксической конструкции):

     For  =  То    Next []

    Несколько пояснений к приведенному описанию:

    • — может быть как положительным, так и отрицательным числом. Если использовать отрицательное приращение, то конечное значение должно быть меньше либо равно начальному значению для того, чтобы тело цикла выполнилось хотя бы один раз;
    • после завершения работы цикла For. . .Next переменная, которая использовалась в качестве счетчика, получает значение, обязательно превосходящее конечное значение в том случае, если приращение положительно, и строго меньшее конечного значения, если приращение отрицательно;
    • если начальное и конечное значения совпадают, тело цикла выполняется лишь один раз.

    Рассмотрим еще одну разновидность цикла For. . .Next, часто использующуюся в VBA при обработке объектов, составляющих массив или семейство однородных объектов. В этой разновидности цикла счетчик отсутствует, а тело цикла выполняется для каждого элемента массива или семейства объектов. Вот синтаксис такого цикла:

     For Each  In   Next []

    где:

    — это переменная, используемая для ссылки на элементы семейства объектов;

    — это имя массива или семейства.

    Приведем пример использования подобного цикла. Следующая процедура предназначается для выдачи на печать списка всех полей для всех таблиц текущей открытой базы данных:

     Public Sub EnumerateAllFields() Dim MyBase As Database Dim tdf As TableDef, fid As Field Set MyBase = CurrentDb() For Each tdf In MyBase.TableDefs Debug.Print "Таблица: " & tdf.Name For Each fid In tdf.Fields Debug.Print " Поле: "& fid.Name Next fid Next tdf Set MyBase = Nothing End Sub

    Итак, в операторах Dim мы объявили переменную MyBase как объект «база данных DАО», переменные tdf и fid — как определение таблицы и поле таблицы, соответственно. Оператор Set назначает переменной MyBase текущую открытую базу данных. Далее для каждого определения таблицы выполняется вывод на печать названия таблицы, а затем вложенный цикл такого же типа печатает названия всех ее полей.

    Приведем еще один пример использования подобного оператора цикла For Each. . .Next для обработки всех элементов многомерного массива. Пусть у нас имеется трехмерный числовой массив из 1000 элементов (размерами 10x10x10), который мы хотим заполнить случайными вещественными числами в диапазоне от 0 до 1. Если бы мы применяли обычные циклы For. . .Next со счетчиками, используя счетчики в качестве индексов элементов массива, то для решения этой задачи потребовалось бы написать три вложенных цикла For. . . Next:

     Dim tArray{9, 9, 9) As Single Dim i%, j%, k% Randomize For i=0 To 9 For j=0 To 9 For k=0 To 9 tArray(i, j, k) = Rnd() Next k Next j Next i

    На самом же деле достаточно всего одного цикла, если вместо циклов со счетчиками воспользоваться циклом For Each . . . Next:

     Dim tArray(9, 9, 9) As Single Dim elem As Variant Randomize For Each elem In tArray elem = Rnd() Next

    Еще раз порекомендуем использовать отступы при записи циклов, так же, как и при записи операторов ветвления.

    Обычно выполнение процедуры заканчивается после выполнения ее последнего оператора, а выполнение цикла — после нескольких выполнений тела цикла, когда достигнуто условие завершения его работы. Однако в некоторых случаях бывает нужно прекратить выполнение процедуры или цикла досрочно, избежав выполнения лишних операторов процедуры или лишних повторений цикла. Например, если при выполнении процедуры произошла ошибка, которая делает продолжение ее работы бессмысленным, можно выполнить команду немедленного выхода из процедуры. Другой пример: если цикл For. . .Next используется для поиска нужного значения в массиве, то после того, как нужный элемент массива найден, нет смысла продолжать дальнейший перебор элементов массива. Досрочный выход из управляющей конструкции можно осуществить с помощью одного из операторов Exit. Для досрочного выхода из циклов Do. . .Loop используется оператор Exit Do, a для выхода из циклов For — оператор Exit For. Для досрочного выхода из процедур и функций применяются операторы Exit Sub и Exit Function соответственно. Следует, однако, отметить, что хотя использование оператора Exit может быть вполне оправданным, необходимо избегать излишнего употребления этого оператора, прибегая к нему только в крайних случаях. Излишне частое употребление данного оператора затрудняет понимание написанного текста программы и его отладку.

    Например, в следующем цикле поиска For. . .Next используется оператор Exit For:

     ub = Ubound(dArray) fFound = False For i=LBound(dArray) To ub If dArray(i) = searchValue Then fFound = True Exit For End If Next

    Однако такого применения оператора Exit вполне можно избежать. Вот пример подобного же цикла поиска, но без использования Exit:

     i = Lbound(dArray) ub = Ubound(dArray) fFound = False Do If dArray(i) = searchValue Then fFound = True i = i + 1 Loop Until (i > ub) Or fFound

    На этом мы заканчиваем краткое знакомство с основными понятиями языка VBA. Если читателю требуется более подробное и строгое изложение синтаксиса языка, то лучше обратиться к специальным книгам, посвященным этому языку. В других разделах настоящей главы, а также в последующих главах мы покажем, как VBA используется при разработке приложений, и познакомим с теми его особенностями, которые специфичны именно для Access. Это касается в первую очередь объектов Access и объектов данных.

    Язык Visual Basic for Applications является объектно-ориентированным языком программирования. Стандартные объекты Visual Basic представляют собой основное средство манипуляции с данными Microsoft Access и других приложений семейства Microsoft Office. Знание технологии объектно-ориентированного программирования и состава объектных моделей Visual Basic позволяет разрабатывать профессиональные приложения, выполняющие всю необходимую обработку данных.

    Начнем с определения основных понятий, которые потребуются для понимания работы с объектами в языке VBA. Такими понятиями в данном случае будут:

    • объект
    • семейство
    • метод
    • класс
    • свойство
    • событие
    • объектная модель

    Объект — это абстракция, с которой мы оперируем в объектно-ориентированных г языках программирования. Объект обладает собственными характерными признаками, отличающими его от других объектов, и имеет свое поведение. Примерами объектов Access являются уже известные вам таблицы, формы, отчеты, запросы.

    Класс представляет собой описание совокупности однотипных объектов. Класс можно сравнить с типом данных, где переменной такого специфического типа является объект. В этом случае говорят, что объект представляет собой экземпляр определенного класса.

    Каждый объект имеет свойства и методы, которые различны у разных классов объектов, но применяются они одинаково, в чем вы скоро убедитесь на примерах использования объектов в процедурах VBA.

    Свойством называют отдельную характеристику объекта или класса. Например, знакомые уже вам свойства формы являются свойствами объекта Form. Свойство .объекта может принимать определенное значение. Например, свойство Вывод на экран (Visible) может принимать значение True или False, в зависимости от чего форма будет появляться или исчезать с экрана.

    Метод представляет собой процедуру (или функцию) объекта или класса. Совокупность методов объекта определяет его «поведение». Например, объект Form имеет метод Refresh, вызов которого позволяет обновить данные в форме Access.

    Объект может реагировать на определенные события, происходящие в процессе работы приложения и влияющие на объект. Совокупность событий, на которые объект способен реагировать, определяется создателем класса, экземпляром которого является данный объект. Например, набор событий, которые определены для формы Access, мы видим на вкладке События (Event) диалогового окна Свойства (Properties). Реакцией объекта на произошедшее событие может быть выполнение объектом некоторой специальной процедуры, которая называется процедурой обработки события. Любому событию объекта может быть назначена некоторая процедура его обработки.

    Упорядоченный набор однотипных объектов — экземпляров одного класса называется семейством. Семейство тоже является объектом. Одним из методов этого объекта является процедура, возвращающая ссылку на конкретный объект в семействе. Одним из свойств семейства является число объектов, хранящихся в нем. Например, совокупность элементов управления в форме образует семейство Controls.

    Объекты и семейства сгруппированы в виде иерархических структур, которые называются объектными моделями. В VBA определены специальные объектные модели для каждого компонента семейства Microsoft Office и объектные модели, общие для всех компонентов Microsoft Office. Объектные модели VBA можно изучать, используя справочную систему и окно просмотра объектов. Окно просмотра объектов представляет собой специальное средство редактора Visual Basic, позволяющее просматривать содержимое библиотек объектов и производить поиск справочной информации. (Описание окна просмотра объектов можно найти в данной главе, в разд. «Среда программирования Access 2002».)

    Управление приложениями семейства Microsoft Office 2002 осуществляется интерактивно — с помощью интерфейса пользователя или программно — с помощью объектных моделей. Каждый из компонентов Microsoft Office предоставляет свои объектные модели в виде одноименной библиотеки объектов (файл с расширением olb), которая может быть использована в других приложениях. Microsoft Access 2002, как компонент Microsoft Office, имеет такую библиотеку — Microsoft Access 10.0 Object Library. Доступ и управление данными в Microsoft Access могут осуществляться с помощью объектных моделей, реализованных в нескольких библиотеках:

    • библиотека объектов Microsoft Access (Microsoft Access 10.0 Object Library);
    • библиотека объектов доступа к данным (Microsoft DAO 3.6 Object Library);
    • библиотека объектов ActiveX (Microsoft ActiveX Data Objects 2.6);
    • расширения ADO для поддержки DDL и защиты информации (Microsoft ADO Extensions 2.6 for DDL and Security);
    • библиотека объектов Microsoft Jet и репликации (Microsoft Jet and Replication Objects 2.6).

    Кроме этого, в приложениях Access обычно используются:

    • библиотека объектов Visual Basic (Microsoft Visual Basic for Applications);
    • библиотека объектов Microsoft Office (Microsoft Office 10.0 Object Library). Две эти библиотеки являются общими для всех приложений Microsoft Office.

    Кроме перечисленных библиотек объектов, при написании программ в приложениях Access могут использоваться библиотеки, предоставляемые другими приложениями Microsoft Office, например Microsoft Excel 10.0 Object Library или Microsoft Word 10.0 Object Library. В этом случае приложение Access выступает в качестве клиентского приложения Automation, обеспечивая совместную работу нескольких компонентов Microsoft Office. (Об использовании Automation для интеграции приложений Microsoft Office см. гл. 15.)

    Объектная модель Microsoft Access 2002 реализована в виде набора объектов, собранных в библиотеке Access. Основным элементом в иерархии объектов библиотеки Access является объект Application. Он содержит ссылки на все объекты и семейства объектов Microsoft Access. Каждый объект из библиотеки Access имеет в качестве свойства объект Application (в том числе и сам объект Application имеет свойство Application), который ссылается на активное приложение Microsoft Access.

    Иерархия объектов и семейств объектов Microsoft Access 2002 представлена на рис. 13.1 — 13.3. Названия объектов, являющихся элементами семейств, приведены в скобках. Новые объекты, появившиеся в Microsoft Access 2002, отмечены звездочкой. Иерархия объектов, представленная на рисунках, образована следующим образом:

    • каждый объект может содержать набор свойств, часть из которых может являться ссылками на другие объекты;
    • в каждый новый уровень иерархии входят объекты, ссылки на которые хранятся в объектах, расположенных на предыдущем уровне иерархии.

    Если свойство объекта представляет собой ссылку на объект, определенный в другой библиотеке (не в библиотеке Access), для него приводится название этой библиотеки.

    Рис. 13.1. Первый уровень иерархии объектной модели Microsoft Access 2002

    Рис. 13.2. Второй уровень иерархии объектной модели Microsoft Access 2002 — объекты баз данных

    Рис. 13.3. Второй уровень иерархии объектной модели Microsoft Access 2002 — объекты для работы с базой данных и проектом

    Глядя на схемы объектной модели, можно определить какие объекты описывают приложение, как они связаны между собой и как составить ссылку для доступа к конкретному объекту.

    Табл. 13.3 содержит описание объектов Microsoft Access 2002, определенных в библиотеке Access, если не указана другая библиотека объектов.

    Объект Тип Описание
    Application Объект Ссылается на активное приложение Microsoft Access. Используется для управления приложением. Этот объект является» СОМ-компонентом и может быть использован другим приложением, которое поддерживает Automation
    Forms Семейство Содержит объекты Form, соответствующие всем открытым в данный момент формам в базе данных Access
    Form Объект Ссылается на конкретную форму Access, описывает свойства формы, элементы управления и модуль, содержащий процедуры формы. Каждый объект Form содержит в качестве свойства по умолчанию семейство Controls, представляющее элементы управления данной формы. Поэтому доступ к элементам управления формы может осу- ществляться двумя способами: явно (как к элементу семейства Controls) и неявно (как к элементу объекта Form): Forms ! Заказы. Controls ШомерЗаказа, Forms ! Заказы ! НомерЗаказа. Последний способ доступа обрабатывается быстрее
    Reports Семейство Содержит объекты Report, соответствую щие всем открытым в данный момент отчещие всем открытым в данный момент отчетам в базе данных Access
    Report Объект Ссылается на конкретный отчет Access, опи- сывает свойства отчета, элементы управле- ния и модуль, содержащий процедуры отче- та. Доступ к элементам управления отчета осуществляется с помощью семейства Controls (свойства по умолчанию) двумя способами — явно или неявно
    Modules Семейство Содержит объекты Module, соответствующие всем открытым в данный момент стандартным модулям и модулям объектов в базе данных Access
    Module Объект Ссылается на конкретный стандартный мо- дуль или модуль класса Access, описывает содержимое модуля в строках кода. Приложение Microsoft Access, кроме стандартных модулей, не привязанных к объектам, модулей форм и отчетов, привязанных, соответственно, к форме или отчету, может иметь модули классов, не зависящие от других объектов приложения и определяющие новый класс. Тип модуля можно узнать с помощью свойства Туре
    References Семейство Содержит объекты Reference, представ- ляющие собой установленные ссылки в при- ложении Access, С помощью данного семей- ства в приложении можно динамически устанавливать или удалять ссылки на внеш- ние библиотеки
    Reference Объект Соответствует ссылке, установленной на библиотеку объектов или типов, содержит информацию о ссылке, включая имя библиотеки и путь к соответствующему файлу
    Printers Новое семейство Содержит объекты Printer, представляющие собой установленные ссылки на все печатающие устройства, доступные в приложении
    Printer Новый объект Ссылается на конкретное печатающее устройство
    DataAccess Pages Семейство Содержит объекты DataAccessPages, со- ответствующие открытым в данный момент страницам доступа к данным в базе данных или проекте Access
    DataAccessPage Объект Ссылается на конкретную страницу доступа к данным Access. Описывает свойства страницы
    Screen Объект Ссылается на конкретную форму, отчет или элемент управления, который в данный момент имеет фокус
    DoCmd Объект Позволяет выполнить макрос или встроенную инструкцию Access с помощью процедуры на Visual Basic
    VBE Объект из библиотеки VBIDE Предоставляет доступ к функциональным средствам редактора Visual Basic для Micro- soft Access
    DefaultWebOptions Объект Предоставляет доступ к атрибутам приложе- ния, используемым в Access по умолчанию при открытии и сохранении Web-страниц
    WebOptions Новый объект Предоставляет доступ к атрибутам конкрет- ной страницы доступа к данным, используе- мым в Access при открытии и сохранении Web-страниц. Эти атрибуты имеют более высокий приоритет, чем соответствующие атрибуты приложения. Если установлены атрибуты страницы доступа к данным, то соответствующие атрибуты приложения для работы с Web-страницами игнорируются.
    References Семейство Содержит объекты Reference, представляющие собой установленные ссылки в приложении Access. С помощью данного семейства в приложении можно динамически устанавливать или удалять ссылки на внешние библиотеки
    Reference Объект Соответствует ссылке, установленной на библиотеку объектов или типов, содержит информацию о ссылке, включая имя библиотеки и путь к соответствующему файлу
    Printers Новое семейство Содержит объекты Printer, представляющие собой установленные ссылки на все печатающие устройства, доступные в приложении
    DataAccessPages Семейство Содержит объекты DataAccessPages, соответствующие открытым в данный момент страницам доступа к данным в базе данных или проекте Access
    DataAccessPage Объект Ссылается на конкретную страницу доступа к данным Access. Описывает свойства страницы
    Screen Объект Ссылается на конкретную форму, отчет или элемент управления, который в данный момент имеет фокус
    DoCmd Объект Позволяет выполнить макрос или встроенную инструкцию Access с помощью процедуры на Visual Basic
    VBE Объект из библиотеки VBIDE Предоставляет доступ к функциональным средствам редактора Visual Basic для Microsoft Access
    DefaultWebOptions Объект Предоставляет доступ к атрибутам приложения, используемым в Access по умолчанию при открытии и сохранении Web-страниц
    WebOptions Новый объект Предоставляет доступ к атрибутам конкретной страницы доступа к данным, используемым в Access при открытии и сохранении Web-страниц. Эти атрибуты имеют более высокий приоритет, чем соответствующие атрибуты приложения. Если установлены атрибуты страницы доступа к данным, то соответствующие атрибуты приложения для работы с Web-страницами игнорируются. Если изменяются атрибуты страницы доступа к данным, автоматически такие же значения получают атрибуты приложения. Поэтому полезно сохранять текущие атрибуты приложения, чтобы восстанавливать их после изменения атрибутов страницы доступа к данным.
    DBEngine Объект из библиотеки DAO Является объектом самого верхнего уровня в объектной модели DАО. Позволяет использовать объекты доступа к данным в приложении Access
    Current Project Объект Ссылается на программный проект (представляющий совокупность всех программных модулей, включая стандартные модули и модули классов) текущей базы данных или проекта Microsoft Access. Этот объект содержит семейства объектов AccessObjects, соответствующих реальным объектам базы данных или проекта: AllForms, AllReports, AllMacros, AllModules, AllDataAccessPages. Перечисленные семейства включают в себя все реальные объекты базы данных, независимо от того, открыты они или закрыты в данный момент
    CurrentData Объект Ссылается на объекты, сохраненные приложением — источником данных (ядром Jet или SQL-сервером) в текущей базе данных. Содержит семейства объектов AccessObject: AllTables, AllQueries, AllViews, AllStoredProcedures, All Functions, AllDatabaseDiagrams. Перечисленные семейства включают в себя все реальные объекты базы данных, незави- симо от того, открыты они или закрыты в данный момент
    CodeProject Объект Ссылается на программный проект кода той базы данных (или проекта Microsoft Access), в которой выполняется (и содержится) код VBA, включающий данную ссылку. Этот объект содержит семейства объектов AccessObjects, соответствующих реаль- ным объектам базы данных или проекта: AllForms, AllReports, AllMacros, AllModules, AllDataAccessPages. Перечисленные семейства включают в себя все реальные объекты базы данных, незави- симо от того, открыты они или закрыты в данный момент.
    CodeData Объект Ссылается на объекты, сохраненные прило- жением — источником данных (ядром Jet или SQL-сервером) в той базе данных, в которой выполняется (и содержится) код VBA, вклю- чающий данную ссылку. Содержит семейст- ва объектов AccessObj ect: AllTables, AllQueries, AllViews, AllStoredProcedures, All Functions, AllDatabaseDiagrams. Перечисленные семейства включают в себя все реальные объекты базы данных, незави- симо от того, открыты они или закрыты в данный момент
    Controls Семейство Содержит объекты Control, представляю- щие все элементы управления в конкретной форме, отчете или секции, вложенные или присоединенные элементы управления. Это семейство является свойством объектов Form, Report, Section и Control
    Control Объект Представляет собой любой конкретный эле- мент управления в форме, отчете или сек- ции, вложенный или присоединенный эле- мент управления. Объект Control может ссылаться на один из объектов, характери- зующих элемент управления определенного типа, такой как: CheckBox, TextBox, ComboBox, CommandButton, CustomControl, BoundObjectFrame, Image, ListBox, ObjectFrame, OptionButton, OptionGroup, Page, Section, SubForm, TogleButton
    FormatConditions Семейство Содержит объекты FormatCondition и представляет набор форматов по условию для объекта TextBox или ComboBox
    Forma tCondit ion Объект Представляет форматирование по условию, определенное для элемента управления типа поле ввода (объект TextBox) или спи- сок с полем ввода (объект ComboBox)
    AccessObjectProperties Семейство Содержит настраиваемые объекты AccessObj ectProperty, описывающие свойства и однозначно характеризующие конкретный объект AccessObject, CodeData, CodeProject, CurrentData или CurrentProject
    AccessObject Объект Ссылается на реальный объект Microsoft Access в любом из семейств: AllForms, AllReports, AllMacros, AllModules, AllDataAccessPages, AllTables, AllQueries, AllViews, AllStoredProcedures, All Functions, AllDatabaseDiagrams. В зависимости от того, к какому семейству он принадлежит, этот объект представляет собой любой из объектов Access: таблицу (Table), запрос (Query), отчет (Report), форму (From), модуль (Module), макрос (Macro), страницу доступа к данным (Data access page), представление (view), хранимую процедуру (stored procedure) или схему базы данных (Database diagram). Объект AccessObject ссылается на существующий объект базы данных, нельзя создать новый или удалить существующий объект AccessObject
    AccessObjectProperty Объект Представляет встроенные или определенные пользователем характеристики (свойства) любого объекта AccessObject, CodeData, CodeProject, CurrentData или CurrentProject

    Таблица 13.3. Описание основных элементов объектной модели Microsoft Access 2002

    В Microsoft Access 2002 появились два новых семейства, содержащих новые объекты:

    • Printers — обеспечивает программное управление параметрами печати. Теперь есть возможность вывести документ на печать на любой из доступных принтеров, указать количество копий документа, который нужно напечатать, определить размер страницы и поля и т. д.
    • AllFunctions — используется для программного доступа к пользовательским функциям, определенным в базе данных Microsoft SQL Server (объект, аналогичный запросу, который существует в проекте Microsoft Access). Этот объект может быть открыт в режиме Конструктора, режиме Таблицы, режиме Предварительного просмотра и в режиме Сводной таблицы или Сводной диаграммы как обычный запрос.

    Объекты доступа к данным предназначены для программного доступа и управления данными в локальной или удаленной базе данных, а также для программного управления самими базами данных, их объектами и структурой. В Microsoft Access 2002, так же как и в Microsoft Access 2000, сохранилась возможность двух способов работы с данными:

    • старый, посредством DAO (Data Access Objects);
    • новый, посредством ADO (ActiveX Data Objects). Каждому из этих способов соответствует своя объектная модель.

    Объекты доступа к данным (DAO, Data Access Objects) создавались, как объектно-ориентированный интерфейс для ядра баз данных Jet фирмы Microsoft. В ранних версиях Microsoft Office доступ к данным обеспечивался исключительно ядром Jet. Сначала ядро Jet могли использовать только Access и Visual Basic, но с выходом пакета Microsoft Office 95 ядро Jet стало сервером Automation, что позволило использовать DАО для доступа к данным из любого клиента Automation.

    В версии Office 97 компоненты Excel, Word и PowerPoint стали клиентами Automation и вышла новая версия DAO 3.5. В DАО 3.5 появился новый режим доступа к данным ODBCDirect, который позволяет манипулировать данными в обход ядра Jet, напрямую связываясь с источниками данных ODBC no технологии «клиент-сервер». За счет прямого доступа к данным получается выигрыш в производительности, при этом конечный пользователь имеет стандартный объектно-ориентированный интерфейс доступа к различным типам данных, начиная от баз данных Access до баз данных ISAM (Indexed Sequential Access Method — индексно-последовательный метод доступа) и SQL. Отсюда можно заключить, что DАО — это унифицированный набор объектов для доступа к данным.

    В Microsoft Office 2000 вошли новая версия DAO 3.6 и новая версия Microsoft Jet 4.0, в которой реализована поддержка Unicode, т. е. в базах данных появилась возможность хранить символы любых национальных алфавитов одновременно. В версии Microsoft Access 2002 используются те же версии Jet и DАО.

    DАО версии 3.5 и выше включает две объектные модели, соответствующие двум типам «рабочей области» (сеанс работы с базой данных), в зависимости от того, используется ли ODBCDirect. При доступе к данным с помощью ядра Microsoft Jet применяется рабочая область Microsoft Jet. В случае прямого доступа к источнику данных ODBC используется рабочая область ODBCDirect. Тип рабочей области и связанного с ней источника данных определяет, какие объекты, свойства и методы DАО можно использовать (рис. 13.4, 13.5).

    Применяйте рабочую область Microsoft Jet для доступа к базам данных Jet (таким, как MDB-файлы Access) или другим настольным базам данных ISAM или в том случае, когда требуется использовать уникальные средства ядра Jet, такие как объединение данных в разных форматах.

    Применяйте в клиентском приложении рабочую область ODBCDirect вместо рабочей области Jet в следующих случаях:

    • если нужно только выполнить запрос или хранимую процедуру на сервере баз данных, таком как SQL Server;
    • когда требуется воспользоваться специфическими возможностями ODBCDirect, такими как пакетное обновление записей, обновленные записи оптируются на локальном компьютере;
    • когда требуется асинхронное выполнение запроса, запрос выполняется в фоновом режиме, не останавливая выполнение других

    Рис. 13.4. Модель объектов доступа к данным для рабочей области Microsoft Jet

    В табл. 13.4 описаны объекты доступа к данным. В первом столбце приведены объекты-семейства, а во втором — объекты, являющиеся элементами соответствующего семейства, в третьем — описание объекта. В последующих главах книги «вы встретитесь с примерами использования объектной модели DAO.

    Рис. 13.5. Модель объектов доступа к данным для рабочей области ODBCDirect

    Семейство  Объект  Описание 
    Connections Connection Предоставляет информацию о соединении с источником данных ODBC (используется только в рабочей области ODBCDirect)
    Containers Container Хранилище информации об объекте предопределенного типа (используется только в рабочей области Microsoft Jet)
    Databases Database DBEngine Открытая база данных Главный объект ядра баз данных Microsoft Jet
    Documents Document Информация о сохраненном объекте предопределенного типа (используется только в рабочей области Microsoft Jet)
    Errors Error Информация об ошибках, ассоциированных с данным объектом
    Fields Field Представляет поле (столбец) таблицы, запроса, индекса, поле связи между таблицами или запросами или поле набора записей
    Groups Group Группа пользователей, определяющая права доступа к данным (используется только в рабочей области Microsoft Jet)
    Indexes Index Определяет порядок и уникальность значений в таблице (используется только в рабочей области Microsoft Jet)
    Parameters Parameter Параметр для параметризованного запроса
    Properties Property Встроенная или определенная пользователем характеристика (свойство)
    QueryDef s QueryDef Описание хранимого в базе данных запроса
    Recordsets Recordset Набор записей в базовой таблице или запросе
    Relations Relation Связь между полями таблиц или запросов (используется только в рабочей области Microsoft Jet)
    TableDefs TableDef Описание хранимой в базе данных таблицы (используется только в рабочей области Microsoft Jet)
    Users User Бюджет пользователя, определяющий права доступа к данным (используется только в рабочей области Microsoft Jet)
    Workspases Workspace Сеанс работы с источником данных с помощью ядра баз данных Microsoft Jet

    Таблица 13.4. Описание объектов доступа к данным

    Объекты управления данными ActiveX (ADO/ ActiveX Data Objects) предназначены для обеспечения доступа к источникам данных разных видов, от текстовых файлов до распределенных баз данных. ADO представляет собой объектно-ориентированный интерфейс для приложений, использующих OLE DB. OLE DB — это программный интерфейс, удовлетворяющий спецификации COM (Component Object Model, компонентная модель объектов), который предоставляет унифицированный способ доступа к различным источникам данных. Интерфейс OLE DB разрабатывался с целью получения оптимальной функциональности для приложений разных видов и поэтому не является простым в использовании. ADO — промежуточное звено между приложением и OLE DB, предоставляющее разработчикам приложений удобный объектно-ориентированный интерфейс.

    Существует три объектных модели, которые вместе обеспечивают те функции работы с данными, которые реализуются объектами DАО:

    • Microsoft ActiveX Data Objects 2.6 (ADODB);
    • Microsoft ActiveX Data Objects Extensions for DDL and Security 2.6 (ADOX);
    • Microsoft Jet and Replication Objects 2.6 (JRO).

    Стандартный набор функций для работы с данными распределяется между этими тремя моделями следующим образом:

    • Управление данными. Объектная модель ADODB обеспечивает вашему приложению доступ к источнику данных и возможность отбирать для просмотра и изменять эти данные. Однако она не предоставляет возможности изменять структуру таблиц и других объектов источника данных.
    • Определение данных и защита. Объектная модель ADOX позволяет программно изменять структуру объектов в источнике данных, в частности добавлять и удалять таблицы, изменять структуру таблиц, создавать и изменять запросы, представления и хранимые процедуры, а также управлять схемой защиты данных: создавать группы пользователей и отдельных пользователей, наделять их требуемыми правами доступа к объектам.
    • Репликация и службы ядра базы данных Jet. Объектная модель JRO позволяет создавать, модифицировать и синхронизировать реплики. Она была спроектирована специально для доступа к объектам Jet и, в отличие от моделей ADODB и ADOX, может работать только с базами данных Access.

    Краткое описание объектов моделей ADO приведено в табл. 13.5—13.7.

    Объект  Тип  Описание 
    Connection Объект Открывает сеанс обмена данными
    Command Объект Представляет собой инструкцию SQL
    Parameter Объект Представляет собой параметр инструкции SQL
    Recordset Объект Представляет собой набор записей и позволяет осуществлять навигацию по записям и манипулировать с данными в нем
    Field Объект Представляет собой поле (столбец) в наборе записей Recordset
    Error Объект Представляет собой информацию об ошибке, произошедшей во время сеанса связи
    Property Объект Представляет характеристику (свойство) любого объекта ADO
    Errors Семейство Все объекты Error в этом семействе создаются в ответ на одну ошибку, произошедшую во время сеанса связи
    Parameters Семейство Содержит все объекты Parameter, ассоциированные с объектом Command
    Fields Семейство Содержит все объекты Field, ассоциированные с набором записей Recordset
    Properties Семейство Содержит все объекты Property, ассоциированные с объектом Connection, Command, Recordset или Field
    Record Объект Представляет собой каталог или файл
    Stream Объект Представляет собой содержимое файла

    Таблица 13.5. Объектная модель ADODB

    Объект  Тип  Описание 
    Catalog Объект Главный объект этой модели. Ссылается на источник данных и обеспечивает доступ ко всем объектам источника — таблицам, представлениям, процедурам, группам, пользователям
    Tables Семейство Семейство таблиц, содержащихся в источнике данных. Каждый объект Table этого семейства ссылается на одну таблицу
    Indexes Семейство Содержит все индексы таблицы. Каждый объект Index семейства ссылается на один из индексов
    Keys Семейство Содержит все ключи таблицы. Каждый объект Key семейства ссылается на один из ключей
    Columns Семейство Содержит объекты Column, которые ссылаются на столбцы в одном из объектов Table, Index, Key
    Groups Семейство Содержит все объекты Group каталога или пользователя. Каждый из объектов Group ссылается на бюджет группы в каталоге или пользователе
    Users Семейство Содержит объекты User, которые представляют собой бюджеты пользователей, имеющих права доступа к защищенной базе данных
    Procedures Семейство Содержит все хранимые процедуры в базе данных. Каждый объект Procedure семейства ссылается на одну из хранимых процедур
    Views Семейство Содержит все представления (view) в базе данных

    Таблица 13.6. Объектная модель ADOX

    Иерархическая структура модели объектов ADOX представлена на рис. 13.6.

    Рис. 13.6. Объектная модель ADOX

    Объект Тип Описание
    JetEngine Объект Обеспечивает доступ к двум сервисам ядра базы данных Jet: сжатие базы данных и выгрузка данных из кэша в файл базы данных MDB
    Replica Объект Представляет собой копию реплицированной базы данных
    Filters Семейство Содержит набор объектов Filter, каждый из которых представляет собой набор записей, которые должны реплицироваться

    Таблица 13.7. Описание объектов JRO

    Более подробное описание объектов JRO и их использования приведено в гл. 18.

    В случае разработки многоуровневого клиент-серверного приложения для доступа к данным используется еще одна объектная модель — RDS (служба удаленного доступа к данным). Она включает три объекта, краткое описание которых приведено в табл. 13.8.

    Объект  Тип  Описание 
    RDS .DataSpace Объект Этот объект содержит метод, позволяющий создать объект (так называемый бизнес-объект) промежуточного сервера передачи данных. В качестве промежуточного сервера может выступать процедура, указанная пользователем, встроенная процедура, используемая по умолчанию, или библиотека динамической компоновки DLL, исполняемая в локальной сети, в Интернете или сети интранет
    RDSServer. DataFactory Объект Представляет собой встроенную программу — сервер данных, которая выполняет обработку данных и возвращает результат обработки
    RDS.DataControl Объект Этот объект может использоваться для следующих целей: автоматическое выполнение функций объектов RDS. DataSpace и RDSServer .DataFactory, выполнение обработки данных или возвращение результата с помощью встроенных служб RDS, представление результата обработки данных в виде совокупности значений для визуальных элементов управления (в форме)

    Таблица 13.8. Объектная модель RDS

    Таблица объектов Visual Basic для приложений

    Объект  Тип  Описание 
    Collection Объект из библиотеки VBA Упорядоченная совокупность объектов, с которой можно обращаться как с единым объектом
    Debug Объект Позволяет выводить текущую информацию в окно отладки непосредственно во время выполнения кода на VBA
    Dictionary Объект из библиотеки Scripting Объект, представляющий пару: ключ и элемент. Представляет собой аналог элемента ассоциативной памяти
    Drives Семейство из библиотеки Scripting Содержит объекты Drive, предоставляющие информацию (только для чтения) обо всех доступных дисках. Является свойством объекта FileSystemObject
    Drive Объект из библиотеки Scripting Предоставляет доступ к свойствам конкретного локального или сетевого диска
    Err Объект из библиотеки VBA Предназначен для обработки ошибок Automation и ошибок модулей VBA во время выполнения кода наЛ/ВА
    Files Семейство из библиотеки Scripting Содержит объекты File и представляет собой совокупность всех файлов в данной папке. Является свойством объекта FileSystemObject
    File Объект из библиотеки Scripting Предоставляет доступ ко всем свойствам файла на диске
    FileSystemObject Объект из библиотеки Scripting Предоставляет доступ к файловой системе компьютера
    Folders Семейство из библиотеки Scripting Содержит объекты Folder и представляет собой совокупность всех папок внутри данной папки. Является свойством объекта Folder (свойство называется SubFolders)
    Folder Объект из библиотеки Scripting Предоставляет доступ ко всем свойствам папки на диске
    TextStream Объект из библиотеки Scripting Обеспечивает последовательный доступ к текстовому файлу
    UserForm Абстрактный объект VBA Object Представляет объект — окно или диалоговое окно, являющееся частью пользовательского интерфейса приложения. Характеристики этого объекта определяются пользователем
    UserForms Семейство из библиотеки VBA Содержит объекты object, соответствующие объектам User Form, и представляет собой совокупность пользовательских форм, загруженных в данный момент в приложение. Это семейство является свойством объекта Global из библиотеки VBA

    Иерархия объектов Microsoft Office 2002 представлена на рис. 13.7.

    Рис. 13.7. Объектная модель Microsoft Office 2002

    Объекты Microsoft Office используются в иерархической структуре других объектных моделей. В объектной модели Microsoft Office 2002 появилось много новых объектов. Описание основных объектов, определенных в библиотеке Office, приведено в табл. 13.10.

    Объект  Тип  Описание 
    AnswerWizard Объект Соответствует Мастеру ответов приложения Microsoft Office. Все приложения семейства Microsoft Office имеют только один Мастер ответов, поэтому все изме- нения над этим объектом немедленно отразятся на активном приложении
    Assistant Обьект и семейство Ссылается на объект, представляющий активного в данный момент помощника Microsoft Office
    COMAddlns Семейство Содержит объекты COMAddln, соответствующие надстройкам СОМ, зарегистрированным в реестре Windows
    CoiranandBars Семейство Содержит объекты CommandBar, соответствующие панелям команд приложения-онтейнера (это могут быть строки меню, панели инструментов, меню и контекстные меню)
    DocumentProperties Семейство Содержит объекты DocumentProperty, каждый из которых представляет собой набор встроенных или определенных пользователем характеристик (свойств) документа-контейнера
    FileDialog Новый объект Реализует диалоговое окно, аналогичное окнам Открыть (Open) и Сохранить (Save) Microsoft Office
    FileDialogFilters Новое семейство Содержит объекты FileDialogFilter, которые представляют собой фильтры, оп- ределяющие, какие файлы будут отображаться в диалоговом окне FileDialog
    FileDialogSelectedl terns Новое семейство Семейство строковых значений, представляющих собой пути к файлам или папкам, выбранным в диалоговом окне FileDialog
    FileSearch Объект Реализует функциональность стандартного диалогового окна открытия файла
    FileTypes Новое семейство Семейство значений типов файлов, которые возвращаются методом Execute диалогового окна FileDialog
    HTMLProject Объект Представляет собой корень дерева проекта Web-страницы, отображаемого в окне просмотра проекта Project Explorer редактора сценариев Microsoft Script Editor. Этот объект содержит семейство HTMLProjectltems объектов HTMLProjectltem, ссылающихся на элементы иерархической структуры проекта. С помощью этого объекта можно управлять проектом Web-страницы, например открыть его в редакторе сценариев.
    LanguageSettings Объект Предоставляет информацию о языковых настройках приложения семейства Microsoft Office
    MsoEnvelope Новый объект Обеспечивает возможность отправки документов по электронной почте
    NewFile Новый объект Содержит список строковых значений, которые отображаются в группе Создание (New) на панели задач
    ODSOColumns Новое семейство Объекты этого семейства представляют собой поля в файле для слияния с документом Word
    ODSOFilters Новое семейство Объекты этого семейства представляют собой фильтры, которые применяются к файлу — источнику данных для документа слияния
    Off iceDataSourceObject Новый объект Представляет собой источник данных для операции слияния
    SearchFolders Новое семейство Содержит набор объектов, представляющих собой папки, в которых ведется поиск при использовании объекта FileSearch
    SignatureSet Новое семейство Содержит набор объектов Signature, каждый из которых представляет собой цифро- вую подпись, связанную с документом
    WebPageFonts Семейство Содержит набор объектов WebPageFont, каждый из которых соответствует одному из поддерживаемых национальных стандартов. Каждый объект определяет шрифты и их размеры, которые используются по умолчанию при сохранении документа в формате Web-страницы
    Scripts Семейство Содержит объекты Script, соответствующие сценариям, определенным в документе Word, электронной таблице Excel или слайде PowerPoint. С помощью этого объекта можно управлять сценариями документа, например создавать новые сценарии.

    Таблица 13.10. Описание объектов Microsoft Office 2002

    Несмотря на разнообразие библиотек объектов, методы работы с объектами в процедурах VBA общие и не зависят от того, к какой библиотеке относится конкретный объект. В данном разделе мы как раз и рассмотрим эти общие методы.

    Первый вопрос, который следует обсудить, — как обратиться к объекту. Для обращения к объекту существует одно общее правило: нужно проследить путь в иерархии объектов, начиная от объекта самого верхнего уровня, до целевого объекта и записать последовательность имен встреченных на пути объектов или семейств, отделяя их друг от друга точкой. Если на пути встречается семейство, то, кроме имени семейства, необходимо в скобках указать индекс или имя его элемента, т. е. задать конкретный объект в семействе. Например, чтобы обратиться к форме, входящей в состав семейства AllForms, необходимо написать следующее выражение:

     Application.CurrentProject.AllForms ("Заказы клиента")

    Таким образом, чтобы правильно создавать ссылки на объекты, нужно достаточно хорошо представлять себе место каждого объекта в иерархии объектов модели. Такие длинные ссылки особенно характерны для моделей, которые имеют многоуровневую, иерархическую структуру, например DАО. На самом деле, на практике чаще применяют не полные, а сокращенные ссылки. Дело в том, что наиболее часто используемые семейства, объекты, свойства и методы считаются глобальными. Ссылки на них хранятся в специальном объекте с именем Global. Для обращения к глобальному объекту можно пропустить объекты более высокого уровня.

    Например, семейство Forms является глобальным. Для доступа к объекту этого семейства можно использовать сокращенную ссылку вида:

    Forms ( «Заказы») вместо полной ссылки:

    Application. Forms ( «Заказы»)

    Замечание

    Узнать, какие объекты, свойства и методы являются глобальными, позволяет окно просмотра объектов. Чтобы отобразить список глобальных компонентов объектной модели, выберите элемент в списке Classes в окне просмотра объектов.

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

    Обычно имя семейства и имя объекта разделяются оператором «!» (восклицательный знак), например:

     Forms ! Товары

    Если имя объекта состоит из нескольких слов, разделенных пробелом, тогда вам придется написать

     Forms!

    Третий способ ссылки состоит в том, что на объект в семействе ссылаются не по названию, а по индексу, например:

     Properties(0)

    Такой способ применяется обычно тогда, когда имя объекта неизвестно. В то же время каждый объект в семействе имеет индекс (порядковый номер), который обычно начинается с нуля. Есть, правда, исключения из этого правила, например в семействе CommandBars модели Microsoft Office нумерация объектов начинается с, единицы. Поэтому перед использованием индексов лучше узнать о способе нумерации в справочной системе Access.

    И наконец, последний способ ссылки на объект состоит в использовании вместо имени объекта строковой переменной, например:

     Reports (strИмяОтчета)

    Если какой-то объект содержит несколько семейств объектов более низкого уровня, то одно из этих семейств, обычно наиболее часто используемое, считается стандартным или семейством по умолчанию. Можно обращаться к объекту, входящему в это семейство, не указывая имени семейства. Например, для объекта TableDef модели DАО стандартным семейством считается Fields. Поэтому для обращения к столбцу таблицы можно использовать сокращенную ссылку

     TableDefs!Должности!Код Должности вместо полной ссылки
     TableDefs!Должности.Fields!КодЦолжности

    Совет

    Использование сокращенных ссылок в программах предпочтительнее еще и потому, что в этом случае программы будут выполняться быстрее.

    Еще одним способом сокращения ссылки на объект является использование объектной переменной. Особенно полезно использовать объектную переменную, если к объекту нужно обратиться несколько раз. (О том, как объявить объектную переменную и установить ссылку на объект см. разд. «Язык Visual Basic для приложений» выше в данной главе.)

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

     Function IsLoaded (strFormName As String) As Boolean

    ‘Возвращает значение True, если форма открыта и False, если нет

     Dim  frm  As Form IsLoaded = False For each frm in Forms If frm.Name = FormName Then IsLoaded = True Exit Function EndIf Next frm End Function

    В данной функции мы сначала объявили объектную переменную типа Form и установили начальное значение функции. Затем мы организуем цикл, в котором перебираем элементы семейства Forms до тех пор, пока не обнаружим в нем объект Form с именем, совпадающим со строковой переменной, которая является аргументом функции. Если такой объект найден, мы присваиваем функции значение True и выходим из нее. Если нет, то когда будут перебраны все элементы семейства Forms, функция вернет значение False.

    Для того чтобы организовать цикл с перебором элементов, количество которых неизвестно, в настоящем примере мы использовали оператор For Each. . .Next. Этот оператор обычно используется при работе с семействами. Однако мы могли организовать такой же цикл, используя обычный оператор For. . .Next, т. к. любое семейство (в том числе и Forms) имеет свойство Count, которое возвращает количество элементов в семействе. Ниже приводится другой вариант организации этого цикла:

     For I = 0 То Forms.Count - 1 If frm(I).Name = FormName Then IsLoaded = True Exit Function EndIf Next I

    Кроме указанного свойства, семейства объектов доступа к данным имеют два метода, которые позволяют добавлять объекты в семейство и удалять их из семейства, — методы Append и Delete. Это обеспечивает оперативное создание объектов доступа к данным, например, временных таблиц. Чтобы создать таблицу программным путем, вы должны не только определить эту таблицу, но и добавить ее в соответствующее семейство. Ниже приводится фрагмент кода процедуры, в котором создается новая таблица, определяются два ее поля и добавляются объекты в семейства Fields и TableDef

    ‘Объявляем объектные переменные для объектов:

    база данных, таблица и поле Dim db As Database,

     td As TableDef, fid As Field

    ‘Устанавливаем ссылку на текущую базу данных

     Set db = CurrentDb

    ‘Создаем новую таблицу, используя метод

     CreateTableDef объекта Database
     Set td = db.CreateTableDef("Временная")

    ‘Создаем поле в таблице, используя метод

     CreateField объекта TableDef

    ‘Поле будет иметь имя «Дата» и тип Дата/время

     Set fid = td.CreateField("Дата",dbDate)

    ‘Добавляем поле «Дата» в семейство Fielfs таблицы

     td.Fields.Append fid

    ‘Создаем второе поле с именем «Сумма» и типом Денежный

     Set fid = td.CreateField("Сумма",dbCurrency)

    ‘Добавляем поле «Сумма» в семейство Fielfs таблицы

     td.Fields.Append fid

    ‘Добавляем таблицу к семейству TableDefs базы данных

     db.TableDefs.Append td

    ‘Обновляем семейство TableDefs

     db.TableDefs.Refresh

    Яосле выполнения этой программы на вкладке Таблицы (Tables) окна базы данных появится новая таблица «Временная».

    Удалить эту таблицу можно аналогичным способом, только уже воспользовавшись методом Delete семейства TableDefs.

     db.TableDefs.Delete "Временная"
     db.TableDefs.Refresh
     Set db = Nothing

    Метод Refresh обновляет количество объектов семейства после добавления или удаления объектов. В последнем предложении мы освобождаем объектную переменную db.

    Замечание

    К сожалению, семейства в модели Microsoft Access не имеют аналогичных методов. Это означает, что вы не можете, например, оперативно добавлять или удалять поля в формах или отчетах. Если в зависимости от условий в форме должны отображаться или не отображаться некоторые поля, приходится создавать элементы управления для всех возможных полей, а затем использовать свойство Visible соответствующих элементов управления, чтобы поля либо были видимы, либо невидимы. В семействах объектной модели Microsoft Office аналогичные свойства есть: Add и Delete. Это позволяет оперативно управлять, например, кнопками на панелях команд.

    Как уже говорилось выше, каждый объект имеет свойства, которые являются его характеристиками, и методы, которые позволяют управлять поведением этого объекта. То же справедливо и для семейств. Работа с объектами и семействами заключается в установке или получении значений конкретных свойств объекта или семейства и вызове их методов. Поэтому для управления объектами приложения необходимо хорошо знать свойства и методы каждого объекта.

    Замечание

    Если вы хотите иметь подробную информацию обо всех свойствах и методах объекта, следует обратиться к соответствующему разделу справки. Например, чтобы получить сведения о любом объекте модели Access, нужно раскрыть раздел Объекты Microsoft Access в папке Программирование, Справочник по языку Visual Basic Microsoft Access и затем щелкнуть на нужном объекте или семействе. Однако делать это вам придется, скорее всего, не очень часто, т. к. краткую информацию обо всех свойствах и методах объекта при написании программы в среде редактора VBA можно получить очень быстро, подключив оперативную подсказку или пользуясь Окном просмотра объектов.

    Установка свойства объекта — это присвоение значения данному свойству. Поэтому для установки свойства используется оператор присваивания, например, чтобы установить свойство Visible (Вывод на экран) элемента управления формы, можно использовать инструкцию VBA:

     Forms! Товары ! КодТовара . Visible = False

    или

     frm! КодТовара. Visible = False

    Таким образом, ссылка на свойство объекта состоит из двух частей, разделенных точкой: ссылки на объект (любого вида) и имени свойства.

    Получить свойство означает прочитать текущее значение этого свойства. Например, инструкция VBA

     intCount = Forms . Count

    присваивает переменной значение свойства Count семейства Forms.

    Метод объекта в инструкциях VBA обозначается так же, как и свойство. Это видно и из приведенных в предыдущем разделе примеров, где мы использовали методы Append, Delete и Refresh семейства TableDefs. Однако, в отличие от свойств, методы могут иметь аргументы. Например, в следующей инструкции VBA применяется метод OpenReport объекта DoCmd.

     DoCmd.OpenReport "Вакинсии", acPreview

    Объект DoCmd — это специальный объект, который позволяет в программах VBA выполнять макрокоманды. Имя каждой макрокоманды является методом этого объекта. В приведенном примере создается отчет «Вакансии» в режиме Предварительного просмотра. При этом метод OpenReport не возвращает никакого значения, и аргументы в данном случае не требуется заключать в скобки.

    Если же метод используется как функция, возвращающая значения, как показано в следующем примере, аргументы необходимо заключить в скобки.

     Dim db As Database, rs As Recordset Set db = CurrentDB Set rs = db.OpenRecordset ("Сотрудники") ............................. rs.Close db.Close

    Метод OpenRecordset объекта Database возвращает ссылку на объект Recordset (Набор записей), присваиваемую объектной переменной rs. Метод close, который имеют оба объекта — Recordset и Database, — не использует аргументов.

    Код VBA в приложении Access содержится в модулях. Модули являются объектами Access, такими же, как таблицы, запросы, формы, отчеты, страницы и макросы, о чем свидетельствует ярлык на панели объектов в окне База данных (Database). Основное содержание модулей — это процедуры на языке VBA. Существуют два типа модулей: стандартные модули и модули класса.

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

    Рис. 13.8. Функция IsLoaded

    Список стандартных модулей приложения всегда можно увидеть, нажав кнопку Модули (Modules) в окне База данных (Database). В этом окне обычно и выполняется работа с модулями. Выделите в окне базы данных (Northwind) модуль «Служебные функции» (Utility Functions) и нажмите кнопку Конструктор (Design). Откроется окно редактора кода VBA, в котором можно увидеть содержание модуля. Модуль состоит из двух строк описания и одной процедуры — функции isLoaded, с которой мы уже встречались (рис. 13.8) (см. гл. 11).

    Это пример универсальной функции, которая проверяет, загружена ли форма, имя которой передается ей в качестве аргумента. Она никак не связана не только с объектом, но и с данным приложением и может использоваться как в нем самом, так и в любом другом приложении Access.

    Вторым типом модуля в Access является модуль класса. Модуль класса отличается от стандартного модуля тем, что, кроме процедур, он содержит описание объекта и используется для создания объектов. Процедуры, определенные в этом модуле, являются методами и свойствами объекта. Примерами модулей класса являются модули форм и отчетов.

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

    Чтобы убедиться в этом, откройте любую форму приложения «Борей» (Northwind) в режиме Конструктора и посмотрите свойства этой формы. На вкладке Другие (Others) есть свойство Наличие модуля (Has Module). Оно должно иметь значение Нет (No). После нажатия кнопки Программа (Code), которая служит для открывания редактора кода VBA, значение этого свойства изменится на Да (Yes) (рис. 13.9).

    Рис. 13.9. Диалоговое окно свойств формы

    В окне редактора VBA отображается объект Форма (Form), а справа — поле со списком событий, которые могут обрабатываться процедурами VBA (рис. 13.10).

    Рис. 13.10. Окно редактора кода VBA

    Если в модуле для некоторого события существует процедура, то это событие выделяется в списке жирным шрифтом. В данном случае таких событий нет, т. к. обработка событий в форме «Клиенты» (Customers), которую мы открыли, выполняется с помощью макросов. При попытке открытия редактора VBA автоматически создается модуль формы, который будет иметь название Fогm_Клиенты (Form_Customers).

    Если теперь закрыть окно редактора кода, а затем форму, то, хотя мы не вносили никаких изменений в форму, на экране появится вопрос: Сохранить изменения макета или структуры формы Клиенты? (Do you want to save changes to the design of form ‘Customers’?). Вопрос связан с появлением модуля формы. Если вы ответите Нет (No), модуль не будет сохранен.

    Для того чтобы из программы VBA открыть форму и изменить какие-либо свойства формы или элементов управления формы, можно использовать два метода.

    • Макрокоманду OpenForm, как метод объекта DoCmd, например:
DoCmd.OpenForm "Товары" Forms!Товары.RecordSource = "Товары клиента"
  • Ссылку на соответствующий модуль класса, например:
Form_ToBapbi.Visible = True Рогт_Товары.RecordSource = "Товары клиента" ,|

В том и в другом случае при выполнении открывается стандартный экземпляр формы «Товары» (Products) и подменяется источник записей для этой формы.

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

Класс формы может иметь только один стандартный экземпляр, поэтому в данном случае придется создать нестандартный экземпляр формы. Для этого в программе нужно описать переменную, типом которой является имя модуля класса формы, при этом в описание переменной включить ключевое слово New. Например, следующая команда создает новый экземпляр формы » Клиенты» (Customers) и связывает его с переменной типа Form:

 Dim frm As New Fоrm_Клиенты

Теперь изменим источник данных для этой формы, расположение на экране (иначе формы просто перекроются) и присвоим свойству Вывод на экран (Visible) значение Да (Yes):

frm.RecordSource = «Наша организация» DoCmd.MoveSize 1440, 2400 frm.Visible = True

Для изменения положения на экране используется макрокоманда СдвигРазмер (MoveSize), в которой в данном случае задаются координаты верхнего левого угла окна формы относительно главного окна Access.

Замечание

Для того чтобы второй экземпляр формы не исчез с экрана сразу после появления, переменная frm должна быть описана на уровне модуля, т. е. объявлена в разделе (Declarations ) модуля с помощью ключевого слова Private.

Значения свойств формы или элементов управления формы относятся только к текущему экземпляру формы и не сохраняются после того, как он закроется. Это является отличием модуля класса от стандартного модуля: они по-разному хранят данные. В стандартном модуле можно объявить переменную Public, и она, будучи установлена, сохраняет свое значение до тех пор, пока явно не будет изменена другой командой в любом другом модуле. В модуле класса данные относятся к одному экземпляру класса, т. е. одному объекту. Они появляются, когда объект создается, и исчезают, когда исчезает объект. Это означает, что переменные Public в модуле класса могут быть доступны только до тех пор, пока существует переменная, содержащая ссылку на отдельный экземпляр класса. Это утверждение справедливо также для процедур, объявленных Public.

Формы и отчеты являются стандартными классами объектов в Access, однако можно использовать модули класса для создания пользовательских объектов. Имя, под которым сохраняется модуль класса, становится именем специального объекта. Процедуры типа Sub и Function, определенные в модуле класса, при этом станут методами объекта, а процедуры типа Property Let, Property Get и Property Set-свойствами объекта. Для описания метода, не возвращающего никакого значения, используется процедура Sub, а для метода, возвращающего значение, — процедура Function. Процедура Property Get возвращает значение свойства объекта. Процедура Property Set присваивает значение свойству объекта. Процедура Property Let устанавливает значение свойства, не принадлежащего объекту. Более детальные сведения об этих процедурах можно получить из справки Access, набрав в качестве критерия поиска имя процедуры: Property Let, Property Get и Property Set соответственно.

Точно так же, как и в модуле формы, новый экземпляр объекта создается путем объявления переменной, например:

 Dim els As New MyClass

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

 cls.MyProcedure

Для того чтобы создать стандартный модуль или модуль класса, нужно:

  1. Выбрать команду Модуль (Module) или Модуль класса (Class Module) в меню Вставка (Insert) или в списке кнопки Новый объект (New Object) выбрать соответствующий объект (рис. 13.11). При этом откроется редактор кода VBA с пустым окном модуля.

Рис. 13.11. Создание нового модуля

  1. Создать необходимые процедуры и описания.
  2. Сохранить модуль, нажав кнопку Сохранить (Save) на панели инструментов. При этом выдается диалоговое окно Сохранение (Save), в котором необходимо ввести имя нового модуля и нажать кнопку ОК.

После этого новый модуль появляется в списке модулей окна базы данных. Чтобы его открыть, можно нажать кнопку Конструктор (Design) окна базы данных. Если у вас открыты форма или отчет в режиме Конструктора, то для того, чтобы открыть модуль формы (отчета), следует нажать кнопку Программа (Code) на панели инструментов.

Для обращения к модулям в программах VBA используется семейство Modules, которое содержит все открытые объекты типа Модуль (Module). Для того чтобы открыть объект Module, можно использовать макрокоманду ОткрытьМодуль (OpenModule). Ссылка на модуль может быть создана тремя способами:

  • имяСемейства!имяОбъекта, например Modules!Startup;
  • имяСемейства («имяОбъекта»), например Modules («Startup»);
  • имяСемейства (индекс), где индекс— индекс объекта в семействе.

Для ссылки на модуль формы или отчета можно использовать или имя модуля, например «Modules!Fоrm_Клиенты«, или свойство формы, например «Forms!Клиенты.Module«.

Объект Module имеет свойство туре. Значение этого свойства определяет тип модуля: для стандартного модуля используется значение 0, для модуля класса — 1.

Среда программирования в Access 2002 включает все средства, необходимые для написания программ отладки процедур VBA. Самым главным компонентом этой среды является редактор кода Visual Basic Editor (VBE), обладающий богатыми возможностями для облегчения процесса ввода программного кода. Кроме того, среда программирования содержит еще массу диалоговых окон, в которых отображается дополнительная информация, требующаяся как в процессе создания, так и в процессе отладки кода.

Для того чтобы открыть окно редактора, достаточно открыть любой модуль Access (рис. 13.12).

Замечание

Даже в локализованных версиях Access окно редактора кода VBA, а также все другие диалоговые окна, составляющие среду программирования VBA, традиционно не локализуются. Поэтому все рисунки в этом разделе главы, а также экранные термины (названий команд меню, диалоговых окон и т. д.) приводятся в нелокализованном варианте.

Рис. 13.12. Окно редактора кода VBA

Обычно в окне редактора используются три панели (три отдельных окна). На самом деле окон может быть и больше и меньше, и скоро вы узнаете обо всех, но на рис. 13.12 показано только расположение основных окон.

  • Project (Панель проекта), располагается в верхнем левом углу редактора. В ней отображается иерархическое дерево модулей приложения. Если это окно неактивно, выполните команду View, Project Explorer либо нажмите комбинацию клавиш +.
  • Properties (Панель свойств), находится под панелью проекта. Она позволяет просматривать и изменять свойства различных входящих в проект объектов, отображаемых на панели проекта. Список свойств может отображаться как в алфавитном порядке, так и по категориям.
  • Code (Панель редактора кода). Это окно занимает большую часть экрана и является «многодокументным», т. е. можно открыть одновременно несколько окон данного типа для разных модулей. Оно представляет собой высокоинтеллектуальный текстовый процессор, существенно облегчающий написание кода VBA.

Проект приложения состоит из модулей, которые делятся на три категории:

  • Microsoft Access Class Objects (Модули классов Access) — включает все модули форм и отчетов;
  • Modules (Модули) — стандартные модули;
  • Class Modules (Модули классов) — модули пользовательских классов, если они присутствуют в приложении.

Список объектов в окне проекта является иерархическим, кроме модулей самого проекта, он может включать ссылки на объекты из внешних библиотек и список модулей этих библиотек.

В верхней части панели проекта расположены три кнопки:

  • View Code (Просмотр кода). При нажатии этой кнопки указатель мыши перемещается в окно кода, в котором отображается код выделенного в иерархии проекта объекта.
  • View Object (Просмотр объекта). Эта кнопка доступна только когда в дереве проекта выделен модуль формы или отчета. Тогда она позволяет быстро переключиться на соответствующий модулю объект, т. е. в окно Конструктора формы или отчета.
  • Toogle Folders (Переключение видов представления дерева). При нажатой кнопке все элементы в дереве проекта группируются в папках по категориям, при отжатой — они отображаются в алфавитном порядке..

Панель свойств позволяет просматривать и изменять свойства различных объектов, входящих в проект. Для отображения свойств объекта его нужно выделить либо в дереве проекта, либо в окне Конструктора формы (отчета). Во многом эта панель дублирует диалоговое окно Свойства (Properties) в формах и отчетах. И в том и в другом случае изменение свойств объекта статично, поэтому они могут быть использованы для задания начальных или постоянных свойств объекта.

Чтобы изменить значение свойства объекта, необходимо:

  1. Выделить имя свойства в левой колонке.
  2. Изменить значение в правой колонке, либо введя его вручную, либо путем выбора из списка.

Для каждого модуля, выбранного на панели проекта, открывается свое окно редактора кода. В данном случае в окне редактора мы видим модуль «Заставка» (Startup) приложения «Борей» (рис. 13.13).

Код в каждом модуле состоит из разделов, переключение между которыми выполняется путем выбора значения из списка Object (Объект), который размещается в левом верхнем углу окна. Список разделов различается для разных типов модулей.

Для модуля формы этот список включает раздел General (Общая область), который содержит объявления переменных, констант, специальных типов, внешних процедур. Данный раздел открывается по умолчанию при открытии окна кода. Для стандартного модуля этот раздел единственный — он содержит описание всех процедур. Модуль класса имеет разделы General и Class. Модуль формы, кроме раздела General, содержит раздел самой формы и разделы для каждого элемента управления. Модуль отчета включает в себя раздел для объекта Report (Отчет) и разделы для каждой области отчета. Для полей отчета не определены события, поэтому отсутствуют и соответствующие разделы в модуле кода.

Рис. 13.13. Стандартный модуль в окне редактора

Каждый раздел может содержать несколько процедур, выбираемых из списка Procedure в правом верхнем углу окна на рис. 13.13. Список процедур в стандартном модуле содержит Declarations (Описания) и имена всех процедур модуля в алфавитном порядке. Список процедур для модуля формы включает в себя перечень всех событий формы и ее элементов. Для модуля класса список процедур содержит только две процедуры для событий класса: Initialize и Terminate.

С помощью кнопок в левом нижнем углу окна можно выбрать один из видов представления кода в окне.

  • Procedure View (Представление процедуры), когда в окне отображается только одна выбранная процедура.
  • Full Module View (Представление полного модуля), когда в окне отображается сразу несколько процедур, отделенных друг от друга тонкой линией.

Для настройки параметров редактора используется также диалоговое окно Options (Параметры), которое можно открыть, выбрав команду Options в меню Tools (Сервис) (рис. 13.14). Это окно описывает только параметры редактора кода и вызывается из среды редактора кода.

Рис. 13.14. Диалоговое окно параметров редактора кода

Оно содержит четыре вкладки.

Первая вкладка Editor (Редактор) состоит из двух групп параметров: Code Settings и Window Settings.

  • Группа Code Settings (Программирование) содержит шесть флажков, которые позволяют включать и отключать интеллектуальные функции редактора, такие как автоотступ, автоматическая проверка синтаксиса, подсказки при написании пользователем программ.
  • Группа Window Settings (Параметры окна) включает в себя три флажка, влияющих на представление кода в окне редактора. Эти флажки позволяют переключаться между представлениями полного модуля и процедуры, выводить или не выводить на экран тонкие линии, разделяющие процедуры, включать или отключать функцию перетаскивания текста, т. е. перемещения выделенного фрагмента кода с помощью мыши.

Вторая вкладка Editor Format (Формат редактора) позволяет определить шрифт, его размер и цвет для разных областей текста. Открыв любой модуль, вы можете убедиться, что текст программ представлен несколькими цветами: по умолчанию комментарии выделяются зеленым цветом, ключевые слова — синим. При отладке программ используются и другие цветовые выделения фрагментов текста: точек останова, текущей команды и т. д. Все эти способы выделения могут быть настроены в соответствии с вашим вкусом в данном окне.

Третья вкладка General (Общая) содержит несколько групп переключателей и флажков.

  • Группа Form Grid Setting относится к созданию форм в Microsoft Visual Basic 6.0 и в других компонентах Office и не используется в Access.
  • Флажок Show ToolTips позволяет включить или отключить вывод всплывающих подсказок для кнопок на панели инструментов.
  • Флажок Collapse Proj. Hides Windows определяет, будет ли скрываться окно редактора при закрытии проекта на панели проекта.
  • Флажок Notify Before State Loss определяет, получит ли пользователь сообщение о том, что предпринимаемое действие вызовет потерю состояния текущего проекта.
  • Переключатели Error Trapping определяют установки по умолчанию, используемые при обработке ошибок в программах:
    • Break on All Errors — любая ошибка, независимо от того, обрабатывается ли она программой, приведет к прерыванию выполнения программы;
    • Break in Class Module — любая необработанная ошибка в модулях класса приведет к прерыванию выполнения программы;
    • Break on Unhandled Errors — прерывание программы вызывают все необработанные ошибки.

Последняя группа флажков определяет, когда компилируются модули проекта:

  • Compile On Demand — определяет, будут ли все модули проекта компилироваться перед началом работы или только по требованию, в первом случае запуск приложения будет более длительным;
  • Background Compile — определяет, будет ли компиляция модулей выполняться в фоновом режиме.

На последней вкладке Docking находятся флажки, позволяющие закрепить положение основных окон на экране.

Для того чтобы убедиться, что наши утверждения об интеллектуальности редактора не являются голословными, достаточно попробовать написать даже самую простую программу. Давайте заменим в форме «Клиенты» (Customers) макрос, который открывает форму «Заказы» (Orders) при нажатии кнопки Заказы клиента, процедурой VBA, которая выполняет те же действия. Мы создавали такой макрос в разд. «Назначение макроса событию»гл. 11. Если вы этого не делали, тогда создайте сейчас командную кнопку в области заголовка окна и назовите ее «Заказы клиента» (кнопка Мастера на панели элементов при этом должна быть отжата).

После этого нажмите кнопку Программа (Code) на панели инструментов. Откроется редактор кода VBA, который по умолчанию попытается создать процедуру обработки события Load формы. Выберите из списка слева объект Заказы клиента. Редактор автоматически вставит заголовок и концовку процедуры обработки события Click (рис. 13.15). Открыв список справа, вы можете увидеть, как много различных событий связано с командной кнопкой, однако наиболее часто используется именно событие Click. Так как с этим событием сейчас не связано никакой процедуры, редактор сразу пытается ее создать.

Начнем писать текст процедуры. Процедура будет состоять из нескольких команд. Нам необходимо открыть форму «Заказы» (Orders) и показать в этой форме только те заказы, которые относятся к определенному клиенту, поэтому придется задать условие для отбора записей в форме «Заказы» (Orders). Обычно для этого используют переменную типа string, которой сначала присваивают нужное значение, а потом подставляют в качестве параметра в макрокоманду Открытьформу (OpenForm). Чтобы использовать такую переменную, ее сначала нужно описать, поэтому первое предложение в процедуре должно быть следующим:

Dim stLinkCriteria As String

Рис. 13.15. Создание процедуры обработки события

Как только вы напишете первые три слова Dim stLinkCriteria As, на экране появится список слов (рис. 13.16), которые могут быть использованы в данном предложении.

Рис. 13.16. Автоматический вывод списка компонентов

Вы набираете следующие буквы — str, после чего курсор в списке устанавливается на слове string. Дальше можно не продолжать, а просто нажать клавишу — конец слова допишется автоматически. Нажмите клавишу , курсор перейдет на новую строку, а текст во введенной строке изменится: все ключевые слова — Dim, As, string — будут выделены синим цветом. При вводе ключевых слов можно не беспокоиться о том, чтобы слово начиналось с заглавной буквы. Вы можете набирать весь текст строчными буквами — необходимое преобразование будет выполняться автоматически. Но, конечно, названия переменных, элементов управления и других объектов, на которые имеются ссылки в тексте, вы должны вводить сами с использованием нужного регистра, т. к. в них преобразования выполняться не будут.

Следующая строка будет присваивать переменной strLinkCriteria значение: stLinkCriteria = «=» & «‘» & Me! & «‘»

Две формы будут связаны по значению поля CustomerID. Первое выражение относится к форме «Заказы» (Orders), а второе значение Me! — к текущей форме «Клиенты» (Customers), о чем говорит слово Me. Теперь используем макрокоманду Открыть форму (OpenForm) для того, чтобы открыть форму «Заказы» (Orders). Как только набирается docmd, появляется новая подсказка — список макрокоманд (рис. 13.17).

Рис. 13.17. Автоматический вывод методов объекта

Уже известным способом выбираем нужную макрокоманду, нажимаем пробел и опять подсказка — синтаксис макрокоманды Открыть форму (OpenForm) (рис. 13.18).

Рис. 13.18. Автоматический вывод кратких сведений

И это очень кстати, т. к. позволяет не запоминать все аргументы макрокоманды и порядок их следования. Введите имя формы: Заказы (Orders), запятую, и опять появится подсказка с именами возможных констант, которые могут быть указаны в следующем параметре. Выберите константу acNormal и продолжайте ввод. Должна получиться строка:

DoCmd.OpenForm «Заказы», acNormal, , stLinkCriteria

Две следующие подряд запятые говорят о пропущенном параметре — имя фильтра.

Теперь добавим еще одну команду — изменим заголовок формы:

Forms!Заказы.Caption = «Заказ» & Название

И наконец, напишем комментарий, который объясняет, что делает данная программа. Для этого поместите курсор в начало второй строки программы и нажмите клавишу . Появится пустая строка. Введите символ (‘) в начало новой строки и пишите дальше текст комментария. Закончите ввод нажатием клавиши , и вы увидите, что комментарий оказался выделен зеленым цветом. В целом текст программы должен выглядеть как на рис. 13.19.

Рис. 13.19. Программа открытия формы «Заказы»

На примере этой простой программы мы продемонстрировали три очень полезных свойства редактора.

  • Автоматическая проверка синтаксиса — ввод команды успешен и все слова выделяются нужным цветом, только когда синтаксис предложения правилен, в противном случае вы услышите звуковой сигнал, текст будет выделен красным цветом и появится сообщение об ошибке.
  • Автоматический вывод списка компонентов Auto List Members позволяет избежать ошибок при вводе наименований свойств объектов, встроенных констант, типов переменных. Особенно эта функция полезна при установке свойств, т. к. позволяет не только вспомнить правильное имя свойства, но и увидеть, какие свойства объекта доступны в данный момент.
  • Автоматический вывод кратких сведении Auto Quick Info показывает в виде всплывающей подсказки синтаксис встроенных функций и макрокоманд. По мере ввода параметров очередной параметр выделяется в подсказке жирным шрифтом.

Когда вы уже усвоите язык VBA, такие подсказки могут показаться вам навязчивыми. Тогда вы можете отключить их, сбросив соответствующие флажки в диалоговом окне Options (Параметры) редактора кода (вкладка Editor).

Однако при необходимости вы легко получите требуемую помощь, если воспользуетесь контекстным меню редактора кода (рис. 13.20).

Рис. 13.20. Контекстное меню редактора кода

Кроме описанных выше функций, в контекстном меню присутствуют и другие очень полезные функции, способствующие быстрому написанию кода, — List Constants, Parameter Info, Complete Word, а также две команды, очень упрощающие навигацию среди программных модулей:

  • Definition. Если в процедуре выполняется вызов другой процедуры, то, установив курсор на имя вызываемой процедуры и выбрав из контекстного меню команду Definition (а еще быстрее, нажав комбинацию клавиш +), вы сразу попадете в тело вызываемой процедуры;
  • Last Position — позволяет после такого перехода вернуться обратно.

Команда Definition позволяет также быстро открыть окно Object Browser и посмотреть описание нужного свойства, метода или объекта приложения. Для этого нужно установить курсор на интересующий объект, свойство, метод и нажать комбинацию клавиш +.

Окно Object Browser (Обозреватель объектов) позволяет просматривать все объекты, их свойства и методы, доступные для текущего проекта. Объекты могут быть встроенными объектами Access или VBA, объектами, которые вы создали в своем приложении, а также объектами, входящими во внешние библиотеки, на которые имеются ссылки в текущем проекте. Вызвать окно просмотра объектов можно тремя способами:

  • нажать клавишу — самый быстрый;
  • нажать кнопку Object Browser (Обозреватель объектов) на панели инструментов — удобный;
  • выбрать команду View, Object Browser (Вид, Обозреватель объектов) — если вы забыли другие способы.

Окно Object Browser (Обозреватель объектов) состоит из нескольких списков (рис. 13.21), которые обеспечивают трехуровневое представление информации.

Список Project/Library (Проект/Библиотека) в левом верхнем углу окна содержит перечень всех библиотек и проектов, на которые имеются ссылки в данном проекте. Как минимум, он включает библиотеку Access, библиотеку VBA, библиотеку текущего проекта.

При выборе из списка одной из библиотек в нижнем левом поле Classes (Классы) отображается список следующего уровня — перечень всех объектов, входящих в эту библиотеку. Например, если выбрать библиотеку Access, то в списке Classes вы увидите много знакомых объектов. Выбрав один из них, например DoCmd, в правом поле Members of можно увидеть все методы этого объекта. Если бы мы выбрали объект Form, то в списке справа отобразились бы все свойства и методы объекта Form.

Рис. 13.21. Окно просмотра объектов

При этом в нижней части окна, которая называется область описания, отображается описание выбранного элемента.

Если выбрать в поле Project/Library (Проект/Библиотека) текущее приложение «Борей» (Northwind), то в поле Classes (Классы) отобразятся все модули форм, отчетов и стандартные модули приложения (рис. 13.22).

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

Рис. 13.22. Объекты приложения «db1»

Для поиска необходимого объекта, метода или свойства существует поле Search Text (Образец поиска). Это второе поле со списком в верхней части окна. В него можно ввести фрагмент текста для поиска и нажать кнопку с биноклем, которая находится рядом. Тогда открывается дополнительная область Search Results (Результаты поиска), в которой отображается список компонентов, удовлетворяющих условию поиска (рис. 13.23).

Рис. 13.23. Отображение результатов поиска

Выделив в списке нужную строку, можно снова воспользоваться кнопкой View Definition, чтобы открыть нужную процедуру.

Еще одна очень полезная кнопка в этом окне Copy to Clipboard (Копировать в буфер обмена). Она позволяет копировать выбранный объект в буфер, после чего объект можно будет вставить прямо в текст программы.

При обращении к объекту из процедуры VBA вы можете получить сообщение об ошибке, которое может быть вызвано тем, что не подключена соответствующая библиотека. При установке Access по умолчанию подключаются следующие библиотеки:

  • Visual Basic for Application;
  • Microsoft Access 10.0 Object Library;
  • Microsoft DAO 3.6 Object Library.

Все остальные библиотеки при необходимости должны быть подключены вручную, для чего нужно установить ссылку на соответствующую библиотеку.

Откройте редактор VBA и выполните команду Tools, References (Сервис, Ссылки). В открывшемся диалоговом окне References (Ссылки) (рис. 13.24) найдите требуемую библиотеку и установите необходимый флажок.

Рис. 13.24. Диалоговое окно References

Все библиотеки, на которые установлены ссылки, помещаются в начале списка, причем, пользуясь кнопками Priority, вы можете поменять порядок их следования. Обращение к этим библиотекам при разрешении ссылок на объекты выполняется в том порядке, в каком они следуют в списке.

Помимо интеллектуального редактора текста профессиональная среда программирования обычно содержит инструментальные средства отладки. Инструментальные средства отладки призваны дать разработчику максимально ясное представление о том, как работает его программа. И уже искусство разработчика состоит в том, чтобы, используя все имеющиеся в его распоряжении средства, быстро выявить ошибки. Набор средств отладки в Access широк: это и специальное меню Debug (Отладка), и во многом дублирующие его кнопки на панели инструментов, и специальные окна отладки. Далее кратко дается описание каждого средства.

Меню Debug (Отладка) и специальная панель инструментов Debug (Отладка) представлены на рис. 13.25. Назначение команд меню описано в табл. 13.11.

Рис. 13.25. Меню и панель инструментов Debug

Команда  Назначение 
Compile (Компиляция) Компилирует все модули в текущей базе данных
Step Into (Шаг с за ХОДОМ) Исполняет очередную строку кода с заходом в процедуры
Step Over (Шаг с обходом) Исполняет очередную строку кода без захода в процедуры, т. е. функции и процедуры выполняются за один шаг
Step Out (Шаг с выходом) Выполняет остаток текущей процедуры и останавливается в вызывающей программе на следующей строке после вызова этой процедуры
Run to Cursor (Запуск до курсора) Выполняются все строки кода от текущей строки до строки, в которой установлен курсор. Останавливается перед этой строкой
Add Watch (Добавление контрольного значения) Открывает окно Добавление контрольного значения
Edit Watch (Изменение контрольного значения) Открывает окно Изменение контрольного значения
Quick Watch (Быстрый просмотр) Выводит в специальном окне текущее значение выражения в точке останова
Toggle Breakpoint (Установка/сброс точек останова) Устанавливает/снимает точку останова на строку, в которой находится курсор
Clear All Breakpoints (Сброс всех точек останова) Снимает все точки останова, установленные в данном модуле
Set Next Statement (Установка следующего предложения) Устанавливает очередную выполняемую команду на строку, в которой находится курсор
Show Next Statement (Показ следующего предложения) Отображает в окне редактора очередную команду для выполнения

Таблица 13.11. Команды меню Debug

Кнопки на инструментальной панели в основном повторяют описанные команды. Это видно из значков, находящихся рядом с командой и на кнопках. Кроме того, здесь существуют кнопки, соответствующие меню Run:

  • Run Sub/UserForm — продолжает выполнение процедуры после точки останова, снимая при этом пошаговый режим, если он был установлен;
  • Break — прекращает выполнение процедуры;
  • Reset (Сброс) — прекращает выполнение процедуры и присваивает переменным начальные значения по умолчанию.

Еще несколько кнопок инструментальной панели позволяют открыть специальные окна отладки.

Специальные окна отладки используются главным образом для того, чтобы просматривать промежуточные значения данных: переменных, выражений, свойств объектов и т. д. К ним относятся два окна: Locals (Локальные) и Watches (Контрольные). Чтобы познакомиться с этими окнами, давайте установим точку останова на одной из команд написанной нами ранее процедуры 3aKaaH_Click в форме «Клиенты» (Customers). Для этого нужно:

  1. Открыть данную процедуру в окне редактора кода, как это описывалось выше.
  2. Установить курсор на строку DoCmd.OpenForm «Заказы», acNormal, stLinkCriteria
  3. Нажать кнопку на панели инструментов с изображением руки или выбрать команду Toggle Breakpoint в меню Debug. Строка будет выделена коричневым фоном и на панели слева, напротив этой строки, появится специальный значок — жирная коричневая точка.

Совет

Самый простой и естественный способ установки точек останова: щелкните мышью по серой полосе у левого края окна редактора напротив нужной строки. Снять точку можно щелчком мыши по коричневой точке напротив нужной строки.

Теперь окно модуля можно закрыть, открыть форму «Клиенты» (Customers) в режиме формы и нажать кнопку Заказы клиента. При нажатии этой кнопки запускается наша процедура обработки событий и, как только выполнение дойдет до помеченной строки, произойдет останов, а на экране появится окно редактора кода, в котором помеченная строка выделена желтым цветом, означающим, что это текущая команда. Нажмите кнопку Local Window или выберите соответствующую команду из контекстного меню редактора. Тогда в нижней части экрана появится новое окно Locals (Локальные) (рис. 13.26). В этом окне можно увидеть все локальные переменные и константы текущей процедуры, а также иерархический список свойств всех объектов формы, который скрывается за коротеньким словом ме. Именно эти свойства и интересуют, как правило, разработчика, т. к. в большинстве случаев значения переменных в точке останова можно увидеть просто подведя курсор к этой переменной в окне редактора. Тогда появляется всплывающая подсказка со значением переменной, как это показано на рис. 13.26.

Замечание

Если подсказка не появляется, проверьте значение флажка Auto Value Tips на вкладке Editor окна Options.

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

Рис. 13.26. Установка точки прерывания в программе

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

Для того чтобы отследить контрольные значения, их сначала нужно задать. Для этого используется команда Add Watch (Добавить контрольное значение) в меню Debug (Отладка). Добавлять контрольные значения можно как в обычном режиме редактирования кода, так и в режиме останова. При выборе команды появляется диалоговое окно Add Watch (Добавление контрольного значения) (рис. 13.27). В поле Expression (Выражение) можно ввести контрольное значение — это может быть переменная, свойство или любое допустимое выражение. Давайте введем в это поле условие останова приложения stbinkcritria «», а в группе переключателей Watch Type (Тип контрольного значения) выберем переключатель Break When Value Is True (Останов, если значение истинно).

Рис. 13.27. Добавление контрольного значения

Замечание

Группа Context (Контекст) в окне Add Watch позволяет определить область контроля заданного значения или выражения: конкретная процедура текущего модуля, все процедуры текущего модуля или все модули текущей базы данных.

Рис. 13.28. Окно Watches редактора кода

Теперь нужно снять точку останова, которую мы установили. Для этого щелкните правой кнопкой мыши в строке останова и выберите команду Toggle, Breakpoint из контекстного меню (или нажмите клавишу ). Строка примет обычный вид.

Закройте окно редактора кода и снова нажмите кнопку Заказы клиента в форме ‘Клиенты» (Customers). Выполнение программы остановится на той же команде. Нажмите кнопку Watch Window на панели инструментов или выберите соответствующую команду в меню View. В нижней части редактора появляется новое окно Watches (рис. 13.28), в котором будет выведена одна строка, содержащая контрольное выражение, его значение, тип и контекст, т. е. процедура, в которой вычисляется контрольное значение. Выражение истинно, и программа остановлена.

Существует очень простой способ добавления контрольных значений в окно Watches. Можно просто выделить в тексте процедуры выражение и перетащить его в это окно мышью. Попробуйте проделать эту операцию с выражением Forms! Заказы. Caption и выполните несколько шагов процедуры, наблюдая, как изменяется выражение в окне Watches.

Окно Quick Watch (Быстрый просмотр) используется для просмотра значения свойства, переменной или выражения, которое не определено заранее как контрольное значение. Чтобы открыть это окно, необходимо:

  1. Выделить в тексте программы интересующее выражение.
  2. Нажать кнопку Quick Watch на панели инструментов, или выбрать команду Debug, Quick Watch (Быстрый просмотр), или нажать комбинацию клавиш +.

Диалоговое окно на рис. 13.29 отображает значение переменной stLinkCriteria.

Рис. 13.29. Диалоговое окно Quick Watch

Если вы решите добавить выбранное выражение к контрольным значениям, просто нажмите кнопку Add (Добавить).

Кроме всех перечисленных окон отладки, в Access 2002 сохранилось окно Immediate (Отладка) для тестирования данных и процедур, которое присутствовало еще в Access 2.0. Это окно может быть использовано двояким образом: можно вручную проверить значение выражения с помощью команды Print или «?» (рис. 13.30) или, вставив в код программы команду Debug.Print, посмотреть в этом окне контрольную печать.

Рис. 13.30. Окно Immediate

Окно Immediate открывается при нажатии кнопки Immediate Window на панели инструментов, или при выполнении соответствующей команды в меню View, или при нажатии комбинации клавиш +. Это окно отображается на экране, даже если окно редактора закрыто и выполняется приложение. При этом в нем можно наблюдать значения указанных данных. Выводить в это окно можно любые допустимые выражения, включая свойства объектов.

Для того чтобы вывести значение переменной, нужно ввести знак «?» и имя переменной и нажать клавишу . Значение переменной отобразится на следующей строке.

Метод Print объекта Debug направляет вывод в это окно в процессе выполнения программы. Например, команда

 Debug.Print "Цена.Enabled = "; Цена.Enabled

печатает значение свойства Доступ (Enabled) поля «Цена» (UnitPrice) в окне Immediate.

В окне Immediate можно не только выводить значения переменных и свойств, но и задавать их, например можно в режиме останова ввести команду

 Цена.Enabled = True

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

Окно Call Stack (Стек вызовов) содержит список всех незавершенных процедур приложения и используется для трассировки вложенных процедур. При этом самая перва из вызванных процедур будет размещаться в нижней части стека, а самая последняя — в верхней части. Наименование процедуры состоит из трех частей: имени проекта, имени модуля (в том числе модуля формы), имени процедуры (рис. 13.31).

Рис. 13.31. Диалоговое окно Call Stack

Выбрав в стеке нужную процедуру, можно нажать кнопку Show (Показать), тогда окно Call Stack закроется и в окне кода модуля появится выбранная процедура. При этом курсор устанавливается на строку кода, вызывающую следующую процедуру из стека. Если выбирается текущая процедура, то курсор устанавливается на текущую команду.

Окно Call Stack вызывается несколькими способами:

  • нажать кнопку Call Stack на панели инструментов;
  • выбрать команду View, Call Stack;
  • нажать комбинацию клавиш +;
  • нажать кнопку с многоточием в верхнем правом углу окна Locals.

Данное окно может быть открыто только в режиме останова.

Поскольку работа в редакторе — это главным образом работа с клавиатурой, существует большое количество специальных клавиш и комбинаций клавиш быстрого вызова для выполнения определенных функций. Вы можете увидеть их в меню Run, Debug и View. Список наиболее часто используемых клавиш и их комбинаций приведен в табл. 13.12.

Комбинация клавиш  Назначение 
Открыть окно редактора кода
+ Найти
+ Заменить
Найти далее
+ Найти ранее
+ К следующей процедуре
+ К предыдущей процедуре
+ List Properties/Members
++ List Constant
+ Quick Info
++ Parameter Info
+ Закончить слово
Продолжить
+ Сброс
Шаг с заходом
+ Шаг с обходом
++ Шаг с выходом
Установка/сброс точки останова
+ Вызов окна Quick Watch
++ Сброс всех точек останова
Вызов окна просмотра объектов Object Browser
+ Definition
++ Last Position
+ Вызов окна Immediate
+ Вызов окна Call Stack

Таблица 13.12. Комбинации клавиш быстрого вызова редактирования и отладки кода VBA

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

В данном разделе мы хотим сделать обзор этих событий и описать последовательность их возникновения с тем, чтобы читатель мог их правильно использовать.

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

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

В Microsoft Access 2002 появилось несколько новых событий для формы, связанных с выполнением транзакций. Эти события возникают только в формах проекта Access и в данном разделе рассматриваться не будут (о проектах Microsoft Access см. гл. 17). Кроме того, в связи с появлением двух новых режимов формы: Сводной таблицы и Сводной диаграммы, появились события, позволяющие программно управлять отображением данных в этих режимах: После конечного отображения (AfterFinalRender), До разметки (AfterLayout), После отображения (AfterRender), До отображения (BeforeRende), До экранной подсказки (BeforeScreenTip), Изменение представления (ViewChange), До запроса (BeforeQuery), Запрос (Query), До выполнения команды (CommandBeforeExecute), Включение команды (CommandEnabled), Выполнение команды (CommandExecute), Проверка команды (CommandChecked), Изменение набора данных (DataSetChange), Изменение сводной таблицы (PivotTableChange), Изменение выбора фрагмента (SelectionChange), Соединение (OnConnect), Отсоединение (OnDisconnect). Эти события также не будут здесь рассматриваться. При необходимости обработки этих событий вы можете найти информацию о них в справке Access в разделе Программирование в Visual Basic, Microsoft Access Visual Basic Reference, Events.

К этому типу относятся события, происходящие тогда, когда пользователь вводит, удаляет или изменяет данные в форме, а также перемещается от одной записи к другой.

Текущая запись

Событие Текущая запись (Current) происходит, когда очередная запись получает фокус или выполняется повторное обращение к источнику данных формы — таблице или запросу. Таким образом, оно возникает как при открытии формы, так и при переходе от одной записи к другой. Чаще всего это событие используется для синхронизации записей в связанных формах.

Удаление

Событие Удаление (Delete) происходит, когда пользователь пытается удалить запись из формы. Оно происходит до того, как запись реально удаляется из базы данных. Процедура обработки этого события имеет параметр Cancel. Установка значения этого параметра в процедуре равным True позволит предотвратить удаление записи.

До подтверждения Del

Удаление записи из базы данных имеет такое большое значение, что с ним связано несколько событий. После события Удаление (Delete) Access выдает специальное окно, запрашивающее подтверждение удаления записи. Событие До подтверждения Del (BeforeDelConfirm) возникает до появления этого окна. Процедура обработки данного события имеет два параметра: Cancel и Response. Присваивая в процедуре значение True параметру Cancel, можно отменить удаление, и окно подтверждения выдаваться на экран не будет. Так что это еще одна возможность отменить удаление программно (третья возможность отмены будет предоставлена пользователю в диалоговом окне подтверждения удаления). Если же параметру Cancel присвоить значение False, то параметр Response можно использовать, чтобы определить, нужно ли выдавать окно подтверждения. Если Response = 1, то запись будет удалена без подтверждения, если же Response установить равным 0, то Access выдаст окно, запрашивающее у пользователя подтверждение удаления записи.

Замечание

Если окно подтверждения удаления не выдается или событие До подтверждения Del (BeforeDelConfirm) не возникает, проверьте установку флажка Изменения записей (Record Changes) в окне Параметры (Options) (на вкладке Правка и поиск, группа Подтверждение).

После подтверждения Del

Событие После подтверждения Del (AfterDelConfirm) происходит как после подтверждения удаления записи, так и при отмене удаления. Процедура обработки данного события имеет один параметр — status, который принимает значения О, 1 или 2 и определяет, была ли удалена запись. Значение 0 указывает, что запись была успешно удалена, 1 означает, что удаление отменено программой обработки события, а значение 2 указывает, что удаление было отменено пользователем в окне подтверждения удаления. Это событие может быть использовано в программе для проверки, была ли удалена запись.

До вставки

Со вставкой новой записи связаны два события: До вставки (Beforelnsert) и описанное далее После вставки (AfterInsert). Событие До вставки (Beforelnsert) происходит, как только пользователь вводит первый символ в новую запись (одно из полей, необязательно первое), но до того, как запись фактически будет создана. Процедура обработки этого события может быть использована для проверки того, разрешена ли вставка. Процедура имеет один параметр: Cancel. Если установить его значение равным True, то вставка записи будет запрещена. После этого события отменить вставку будет уже нельзя, можно только удалить вставленную запись.

После вставки

Событие происходит после того, как в таблицу добавлена новая запись. Обычно это бывает при переходе к следующей записи в форме. Процедура обработки этого события обычно используется для того, чтобы сделать повторный запрос к источнику данных с целью вывода новой записи.

До обновления

Событие До обновления (BeforeUpdate), так же как и следующее событие После обновления (AfterUpdate), возникает при любом изменении данных в записи или элементе управления. Это событие может относиться как к элементу управления, так и к записи в целом. Процедура обработки данного события имеет один параметр — Cancel, использующийся для того, чтобы отменить введенные изменения. Для этого ему необходимо присвоить значение True. Данное событие обычно применяется с целью проверки условий на значение в поле таблицы или записи в целом, если эти условия сложные (простые условия обычно задаются в свойстве Условие на значение (ValidationRule) элемента управления). Условия проверяются сразу для нескольких значений, причем в них используются ссылки на элементы управления в других формах. При разных значениях введенных данных выдаются разные сообщения об ошибках.

При невыполнении условий можно отменить введенные изменения перед переходом на другую запись.

В следующем разделе будет описан порядок возникновения событий, относящихся как к элементу управления, так и к записи в целом.

После обновления

Событие После обновления (AfterUpdate) происходит после обновления данных в записи или элементе управления. И хотя обновление уже произошло, можно восстановить старые значения, воспользовавшись свойством OldValue элемента управления. Оно сохраняет старое значение элемента управления, которое сменится только после события После обновления (AfterUpdate).

Замечание

События До обновления (BeforeUpdate) и После, обновления (AfterUpdate), а также До вставки (Beforelnsert) и После вставки (Afterlnsert) не возникают, когда значения элементов управления формы изменяются с помощью программы VBA или макрокоманды УстановитьЗначение (SetValue). Кроме того, события До обновления (BeforeUpdate) и После обновления (AfterUpdate)He возникают для вычисляемых элементов управления.

Изменение

Событие Изменение (Change) возникает в следующих случаях:

  • при изменении содержимого текстового поля или поля со списком, при этом изменением может считаться любой непосредственно введенный или удаляемый символ;
  • при изменении значения свойства Текст (Text) элемента управления с помощью макроса или процедуры VBA;
  • в элементе управления Набор вкладок (Tab Control) при переходе с одной вкладки на другую.

Замечание

Событие Изменение (Change) не возникает при изменении значения вычисляемого элемента управления, а также, если с помощью макроса или программы VBA установлено значение текстового поля или поля со списком или если значение поля со списком выбрано из списка.

Некорректная программа обработки данного события может привести к каскадным событиям. Чтобы избежать этого, не следует использовать в настоящей процедуре команды, которые меняют содержимое элемента управления, а также не стоит создавать два и более поля, которые воздействуют друг на друга, например обновляют друг друга.

Отсутствие в списке

Событие Отсутствие в списке (NotlnList) возникает в поле со списком, когда пользователь вводит вручную значение в текстовую часть поля, которое отсутствует в списке, и после этого пытается перейти в другое поле или сохранить запись. Для того чтобы данное событие происходило, нужно присвоить свойству Ограничиться списком (LimitToList) значение Yes. Если это свойство имеет значение No, то разрешается ввод в поле данных, не совпадающих ни с одним значением из списка. Процедура обработки настоящего события имеет два параметра: NewData и Response. Параметр NewData содержит введенные данные, a Response управляет обработкой события и может иметь значения 0, 1 или 2. Значение 0 позволяет вывести на экран стандартное сообщение о том, что введенные данные отсутствуют в списке, и запретить ввод. Значение 1 позволяет вместо стандартного сообщения вывести специальное сообщение, например запрашивающее, следует ли сохранить введенное значение. Новые данные при этом не добавляются в список. Значение 2 разрешает добавить новое значение в список. При этом в процедуре обработки данного события нужно добавить значение к источнику строк для поля со списком, после чего поле обновляется, т. к. Access повторно запрашивает источник строк.

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

Внесены изменения

Событие Внесены изменения (Dirty), так же как и Изменение (Change), возникает в следующих ситуациях:

  • при изменении содержимого текстового поля или поля со списком, при этом изменением может быть любой непосредственно введенный или удаляемый символ;
  • при изменении значения свойства Текст (Text) элемента управления с помощью макроса или процедуры VBA;
  • в элементе управления Набор вкладок (Tab Control) при переходе с одной вкладки на другую.

Но в отличие от события Изменение (Change) оно относится к форме. Процедура имеет один параметр: Cancel. Если установить его значение равным True, то событие будет отменено. Отмена события будет вызывать откат всех изменений в записи, что эквивалентно нажатию клавиши . Это событие удобно использовать для проверки, были ли изменения в записи.

При обновлении

Событие При обновлении (Updated) возникает при изменении объекта OLE и применяется только к свободным и присоединенным рамкам объекта.

Процедура обработки данного события используется для проверки, были ли данные в объекте OLE изменены после последнего сохранения. Процедура имеет один параметр — Code, который указывает, каким образом обновлялся объект, и может иметь значения 0, 1, 2 и 3. Значение 0 указывает, что данные объекта изменены. Значение 1 указывает, что данные объекта сохранялись приложением, создавшим объект. Значение 2 указывает, что файл объекта OLE закрывался приложением, которое его создало. Значение 3 указывает, что файл объекта OLE переименован создавшим его приложением.

Уход с записи

Событие Уход с записи (RecordExit) происходит всякий раз, когда пользователь пытается выйти (переместить фокус) с текущей записи: перейти к другой записи, закрыть форму, обновить данные в форме и т. д. Процедура обработки этого события может использоваться для проверки корректности данных в текущей записи. Процедура имеет один параметр: cancel. Если установить его значение равным True, то можно запретить пользователю покидать текущую запись.

Отмена

Событие происходит, когда пользователь отменяет изменения, сделанные в текущем поле или текущей записи, например, нажав клавишу или кнопку $$ (Undo Field/Record) на панели инструментов. Процедура обработки этого события имеет один параметр: Cancel. Установив его значение равным True, можно прервать операцию отмены, и тогда данные в текущем поле или записи останутся измененными.

События фокуса происходят, когда форма, отчет или элемент управления в форме получают или теряют фокус, а также когда форма или отчет становятся активными или, наоборот, неактивными.

Вход

Событие Вход (Enter) происходит перед тем, как элемент управления в форме получает фокус от другого элемента управления в той же форме или когда при открытии формы получает фокус первый элемент управления. Его удобно использовать для вывода на экран каких-либо сведений об этом элементе. Оно происходит до события Получение фокуса (GetFocus), но после события Текущая запись (Current).

Выход

Событие Выход (Exit) происходит перед тем, как данный элемент управления передаст фокус другому элементу управления той же формы, но до события Потеря фокуса (LostFocus).

Замечание

События Вход (Enter) и Выход (Exit) не определены для флажков и переключателей в группах, они определены только для группы как целого. События Вход (Enter) и Выход (Exit) не происходят, если фокус переходит к элементу другой формы или отчета. Это отличает их от событий Получение фокуса (GetFocus) и Потеря фокуса (LostFocus).

Получение фокуса

Событие Получение фокуса (GetFocus) происходит, когда форма или элемент управления формы получают фокус. Элемент управления может получить фокус, только если оно видимо и доступно (его свойства Вывод на экран (Visible) и Доступ (Enabled) имеют значения Да). При этом событие Получение фокуса (GetFocus) происходит после события Вход (Enter). Форма может получить фокус, только если все поля в ней заблокированы, в противном случае событие Получение фокуса (GetFocus) для формы не возникает.

Потеря фокуса

Событие Потеря фокуса (LostFocus) происходит каждый раз, когда форма или элемент управления в форме теряют фокус. Событие происходит после события Выход (Exit).

Замечание

События Получение фокуса (GetFocus) и Потеря фокуса (LostFocus) происходят не только, когда фокус перемещается путем действий пользователя (с помощью клавиатуры или мыши), но и в результате вызова метода SetFocus объекта в форме или выполнения макрокоманд

ВыделитьОбъект(SelectObject), НаЗапись(GoToRecord), КЭлементуУправления(GoToControl) и НаСтраницу(GoToPage).

Кроме того, эти события определены для элементов (флажков и переключателей) внутри группы.

Включение

Событие Включение (Activate) возникает, когда форма или отчет получают фокус, становясь активной формой или отчетом. Это происходит, когда форма или отчет открываются, когда пользователь щелкает мышью на одном из элементов управления, перенося, таким образом, фокус, и когда в программе VBA выполняется метод SetFocus объекта. Форма при этом обязательно должна быть видима. Событие Включение (Activate) возникает до события Получение фокуса (GetFocus). Это событие удобно использовать для того, чтобы вывести на экран панель инструментов, связанную с формой.

Отключение

Событие Отключение (Deactivate) происходит, когда фокус из формы или отчета переносится на другое окно (таблицы, запроса, формы, отчета, макроса, модуля или окно базы данных). Однако это событие не возникает, когда фокус переходит в диалоговое окно или другое приложение. Событие Отключение (Deactivate) возникает после события Потеря фокуса (LostFocus).

События клавиатуры происходят в форме и элементе формы, когда пользователь нажимает клавиши на клавиатуре или же выполняется макрокоманда sendKeys.

Все события клавиатуры связываются с тем объектом в форме, который имеет в данный момент фокус. Обычно это один из элементов управления. Форма может получить фокус (а значит, и события клавиатуры могут относиться к форме), только если все ее элементы управления заблокированы или невидимы. Если нужно привязать эти события именно к форме, а не к элементу формы, то можно присвоить свойству Перехват нажатия клавиш (KeyPreview) для формы значение Да (Yes). Тогда все события клавиатуры возникают сначала для формы, а потом уже для элемента управления, имеющего фокус. Это дает возможность запрограммировать реакцию формы на нажатие определенных клавиш вне зависимости от того, в каком элементе управления формы находится фокус.

Замечание

События клавиатуры не определены для элементов управления в отчетах, а также для флажков и переключателей в группах. Они определены только для группы в целом.

Клавиша вниз и Клавиша вверх

События Клавиша вниз (KeyDown) и Клавиша вверх (KeyUp) возникают всякий раз, когда пользователь нажимает или отпускает клавишу на клавиатуре и при этом фокус находится на элементе управления или форме. Процедуры обработки этих событий используют, когда требуется определить, какую клавишу нажал пользователь — функциональную, клавишу управления курсором, клавишу цифровой панели или комбинацию клавиш с , или . Они имеют два параметра: KeyCode и Shift. Параметр KeyCode — это целое число, представляющее код нажатой клавиши. Параметр Shift позволяет определить, какие сочетания клавиш нажимались: 1 — соответствует , 2 — , 4 — , 0 — не использовалось сочетание клавиш. Если же нажималась комбинация клавиш , , в любом сочетании, то параметр Shift будет равен сумме значений каждой клавиши.

Нажатие клавиши

Событие Нажатие клавиши (KeyPress) происходит, если пользователь нажимает и отпускает любую комбинацию клавиш для элемента управления или формы, имеющей фокус. В отличие от событий Клавиша вниз (KeyDown) и Клавиша вверх (KeyUp), данное событие не происходит, когда нажимаются функциональные клавиши, клавиши управления курсором и клавиши , или . Кроме того, эти события различны для верхнего и нижнего регистров. Процедура обработки настоящего события имеет один аргумент: KeyAscii — целое число, представляющее код нажатой клавиши.

Если пользователь нажимает и удерживает некоторую клавишу, то возникают повторяющиеся события Клавиша вниз (KeyDown) и Нажатие клавиши (KeyPress) до тех пор, пока он не отпустит клавишу. Тогда возникает событие Клавиша вверх (KeyUp).

Если результатом нажатия клавиши является перевод фокуса с одного элемента на другой, то событие Клавиша вниз (KeyDown) возникает для первого элемента, а события Нажатие клавиши (KeyPress) и Клавиша вверх (KeyUp) — для второго.

Если в результате нажатия клавиши появляется диалоговое окно, то возникают события Клавиша вниз (KeyDown) и Нажатие клавиши, а событие Клавиша вверх (KeyUp) не возникает.

События мыши происходят, когда какое-либо действие в форме или ее элементе управления выполняется с помощью мыши. События мыши не определены для элементов управления в отчетах, а также для флажков и переключателей в группах, они определены только для группы в целом.

Нажатие кнопки

Это наиболее широко распространенное событие. Оно возникает как в самой форме, так и в элементах управления формы. Для формы событие Нажатие кнопки (Click) возникает, когда пользователь щелкает мышью на пустой области формы или на области выделения записи в форме. Для элемента управления событие Нажатие кнопки (Click) возникает при щелчке мыши не только на самом элементе, но и на присоединенной к нему надписи. Однако для элемента управления оно возникает не только при щелчке мыши, но и в некоторых других случаях, а именно:

  • при выборе элемента из списка, независимо от того, был ли он выбран с помощью мыши или клавиш управления курсором с последующим нажатием ;
  • при нажатии клавиши , когда фокус установлен на флажке, переключателе или командной кнопке;
  • при нажатии клавиши в форме, которая содержит кнопку свойства По умолчанию (Default) со значением Да, тогда именно на эту кнопку по умолчанию устанавливается фокус;
  • при нажатии клавиши в форме, которая содержит кнопку свойства Отмена (Cancel) со значением Да;
  • при нажатии клавиш доступа, если они связаны с кнопками на форме.

Таким образом, процедуры обработки события Нажатие кнопки (Click) для кнопок запускаются независимо от того, каким образом эта кнопка выбрана — щелчком мыши, нажатием клавиши или клавиши доступа. Процедура обработки события запускается только один раз. Если требуется, чтобы она запускалась несколько раз, пока кнопка остается нажатой, необходимо использовать свойство Автоматический повтор (AtitoRepeat) для кнопки. Если нужно определить, какой кнопкой мыши выполнялся щелчок, следует использовать события Кнопка вниз (MouseDown) и Кнопка вверх (MouseUp).

Двойное нажатие кнопки

Событие Двойное нажатие кнопки (DblClick) происходит после быстрого двойного щелчка любой клавиши на форме или элементе управления, при этом интервал между щелчками не должен превышать предельного времени, заданного в панели управления Windows. Событие Двойное нажатие кнопки (DblClick) для формы и элемента управления формы определено так же, как и событие Нажатие кнопки (Click). Однако для элементов управления результат этого события зависит от типа элемента управления. По умолчанию двойной щелчок мыши в текстовом поле приводит к выделению слова, а в объекте OLE — запускает этот объект для редактирования. Вводя процедуру обработки для настоящего события, можно переопределить стандартные действия Access. Процедура имеет один параметр: Cancel. Если присвоить ему в процедуре значение True, то можно отменить это событие.

Замечание

Двойное нажатие кнопки мыши на элементе управления на самом деле вызывает сразу два события: сначала Нажатие кнопки (Click), а потом — Двойное нажатие кнопки (DblClick).

Перемещение указателя

Это событие генерируется непрерывно, когда пользователь перемещает указатель мыши по объектам формы. Пока указатель движется в границах объекта, событие Перемещение указателя (MouseMove) генерируется для данного объекта, когда указатель попадает на пустую область формы, область выделения записи или полосу прокрутки, генерируется событие Перемещение указателя (MouseMove) для формы. Событие возникает также при перемещении формы или элемента управления, например с помощью процедуры VBA, при неподвижном указателе мыши. Процедура обработки события имеет четыре параметра:

  • Button — определяет состояние кнопок мыши в момент возникновения события (перемещение указателя может происходить при нескольких нажатых или не нажатых кнопках мыши);
  • Shift — определяет состояние клавиш , и в тот момент, когда нажата кнопка, определяемая параметром Button;
  • X и Y — текущие координаты указателя мыши в типах.

Колесико мыши

Событие возникает, когда пользователь перемещает указатель мыши с помощью колесика скроллирования. Процедура обработки события имеет два параметра:

  • Page — принимает значение True при перемещении указателя на другую страницу;
  • Count — количество линий, на которое переместился указатель при прокрутке формы с помощью колесика мыши.

Кнопка вниз и Кнопка вверх

События Кнопка вниз (MouseDown) и Кнопка вверх (MonseUp) возникают, когда пользователь нажимает и, соответственно, отпускает кнопку мыши, и, в отличие от событий Нажатие кнопки (Click) и Двойное нажатие кнопки (DblClick), оно позволяет определить, какая кнопка нажата. Процедуры обработки этих событий имеют четыре параметра: Button, Shift, х и Y. Эти параметры аналогичны параметрам процедуры для события Перемещение указателя (MouseMove) за исключением первого параметра — Button. Так как в данном случае нажимается конкретная кнопка мыши, параметр Button определяет, какая это кнопка. Если пользователь нажмет сразу две кнопки, то возникнут отдельно события для первой и для второй кнопок.

Замечание

Если кнопка мыши была нажата, когда указатель находился на одном из элементов управления формы, то именно к этому объекту будут относиться все остальные события мыши до последнего Кнопка вверх (MouseUp) включительно.

События печати вызываются отчетом и любой из его областей при печати или предварительном просмотре.

Форматирование

Событие Форматирование (Format) происходит после того, как отобраны данные для отчета, но перед тем, как фактически форматируется каждый раздел отчета. При этом для раздела данных это событие происходит для каждой записи в отчете, что позволяет при необходимости по-разному форматировать каждую запись. Для заголовка группы в отчете событие возникает для каждой группы. Процедура обработки данного события имеет два параметра — Cancel и FormatCount. Cancel позволяет отменить форматирование данного раздела, для чего нужно присвоить ему значение True. Это дает вам возможность пропускать разделы отчета, не оставляя пустого места на странице. FormatCount — счетчик, который считает, сколько раз произошло событие Форматирование (Format).

Возврат

Событие происходит, если при форматировании раздела требуется вернуться к разделу, который уже отформатирован. Оно происходит после события Форматирование (Format), но до события Печать (Print). Процедура обработки данного события позволяет изменить любое уже выполненное форматирование и обеспечить, таким образом, нужное расположение элементов отчета на странице.

Замечание

Событие Возврат (Retreat) не определено для верхних и нижних колонтитулов отчета.

Печать

Событие Печать (Print) возникает после того, как выполнено форматирование раздела отчета, но до того, как он напечатан. Это событие возникает практически после каждого события Форматирование (Format), кроме тех разделов, которые не будут печататься. Так же, как и при форматировании, процедура обработки событий имеет два параметра: Cancel и PrintCount. Cancel позволяет отменить печать текущего раздела или текущей записи в отчете, для чего нужно присвоить ему значение True. Однако при этом остается пустое место на странице, поэтому данную процедуру можно использовать, когда изменения не касаются формата страницы отчета. PrintCount — счетчик, который считает, сколько раз произошло событие Печать (Print).

Страница

Событие Страница (Page) возникает после форматирования страницы отчета, но до вывода ее на печать, и позволяет с помощью процедуры обработки этого события добавить на страницу некоторые элементы оформления, например рамку.

Отсутствие данных

Событие Отсутствие данных (No Data) возникает после форматирования отчета, но до его вывода на печать (до первого события Страница (Page)) и позволяет обнаружить отсутствие записей для отчета, в этом случае печать можно отменить. Процедура обработки данного события имеет один параметр: Cancel, которому следует присвоить значение True, если нужно отменить печать отчета.

События фильтра происходят при применении или удалении фильтра в форме.

Применение фильтра

Событие Применение фильтра (ApplyFilter) возникает во всех случаях, когда пользователь выполняет фильтрацию записей в форме с помощью соответствующих команд меню, контекстного меню или кнопки панели инструментов (применить или удалить фильтр). Программу обработки этого события обычно используют либо для проверки условия в фильтре, либо для изменения вида формы перед применением фильтра, если требуется скрыть лишние поля или, наоборот, показать скрытые. Программа обработки события имеет два параметра — Cancel и ApplyType. Cancel позволяет отменить операцию фильтрации, если, например, условие сформулировано неправильно, для чего нужно присвоить ему значение True. ApplyType определяет исполняемое действие и может принимать значения 0, 1 и 2. Значение 0 указывает на удаление фильтра, 1 — на применение фильтра, 2 — на закрытие окна фильтра.

Замечание

Событие не возникает при выполнении операций фильтрации с помощью макрокоманд ПрименитьФильтр(ApplyFilter) , ОткрытьФорму(OpenForm), ПоказатьВсеЗаписи (ShowAllRecords), соответствующих им методов объекта DoCmd, или при закрытии окна фильтра (любого) с помощью макрокоманды Закрыть(Close).

Фильтрация

Событие Фильтрация (Filter) возникает перед открытием окна фильтра или расширенного фильтра, когда пользователь пытается выполнить команду Изменить фильтр (Filter by Form). Использовать это событие очень удобно, если требуется, например, ввести в фильтр некоторые условия по умолчанию или запретить включать в условия отбора некоторые поля. Чтобы запретить включать некое поле в условие отбора в окне фильтра, достаточно скрыть его в процедуре обработки события Фильтрация (Filter). Правда, это относится только к окну обычного фильтра, т. к. в окне расширенного фильтра выводятся все поля, в том числе и скрытые. Можно даже заменить стандартное окно фильтра своим собственным, в котором пользователь и будет задавать условия отбора. Процедура обработки события имеет два параметра — Cancel и FilterType. Cancel позволяет отменить открытие стандартного окна фильтра, если вместо него будет выводиться специальная форма, для чего нужно присвоить ему значение True. Параметр FilterType определяет, какое окно открывается, и может принимать значения 0 или 1. Значение 0 соответствует обычному фильтру, 1 — расширенному фильтру.

События окна запускаются при открытии и закрытии форм и отчетов, а также при изменении размеров формы.

Открытие

Событие Открытие (Open) происходит после того, как выполнен запрос, лежащий в основе формы или отчета, но до отображения первой записи или печати отчета. Процедура обработки этого события имеет один параметр — Cancel, при установке которого в значение True отменяется открытие формы или отчета. Обычно процедура обработки события Открытие (Open) используется для проверки условий и предотвращения открытия формы, т. к. следующее по времени событие Загрузка (Load) уже не может быть отменено.

Закрытие

Событие Закрытие (Close) является последним перед тем, как форма будет удалена с экрана. Обычно его используют для открытия другой формы. Для отчета событие происходит, когда закрывается режим Предварительного просмотра или заканчивается печать отчета. Как и в случае с формой, его можно использовать для определения дальнейших действий пользователя.

Загрузка

Событие Загрузка (Load) происходит сразу после события Открытие (Open), но в отличие от него не может быть отменено. Обычно его используют для динамического изменения свойств формы или элементов управления перед тем, как форма будет выведена на экран.

Выгрузка

Событие Выгрузка (Unload) происходит при закрытии формы до события и может быть отменено. Обычно это событие используется для проверки различных условий, которые определяют, можно ли закрывать форму. Процедура обработки этого события имеет один параметр — Cancel, при установке которого в значение True отменяется закрытие формы.

Замечание

Если вы используете процедуру обработки события Выгрузка (Unload), в которой параметру Cancel присваивается значение True, не забудьте явно присвоить ему значение False в случае выполнения всех условий для закрытия формы. Иначе после того как этот параметр будет установлен в True, форму нельзя будет закрыть никогда.

Изменение размера

Событие Изменение размера (Resize) возникает при открытии формы и при изменении ее размеров. Его обычно применяют, если требуется подстроить размер элементов управления под изменяющиеся размеры формы или вычислить заново вычисляемые элементы. Если нужно, чтобы при каждом изменении размеров формы происходило обновление экрана, используйте в процедуре обработки этого события метод Repaint.

Замечание

При создании процедур обработки событий часто возникают сомнения, какое из двух событий — Открытие (Open) или Загрузка (Load) — использовать (или, соответственно, Закрытие (Close) или Выгрузка (Unload)). Рекомендуется принимать во внимание следующее соображение. Если требуется возможность отменить событие, то пользуйтесь событиями Открытие (Open) и Выгрузка (Unload), в противном случае можно использовать любое.

Событие Ошибка (Error) возникает, когда в процессе обработки формы или отчета ядром Access возникает ошибка. В процедуре обработки этого события можно перехватить стандартное сообщение об ошибке, которое выдает Access, и выдать собственное сообщение. Процедура имеет два параметра — DataErr и Response. Параметр DataErr содержит код ошибки, а параметр Response может принимать два значения — 0 и 1. Значение 0 отменяет выдачу стандартного сообщения об ошибке, а 1 — позволяет его отобразить.

Замечание

Это событие не возникает, когда ошибка встречается в коде VBA.

Событие Таймер (Timer) возникает регулярно через интервал времени, который задается свойством Интервал таймера (Timerlnterval) формы. Оно позволяет определять действия, которые должны выполняться периодически по сигналу таймера. Обычно используется для регулярных обновлений экрана в многопользовательском приложении, тогда в процедуре обработки события Таймер (Timer) нужно использовать метод Requery, который будет выполнять повторный запрос источника данных формы.

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

При установке фокуса на элемент управления щелчком мыши, при нажатии клавиши или при открытии формы происходят события: Вход (Enter) => Получение фокуса (GotFocus).

Когда элемент теряет фокус, например при закрытии формы или переносе фокуса на другой элемент управления той же формы, происходят события: Выход (Exit) => Потеря фокуса (LostFocus).

При переносе фокуса в другую форму элемент первой формы теряет фокус, но не возникает события Выход (Exit). Соответственно, когда фокус переносится обратно, т. е. к элементу, который уже имел фокус, когда форма последний раз была активной, то не происходит события Вход (Enter), а только событие Получение фокуса (GotFocus).

Замечание

В дальнейшем при описании последовательностей событий мы не будем приводить английские эквиваленты названий событий, дабы не загромождать представление. Кроме того, вводятся сокращения для обозначения объектов, к которым относится событие, например: э — элемент, ф — форма.

При переносе фокуса из элемента управления в главной форме на элемент управления в подчиненной форме события происходят в следующем порядке: Выход (г.ф., т.ф.) => Потеря фокуса (г.ф., т.ф.) => Вход (г.ф., э.п.) => Выход (п.ф., т.ф.) => Потеря фокуса (п.ф., т.ф.) => Вход «(п.ф., п.ф.) => Получение фокуса (п.ф., п.ф.) Это самая сложная цепочка событий, в которой задействованы сразу четыре элемента управления: г.ф., т.ф. — элемент главной формы, теряющий фокус; г.ф., э.п. — элемент главной формы, содержащий подформу; п.ф., т.ф. — элемент подформы, теряющий фокус (если мы переносим фокус на тот элемент подформы, который до этого фокуса не имел); п.ф., п.ф. — элемент подформы, принимающий фокус. Если перенос фокуса выполняется на элемент подчиненной формы, который имел фокус, когда она последний раз была активной, то в цепочке отсутствуют события: Выход (п.ф., т.ф.) => Потеря фокуса (п.ф., т.ф.) => Вход (п.ф., п.ф.).

Последовательность событий изменения данных в элементе управления

Когда вводят или изменяют данные в элементе управления, а затем переходят к следующему элементу управления, возникает следующая цепочка событий: {Клавиша вниз => Нажатие клавиши => Внесены изменения ==> Изменение => Клавиша вверх}=> До обновления После обновления => Выход => Потеря фокуса

Фигурные скобки в приведенном выражении означают, что выделенная цепочка событий возникает при каждом нажатии клавиши на клавиатуре.

Еcли ввод выполняется в поле со списком, то в конец последней цепочки, после события Клавиша вверх, могут добавиться события Отсутствие в списке (NotlnList) и Ошибка (Error), и цепочка будет выглядеть следующим образом: Клавиша вниз => Нажатие клавиши => Внесены изменения => Изменение => Клавиша вверх} => Отсутствие в списке => Ошибка => До обновления => После обновления => Выход => Потеря фокуса

Последовательность событий в форме, связанных с записями

Если просто просматриваются записи в форме, то при переходе к каждой новой записи выполняются событие Текущая запись (Current) для формы и все события, связанные с установкой фокуса в элементах формы. Если данные в записи меняются, то сохранение изменений происходит только при переходе к следующей записи или при закрытии формы (если нашли нужную запись, изменили и закрыли форму). Поскольку все изменения в записи происходят в элементах управления формы, одновременно будут возникать соответствующие события в элементах формы. Рас-смотрим типичную ситуацию, когда в форме выводится запись, в ней перемещаются по элементам управления до нужного элемента, изменяют в нем данные и переходят к следующей записи. В этом случае последовательность возникновения событий будет выглядеть так: Текущая запись (ф) => {Вход (э) => Получение фокуса (э) => Выход (э) => Потеря фокуса (э)} => Вход (э) => Получение фокуса (э) => До обновления (э) => После обновления (э) => До обновления (ф) => После обновления (ф) => Выход (э) => Потеря фокуса (э) => RecordExit => Текущая запись (ф) => Вход (э) => Получение фокуса (э)

В этой цепочке для упрощения опущены все события клавиатуры, а фигурные скобки выделяют цепочки событий, которые возникают при переходе между элементами управления формы. При изменении данных события До обновления (BeforeUpdate) и После обновления (AfterUpdate) происходят сначала для элемента, а затем для формы. Затем последний элемент (в данном случае тот, в котором происходили изменения) теряет фокус, происходит событие RecordExit (Выход из записи), выводится следующая запись, и фокус устанавливается на первый элемент в этой записи. События До обновления (BeforeUpdate) и После обновления (AfterUpdate) всегда возникают непосредственно перед переходом к следующей записи. После этого запись (элемент управления, в котором перед этим находился фокус) теряет фокус.

Замечание

Если запись сохраняется с помощью команды меню Записи, Сохранить запись (Records, Save Record), то последних событий Выход (Exit) и Потеря фокуса (LostFocus) не происходит. Это полезно знать, т. к. иногда требуется обойти эти события.

При удалении записи происходят события: Удаление => До подтверждения Del => После подтверждения Del => Текущая запись => Вход => Получение фокуса

Если событие Удаление (Delete) отменяется, то остальные события не возникают. После удаления записи фокус переходит на следующую запись, поэтому происходят события Текущая запись (Current) формы и Вход (Enter) и Получение фокуса (GetFocus) первого элемента в этой записи.

Добавление новой записи осуществляется после того, как пользователь вводит первый символ новой (пустой) записи. При этом события происходят в следующем порядке: Текущая запись (ф) => Вход (э) => Получение фокуса (э) => До вставки (ф) => Изменение (э) => До обновления (ф) => После обновления (ф) => После вставки (ф)

В этой цепочке пропущены все события клавиатуры и До обновления (BeforeUpdate) и После обновления (AfterUpdate) для элементов формы, т. к. они описаны выше. Событие Изменение (Change) происходит, если первый символ новой записи вводится в текстовое поле.

Последовательность событий в формах

При открытии формы происходит следующая цепочка событий: Открытие => Загрузка => Изменение размера => Включение => Текущая запись => Вход => Получение фокуса

События Вход (Enter) и Получение фокуса (GetFocus) возникают для первого элемента в первой записи. Если форма не имеет видимых или доступных элементов управления, то последовательность событий несколько иная: Открытие => Загрузка => Изменение размера => Включение => Получение фокуса => Текущая запись

В этом случае событие Получение фокуса (GetFocus) относится к форме. При закрытии формы последовательность событий следующая: Выход => Потеря фокуса => Выгрузка => Отключение => Закрытие

То есть сначала теряет фокус последний элемент в форме, а затем выполняются события для формы. Если в форме не было видимых или доступных элементов, то последовательность другая: Выгрузка => Потеря фокуса (ф) => Отключение => Закрытие

При переключении между двумя открытыми формами последовательность событий следующая: Потеря фокуса (э1) => Отключение (ф!) => Включение (ф2) => Вход (э2) => Получение фокуса (э2)

Если из открытой формы открывают другую форму, то сначала в открываемой форме происходят события Открытие (Open), Загрузка (Load) и Изменение размера (Resize), и только после этого в первой форме произойдет событие Отключение (Deactivate): Открытие (ф2) => Загрузка (ф2) => Изменение размера (ф2) => Отключение (ф1) => Включение (ф2) => Текущая запись (ф2)

Это дает возможность проконтролировать открытие второй формы. Кроме того, событие Включение (Activate) происходит каждый раз, когда форма получает фокус, а события Открытие (Open) и Загрузка (Load) не происходят, если форма уже открыта, даже если переход в эту форму выполняется с помощью макрокоманды ОткрытьФорму (OpenForm). Событие Отключение (Deactivate) для формы не происходит, если фокус переносится в диалоговое окно.

Если открываемая форма содержит подчиненные формы, то сначала загружаются подчиненные формы и осуществляются все события в них, которые обычно происходят при открытии формы, кроме события Включение (Activate) — оно не возникает. Затем загружается главная форма в обычном порядке и для нее выполняется событие Включение (Activate).

Аналогично при закрытии такой формы сначала выгружаются все подчиненные формы, но в них не возникает событие Отключение (Deactivate). События при этом происходят в следующем порядке:

  1. События для элементов подчиненной формы, например Выход (Exit) и Потеря фокуса (LostFocus).
  2. События элементов управления в главной форме, в том числе для того элемента, который содержит подчиненную форму.
  3. События для главной формы.
  4. События для подчиненной формы.

Последовательность событий клавиатуры и мыши

При нажатии и отпускании любой клавиши на клавиатуре в том случае, если фокус находится в одном из элементов управления формы, возникает следующая цепочка событий: Клавиша вниз => Нажатие клавиши => Клавиша вверх

При щелчке мышью на элементе управления формы, соответственно: Кнопка вниз => Кнопка вверх => Нажатие кнопки

Об особенностях этих событий подробно говорилось выше при их описании, поэтому сейчас мы позволим себе не повторяться.

Последовательность событий в отчетах

В отчетах события возникают только для самого отчета и его разделов. Для полей отчета события отсутствуют. При выводе отчета на печать события обычно возникают в следующей последовательности: Открытие => Включение => {Формат => Печать} => Закрытие => Отключение

События Форматирование (Format) и Печать (Print) относятся к разделам отчета и возникают при обработке каждого раздела. Дополнительными событиями могут быть события:

  1. Отсутствие данных (NoData), которое возникает перед первым событием Печать (Print), если источник записей не содержит записей.
  2. Страница (Page), которое возникает после всех событий Печать (Print) для страницы отчета.
  3. Событие Возврат (Retreat) возникает в процессе форматировании страницы отчета, когда требуется вернуться к предыдущему разделу, перед событиями Печать (Print) для страницы.

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

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

Рис. 13.32. Диалоговое окно событий формы

Если процедура обработки выбранного события имеет аргументы, они будут также присутствовать в заголовке процедуры (рис. 13.34).

Теперь нужно ввести код процедуры между этими двумя строками. Ниже приведены некоторые примеры процедур обработки событий.

Рис. 13.33. Заготовка процедуры обработки события

Рис. 13.34. Процедура обработки событий с аргументом Cancel

Пример синхронизации данных в двух связанных формах с помощью процедуры обработки события Текущая запись (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, процедура закрывает набор записей (рекомендуется не забывать это делать) и завершает свою работу.

Рассмотрим возможности обработки событий в отчете на примере отчета «Выработка сотрудников». Этот отчет строится на базе перекрестного запроса и показывает выработку сотрудников отдела продаж за год по месяцам. Максимальное число столбцов в отчете — 14. Первый столбец содержит фамилии сотрудников, следующие двенадцать столбцов — выработку для каждого месяца и последний столбец — итоговый. (Как выглядит этот отчет, мы показывали в разд. «Перекрестные отчеты»гл. 10.)

В качестве источника данных для такого запроса используется перекрестный запрос «Выработка сотрудников», представленный на рис. 13.35.

Рис. 13.35. Перекрестный запрос «Выработка сотрудников»

Поле «Отпускная цена» является вычисляемым, и для его вычисления используется формула

 CCur(CLng(.*
 *(1-)*100)/100)

Создание такого отчета требует написания довольно большого числа процедур обработки событий.

В запросе в качестве критерия выборки заказов указан год — 1998. Нужно вывести приглашение пользователю, чтобы он, в свою очередь, мог ввести желаемый год. Это можно сделать при открытии отчета. Сначала нужно создать базовый набор записей для отчета и посчитать, сколько получилось столбцов в этом наборе. Следующая процедура обрабатывает событие Открытие (On Open) отчета:

 Private Sub Report_0pen(Cancel As Integer) On Error Resume Next

‘ Создает базовый набор записей для отчета.

 Dim intX As Integer Dim qdf As QueryDef Dim frm As Form Dim StrSql As String

‘ Связывает переменную с текущей базой данных.

 Set dbsReport = CurrentDb

‘ Открывает запрос (объект QueryDef).

 Set qdf = dbsReport.QueryDefs("Выработка сотрудников")

‘ Запрашивает год.

 Год = InputBox("Отчет за год:", "Год", 1998) StrSql = Left(qdf.SQL, InStr(qdf.SQL, "where") - 1) & " WHERE_ (((Year()) = " & Год  &  "))" & Right(qdf.SQL, Len(qdf.SQL) - InStr(qdf.SQL, "GROUP BY") + 1) qdf.SQL = StrSql

‘ Открывает набор записей

 Set rstReport = qdf.OpenRecordset()

‘ Определяет количество столбцов в перекрестном запросе.

 intColumnCount = rstReport.Fields.Count End Sub

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

Для событий Форматирование (On Format) верхнего колонтитула (листинг 13.1) и области данных отчета (листинг 13.2) необходимо определить процедуры, которые бы заполняли поля заголовков и значений и скрывали неиспользуемые поля.

Листинг 13.1. Процедура обработки события Форматирование верхнего колонтитула

 Private Sub PageHeader()_Format(Cancel As Integer,_FormatCount As Integer) Dim intx As Integer

‘ Помещает заголовки столбцов в поля в верхнем колонтитуле.

 Me("Head" + Format(0)) = rstReport(0).Name For intX = 1 To intColumnCount - 1 Me("Head" + Format(intX)) = _MonthRus(CInt(rstReport(intX).Name)) Next intX

‘ Вводит в ближайшее свободное поле заголовок «Итого».

 Me("Head" + Format(intColumnCount)) = "Итого"

‘ Скрывает пустые поля в верхнем колонтитуле.

 For intX = (intColumnCount +1) То conTotalColumns - 1 Me("Head" + Format(intX)).Visible = False Next intX End Sub

В этой процедуре используется функция MonthRus, которая по порядковому номеру месяца выдает его название. Мы здесь не приводим текста этой функции, надеясь, что вы сможете написать ее сами conTotalColumns — константа, которая описана на уровне модуля и значение которой определяет максимальное число столбцов в отчете. В данном примере conTotalColumns равна 14.

Листинг 13.2. Процедура обработки события Форматирование области данных 1

 Private Sub Detaill_Format(Cancel As Integer,_ FormatCount As Integer)

‘ Вводит значения в поля и скрывает пустые поля.

 Dim intX As Integer

‘ Проверяет, что не достигнут конец набора записей.

 If Not rstReport.EOF Then

‘Помещает значения из набора записей в поля области данных

 If Me.FormatCount = 1 Then For intX = 0 To intColumnCount - 1

‘ Преобразует пустые значения в 0.

 Me ("Col" + Format(intX)} = _xtabCnulls(rstReport(intX)) Next intX

‘ Скрывает неиспользуемые поля в области данных.

 For intX = intColumnCount + 1 То conTotalColumns - 1 Me("Col" + Format(intX)).Visible = False Next intX

‘ Переходит к следующей записи в наборе. rstReport.Move

 Next End If End If End Sub

Свойство FormatCount отчета содержит значение, равное количеству столбцов для форматирования, поэтому в процедуре проверяется это свойство, и присвоение значений полям в области данных выполняется, только если это значение не 0. В процедуре используется также функция xtabCnulls, преобразующая пустое значение в 0.

Для события Печать (On Print) области данных отчета нужно создать процедуру, которая бы суммировала значения по строке отчета, выводила полученное значение в последнем столбце и, кроме того, добавляла эту сумму в массив итоговых значений по столбцам (листинг 13.3). Массив итоговых значений по столбцам IngRgColumnTotal и переменная IngReportTotal, определяющая общий итог, должны быть описаны на уровне модуля. Кроме того, они должны быть инициализированы, т. е. им нужно присвоить начальные значения 0. Это можно сделать в процедуре обработки события Загрузка (On Load) отчета.

Листинг 13.3. Процедура обработки события Печать области данных

 Private Sub Detaill_Print(Cancel As Integer, PrintCount As Integer) Dim intX As Integer Dim IngRowTotal As Long

‘ Вычисляет сумму по строке и добавляет ее к итоговому значению. ‘ по столбцу и общему итогу

 If Me.PrintCount = 1 Then IngRowTotal = 0 For intX = 1 To intColumnCount - 1

‘ Начиная со столбца 1 (первый столбец с перекрестными значениями), вычисляет сумму по строке.

 lngRowTotal = IngRowTotal + Me("Col" + Format(intX))

‘ Добавляет итоговое значение для текущего столбца.

 IngRgColurenTotal(intX) = IngRgColumnTotal(intX) + Me("Col" + Format(intX)) Next intX

‘ Заносит сумму по строке в поле в области данных.

 Me("Col" + Format(intColumnCount)) = IngRowTotal

‘ Прибавляет сумму по строке к общему итогу.

 IngReportTotal = IngReportTotal + IngRowTotal End If End Sub

Процедура обработки события Печать (On Print) примечания отчета должна заполнить поля примечания итоговыми значениями по столбцам из массива IngRgColumnTotal (листинг 13.4).

Листинг 13.4. Процедура обработки события Печать примечания

 Private Sub ReportFooter4_Print(Cancel As Integer, PrintCount As Integer) Dim intX As Integer

‘ Помещает суммы по столбцам в поля примечания.

 For intX = 1 То intColumnCount - 1 Me("Tot" + Format(intX)) = IngRgColumnTotal(intX) Next intX

‘ Помещает общий итог в поле примечания.

 Me("Tot" + Format(intColumnCount)) = IngReportTotal

‘ Скрывает неиспользуемые поля в примечании отчета.

 For intX = intColumnCount + 1 То conTotalColumns - 1 Me("Tot" + Format(intX)).Visible = False Next intX End Sub

Для корректной работы нужно еще добавить две небольшие процедуры в свойства отчета:

  • при закрытии отчета нужно закрыть базовый набор записей — обработка события Закрытие (On Close);
  • при отсутствии данных в базовом наборе записей нужно закрыть этот набор и прервать формирование отчета — событие Отсутствие данных (On No Data).

Ниже приведены обе эти процедуры (листинги 13.5 и 13.6).

Листинг 13.5. Процедура обработки события Закрытие отчета

 Private Sub Report_Close() On Error Resume Next rstReport.Close End Sub

Листинг 13.6. Процедура обработки события Отсутствие данных отчета

Private Sub Report_NoData(Cancel As Integer) MsgBox "He найдены записи, удовлетворяющие указанным условиям.", vbExclamation, "Записи не найдены" rstReport.Close Cancel = True End Sub

Обычно для обработки событий в формах и отчетах используют процедуры типа Sub (подпрограммы) или макросы. Однако иногда можно и даже нужно использовать функции. Дело в том, что если в рамках одной формы делается множество однотипных задач, то лучше создать одну процедуру — функцию для выполнения этих задач, описать ее на уровне модуля формы, т. е. в разделе General, а потом вызывать из любого места в форме. Если это необходимо, для такой функции определяется один или несколько параметров, которые передаются при вызове данной функции. И хотя значение, возвращаемое функцией, не используется (а обычно и не определяется), применение ее оправдано не только потому, что требуется писать меньше строк кода, а главным образом потому, что минимизация кода в модуле формы ускоряет ее открытие.

Если же идентичные задачи решаются в разных формах, например, одна и та же реакция предусматривается для одинаковых кнопок в разных формах, то такую функцию нужно написать в стандартном модуле базы данных.

Совет

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

Допустим, вы отображаете в форме список каких-либо объектов, например счетов клиента. Обычно это делается в подчиненной форме табличного или ленточного вида, в которой отображаются наиболее важные характеристики счета: номер счета, дата выписки, наименование клиента, сумма. И вы хотите дать возможность пользователю при желании посмотреть тот счет, который он выбрал, установив курсор на соответствующую строчку. Это можно сделать, создав процедуру открытия формы счета с нужной записью при двойном щелчке мыши на строчке счета. Естественно, что форма должна открываться при щелчке в любом поле подчиненной формы. Вместо того чтобы в каждом поле подчиненной формы на событие Двойное нажатие (DblClick) создавать процедуру обработки событий, можно создать одну функцию и присоединить ее ко всем полям. Функция будет выглядеть так:

 Private Function Order_DblClick() Dim strCriteria As String On Error Goto Err Order DblClick strCriteria = "КодЗаказа = Forms!!.form!КодЗаказа" DoCmd.OpenForm "Заказы", acNormal, , strCriteria Exit_Order_DblClick: Exit Function Err_Order_DblClick: ; MsgBox Err.Description Resume Exit_Order_DblClick End Function

А присоединить эту функцию к событию элемента управления формы можно так, как показано на рис. 13.36. Мы сделали это для формы «Заказы клиента» (Customer Orders) приложения (NorthWind).

Рис. 13.36. Использование функции при обработке событий в форме

Еще один пример применения функции для обработки событий в форме вы может увидеть в базе данных «Контакты» (Contacts) (см. пример к гл. 18 на компакт-диске) В этом приложении с помощью Мастера кнопочных форм создана главная кнопоч ная форма, которая открывается при открытии приложения. На форме имеются не сколько кнопок, каждая из которых выполняет определенную функцию, но обрабаты ваются они все одинаково. Для этого мастер создает функцию =HandleButtonClick которая имеет один аргумент — идентификатор нажатой кнопки. Вызов функци! выполняется, как показано на рис. 13.37. Аргумент определяет нажатую клавишу. Oi обрабатывается программой в блоке Select Case, после чего выполняется соот ветствующее действие.

Рис. 13.37. Вызов функции для обработки события Нажатие кнопки

В данной главе были приведены основные сведения, необходимые для программирования приложений в Access 2002, и мы рассмотрели несколько примеров использования процедур обработки событий в формах. Овладев основным инструментарием и получив необходимые навыки, вы сможете сами создавать процедуры обработки событий в приложениях Access. Дальнейшие главы расширят ваше представление о возможностях языка VBA при интеграции приложений Access с другими компонентами семейства Microsoft Office, а также при создании сложных многопользовательских и клиент-серверных приложений.