Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

2 Курс Информатика VBA(ЗО) / Книги / В.Д.Хорев - Самоучитель программирования на VBA в Microsoft Office

.pdf
Скачиваний:
2702
Добавлен:
31.05.2015
Размер:
21.66 Mб
Скачать

Создание экранных форм 143

Рис. 5.17. Панель элементов

Рис. 5.18. Начало создания подчиненной формы

управления

 

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

подчиненных форм (рис. 5.18).

Как создать подчиненную форму при помощи Мастера подчиненных форм

1. Необходимо установить переключатель в позицию Имеющиеся формы, а в поле списка выделить пункт “Операции по клиенту”. Завершить этот шаг следует щелчком на кнопке Далее.

Рис. 5.19. Определение поля связи между главной и подчиненной формами

2.Следующее диалоговое окно определяет поле связи между главной и подчиненной формами.

Вданном случае можно оставить настройки по умолчанию без изменений (см. рис. 5.19). Просто щелкните на кнопке Далее.

144 Глава 5. Access: создание офисной базы данных

3.На последнем шаге мастера необходимо задать надпись над подчиненной формой — пусть она называется “Операции по клиенту”.

4.Завершить работу мастера следует щелчком на кнопке Готово. В результате окно конструктора приобретет вид, как на рис. 5.20.

Рис. 5.20. Окно конструктора: создана подчиненная форма

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

5.21).

Рис. 5.21. Подчиненная форма “Операции по клиенту” отображает только те записи из таблицы “Операции”, которые относятся к текущему клиенту формы “Клиенты”

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

Как запретить изменение данных, отображаемых формой

1.Откройте окно базы данных на вкладке Формы.

2.Выделите значок формы “Операции по клиенту”.

3.Щелкните на кнопке Конструктор.

4.Выберите в меню Вид команду Свойства. В результате откроется окно свойств формы.

Усовершенствуем форму при помощи VBA 145

ПРИМЕЧАНИЕ

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

5.На вкладке Данные окна свойств формы (рис. 5.22) необходимо выбрать значения “Нет” для полей “Разрешить удаление”, “Разрешить изменение”, “Разрешить добавление” и “Ввод данных”.

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

Рис. 5.22. Окно свойств формы

Теперь форма “Клиенты” позволит вводить и изменять данные только из таблицы “Клиенты”. Данные об операциях по клиенту можно будет только просматривать.

Усовершенствуем форму при помощи VBA

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

Автоматическое заполнение поля Скидка

Подобно любому объекту Office, форма генерирует ряд событий. И элементы управления, размещенные на форме, также генерируют события.

Постановка задачи

Среди прочих элементов формы, Мастер форм поместил на форму “Клиенты” Поле со списком “КодТипа”. В режиме просмотра формы это название не видно, поскольку надпись над этим полем гласит: “Тип Клиента”. Мастер форм выбрал такую надпись потому, что при создании подстановочного поля при помощи Мастера подстановок уже была задана подпись поля в таблице. Но само поле в таблице все-таки содержит значения из столбца “КодТипа” и поэтому, на форме отображается элемент управления Поле со списком “КодТипа”. Как и всякое поле со спи-

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

Рис. 5.23. Диалоговое окно По-
строитель

146 Глава 5. Access: создание офисной базы данных

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

ПРИМЕЧАНИЕ

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

Итак, теперь уже в среде Access, применим VBA.

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

1.Откройте форму “Клиенты” в режиме конструктора.

2.Щелкните правой кнопкой мыши на поле КодТипа

(речь идет о белом поле на сером фоне, не перепутайте его с надписью “Тип Клиента” на сером фоне, см. рис.

5.20).

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

Обработка событий.

4.В результате на экране появится диалоговое окно Построитель (рис. 5.23). Выделите в списке пункт Программы, как показано на рисунке, и щелкните на

кнопке OK.

5. На экране отобразится окно редактора программного кода. В окне присутствует заголовок процедуры КодТипа_BeforeUpdate. Эта процедура обрабатывает

событие “перед обновлением”. Но в данном случае нужно обработать другое событие.

6.Выберите в списке событий (в правом вверхнем углу окна) пункт AfterUpdate вместо

BeforeUpdate.

Теперь все готово для ввода исходного текста процедуры обработки события “После обновления” для поля со списком КодТипа. Текст, который следует ввести представлен на листинге 5.1.

ЛИСТИНГ 5.1

Private Sub КодТипа_AfterUpdate()

Select Case КодТипа

Case 1: Скидка.Value = 0.1 Case 2: Скидка.Value = 0.15 Case 3: Скидка.Value = 0.05

End Select

End Sub

В зависимости от того, какой тип выбран для текущего клиента, в поле Скидка помещается одно из значений: 5% — для случайных клиентов, 10% — для реализаторов и 15% — для постоянных покупателей. Заметим, что это не помешает пользователю ввести в поле Скидка любое другое значение.

Усовершенствуем форму при помощи VBA 147

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

А у вас сегодня день рождения!

Постановка задачи

