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



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

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

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

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



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





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

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

Замечание

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



До вставки



До вставки

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



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



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

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

Замечание

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



Фильтрация



Фильтрация

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



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



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

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



Данная глава посвящена основному средству



Глава 13.

Программирование в Access 2002

Данная глава посвящена основному средству программирования в 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
События форм, отчетов и элементов управления и последовательности их возникновения
Примеры применения процедур обработки событий в формах и отчетах

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



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




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



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



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



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

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

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



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



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

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



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



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



Объектная модель ADOX



Иллюстрация 13.6. Объектная модель ADOX



Объектная модель Microsoft Office 2002



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


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



Функция IsLoaded



Иллюстрация 13.8. Функция IsLoaded

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

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



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



Иллюстрация 13.9. Диалоговое окно свойств формы

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



Окно редактора кода VBA



Иллюстрация 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



Создание нового модуля



Иллюстрация 13.11. Создание нового модуля

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



Окно редактора кода VBA



Иллюстрация 13.12. Окно редактора кода VBA

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

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

Microsoft Access Class Objects (Модули классов Access) — включает все модули форм и отчетов;
Modules (Модули) — стандартные модули;
Class Modules (Модули классов) — модули пользовательских классов, если они присутствуют в приложении.
Список объектов в окне проекта является иерархическим, кроме модулей самого проекта, он может включать ссылки на объекты из внешних библиотек и список модулей этих библиотек.

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

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

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

Выделить имя свойства в левой колонке.
Изменить значение в правой колонке, либо введя его вручную, либо путем выбора из списка.
Для каждого модуля, выбранного на панели проекта, открывается свое окно редактора кода. В данном случае в окне редактора мы видим модуль "Заставка" (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. Дальше можно не продолжать, а просто нажать клавишу <Таb> — конец слова допишется автоматически. Нажмите клавишу <Enter>, курсор перейдет на новую строку, а текст во введенной строке изменится: все ключевые слова — 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 = "Заказ" & Название

И наконец, напишем комментарий, который объясняет, что делает данная программа. Для этого поместите курсор в начало второй строки программы и нажмите клавишу <Enter>. Появится пустая строка. Введите символ (') в начало новой строки и пишите дальше текст комментария. Закончите ввод нажатием клавиши <Enter>, и вы увидите, что комментарий оказался выделен зеленым цветом. В целом текст программы должен выглядеть как на рис. 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 (а еще быстрее, нажав комбинацию клавиш <Shift>+<F2>), вы сразу попадете в тело вызываемой процедуры;
Last Position — позволяет после такого перехода вернуться обратно.
Команда Definition позволяет также быстро открыть окно Object Browser и посмотреть описание нужного свойства, метода или объекта приложения. Для этого нужно установить курсор на интересующий объект, свойство, метод и нажать комбинацию клавиш <Shift>+<F2>.



Окно просмотра объектов



Иллюстрация 13.21. Окно просмотра объектов

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

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

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



Объекты приложения "db1"



Иллюстрация 13.22. Объекты приложения "db1"

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



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



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

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

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



Диалоговое окно References



Иллюстрация 13.24. Диалоговое окно References

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



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



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



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



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

Замечание

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



Окно Watches редактора кода



Иллюстрация 13.28. Окно Watches редактора кода

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

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

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



Диалоговое окно Quick Watch



Иллюстрация 13.29. Диалоговое окно Quick Watch

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



Окно Immediate



Иллюстрация 13.30. Окно Immediate

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

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

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

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

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

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

Цена.Enabled = True

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



Диалоговое окно Call Stack



Иллюстрация 13.31. Диалоговое окно Call Stack

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

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

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



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



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

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

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



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



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

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



Перекрестный запрос "Выработка сотрудников"



Иллюстрация 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.36. Использование функции при обработке событий в форме

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

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



Инструментальные средства отладки



Инструментальные средства отладки

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



Использование функций для обработки событий



Использование функций для обработки событий

Обычно для обработки событий в формах и отчетах используют процедуры типа 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).



Использование комбинаций клавиш быстрого вызова



Использование комбинаций клавиш быстрого вызова

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



Использование объектов и семейств



Использование объектов и семейств

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



Использование окна просмотра объектов



Использование окна просмотра объектов

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

нажать клавишу <F2> — самый быстрый;
нажать кнопку Object Browser (Обозреватель объектов) на панели инструментов — удобный;
выбрать команду View, Object Browser (Вид, Обозреватель объектов) — если вы забыли другие способы.
Окно Object Browser (Обозреватель объектов) состоит из нескольких списков (рис. 13.21), которые обеспечивают трехуровневое представление информации.

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

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



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



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

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

Замечание

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



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



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

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



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



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

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

Замечание

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



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



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

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

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


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



Листинг 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



Массивы



Массивы

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

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

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

Dim <имяМассива> (<размер1>, <размер2>, ...) As <типДанных>

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

Dim Array1 (9) As Integer

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

Dim Array2 (4, 9) As Variant

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

Замечание

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

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

Dim <имяМассива> (<мин1> То <макс1>, ...)

As <типДанных>

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

Dim Temperature (-14 То 0)

As Single

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

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

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

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

Dim <имяМассива> ( ) As <типДанных>

ReDim <имяМассива> (<размер1>, <размер2>, . . . )

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

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)



