Объектная модель 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.
Если вы будете выполнять процедуру по шагам, то сможете наблюдать, как меняются значения свойств.
![](images/image_311.gif)
![](images/image_312.gif)
Рис. 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, причем переменные, переданные по ссылке, увеличились, а переменная, переданная по значению — нет).
Программа может состоять (и обычно состоит) из многих процедур и функций, которые могут располагаться в одном или нескольких
модулях.
Модули группируются в
проекты,
при этом в одном проекте могут мирно сосуществовать несколько различных программ, использующих общие модули или процедуры.
Каждая из процедур, находящихся в одном модуле, должна иметь уникальное имя, однако в проекте может содержаться несколько различных модулей. Обычно рекомендуется использовать только уникальные имена процедур в одном проекте, но допустимы и исключения. В том случае, если в проекте содержится несколько различных процедур с одним и тем же именем, необходимо для уточнения имени использовать при вызове процедуры следующий синтаксис:
<имяМодуля>.<имяПроцедуры>
Если при этом имя модуля состоит из нескольких слов, следует заключить это имя в квадратные скобки. Например, если модуль называется "Графические процедуры", а процедура — "Крестик", вызов может выглядеть следующим образом:
[Графические процедуры].Крестик
Допускается также использование процедур, расположенных и в других проектах. При этом может потребоваться еще один уровень уточнения имени:
<имяПроекта>.<имяМодуля>.<имяПроцедуры>
Данная глава посвящена основному средству
Глава 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
События форм, отчетов и элементов управления и последовательности их возникновения
Примеры применения процедур обработки событий в формах и отчетах
Программирование в формах и отчетах
Программирование в формах и отчетах, как правило, составляет большую часть кода приложения, т. к. именно формы и отчеты являются основой интерфейса пользователя и с помощью программирования этот интерфейс гибко настраивается нужным образом. Основой для программирования в формах и отчетах является множество событий, обрабатывающихся специальными процедурами. О создании таких процедур, а также использовании макросов для обработки событий мы уже говорили выше
(см. разд. "Применение макросов" гл. 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. Это позволяет оперативно управлять, например, кнопками на панелях команд.
Первый уровень иерархии...
Рис. 13.1.
Первый уровень иерархии объектной модели Microsoft Access 2002
Второй уровень иерархии...
Рис. 13.2.
Второй уровень иерархии объектной модели Microsoft Access 2002 — объекты баз данных
Второй уровень иерархии...
Рис. 13.3.
Второй уровень иерархии объектной модели Microsoft Access 2002 — объекты для работы с базой данных и проектом
Глядя на схемы объектной модели, можно определить какие объекты описывают приложение, как они связаны между собой и как составить ссылку для доступа к конкретному объекту.
Табл. 13.3 содержит описание объектов Microsoft Access 2002, определенных в библиотеке Access, если не указана другая библиотека объектов.
Модель объектов доступа...
Рис. 13.4.
Модель объектов доступа к данным для рабочей области Microsoft Jet
В табл. 13.4 описаны объекты доступа к данным. В первом столбце приведены объекты-семейства, а во втором — объекты, являющиеся элементами соответствующего семейства, в третьем — описание объекта. В последующих главах книги "вы встретитесь с примерами использования объектной модели DAO.
Модель объектов доступа...
Рис. 13.5.
Модель объектов доступа к данным для рабочей области ODBCDirect
|