Среди событий непосредственно самой формы особое место занимает событие Current, — это событие происходит при смене текущей записи, при открытии формы, а также во многих других случаях. Очень часто программный код, служащий для автоматизации формы, помещают в обработчик этого события. В самом деле, каждый раз, когда форма переходит на новую запись, программный код VBA может “просмотреть” эту запись и предпринять по этому поводу какие-то действия. Например, почему бы не обратить внимание пользователя на тот факт, что как раз сегодня, как раз у этого самого клиента — день рождения!?

Создание обработчика события Current

Вначале необходимо создать процедуру обработки события Current для формы “Клиенты”. Последовательность действий немногим отличается от описанной последовательности действий в предыдущем разделе. Если окно редактора Visual Basic еще не открывалось, то следует открыть форму “Клиенты” в режиме конструктора, щелкнуть правой кнопкой мыши на титульной строке окна формы и выбрать в контекстном меню команду Обработка событий. Затем, как описывалось выше, в окне Построитель (см. рис. 5.23) следует выделить пункт Программы и щелкнуть на кнопке OK. Останется лишь выбрать в списке событий пункт Current.

Если же окно редактора кода все еще открыто, то достаточно выбрать в верхней части окна Form в списке объектов (список слева) и Current в списке событий (список справа). Текст, который следует ввести представлен на листинге 5.2.

ЛИСТИНГ 5.2

Private Sub Form_Current()

If Month(Forms![Клиенты].[Дата Рождения].Value) = Month(Date) _

And _

Day(Forms![Клиенты].[Дата Рождения].Value) = Day(Date) _

Then

Forms![Клиенты].[Дата Рождения].BackColor = vbYellow

Else

Forms![Клиенты].[Дата Рождения].BackColor = vbWhite

End If

End Sub

Вот краткий “перевод” кода этого макроса: если месяц даты рождения совпадает с месяцем текущей системной даты, È день месяца даты рождения совпадает с днем месяца системной даты, то задать для элемента управления Дата Рождения цвет фона — желтый. В противном случае задать для элемента управления Дата Рождения цвет фона — белый.

Использование функций Month и Day

Понятно, что функции Month() и Day() возвращают номера месяца и дня в месяце из значения даты, переданного им в качестве параметра (см. листинг 5.1).

см. также в приложении разделы “Функция Month” и “Функция Day”.

Но что же такое здесь “дата рождения”? Замысловатое выражение

Forms![Клиенты].[Дата Рождения].Value

переводится на обычный язык следующим образом: значение, которое содержится в элементе управления с именем “Дата Рождения”, который находится на форме с именем “Клиенты”, кото-

148 Глава 5. Access: создание офисной базы данных

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

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

Глава 6

Access: автоматизация офисной базы данных

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

Существует множество направлений развития, в которых могла бы “двигаться” созданная в предыдущей главе база данных, например, можно было бы заняться созданием различных запросов и отчетов, изучить весьма интересный механизм макрокоманд Access — поверьте, “в глубинах” MS Access есть много вещей, достойных изучения. Однако, в соответствии с темой книги, сосредоточимся на направлении развития, связанном с применением VBA-программ для автоматизации работы с базой данных.

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

Автоматизация ввода данных

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

Постановка задачи

Каждая приходная или расходная операция влечет за собой какое-то движение документов. Если документы, о которых идет речь, на некотором этапе своего оборота существуют в электронной форме, то эта их форма существования и предоставит весь набор возможностей для автоматизации работы с документооборотом. Предположим, например, что отпуск товара покупателю или реализатору сопровождается выдачей накладной. Предположим далее, что для печати накладной используется шаблон-заготовка на рабочем листе Excel. Каким бы образом ни был бы организован этот процесс, — в любом случае будет существовать момент времени, когда шаблон накладной на рабочем листе будет отображать все реквизиты реальной операции, подлежащей учету в базе данных. Это и будет подходящим моментом для программного кода VBA, который зарегистрирует операцию в таблице “Операции”.

Шаблон-“полуфабрикат”, который используется для печати накладной при отпуске товара покупателю или реализатору, вполне мог бы выглядеть подобно изображенному на рис. 6.1.

150 Глава 6. Access: автоматизация офисной базы данных

Рис. 6.1. Шаблон накладной для отпуска товара

На самом рабочем листе Excel могут использоваться различные способы автоматизации, например, имя и код клиента могут выбираться из списка, соответствующего именованному диапазону, который в свою очередь, может быть связан посредством Automation с каким-то иным источником данных. Такого рода возможности были рассмотрены достаточно подробно в предыдущих главах. Чтобы не усложнять задачу, будем сейчас исходить из “простого” устройства рабочего листа Excel. Для каждого клиента здесь используется отдельный рабочий лист, где зафиксировано его имя. В соответствующих ячейках содержатся формулы для расчета итоговой суммы, величины НДС и суммы “всего с НДС”.

Подготовка рабочего листа