Меню Debug



Меню Debug

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



Модель объектов ActiveX для управления данными



Модель объектов ActiveX для управления данными

Объекты управления данными 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.



Модули как объекты Access


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



Модули класса



Модули класса

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

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

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



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



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

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

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

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

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



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



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

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

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



Объектная модель Microsoft Access 2002



Объектная модель Microsoft Access 2002

Объектная модель 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), для него приводится название этой библиотеки.



Data Access Objects) создавались, как



Объектная модель Microsoft DAO 3.6

Объекты доступа к данным (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, такими как пакетное обновление записей, обновленные записи оптируются на локальном компьютере;
когда требуется асинхронное выполнение запроса, запрос выполняется в фоновом режиме, не останавливая выполнение других


Объектная модель Microsoft Office 2002



Объектная модель Microsoft Office 2002

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



Объектная модель Visual Basic для приложений


Объектная модель 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 Access 2002, так же как и в Microsoft Access 2000, сохранилась возможность двух способов работы с данными:

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



Язык Visual Basic for Applications



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



Объектные модели Microsoft Office 2002



Объектные модели Microsoft Office 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.)



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



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

Все процедуры, функции, переменные и константы в 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.



Окно Call Stack



Окно Call Stack

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



Окно Immediate



Окно Immediate

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



Окно Locals



Окно Locals

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

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

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

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

Замечание

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

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

Иллюстрация 13.26. Установка точки прерывания в программе



Окно Quick Watch



Окно Quick Watch

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

Выделить в тексте программы интересующее выражение.
Нажать кнопку Quick Watch на панели инструментов, или выбрать команду Debug, Quick Watch (Быстрый просмотр), или нажать комбинацию клавиш <Shift>+<F9>.
Диалоговое окно на рис. 13.29 отображает значение переменной stLinkCriteria.



Окно редактора кода



Окно редактора кода

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

Замечание

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



Окно Watches



Окно Watches

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

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



Основные понятия



Основные понятия

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

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

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

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

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

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

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

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

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



Отключение



Отключение

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



Открытие



Открытие

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



Отмена



Отмена

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



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



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

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



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



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

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

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



Содержание главы




Содержание главы




Печать



Печать

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



Переменные, константы и типы данных



Переменные, константы и типы данных

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

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

Dim <имяПеременной> [Аs<типДанных>]

В 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).



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



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

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

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


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



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

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



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



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

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

Замечание

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

Изменение

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

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

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

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



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



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

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



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



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

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



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



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

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

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

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

Замечание

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

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



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



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

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

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

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



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



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

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

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

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



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



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

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

События Вход (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). События при этом происходят в следующем порядке:

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


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



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

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

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

Замечание

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

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

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

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

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



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



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

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

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

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

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



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

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



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



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

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

Замечание

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

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

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



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



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

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

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



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



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

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

Замечание

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



Процедуры и функции, их вызов и передача параметров



Процедуры и функции, их вызов и передача параметров

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

Sub <имяПроцедуры> (<аргумент1>, <аргумент2>, ... )

<onepaтopVisualBasic1> <onepaтopVisualBasic2>

End Sub

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

F unction <имяФункции> (<аргумент1>, <аргумент2>, ... )

<onepaторVisualBasicl> <onepaторVisualBasic2>

<имяФункции> = <возвращаемоеЗначение>

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

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

<имяМодуля>.<имяПроцедуры>

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

[Графические процедуры].Крестик

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

<имяПроекта>.<имяМодуля>.<имяПроцедуры>



Программирование в формах и отчетах


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

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

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



Проверка дублирования значений первичного ключа



Проверка дублирования значений первичного ключа

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



Работа с объектами в семействах



Работа с объектами в семействах

Доступ к объектам, входящим в семейство, в большинстве случаев возможен только через упоминание имени семейства, поэтому в программах 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 s

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

база данных, таблица и поле 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. Это позволяет оперативно управлять, например, кнопками на панелях команд.



Синхронизация данных в связанных формах



Синхронизация данных в связанных формах

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



Событие ошибок



Событие ошибок

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

Замечание

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



Событие таймера



Событие таймера

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



События Access



События Access

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

В 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.



События данных



События данных

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



События фильтра



События фильтра

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



События фокуса



События фокуса

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



События клавиатуры



События клавиатуры

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

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

Замечание

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



События мыши



События мыши

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



События окна



События окна

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



События печати



События печати

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



Создание модулей



Создание модулей

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

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


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



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

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

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



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



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

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

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


в Access 2002 включает все



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



Ссылки на объект Module



Ссылки на объект Module

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

имяСемейства!имяОбъекта,например Modules!Startup;
имяСемейства ("имяОбъекта"), например Modules ("Startup");
имяСемейства (индекс), где индекс— индекс объекта в семействе.
Для ссылки на модуль формы или отчета можно использовать или имя модуля, например Modules ! Fоrm_Клиенты, или " . свойство формы, например

Forms!Клиенты.Module.

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



Ссылки на объекты



Ссылки на объекты

Кроме обычных переменных, в 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 ей можно снова присвоить ссылку на объект.

Замечание

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



Ссылки на объекты


Ссылки на объекты

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

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

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

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

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

Application. Forms ( "Заказы")

Замечание

Узнать, какие объекты, свойства и методы являются глобальными, позволяет окно просмотра объектов. Чтобы отобразить список глобальных компонентов объектной модели, выберите элемент <globals> в списке Classes в окне просмотра объектов (см. разд. "Использование обозревателя объектов в редакторе VBA " данной главы).

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

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

Forms ! Товары

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

Forms![Заказы клиента]

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

Properties(0)

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

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

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

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

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

TableDefs!Должности.Fields!КодЦолжности

Совет

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

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



Стандартные модули



Стандартные модули

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



Страница



Страница

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



Свойства и методы объектов



Свойства и методы объектов

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

Замечание

Если вы хотите иметь подробную информацию обо всех свойствах и методах объекта, следует обратиться к соответствующему разделу справки. Например, чтобы получить сведения о любом объекте модели 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



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

Тип данных

Описание

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 байт на каждый символ строковых значений.

Символ определения типа по умолчанию: отсутствует

Определяемый пользователем тип

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

При описании переменной указание типа данных может быть опущено. Тип переменной в таком случае определяется последним символом имени переменной: @, #, %, &, ! или $ (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 <имяКонстанты>

[As <типДанных>] = <выражение>

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

Const maxLen% = 30

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

Совет

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

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

Например, в команде

DoCmd.OpenForm "Orders",

acNormal, , stLinkCriteria

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



Синтаксис операторов цикла Do



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

Конструкция

Описание

Do While <условие> <блокОператоров> Loop


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


Do Until <условие> <блокОператоров> Loop Условие проверяется до того, как выполняется группа операторов, образующих тело цикла. Цикл продолжает свою работу, если это условие еще не выполнено, и прекращает работу, когда оно станет истинным, иными словами, в этой конструкции указывается условие прекращения работы цикла
Do <блокОператоров> Loop Until <условие> Условие проверяется после того, как операторы, составляющие тело цикла, будут выполнены хотя бы один раз. Цикл продолжает свою работу, если это условие еще не выполнено, а когда оно станет истинным, цикл прекращает работу, иными словами, в этой конструкции указывается условие прекращения работы цикла
Do

<блокОператоров> Loop While <условие>

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

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

For <счетчик> = <начальноеЗначение>

То <конечноеЗначение>

[Step <приращение>]

<блокОператоров> 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

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



Описание основных элементов объектной модели



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

Объект

Тип Описание

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

Новый объект

Ссылается на конкретное печатающее уст-





ройство

Da taAccess Pages

Семейство

Содержит объекты DataAccessPages, со-





ответствующие открытым в данный момент





страницам доступа к данным в базе данных





или проекте Access

DataAccessPage

Объект

Ссылается на конкретную страницу доступа





к данным Access. Описывает свойства стра-





ницы

Screen

Объект

Ссылается на конкретную форму, отчет или





элемент управления, который в данный мо-





мент имеет фокус

DoCmd

Объект

Позволяет выполнить макрос или встроен-