Чтобы подготовить такой рабочий лист Excel для использования VBA-кода, обращающегося к базе данных Access, достаточно снабдить его командной кнопкой, при помощи которой будет запускаться соответствующий макрос. Пусть в ячейке C6 содержится код клиента в таблице клиентов, а в ячейке E6 — код операции, которые неизменен, поскольку речь в этом случае всегда идет об отпуске товара. Значение суммы операции можно взять из ячейки F15, где соответствующая формула вычисляет величину “всего с НДС”. В качестве значения даты используем системную дату компьютера, предполагая, что операции проводятся в реальном времени. Таким образом, лист Excel, представленный на рис. 6.1, примет вид, показанный на рис. 6.2.

Как снабдить рабочий лист кнопкой, читатель уже знает. Следует открыть панель инструментов Формы, выбрать на ней значок Кнопка, и “нарисовать” кнопку на поверхности листа. Затем, в открывшемся диалоговом окне Назначить макрос объекту, следует либо выбрать заранее созданный макрос и щелкнуть на кнопке OK, либо щелкнуть на кнопке Создать, а после ввести исходный текст макроса.

см. подробнее в раздел “Как поместить на лист элемент управления” гл. 1.

Автоматизация ввода данных 151

Рис. 6.2. Рабочий лист снабжен кнопкой для запуска макроса

Ссылка на библиотеку объектов MS Access

Как и в прежде рассмотренных примерах, когда макрос VBA должен был обращаться к объектам другого приложения MS Office (“другого” означает — не того приложения, в среде которого работает данный макрос), перед вводом исходного текста макроса необходимо задать ссылку на библиотеку объектов этого (другого) приложения. В случае MS Access дело обстоит сложнее обычного. Кроме объектной библиотеки, предназначенной для работы с собственно приложением Access, существует целый ряд библиотек, обеспечивающих работу с данными Access. Для доступа к базам данных Access существует несколько библиотек, причем эти библиотеки моут “мешать“ работе друг другу, поэтому задавать ссылки необходимо с пониманием факта возможного конфликта.

см. подробнее в этой главе раздел “Ссылки на библиотеки объектов: DAO или ADO?”.

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

Для того чтобы задать ссылку на библиотеку объектов Access, необходимо воспользоваться командой Сервис | Ссылки (Tools | References). Имя библиотеки может отличаться в различных версиях Office, в пакете MS Office 2000 эта библиотека называется Microsoft Access 9.0 Ob-

ject Library.

см. также в гл. 2 раздел “Как задать ссылку на библиотеку объектов Word в среде MS Excel”, гл. 3 раздел “Как задать ссылку на библиотеку объектов Excel в среде MS Word” и в гл. 9 раздел “Как подключить к Excel библиотеку типов Outlook”.

Исходный текст макроса, записывающего операцию в базу данных Access

Ниже приведен исходный текст (листинг 6.1), который необходимо ввести, как и ранее в подобных случаях, вступая на совершенно “неосвоенную” территорию. Сначала введем текст макроса и понаблюдаем, как он работает, а затем уже рассмотрим его код более подробно.

152 Глава 6. Access: автоматизация офисной базы данных

ЛИСТИНГ 6.1

Sub Запись_операции()

Dim MyAC As Access.Application

Set MyAC = CreateObject("Access.Application")

MyAC.OpenCurrentDatabase "C:\MyOffice.mdb"

MyAC.Visible = True

MyAC.DoCmd.OpenForm "Все операции"

MyAC.DoCmd.GoToRecord acDataForm, "Все операции", acNewRec

MyAC.Forms![Все операции]!Дата = Date

MyAC.Forms![Все операции]!СуммаОперации = _

ActiveSheet.Range("F15").Value

MyAC.Forms![Все операции]!КодОперации = _

ActiveSheet.Range("E6").Value

MyAC.Forms![Все операции]!КодКлиента = _

ActiveSheet.Range("C6").Value

MyAC.CloseCurrentDatabase

MyAC.Quit

Set MyAC = Nothing

End Sub

После ввода программного кода можно проверить его в работе. Достаточно щелкнуть на командной кнопке, которая связана с макросом, и, если компьютер не слишком быстр, то можно успеть увидеть, как VBA-код откроет окно MS Access, а в этом окне откроет окно базы данных “MyOffice”. Затем откроется форма “Все операции”, курсор ввода переместится на новую запись, и в нее будут введены соответствующие данные. После чего все окна закроются в обратном порядке.

Анализ процедуры Запись_операции

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

Объекты MS Access

Для того, чтобы работать с объектами Access, придется познакомиться с некоторыми новыми понятиями и освоить несколько иной подход в работе с объектами Office, — хотя в версии пакета 2000 многое сделано для того, чтобы унифицировать работу с объектами всех приложений, традиционно (так уж сложилось) MS Access отчасти “выбивается из стройных рядов” MS Office.

Как и в других случаях, когда VBA-программа должна работать с другим приложением Office, прежде всего, необходимо объявить объектную переменную, которая будет представлять это другое приложение:

Dim MyAC As Access.Application

Далее будет создан объект — приложение MS Access:

Set MyAC = CreateObject ("Access.Application")

Соседние файлы в папке Книги