ную инструкцию Access с помощью проце-





дуры на Visual Basic

VBE

Объект из

Предоставляет доступ к функциональным



библиотеки

средствам редактора Visual Basic для Micro-

VBIDE

soft Access

DefaultWebOptions

Объект

Предоставляет доступ к атрибутам приложе-





ния, используемым в Access по умолчанию





при открытии и сохранении Web-страниц

WebOptions

Новый объект

Предоставляет доступ к атрибутам конкрет-





ной страницы доступа к данным, используе-





мым в Access при открытии и сохранении





Web-страниц. Эти атрибуты имеют более





высокий приоритет, чем соответствующие





атрибуты приложения. Если установлены





атрибуты страницы доступа к данным, то



соответствующие атрибуты приложения для





работы с Web-страницами игнорируются.

Объект

Тип

Описание

References

Семейство

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

Reference

Объект

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

Printers

Новое семейство

Содержит объекты Printer, представляющие собой установленные ссылки на все печатающие устройства, доступные в приложении

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

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

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

Описание объектов доступа к данным



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

Семейство

Объект

Описание

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



Объектная модель ADODB



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

Объект

Тип

Описание

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

Объект

Представляет собой содержимое файла



Объектная модель ADOX



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

Объект

Тип

Описание

Catalog Объект Главный объект этой модели. Ссылается на источник данных и обеспечивает доступ ко всем объектам источника — таблицам, представлениям, процедурам, группам, пользователям
Tables

Семейство

Семейство таблиц, содержащихся в источнике данных. Каждый объект Table этого семейства ссылается на одну таблицу

Indexes

Семейство

Содержит все индексы таблицы. Каждый объект Index семейства ссылается на один из индексов

Keys

Семейство

Содержит все ключи таблицы. Каждый объект Key семейства ссылается на один из ключей

Columns

Семейство

Содержит объекты Column, которые ссылаются на столбцы в одном из объектов Table, Index, Key

Groups

Семейство

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

Users

Семейство

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

Procedures

Семейство

Содержит все хранимые процедуры в базе данных. Каждый объект Procedure семейства ссылается на одну из хранимых процедур

Views

Семейство

Содержит все представления (view) в базе данных

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



Описание объектов JRO



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

Объект

Тип

Описание

JetEngine

Объект

Обеспечивает доступ к двум сервисам ядра базы данных Jet: сжатие базы данных и выгрузка данных из кэша в файл базы данных MDB

Replica Объект Представляет собой копию реплицированной базы данных
Filters Семейство Содержит набор объектов Filter, каждый из которых представляет собой набор записей, которые должны реплицироваться
Более подробное описание объектов JRO и их использования приведено в гл. 18.

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



Объектная модель RDS



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

Объект

Тип Описание

RDS .DataSpace

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

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


Описание объектов Microsoft Office 2002



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

Объект

Тип

Описание

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-страницы, например открыть





его в редакторе сценариев

LanguageSet tings

Объект

Предоставляет информацию о языковых





настройках приложения семейства Micro-





soft Office

MsoEnvelope

Новый

Обеспечивает возможность отправки до-



объект

кументов по электронной почте

NewFile

Новый

Содержит список строковых значений,



объект

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





(New) на панели задач

ODSOColumns

Новое се-

Объекты этого семейства представляют



мейство

собой поля в файле для слияния с доку-





ментом Word

ODSOFilters

Новое се-

Объекты этого семейства представляют



мейство

собой фильтры, которые применяются к





файлу — источнику данных для документа





слияния

Off iceDataSourceObject

Новый

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



объект

операции слияния

SearchFolders

Новое се-

Содержит набор объектов, представляю-



мейство

щих собой папки, в которых ведется поиск





при использовании объекта FileSearch

SignatureSet

Новое се-

Содержит набор объектов Signature, каж-



мейство

дый из которых представляет собой цифро-





вую подпись, связанную с документом

WebPageFonts

Семейство

Содержит набор объектов WebPageFont,





каждый из которых соответствует одному из





поддерживаемых национальных стандартов.





Каждый объект определяет шрифты и их





размеры, которые используются по умолча-





нию при сохранении документа в формате





Web-страницы

Scripts

Семейство

Содержит объекты Script, соответствую-





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





Word, электронной таблице Excel или слай-





де PowerPoint. С помощью этого объекта





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





например создавать новые сценарии



Команды меню Debug



Таблица 13.11. Команды меню 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

(Показ следующего предложения)

Отображает в окне редактора очередную команду для выполнения

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

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



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



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

Комбинация клавиш

Назначение

<F7>

Открыть окно редактора кода

<Ctrl>+<F>

Найти

<Ctrl>+<F>

Заменить

<F3>

Найти далее

<Shift>+<F3>

Найти ранее

<Ctrl>+<t>

К следующей процедуре

<Ctrl>+<n>

К предыдущей процедуре

<Ctrl>+<J>

List Properties/Members

<Ctrl>+<Shift>+<J>

List Constant

Комбинация клавиш

Назначение

<Ctrl>+<|>

Quick Info

<Ctrl>+<Shift>+<|>

Parameter Info

<СМ>+<Пробел>

Закончить слово

<F5>

Продолжить

<Shift>+<F5>

Сброс

<F8>

Шаг с заходом

<Shift>+<F8>

Шаг с обходом

<Ctrl>+<Shift>+<F8>

Шаг с выходом

<F9>

Установка/сброс точки останова

<Shift>+<F9>

Вызов окна Quick Watch

<Ctrl>+<Shift>+<F9>

Сброс всех точек останова

<F2>

Вызов окна просмотра объектов Object Browser

<Shift>+<F2>

Definition

<Ctrl>+<Shift>+<F2>

Last Position

<Ctrl>+<G>

Вызов окна Immediate

<Ctrl>+<L>

Вызов окна Call Stack



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



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

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



Удаление



Удаление

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



Уход с записи



Уход с записи

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



Управляющие конструкции



Управляющие конструкции

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



Установка ссылок на объектные библиотеки



Установка ссылок на объектные библиотеки

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

Visual Basic for Application;
Microsoft Access 10.0 Object Library;
Microsoft DAO 3.6 Object Library.
Все остальные библиотеки при необходимости должны быть подключены вручную, для чего нужно установить ссылку на соответствующую библиотеку.

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



Ветвления



Ветвления

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

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

If <условие> Then <оператор>

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

If <условие> Then

<оператор1>

<оператор2>

End If

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

Замечание

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

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

If <условие> Then

<блокОператоров1> Else

<блокОператоров2>

End If

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

Совет

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

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

If <условие1> Then

<блокОператоров!>

Elseif <условие2> Then

<блокОператоров2>

Elseif <условие3> Then

<блокОператоровЗ>

Elseif <условиеN> Then

<блокОператоровN> Else

<блокОператоров_Еlsе>

End If

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

Select Case <проверяемоеВыражение>

Case <списокЗначений1>

<блокОператоров1>

Case <списокЗначений2>

<блокОператоров2>

Case <списокЗначенийЗ>

<блокОператоровЗ>

Case Else

<блокОператоровЕlsе>

End Select

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

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

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

<выражение> в данном случае проверяется, совпадает ли значение проверяемого выражения с этим выражением;
<выражение1> То <выражение2>в этом случае проверяется, находится ли значение проверяемого выражения в указанном диапазоне значений;
Is <логическийОператор> <выражение> в третьем случае проверяемое выражение сравнивается с указанным значением с помощью заданного логического оператора; например, условие is >= 10 считается выполненным, если проверяемое значение не меньше 10.
Если хотя бы один из элементов списка соответствует проверяемому выражению, то выполняется соответствующая группа операторов и на этом выполнение оператора Select Case заканчивается, а остальные списки выражений не проверяются, т. е. отыскивается только первый подходящий элемент списков выражений. Если же ни один из элементов всех этих списков не соответствует значению проверяемого выражения, выполняются операторы группы Else, если таковая присутствует.



Вход



Вход

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



Включение



Включение

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



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



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

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

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



Возврат



Возврат

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

Замечание

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



Выгрузка



Выгрузка

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

Замечание

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



Выход



Выход

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

Замечание

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



Выход из циклов и процедур



Выход из циклов и процедур

Обычно выполнение процедуры заканчивается после выполнения ее последнего оператора, а выполнение цикла — после нескольких выполнений тела цикла, когда достигнуто условие завершения его работы. Однако в некоторых случаях бывает нужно прекратить выполнение процедуры или цикла досрочно, избежав выполнения лишних операторов процедуры или лишних повторений цикла. Например, если при выполнении процедуры произошла ошибка, которая делает продолжение ее работы бессмысленным, можно выполнить команду немедленного выхода из процедуры. Другой пример: если цикл 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 и объектов данных.



В данной главе были приведены



Выводы

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


Язык Visual Basic для приложений (VBA)


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



Загрузка



Загрузка

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



Закрытие



Закрытие

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