Текст
                    Самоучитель
№1
по
программированию
на языке VBA
в Microsoft Office
2010
CAM 0V4 ИТЕЛЬ
Программирование
УВА
в Microsoft Office 2010
Л.Д. Слепцова
	Основные концепции программирования для
начинающих, среда разработки редактора VBA,
запись и использование макросов
	Синтаксис языка VBA, типы данных, операторы
обработки и управления ходом вычислений,
процедуры и функции
	Основные понятия объектно-ориентированного
программирования, работа с объектами
и коллекциями, создание экранных форм
	Обработка ошибок, отладка и тестирование
программ на VBA
	Особенности программирования для
Microsoft Excel 2010, Microsoft Word 2010
и Microsoft Outlook 2010

Программирование УВА в Microsoft Office 2010
Программирование УВА в Microsoft Office 2010 ЛД. Слепцова дцдласгаикд Москва • Санкт-Петербург • Киев 2010
ББК 32.973.26-018.2.75 С47 УДК 681.3.07 Компьютерное издательство “Диалектика” Зав. редакцией Л. Я Слепцов По общим вопросам обращайтесь в издательство “Диалектика” по адресу: info@dialektika.com, http://www.dialektika.com Слепцова, Л.Д. С47 Программирование на VBAв Microsoft Office 2010. — М.: ООО “И.Д. Вильямс”, 2010.- 432 с. : ил. ISBN 978-5-8459-1663-1 (рус.) ББК 32.973.26-018.2.75 Все названия программных продуктов являются зарегистрированными торговыми марками соответ- ствующих фирм. Никакая часть настоящего издания ни в каких целях не может быть воспроизведена в какой бы то ни было форме и какими бы то ни было средствами, будь то электронные или механические, включая фотокопирование и запись на магнитный носитель, если на это нет письменного разрешения издательства “Диалектика”. Copyright © 2010 by Dialektika Computer Publishing. All rights reserved including the right of reproduction in whole or in part in any form. Научно-популярное издание Лилия Дмитриевна Слепцова Программирование на VBA в Microsoft Office 2010 Самоучитель Литературный редактор Верстка Художественный редактор Корректор Е.Д. Давидян Л. В. Чернокозинская В. Г. Павлютин Л.А. Гордиенко Подписано в печать 18.07.2010. Формат 70x100/16. Гарнитура Times. Печать офсетная. Усл. печ. л. 34,83. Уч.-изд. л. 26,06. Тираж 1500 экз. Заказ № 23169. Отпечатано по технологии CtP в ОАО “Печатный двор” им. А. М. Горького 197110, Санкт-Петербург, Чкаловский пр., 15. ООО “И. Д. Вильямс”, 127055, г. Москва, ул. Лесная, д. 43, стр. 1 ISBN 978-5-8459-1663-1 (рус.) © Компьютерное изд-во “Диалектика”, 2010, текст, оформление, макетирование
Оглавление Введение 15 ЧАСТЬ I. ВВЕДЕНИЕ В VBA 19 Глава 1. Язык VBA и его возможности 21 Глава 2. Редактор Visual Basic 32 Глава 3. Создание и выполнение VBA-программ 48 ЧАСТЬ II. ОСНОВЫ ПРОГРАММИРОВАНИЯ НА VBA 65 Глава 4. Типы данных, переменные и константы 67 Глава 5. Операции и выражения 86 Глава 6. Управляющие операторы 96 Глава 7. Процедуры и функции 113 Глава 8. Объекты и коллекции 130 ЧАСТЬ III. БОЛЕЕ СЛОЖНЫЕ АСПЕКТЫ РАБОТЫ НА VBA 167 Глава 9. Встроенные функции VBA 169 Глава 10. Экранные формы и их элементы 192 Глава 11. Работа с файлами 254 Глава 12. Обработка ошибок и отладка программ 281 ЧАСТЬ IV. СОЗДАНИЕ ПРИЛОЖЕНИЙ В MS OFFICE 309 Глава 13. Программирование на VBA в Excel 311 Глава 14. Программирование на VBA в Word 349 Глава 15. Программирование на VBA в Outlook 370 Глава 16. Общие аспекты программирования на VBA в приложениях Microsoft Office 386 Приложение А. Основы программирования для начинающих 402 Приложение Б. Команды меню редактора VBA 414 Приложение В. Ответы на тестовые задания 420 Предметный указатель 424
Содержание Введение 15 Общие сведения о книге 15 Для кого предназначена эта книга 16 Структура книги 16 Условные обозначения 17 От издательства “Диалектика” 18 ЧАСТЬ I. ВВЕДЕНИЕ В VBA 19 Глава 1. Язык VBA и его возможности 21 Что такое VBA 21 Макросы и их создание 22 Запись макроса 24 Код макросов и его редактирование 26 Выполнение макросов 27 Сохранение макросов в виде модулей 27 Объектная структура языка VBA 29 Резюме 30 Тестовые задания 30 Глава 2. Редактор Visual Basic 32 Запуск редактора VBA 32 Окна редактора VBA и их настройка 32 Комбинации клавиш 34 Меню и панели инструментов редактора 35 Панели инструментов редактора VBA 35 Окно проектов и обозреватель объектов 38 Обозреватель объектов 40 Окна редактирования кода и форм 41 Окно редактирования форм 42 Окно свойств 44 Вызов справки 45 Резюме 46 Тестовые задания 46
Глава 3. Создание и выполнение VBA-программ 48 Общий цикл создания VBA-программы 48 Общие принципы построения VBA-программы 49 Написание новых макросов и процедур 50 Выполнение VBA-программы 54 Создание кнопки запуска VBA-программы 55 Назначение комбинации клавиш для запуска программы 58 Обработка ошибок 60 Резюме 62 Тестовые задания 62 ЧАСТЬ II. ОСНОВЫ ПРОГРАММИРОВАНИЯ НА VBA 65 Глава 4. Типы данных, переменные и константы 67 Типы данных 67 Числовые данные 68 Булевы значения 69 Тип Date 69 Текстовые данные 70 Тип Variant 70 Переменные 71 Присвоение имени и объявление переменных 71 Массивы 74 Статические и динамические массивы 75 Константы 77 Типы данных, определенные пользователем 79 Комментарии 81 Резюме 84 Тестовые задания 84 Глава 5. Операции и выражения 86 Выражения в языке VBA 86 Совместимость типов данных 87 Оператор присваивания 87 Арифметические операторы 88 Логические операторы 89 Операторы сравнения 91 Содержание 7
Строковые операторы 92 Приоритеты выполнения операций 93 Резюме 94 Тестовые задания 94 Глава 6. Управляющие операторы 96 Оператор перехода GoTo 96 Оператор условного перехода If...Then 98 Оператор Select Case 102 Операторы циклов 104 Оператор For...Next 104 Оператор For Each...Next 107 Цикл Do...Loop 108 Резюме 111 Тестовые задания 111 Глава 7. Процедуры и функции 113 Основные понятия о процедурах VBA 113 Аргументы процедур 115 Передача аргументов при вызове процедуры 116 Способы передачи аргументов в процедуру 118 Выполнение процедур 120 Функции языка VBA 122 Процедуры типа Function 122 Аргументы функций 126 Ошибки выполнения 127 Резюме 128 Тестовые задания 128 Diaea 8. Объекты и коллекции 130 Что такое объект 130 Свойства и методы объекта 131 Коллекции и контейнеры 135 События и их обработка 137 Понятие о классах и иерархии объектов 138 Модули классов 139 Создание свойств класса 140 8 Содержание
Создание методов класса События класса Пример использования класса Иерархия объектов Создание и идентификация объектов Объектные переменные Создание новых объектов Получение ссылки на существующий объект Идентификация объекта для использования Работа с объектами в программе Доступ к объектам в иерархии Работа с коллекциями Расширение коллекций Использование оператора With...End With Использование конструкции For Each...Next Окно Object Browser Резюме Тестовые задания 146 147 152 154 155 155 157 158 158 159 159 160 161 162 163 163 164 165 ЧАСТЬ III. БОЛЕЕ СЛОЖНЫЕ АСПЕКТЫ РАБОТЫ НА VBA 167 Глава 9. Встроенные функции VBA Математические функции Функции преобразования данных Форматирование данных Функции проверки типов Функции даты и времени Сложение и вычитание значений даты и времени Получение информации о дате и времени Строковые функции Функция MsgBox Функция InputBox Функция StrConv Функция Chr Финансовые и прочие функции Резюме Тестовые задания 169 169 170 172 175 176 177 178 180 181 183 184 185 187 190 190 Содержание 9
Eiaea 10. Экранные формы и их элементы 192 Формы пользователя 192 Отображение экранной формы 195 Закрытие экранной формы 196 Некоторые свойства объекта UserForm 197 Некоторые методы объекта UserForm 198 Элементы управления в формах 199 Добавление элементов управления 200 Выделение элементов управления 201 Позиционирование и выравнивание элементов управления в форме 202 Изменение свойств элементов управления 206 Свойства элементов управления 207 Надпись 207 Поле ввода 208 Поле со списком 209 Список 211 Флажок, Переключатель и Выключатель 212 Рамка 214 Кнопка 214 Набор страниц 215 Набор вкладок 216 Полоса прокрутки 217 Счетчик 217 Рисунок 218 Элемент управления RefEdit 220 Некоторые общие свойства элементов управления 220 Управление порядком перехода 224 Общие методы и события элементов управления 225 События форм и элементов управления 226 Создание процедур обработки событий 230 Дополнительные элементы управления 235 Проектирование и создание форм 237 Пример создания формы 239 Запуск формы на выполнение 251 Резюме 252 Тестовые задания 252 10 Содержание
Глава 11. Работа с файлами 254 Типы файлов 255 Открытие и закрытие файлов 256 Ввод и вывод данных в файлы последовательного доступа 258 Работа с файлами произвольного доступа 262 Бинарные файлы 264 Операторы и функции управления файлами 266 Поиск файлов и управление их атрибутами 267 Работа с файлами как с объектами 269 Доступ к файлам 269 Управление файлами 273 Резюме 278 Тестовые задания 279 Глава 12. Обработка ошибок и отладка программ 281 Перехват и обработка ошибок 281 Перехват ошибок 283 Продолжение выполнения программы 288 Ошибки модулей класса 289 Тестирование программы обработки ошибок 289 Работа с непредвиденными ошибками 291 Отладка приложений 291 Останов выполнения программы 293 Отладка кода в пошаговом режиме 296 Специализированные окна отладчика 300 Окно Immediate 300 Окно Locals 302 Окно Watches 303 Окно Call Stack 306 Резюме 307 Тестовые задания 307 ЧАСТЬ IV. СОЗДАНИЕ ПРИЛОЖЕНИЙ В MS OFFICE 309 Глава 13. Программирование на VBA в Excel 311 Объектная структура Excel 312 Объект Workbook 315 Содержание 11
Открытие и создание рабочих книг 316 Сохранение и закрытие рабочих книг 316 Вывод на печать содержимого рабочей книги 318 Объект Worksheet 319 Копирование и перемещение рабочих листов 320 Объект Range 321 Определение объекта Range 321 Использование свойства Cells для определения диапазона 324 Выполнение операций над диапазоном ячеек 327 Работа с отдельными ячейками диапазона 327 Работа с текущим выделением 329 Использование диалоговых окон Excel 332 Программирование пользовательских функций 333 Написание пользовательских функций рабочего листа 333 Использование встроенных функций Excel 335 Программирование событий Excel 336 Использование процедур обработки событий 337 Обработка внесения изменений в рабочий лист 338 Работа с диаграммами 342 Программирование динамических диаграмм 342 Резюме 347 Тестовые задания 347 Глава 14. Программирование на VBA в Word 349 Объектная модель Word 349 Доступ к документам Word с помощью VBA 350 Создание, открытие и закрытие документов 351 Управление параметрами и окнами Word 353 Переопределение параметров приложения Word 353 Диалоговые окна приложения Word 353 Обращение к окнам документов из программного кода 356 Объект View 358 Использование объектов Selection и Range 358 Объект Range 360 Работа с текстом 362 Удаление, копирование и вставка текста 365 12 Содержание
Поиск и замена информации 366 Использование переменных документа 367 Резюме 368 Тестовые задания 369 Глава 15. Программирование на VBA в Outlook 370 Объектная структура Outlook 370 Манипулирование папками и их содержимым 372 Обработка почтовых сообщений 374 Создание и отправка сообщений 376 Работа с получателями сообщений 376 Работа с адресной книгой 377 Работа с вложенными файлами 378 Управление событиями Outlook 380 Календарь 381 Резюме 384 Тестовые задания 384 Гцава 16. Общие аспекты программирования на VBA в приложениях Microsoft Office 386 Управление лентой приложения, панелями инструментов и меню 386 Сохранение значений переменных 392 Объект FileDialog 395 Поиск файлов на диске с помощью свойства FileSearch 396 Сохранение информации в реестре Windows 397 Доступ к объектам в других приложениях 398 Резюме 400 Тестовые задания 400 Приложение А. Основы программирования для начинающих 402 Что такое программа 402 Понятие о присвоении значения 404 Управляющие операторы и циклы 405 Операторы управления 406 Циклы 407 Модульное программирование 407 Процедуры 408 Содержание 13
Процедуры-функции 409 Аргументы процедур 411 Резюме 412 Тестовые задания 412 Приложение Б. Команды меню редактора VBA 414 Приложение В. Ответы на тестовые задания 420 Глава 1 420 Глава 2 420 Глава 3 420 Глава 4 420 Глава 5 421 Глава 6 421 Глава 7 421 Глава 8 421 Глава 9 421 Глава 10 422 Глава 11 422 Глава 12 422 Глава 13 422 Глава 14 422 Глава 15 423 Глава 16 423 Приложение А 423 Предметный указатель 424 14 Содержание
Введение Эта книга поможет изучить основные принципы программирования на языке VBA (Visual Basic for Applications) и получить необходимые навыки для создания собственных программ на этом языке. Ее цель — помочь пользователю самостоятельно научиться про- граммировать на языке VBA. Для восприятия материала книги не требуется знакомства с другими языками программирования и наличия программистского опыта. Более того, в нее включено специальное приложение “Основы программирования для начинающих”, в котором просто и доходчиво объясняется, что такое программирование, и излагаются те основные концепции, на основании которых создаются любые программы. Это при- ложение предназначено для читателей, никогда не имевших дела с программами и про- граммированием, и призвано помочь им быстро освоиться в этой области знаний. Если вы уже располагаете определенным опытом программирования, особенно на языке Visual Basic, то сможете изучить некоторые разделы этой книги очень быстро. Книга написана легко и понятно, в ней используется много простых и наглядных при- меров, которые помогут разобраться в излагаемом материале и закрепить полученные знания. Ее также можно использовать как полноценное справочное пособие, охватываю- щее все основные разделы языка VBA и (хотя и в меньшей степени) различные аспекты создания собственных приложений в среде Microsoft Office 2010. Вместе с языком про- граммирования VBA вы изучите мощную и гибкую среду разработки, которая является прекрасным выбором при работе над каким-либо проектом, предназначенным для ис- пользования в среде Microsoft Windows. Общие сведения о книге VBA — это язык программирования, встроенный во множество отдельных программ и прикладных пакетов — от приложений Microsoft Office (включая Microsoft Project и Microsoft Visio) и до таких мощных пакетов, как AutoCAD, CorelDraw и Adobe Creative Suite, не говоря уже о многочисленных специализированных приложениях, предназна- ченных для управления производственными процессами, учета финансовых ресурсов или информационной поддержки клиентов.
В этой книге рассмотрены все сколько-нибудь существенные аспекты программирования в среде VBA. Здесь можно найти достаточно полную информацию по таким темам, как: запись и редактирование макросов; назначение компонентов окна редактора VBA и использование визуальных средств программирования, предоставляемых в этом окне; создание диалоговых окон и других элементов интерфейса пользователя; работа с объектами, корректное использование которых станет ключом к созданию эффективных VBA-приложений; запуск VBA-программ из других приложений. Для кого предназначена эта книга Эта книга, прежде всего, для тех, у кого нет времени на продолжительное обучение, но есть большое желание научиться программировать на языке VBA. Практическое вы- полнение всех приведенных в книге пошаговых инструкций и применение на практике описанных приемов работы быстро научат вас создавать собственные VBА-программы, с помощью которых вы повысите эффективность своего труда. Данная книга предназначена для индивидуального обучения, однако она может стать и настольным справочником, которым можно будет воспользоваться в любой момент, столкнувшись со сложной или неизвестной ситуацией. В ней вы найдете ответы на мно- гие практические вопросы, которые, безусловно, возникнут у вас в процессе работы над собственными проектами. Конечно, эта книга не претендует на исчерпывающее описание всех аспектов программирования в среде Microsoft Office 2010 (что просто невозможно в рамках самоучителя), но все, что касается собственно языка VBA и работы в среде его графического редактора, описано здесь исчерпывающе подробно. Структура книги Материал книги состоит из четырех частей. В главах части I, “Введение в VBA”, вы ознакомитесь с основными возможностями языка VBA. Здесь же вы научитесь записывать макросы, чтобы не обращаться к програм- мированию там, где вместо программы вполне можно использовать обычный макрос. В этой части вы также ознакомитесь с принципами работы в визуальной среде програм- мирования редактора VBA и научитесь запускать свои VBA-программы на выполнение. В главах части II, “Основы программирования на VBA”, посвященной основам про- граммирования на языке VBA, я расскажу об использовании переменных, познакомлю вас с операторами и операциями, с помощью которых можно манипулировать данными в программе. Здесь же вас ожидает знакомство с процедурами и функциями, а также с та- кими ключевыми понятиями программирования в среде Microsoft Office 2010, как объек- ты и коллекции, в которые входят эти объекты. В главах части III, “Более сложные аспекты работы на VBA”, обсуждаются более про- фессиональные аспекты работы в визуальной среде разработки редактора VBA. Здесь вы найдете описание встроенных функций VBA, познакомитесь с экранными формами и их элементами управления, научитесь работать с файлами, а также выявлять и исправлять ошибки, которые могут возникнуть при написании программ. 16 Введение
В главах части ГУ, “Создание приложений в MS Office 2010”, речь пойдет об особен- ностях программирования на языке VBA в среде Microsoft Office 2010. Сначала погово- рим о программировании в среде Excel, Word и Outlook, а затем рассмотрим некоторые приемы программирования, применимые практически ко всем приложениям Microsoft Office 2010; они будут представлять интерес для VBA-программистов независимо от того, с какими приложениями они работают. В книгу включено также три приложения. В приложении А для начинающих про- граммистов просто и доходчиво объясняется, что такое программирование, и излагаются те основные концепции, на основании которых строятся любые программы. В приложе- нии Б в качестве полезного справочного материала приводится краткое описание всех команд меню редактора VBA с указанием назначенных им комбинаций клавиш, если таковые имеются. И наконец, в конце каждой главы читателю предлагаются тесты, необходимые для самоконтроля за усвоением материала. Ответы на все эти вопросы помещены в приложе- ние В, причем там же указывается, где в случае необходимости можно найти разъяснения по каждому тесту. Условные обозначения Для того чтобы проще было ориентироваться при работе с книгой и привлечь внима- ние читателя к особенно важным местам излагаемого материала, в текст книги помещены особые значки, или пиктограммы. Обратите внимание на дополнительную или просто важную информацию, приведен- ную в отмеченном этой пиктограммой разделе. Раздел, отмеченный этой пиктограммой, содержит полезный совет, воспользовав- шись которым вы сможете сэкономить свое время или просто упростить выполняе- мую операцию. Будьте особенно внимательны, поскольку этой пиктограммой отмечаются разделы кни- J s ги с указаниями, как избежать чаще всего возникающих недоразумений или исключить неправильное толкование излагаемого материала. Этой пиктограммой отмечаются разделы, в которых представлены подробности или технические детали определенной темы. Введение 17
От издательства “Диалектика” Вы, читатель этой книги, и есть ее главный критик. Мы ценим ваше мнение и хотим знать, что было сделано нами правильно, что можно было сделать лучше и что еще вы хотели бы увидеть изданным нами. Нам интересно услышать и любые другие замечания, которые вам хотелось бы высказать в наш адрес. Мы ждем ваших комментариев и надеемся на них. Вы можете прислать нам бумажное или электронное письмо либо просто посетить наш веб-сервер и оставить свои замечания там. Одним словом, любым удобным для вас способом дайте нам знать, нравится ли вам эта книга, а также выскажите свое мнение о том, как сделать наши книги более интерес- ными для вас. Посылая письмо или сообщение, не забудьте указать название книги и ее авторов, а так- же ваш обратный адрес. Мы внимательно ознакомимся с вашим мнением и обязательно учтем его при отборе и подготовке к изданию последующих книг. Наши координаты: E-mail: info@dialektika.com WWW: http://www.dialektika.com Информация для писем из: России: 127055, г. Москва, ул. Лесная, д. 43, стр. 1 Украины: 03150, Киев, а/я 152 18 Введение
Часть Введение в VBA В этой части... > Глава 1. Язык VBA и его возможности > Глава 2. Редактор Visual Basic > Глава 3. Создание и выполнение VBA-программ

Глава 1 Язык VBA и его возможности В этой главе... ♦ Что такое VBA ♦ Макросы и их создание ♦ Код макросов и его редактирование ♦ Выполнение макросов ♦ Сохранение макросов в виде модулей ♦ Объектная структура языка VBA ♦ Резюме Что такое VBA VBA (Visual Basic for Application) — это язык программирования, поддерживаемый всеми приложениями пакета Microsoft Office 2010, в состав которого входят такие попу- лярные приложения, как Microsoft Excel, Microsoft Assess, Microsoft PowerPoint, Microsoft Word и др. Это относительно несложный язык программирования, который очень прост и удобен в освоении и позволяет быстро получить ощутимые результаты — конструировать профессиональные приложения для решения практически любых задач в среде Microsoft Windows. Можно сказать, что язык VBA является прямым наследником языка программи- рования Basic, но тем не менее, по сравнению с ним, он шагнул далеко вперед. Поэтому и возможностей, как его внутренних (например, в части вывода на экран всевозможных форм), так и взаимодействия с другими приложениями, у него гораздо больше. Изучив язык Visual Basic for Application, вы поймете, что создавать собственные офисные при- ложения с его помощью гораздо проще и быстрее, чем с помощью других языков про- граммирования. Следует заметить, что, являясь развитым языком программирования, VBA также включает в себя полноценную интегрированную среду разработки с полным набором специализированных окон, упрощающих проектирование, отладку и тестирование про- грамм. Интегрированная среда разработки VBA представлена приложением, называемым редактором Visual Basic. Этот редактор имеет типичное для приложений Windows окно с панелью меню и набором панелей инструментов, которые позволяют получить доступ к ряду окон, предоставляющих инструментальные средства, необходимые для создания программ. Кроме того, редактор VBA включает специализированные средства для бы- строго создания пользовательского интерфейса, что превращает его в визуальную среду разработки приложений.
Макросы и их создание Если у вас есть хотя бы небольшой опыт работы с компьютерными приложениями в любой из операционных систем, то для вас не секрет, что при решении многих задач часто приходится выполнять одну и ту же последовательность операций. Однако в Microsoft Office 2010 вместо многократного повторения одной и той же последовательности дей- ствий вы можете написать макрос (Macro), который будет автоматически выполнять тре- буемую последовательность действий вместо вас. Таким образом, макросы представляют собой средство, с помощью которого можно описать произвольную последовательность действий пользователя для ее последующего многократного выполнения. Для многих VBA-приложений — среди них Microsoft Word, Excel, Assess, PowerPoint и так далее — ма- кросы можно создавать с помощью как языка Visual Basic for Application, так и специаль- ных функций Microsoft Office 2010, используемых для интерактивной записи макросов. Эти функции позволяют записывать все выполняемые пользователем действия в процессе его работы с приложением — до тех пор, пока запись не будет остановлена. После остано- ва записанная последовательность действий сохраняется в виде поименованного макроса. Таким образом, вы сможете пользоваться им каждый раз, когда потребуется повторить выполнение записанной в нем последовательности операций. Следует заметить, что независимо от того, работаете ли вы в Word, Excel, Assess или PowerPoint, создание нового макроса осуществляется одним и тем же способом. Давайте посмотрим, как это выполняется на практике. Откройте Microsoft Excel 2010 и выберите на ленте приложения вкладку Вид — для этого просто щелкните на ее корешке левой кнопкой мыши. Затем в группе Макросы щелкните на кнопке Макросы и в раскрывшемся меню выберите команду Запись макроса — как показано на рис. 1.1. В результате этих действий на экране раскроется диалоговое окно Запись макроса (рис. 1.2). Книга! - Microsoft Excel Вставка Разметка страницы Формулы Данные Рецензирование Бид Разработчик сз £3 Новое окно П _ Я Упорядочить все £3 Обычный Разметка Показать Масштаб 100% Масштабировать страницы а • выделенный фрагмент Закрепить области ’ ~ Сохранить Перейти в рабочею область другое окно Макросы Макросы S3 *3 Запись макроса . $Я| <2тнссительные ссылки Рис. 1.1. Лента приложения Microsoft Excel 2010 с открытой вкладкой Вид, на которой в группе Макросы выбрана команда меню Запись макроса В интерфейс приложений Microsoft Office 2010 — по сравнению с предыдущей по- пулярной версией пакета Office 2003 — были внесены существенные изменения. Так, в этой версии существует такое понятие, как “лента”. Она заменяет собой меню, па- нель задач и панели инструментов, которые использовались для работы в приложени- ях Предыдущих версий пакета, до Office 2007. Она была разработана для упрощения доступа к функциональным возможностям приложений и в версии 2010 получила дальнейшее развитие. Лента объединяет несколько вкладок, каждая из которых со- стоит из нескольких групп элементов управления, близких по назначению. Вкладки ориентированы на выполнение задач, группы на каждой вкладке разбивают задачу на ее составляющие, а кнопки команд, списки, меню и другие элементы управления в каж- дой группе служат для выполнения отдельных команд (более подробно об этом будет говориться далее в этой книге, по мере необходимости). 22 Часть 1. Введение в VBA
Хочу заметить, что, хотя диалоговое окно Запись макроса в разных приложениях Microsoft Office 2010 — Word, Excel или PowerPoint — выглядит несколько по-разному, правила записи нового макроса для всех приложений одинаковы. В частности, надо пом- нить следующее: имя макроса должно начинаться с буквы, хотя внутри имени могут быть и цифры и символ подчеркивания; имя макроса не может включать пробелы или знаки препинания (специальные символы); максимальная длина имени макроса составляет 80 символов. Для разделения слов можно применять символ подчеркивания: Итог_по_строкам, но все же лучше для этой цели использовать прописные буквы внутри имени — например, ИтогПоСтрокам. В зависимости от приложения, в котором создается макрос (редактор Visual Basic, Word, Excel), диалоговое окно Запись макроса может содержать различные поля и опции — на- пример, поле описания макроса, поле для указания места хранения текста макроса, назна- чаемую макросу комбинацию клавиш для его вызова и т.д. Как видно из рис. 1.2, в диалого- вом окне Запись макроса в приложении Excel 2010 присутствует поле Сочетание клавиш, в котором можно указать желаемую комбинацию клавиш, которая будет использоваться для быстрого вызова данного макроса (комбинация клавиш <Ctrl+oaeww/a>). Это при- годится вам в том случае, если вы собираетесь часто использовать записываемый макрос. В приложении Word в диалоговом окне Запись макроса (рис. 1.3), в отличие от Excel, в группе Назначить макрос имеются еще две дополнительные кнопки: кнопке (button) и клавишам (keyboard). Эти кнопки позволяют либо присвоить функцию вызова макроса новой кнопке на панели инструментов, либо назначить для него некоторую комбинацию клавиш быстрого вызова. После щелчка на любой из этих кнопок раскроется еще одно диалоговое окно, в котором необходимо будет сделать соответствующее назначения. Рис. 1.2. Диалоговое окно Запись макроса в Microsoft Excel 2010 Рис. 1.3. Диалоговое окно Запись макроса в Microsoft Word 2010 Следует отметить, что для всех приложений Microsoft Office в диалоговом окне Запись макроса есть и некоторые общие элементы. Поле Имя макроса — здесь указывается имя записываемого нового макроса. По умолчанию VBA помещает в это поле значение Макрос1. Глава 1. Язык VBA и его возможности 23
Поле Описание — в него записывается произвольный текст, т.е. комментарий о том, для чего предназначен данный макрос. По умолчанию VBA заполняет это окно информацией о том, где и кем был создан данный макрос (дата записи макро- са и имя пользователя). Список Макрос доступен для — содержит перечень тех документов, в которых создаваемый макрос может быть сохранен; выберите в нем тот документ, в котором следует сохранить создаваемый новый макрос. Следует отметить, что в Word 2010 макросы могут сохраняться только в файлах документа формата . do ст или в фай- лах шаблонов документов формата . dotm. Кроме того, макрос можно сохранить в документе или шаблоне формата Word 97-2003 (.doc или .dot). В Excel 2010 макросы можно сохранить в рабочей книге формата . xlsm или . xlsb, в шаблоне формата . xltm, а также в документах формата Excel 97-2003 (. xls). Прямым указанием о начале записи макроса во всех приложениях является щелчок на кнопке ОК в диалоговом окне Запись макроса. После щелчка на кнопке ОК в окне при- ложения появится указатель мыши, который будет дополнен небольшим изображением магнитофонной кассеты. Начиная с этого момента, все ваши действия будут записаны и помещены в макрос. После начала записи макроса последовательно выполните все те действия, которые впоследствии должны будут автоматически выполняться при каждом запуске данного макроса. Иначе говоря, выполняйте требуемые команды того приложения, с которым вы сейчас работаете, нажимайте быстрые клавиши или вводите необходимые данные с клавиатуры — все это будет записываться в макрос. Когда требуемая последовательность действий будет выполнена, а значит, и создаваемый макрос уже полностью записан, перейдите на ленте приложения на вкладку Вид, раскройте в группе Макросы меню и вы- берите в нем команду Остановить запись. Теперь запись макроса будет прекращена, а вся последовательность выполненных вами действий сохранится в виде VBА-программы, за- писанной как макрос с заданным именем в указанном документе. Если при записи макроса (в Word) потребуется временно приостановить процесс за- Ж писи, выберите в группе Макросы команду меню Пауза. Это вам понадобится в том случае, если необходимо выполнить какую-то подготовительную операцию, которая не должна стать частью макроса. Выберите эту команду еще раз, когда можно будет про- должить запись приостановленного макроса. Запись макроса Давайте попробуем создать в Excel макрос, который помещает шесть названий месяцев (в виде трехбуквенных сокращений) в верхнюю строку рабочего листа, начиная с ячейки В1. Сначала представим, как будет выглядеть эта операция. В нашем случае все будет просто — необходимо просто ввести указанные данные в лист. Для того чтобы название месяца “Янв” всегда помещалось в ячейку В1, следует включить в макрос операцию вы- деления этой ячейки, иначе ввод последовательности символов “Янв” при выполнении макроса будет осуществляться в текущую активную ячейку, которая может находиться в любом месте листа. Теперь подумаем, в какой момент необходимо завершить запись макроса. Это может быть как после ввода в ячейку слова “Июн”, так и после выбора ячейки в следующей строке — например В2, что впоследствии позволит сразу же после выполнения макроса 24 Часть 1. Введение в VBA
начать ввод данных. Мы выберем, в качестве активной ячейки после завершения работы макроса, ячейку В2, поэтому перед остановом записи макроса выделим ячейку В2. Итак, начнем создание макроса с пустого листа, на котором по умолчанию выделе- на ячейка А1. Для того чтобы начать запись макроса, выберите на ленте приложения вкладку Вид и в группе Макросы выберите команду Запись макроса. В раскрывшемся диалоговом окне Запись макроса введите имя, которое будет присвоено создаваемому макросу, — Полугодие!. В поле Сочетание клавиш (если вам это необходимо) введите единственный символ f, тогда в дальнейшем нажатие комбинации клавиш <Ctrl+f> будет вызывать запуск этого макроса. В поле Сохранить в выберите значение Эта книга для сохранения созданного макроса в активной книге. После заполнения всех полей в диалоговом окне Запись макроса щел- кните на кнопке ОК. Начался процесс записи. Щелкните на ячейке В1 и введите в шесть соседних ячеек названия месяцев, как показано на рис 1.4. Рис. 1.4. Ввод значений в ячейки при создании макроса Теперь дополнительно отформатируем введенные значения. Выделите ячейки B1:G1, перейдите на ленте на вкладку Главная и в группе Шрифт щелкните на кнопках S и И. Затем щелкните на ячейке В2 и остановите запись макроса, для чего откройте на ленте вкладку Вид и выберите в меню группы Макросы команду Останов записи. Сохраните книгу под именем Книга1 . xlsm. Теперь созданный макрос готов к выполнению (под- робнее о сохранении и выполнении макросов еще будет говориться ниже в этой главе). Глава 1. Язык VBA и его возможности 25
Код макросов и его редактирование При записи макроса в любом из выбранных приложений (в Microsoft Word, Excel или PowerPoint) все выполненные вами действия будут записаны в виде последовательности соответствующих операторов языка VBA. Вся совокупность этих операторов будет назы- ваться исходным кодом или кодом макроса. Полученный таким образом код в дальнейшем можно будет использовать при создании собственной программы. Причем в этой про- грамме можно будет как корректировать уже имеющиеся, так и, при необходимости, до- бавлять новые операторы. Напомним, что некоторые VBA-приложения позволяют связать с любым макросом вновь созданную кнопку, которую затем можно поместить на панель быстрого доступа, что за- метно ускоряет процесс вызова макроса. (Панель быстрого доступа расположена слева, в верхней строке окна приложения, непосредственно над корешками вкладок ленты.) Отредактировать или просмотреть текст записанного макроса можно с помощью ко- манды Макросы в меню кнопки Макросы группы Макросы на вкладке Вид приложения или команды меню редактора VBA Tools^Macros (Сервис^Макросы). В результате на экран будет выведено диалоговое окно Макрос, показанное на рис. 1.5. Выберите из списка перечисленных имен макросов требуемый макрос (т.е. щелкните мышью на его имени в списке) и щелкните на кнопке Изменить. На экране откроется окно редактора VBA с про- граммным кодом выбранного макроса, готовым для редактирования. В этом окне можно добавлять, удалять, копировать, изменять, вырезать или вставлять любые операторы на языке VBA, пользуясь командами меню Edit редактора VBA. Для сохранения программного кода отредактированного макроса выберите команду меню File^Save Имя_Документа (Файл^Сохранить в...) редактора VBA или щелкните на кнопке Save Имя_Документа (Сохранить в...) панели инструментов Edit (рис. 1.6). Рис. 1.5. Диалоговое окно Макрос в Microsoft Word 2010 ave Normal (Ctri-rS)]* Рис. 1.6. Кнопка Save панели инструментов Edit редактора VBA 26 Часть 1. Введение в VBA
Выполнение макросов После того как созданный вами макрос записан, он сразу же будет готов для выполне- ния. Для выполнения макроса в любом из приложений Microsoft Office 2010 (Word, Excel или PowerPoint) его необходимо сначала выбрать в списке доступных, а затем запустить. Для этого откройте на ленте соответствующего приложения вкладку Вид и в группе Макросы выберите команду Макросы, если вы решили вызвать макрос из документа Word или Excel. Макрос можно запустить и из окна редактора VBA — для этого выберите в меню редактора VBA команду Tools^Macros (Сервис^Макросы). В любом случае после указанных дей- ствий на экране раскроется диалоговое окно Макрос (см. рис. 1.5). Чтобы выбрать нужный макрос, щелкните мышью на его имени в списке Имя (или Macro Name в редакторе VBA), содержащем имена доступных макросов, а затем щелкните на кнопке Выполнить (Run). Если при создании макроса для него была назначена определенная комбинация клавиш, то выполнить (запустить) этот макрос также можно, нажав выбранную комбинацию кла- виш. Если при создании макроса для него была создана кнопка на панели быстрого до- ступа, то выполнить этот макрос можно будет, просто щелкнув на этой кнопке. Сохранение макросов в виде модулей Как уже было сказано выше, после записи макроса все выполненные при этом дей- ствия фиксируются в виде последовательности соответствующих операторов языка VBA. Текстовое представление операторов на языке VBA, содержащееся в исходном коде ма- кроса, сохраняется в специальной части файла данных приложения, называемой модулем. Файл документа соответствующего типа любого из VBA-приложений может содержать один или несколько модулей или не содержать их вообще. Модулям, сохраняемым в до- кументах Word, по умолчанию присваивается общее название Project (проект), а в до- кументах Excel — VBAPro j ect. Как уже упоминалось выше, макросы, записываемые в Word, можно сохранить в файлах документа формата . doom или в файлах шаблонов документов формата . dotm. Конкретно место сохранения нового макроса указывается в поле Макрос доступен для в диалоговом окне Запись макроса перед началом его записи (см. рис. 1.3). При сохра- нении макросов в шаблоне документа Word записанные макросы сохраняются в модуле NewMacros. Например, если для вновь записываемого макроса указано сохранение в ша- блоне Normal. dotm, то Word сохранит созданный исходный код этого макроса в модуле NewMacros шаблона Normal. dotm. При записи макроса в Excel в окне Запись макроса требуется указать рабочую книгу (формата . xlsm или . xlsb), в которой будет сохранен записанный макрос (рис. 1.7). Для этого в списке Сохранить в следует выбрать одно из доступных значений, определяющих тот документ, в котором будет сохранен записанный макрос: Личная книга макросов, Новая книга и Эта книга. Макросы, имеющие непосредственное отношение к текущей рабочей книге, рекомендуется сохранять, выбрав в списке значение Эта книга. После того как место хранения макроса будет выбрано, щелкните на кнопке ОК. Если в документе, выбранном для хранения записываемого макроса, еще нет модуля, он будет создан с именем Module 1. Если необходимо, чтобы создаваемый макрос был доступен для всех файлов, с которыми вы работаете в Excel, выберите в списке Сохранить в значение Личная книга макросов. В остальных случаях созданный макрос будет досту- пен только в указанном документе. Глава 1. Язык VBA и его возможности 27
Рис. 1.7. Доступные варианты сохранения нового макроса, записываемого в Excel Следует отметить, что личная книга макросов по самой своей сути подходит для хране- ния далеко не каждого макроса, поэтому в ней рекомендуется хранить лишь макросы ’ общего назначения, а не те, которые имеют отношение только к конкретному рабочему листу или книге. Если выбрано сохранение макроса в личной книге макросов, он до- бавляется в специальный файл Excel, который называется Personal. xlsb. Это скры- тый файл, автоматически сохраняемый в каталоге Диск: \Document and Settings \ Пользователь\Арр11са^оп Data\Microsof t\Excel\XLSTART при завершении работы приложения. Файл Personal. xlsb автоматически загружается при каждом запуске Excel, поэтому сохраненные в нем макросы будут доступны для всех книг. Мы так подробно обсуждаем размещение и имена создаваемых модулей по той причи- не, что, зная имена используемых в различных приложениях модулей, вы при необходи- мости сможете быстро находить записанные макросы — например, если потребуется про- смотреть или отредактировать их код. Для того чтобы найти модуль с интересующим вас макросом в любом из приложений VBA, необходимо выполнить следующие действия. 1. Открыть редактор VBA, выбрав на ленте приложения вкладку Разработчик и щел- кнув в группе Код на кнопке Visual Basic (крайняя слева). 2. Открыть окно проектов, выбрав в окне редактора VBA команду меню View^Project Explorer (ВидФОкно проекта). 3. В окне Project Explorer найти в иерархии компонентов имя необходимого модуля и дважды щелкнуть на нем. После выполнения указанных действий редактор VBA откроет окно кода с текстом выбранного модуля. В списке Declarations (Объявления) этого окна (справа вверху) вы- берите имя требуемого макроса в открытом модуле (рис. 1.8), после чего в данном окне можно будет просмотреть или отредактировать исходный код этого макроса. При записи макросов в приложениях Microsoft Office 2010 их текст записывается в виде последовательности операторов языка VBA. Таким образом, можно использовать эти средства для создания заготовок элементов программ, которые предстоит написать на языке VBA. Именно поэтому в данной главе макросам уделено так много внимания. Вместо того чтобы вручную программно описывать некоторую последовательность действий в том или ином приложении Office, можно просто записать соответствующий макрос, а затем скопировать его код в текст создаваемой программы. 28 Часть 1. Введение в VBA
Рис, 1,8, Окно кода с текстом макроса, запомненного в книге Excel Объектная структура языка VBA Главное преимущество языка VBA состоит в том, что он относится к языкам объектно- ориентированного программирования. В основу программирования на VBA положено такое понятие, как объект. Объект позволяет инкапсулировать данные, описывающие некоторый элемент, вместе с программным кодом, предназначенным для обработки этих данных, т.е. объединить их в нечто целое, называемое объектом. В каждом VBA- приложении есть свой уникальный набор объектов с их собственными свойствами (харак- теристиками данного элемента) и методами (командами для той или иной обработки этих свойств). В результате доступ к свойствам объекта (т.е. характеристикам состояния не- которого элемента в приложении) возможен только с помощью его собственных методов (т.е. специально подготовленных команд обработки этих свойств). Управление состоянием элемента осуществляется с помощью посылаемых ему сообщений, указывающих объекту на необходимость выполнить тот или иной метод для достижения требуемого результата. Сами сообщения генерируются системой в ответ на действия пользователя или действия других функционирующих в системе программ, называемых в этом случае событиями. Одно из важнейших понятий объектно-ориентированного программирования — это понятие класса, описывающее типовую структуру сходных по назначению элементов. В системе хранится программное описание каждого используемого класса, на основании которого при необходимости создаются экземпляры объектов, представляющих конкрет- ные элементы программной среды. Например, в программе может быть описан класс кнопки, отображаемой в окнах приложения. Каждая отдельная кнопка (экземпляр объ- екта этого класса) в любом окне приложения создается на основании этого описания, но отличается от других своими свойствами (размером, цветом, надписью, выполняемой после щелчка операцией и т.д.). В языке VBA класс обычно описывается как определенный прототип, на основе ко- торого создается конкретный объект. Класс определяет назначение объекта, его свой- ства и те действия, которые могут быть выполнены над этим объектом. С точки зрения Глава 1. Язык VBA и его возможности 29
программы, сам по себе объект не представляет большого интереса, гораздо важнее то, какие действия можно совершить над этим объектом и какими свойствами он обладает. Действия, выполняемые над объектом, определяются набором его методов, а свойства данного объекта определяют его различные характеристики (размер, цвет, положение на экране и т.д.). Управлять характеристиками объекта программа может только с помощью его же методов, предоставляющих доступ к свойствам этого объекта. Кроме методов и свойств объекта, существует такое понятие, как событие. Событие — это некоторое действие, которое может быть выполнено в отношении объекта и на которое, следовательно, необходимо запрограммировать ответную реакцию данного объекта (от- клик). Например, событием может быть щелчок на изображении объекта, нажатие клавиши на клавиатуре или перемещение указателя мыши над изображением объекта. Другими сло- вами, события в системе возникают в результате действий пользователя, действий данной или другой программы либо действий самой операционной системы. На каждое возможное и интересующее нас событие в программе должен быть описан соответствующий отклик, иначе программа не сможет отреагировать на данное событие, и оно останется безответным. В целом, суть программирования на языке VBA состоит в создании кода программ (методов), которые генерируют необходимые отклики на интересующие нас события. Резюме В этой главе было рассказано о языке VBA и его основных возможностях. Вы узнали о происхождении этого языка и его основном назначении. Далее подробно обсуждался са- мый простой способ создания VBA-программ — запись макросов с помощью инструмента MacroRecorder с последующим анализом и корректировкой. В завершение главы мы озна- комились с базовыми концепциями объектно-ориентированного программирования, что необходимо для ясного понимания материала, излагаемого в последующих главах книги. Тестовые задания Ниже приведено несколько тестовых заданий, предназначенных для закрепления из- ложенного в этой главе материала. В каждом задании вам предлагается вопрос и несколь- ко вариантов ответа на него, один (или несколько) из которых является правильным, а остальные — нет. Укажите правильный ответ. 1. Язык VBA представляет собой: а) самостоятельное приложение работы с данными; б) объектно-ориентированный язык программирования; в) процедурный язык программирования; г) инструмент обработки данных в приложениях Microsoft Office 2010. 2. Редактор Visual Basic представляет собой: а) интегрированную визуальную среду разработки; б) самостоятельное приложение Microsoft Office 2010; в) самостоятельное приложение Microsoft Windows; г) транслятор с языка Visual Basic. 30 Часть 1. Введение в VBA
3. Макрос в языке VBA — это: а) самостоятельная программа Microsoft Office 2010; . б) средство управления работой приложений Microsoft Office 2010; в) поименованная запись последовательности действий пользователя для упроще- ния ее многократного повторения; г) фрагмент документа приложения Microsoft Office 2010. 4. Код макроса на языке VBA сохраняется: а) в теле документа приложения Microsoft Office 2010; б) в шаблоне документа Microsoft Office 2010; в) в отдельном файле с расширением . vba; г) в системных библиотеках. 5. Основными понятиями объектно-ориентированного программирования являются: а) процедуры и функции; б) объекты и события; в) константы и переменные; г) свойства и методы; д) классы. Глава 1. Язык VBA и его возможности 31
Глава 2 Редактор Visual Basic В этой главе... ♦ Запуск редактора VBA ♦ Окна редактора VBA и их настройка ♦ Меню и панели инструментов редактора ♦ Окно проектов и обозреватель объектов ♦ Окна редактирования кода и форм ♦ Окно свойств ♦ Вызов справки ♦ Резюме Запуск редактора VBA Редактор VBA (Visual Basic Editor) используется для создания новых модулей, ре- дактирования уже существующих модулей, создания и редактирования исходного кода макроса, создания пользовательских окон и для решения многих других задач, которые относятся к написанию и обслуживанию программ на языке VBA. Таким образом, чтобы просмотреть модули или исходный код на языке VBA, который они содержат, необходимо запустить редактор VBA. Для запуска редактора VBA в большинстве поддерживающих язык VBA приложений нужно выбрать на ленте вкладку Разработчик и в группе Код щелкнуть на кнопке Visual Basic или нажать комбинацию клавиш <Alt-i-Fl 1 >. В частности, именно так вызывается редактор VBA во всех приложениях из пакета Microsoft Office 2010 (Word, Excel, PowerPoint и т.д.). Общий вид окна редактора VBA представлен на рис. 2.1. Закончить работу в редакторе VBA или выйти из него (в любой момент работы в нем) можно, выбрав команду меню File^Close and Return to <приложение> или нажав ком- бинацию клавиш <Alt-i-Q>. Окна редактора VBA и их настройка В редакторе VBA используется достаточно много окон, а потому держать их все одно- временно открытыми на экране нерационально. Однако следует помнить, что окон форм и программного кода на экране монитора может быть столько, сколько вам необходимо, а вот окна всех остальных типов могут присутствовать на экране только в единственном экземпляре. Для каждого окна редактора VBA существует своя комбинация быстрых клавиш, с помощью которой его можно открыть. Все эти комбинации (а также многие другие) представлены в табл. 2.1. Едва ли вам удастся запомнить комбинации сразу для всех окон
редактора VBA, поэтому не забывайте, что любое из них можно открыть с помощью соот- ветствующей команды меню View редактора VBA. Рис. 2.1. Общий вид окна редактора VBA при первом запуске в программе Word 2010 Чтобы закрыть окно (удалить окно с экрана), необходимо щелкнуть на системной кнопке закрытия окна, расположенной в правом верхнем углу любого окна в среде Windows. Как говорилось выше, окон в редакторе VBA очень много, поэтому если вам пона- добится окно, которое было отображено, но потерялось на экране за другими окнами, вывести его поверх всех других окон можно, выбрав имя этого окна в меню Window. Хочу заметить, что в этом меню представлены имена только перемещаемых окон. Для перехода из одного окна в другое можно воспользоваться специальными комби- нациями клавиш редактора VBA — <Ctrl+Tab> или <Ctrl+F6>. Перечислим основные окна редактора VBA: окно проекта (Project Explorer), предоставляющее быстрый доступ к окнам про- граммного кода и пользовательским формам; окно свойств (Properties Window), позволяющее просмотреть и изменить значения свойств объекта любого типа (проекта, модуля, формы), который в данный момент активен; Глава 2. Редактор Visual Basic 33
окно программы (Code), позволяющее просматривать, редактировать и создавать исходный код на языке VBA. Кроме этих трех основных окон, существует еще четыре окна для отладки программы. С работой в каждом из этих окон мы познакомимся позднее. Комбинации клавиш В табл. 2.1 представлены все комбинации быстрых клавиш, которые могут исполь- зоваться в редакторе VBA для ускорения работы. Кроме того, для управления курсором и редактирования текста можно использовать также стандартные комбинации клавиш Windows. Следует помнить, что комбинация клавиш <Shift+F10> вызывает контекстное меню для окна или иного объекта, активного в данный момент. Таблица 2.1. Комбинации клавиш редактора VBA Действие Клавиши Отображение окон Открыть окно программного кода для данной формы Отобразить форму соответствующего окна программного кода Перейти в следующее окно программного кода или в окно формы Открыть окно обозревателя объектов Открыть окно свойств Открыть окно немедленного выполнения команд Открыть окно стека вызовов во время выполнения программы Работа с программным кодом Перейти к определению объекта в точке ввода Открыть диалоговое окно поиска Найти, где следующий раз встречается текст, заданный в окне поиска Найти, где предыдущий раз появлялся текст, заданный в окне поиска Заменить Перейти к предыдущей редактируемой строке Отменить последнее действие Открыть окно свойств/методов Открыть список констант Получить справку о переменной или объекте, отмеченном курсором ввода Отобразить информацию о параметрах функции, отмеченной курсором ввода Автоматически дополнить вводимое с клавиатуры слово Работа со свойствами Перейти в окне свойств к следующему свойству, которое начинается с задан- ной буквы Выполнение программы Запустить на выполнение форму или процедуру в активном окне Перейти в режим паузы или приостановить выполнение программного кода Начать выполнение программного кода на строке, содержащей курсор ввода <F7> <Shift+F7> <Ctrl+Tab> <F2> <F4> <Ctrl+G> <Ctrl+L> <Shift+F2> <Ctrl+F> <F3> <Shift+F3> <Ctrl+H> <Ctrl+Shift+F2> <Ctrl+Z> <Ctrl+J> <Ctrl+Shift+J> <Ctrl+I> < Ctrl+Shift+I> <Ctrl+пробел > <Ctrl+Shift+ заданная буква> <F5> <Ctrl+Break> <Ctrl+F8> 34 Часть 1. Введение в VBA
Меню и панели инструментов редактора Вам уже, наверняка, известно, как пользоваться меню и панелями инструментов в окнах приложений Windows, поэтому в данном разделе лишь в общих чертах познако- мимся с основными меню и панелями инструментов редактора VBA. Полный перечень команд с указанием их функционального назначения можно найти в приложении Б. Меню File (Файл) содержит команды, необходимые для сохранения изменений в про- екте VBA и вывода на экран или на печать исходного кода макросов. Меню Edit (Правка) содержит команды, предназначенные для управления исходным кодом макроса в окне Code, а также объектами в формах. Меню View (Вид) содержит команды, позволяющие выводить или убирать с экрана различные окна редактора VBA. Команды меню Insert (Вставка) позволяют добавлять в проект различные объекты — процедуры, модули, формы, классы и пр. Меню Format (Формат) содержит команды, используемые при создании пользователь- ских диалоговых окон. Команды этого меню позволяют выравнивать объекты в форме по отношению друг к другу, настраивать размеры и внешний вид элементов управления, а также выполнять многие другие операции. Меню Debug (Отладка) содержит команды, предназначенные для тестирования и от- ладки макросов. Команды этого меню позволяют запускать макрос с заданной точки, от- слеживать выполнение макроса по шагам и останавливать выполняемый макрос в любой момент его выполнения. Меню Run (Запуск) содержит команды, предназначенные для запуска макроса на вы- полнение, прерывания или возобновления его работы, а также для возврата прерванного макроса в начальное его состояние. Меню Tools (Сервис) содержит, в частности, команды, позволяющие выбрать макрос для выполнения или получить доступ к внешним библиотекам макросов. С помощью дру- гих команд этого меню можно получить доступ к диалоговому окну Option (Параметры) редактора VBA и окну свойств проекта VBA. Меню Add-Ins содержит всего одну команду — Add-In Manager, при выборе которой на экране отображается диалоговое окно Add-In Manager. В этом окне можно загружать или выгружать, регистрировать и определять поведение программ-дополнений (надстроек). Кроме указанных выше меню, в редакторе VBA имеется еще два дополнительных меню: Window (Окно) и Help (Справка). Команды этих меню идентичны командам меню Window и Help любых других приложений Windows. Панели инструментов редактора VBA Если вы знакомы с приложениями Word, Excel или PowerPoint ранних версий (до MS Office 2007), то работа с панелями инструментов в редакторе VBA вам покажется вполне удобной и понятной. Редактор VBA предлагает четыре готовые панели инструментов. Standard (Стандартная). Эта панель выводится на экран при первом запуске редак- тора VBA. Панель инструментов Standard содержит 19 кнопок, которые выполняют самые разнообразные функции: сохранение результатов работы, добавление новых форм и модулей, а также редактирование и выполнение программ. Edit (Правка). Кнопки этой панели инструментов позволяют редактировать текст в окне Code (окне программного кода). Они дублируют команды меню Edit. Глава 2. Редактор Visual Basic 35
Назначение кнопок панелей инструментов Standard и Edit описывается в табл. 2.2 и 2.3 соответственно. Debug (Отладка). Кнопки этой панели позволяют запустить программу на вы- полнение, проследить за ходом ее работы, а также обнаружить различные ошибки в отлаживаемых программах. UserForm (Пользовательская форма). Эта панель используется при проектирова- нии форм. Многие ее кнопки дублируют команды меню Format. Таблица 2.2. Кнопки панели инструментов Standard Кнопка Действие [В] View <host-npu/uweHue> (вид приложение) Переключиться в приложение, из которого запускался редактор VBA. Значок кнопки меняется в зависимости от конкретного при- ложения, в котором был запущен редактор VBA |g •; Insert... (вставить ...) Щелчок на кнопке со стрелкой отобразит список объектов, кото- рые можно вставить в текущий проект (UserForm, Module, Class Module, Procedure) 0 Save <документ> (сохранить...) [~] Cut (вырезать) Сохранить текущий проект Вырезать выделенный текст или объект и поместить его в буфер обмена П Сору (скопировать) Q] Paste (вставить) Скопировать выделенный текст или объект в буфер обмена Вставить текст или объект из буфера обмена в окно Code или фор- му пользователя Qj Find (найти) Открыть диалоговое окно Find для нахождения слова или фразы в тексте модуля Q Undo (отменить ввод) |3] Redo (вернуть ввод) Д Run Macro (запуск программы) [й] Breack (прервать) Q] Reset (сброс) [<| Design Mode (конструктор) |S] Project Explorer (окно проекта) QF| Properties Window (окно свойств) £7| Object Browser (обо- зреватель объектов) 2] Toolbox (панель инструментов) Qj Справка: Microsoft Visual Basic [7] More Buttons Отменить последнее выполненное действие (если это возможно) Возвратить последнее отмененное действие (если это возможно) Запустить текущую процедуру или форму Прервать выполнение кода VBA Перезапустить код VBA Перейти в режим Design (конструктора) Отобразить окно Project Explorer (окно проекта) Отобразить окно Properties Window (окно свойств) Отобразить окно Object Browser (обозреватель объектов) Отобразить панель Toolbox (панель инструментов) Отобразить окно справочной системы редактора VBA Добавить или удалить кнопки панели Gauge Крайнее правое поле, в котором при работе в окне Code указыва- ется текущее положение курсора (строка и номер символа) 36 Часть 1. Введение в VBA
Следует также заметить, что во все панели инструментов редактора VBA можно до- бавлять или убирать из них любые кнопки, если по какой-либо причине вас не устраивает стандартный вариант панели, предлагаемый редактором VBA по умолчанию. Для этого достаточно щелкнуть правой кнопкой мыши на любой панели инструментов и выбрать из раскрывшегося контекстного меню команду Настройка. На экран будет выведено диа- логовое окно Настройка. При необходимости перейдите в этом окне на вкладку Команды. В списке Категории выберите интересующую вас группу команд, а затем в списке Команды отыщите требуемую и поместите в ее строку указатель мыши. Нажмите левую кнопку мыши и в строке команды появится изображение “кнопки”. Перетащите его на выбранное вами место в той панели инструментов, где будет находиться эта новая кнопка. Для удаления кнопки из любой панели инструментов просто поместите на нее указатель мыши, нажмите левую кнопку и перетащите выбранный объект в любое свободное место окна редактора VBA. Закончив редактирование панелей инструментов, закройте диалого- вое окно Настройка щелчком на кнопке Закрыть. Общий вид панели инструментов Standard представлен на рис. 2.2. Рис. 2.2. Панель инструментов Standard Панель инструментов Edit Если панель инструментов Edit автоматически не отображается в окне редакто- ра VBA, то для того, чтобы увидеть ее на экране, необходимо выбрать команду меню Vi ew^ Toolbars^ Ed it (Вид ^Панель инструментов1^ Редактирование). В табл. 2.3 пред- ставлены командные кнопки панели инструментов Edit и краткое описание назначения каждой из них. Таблица 2.3. Кнопки панели инструментов Edit Кнопка Действие j List Properties/Methods (список свойств/методов) Fj List Constant (список констант) □ Quick info (сведения) Отобразить список свойств и методов, принадлежащих объекту Отобразить список констант Отобразить окно, показывающее правильный синтаксис для объектного метода Q Parameter Info (параметры) [j Complete Word (завершить слово) |¥] Indent (увеличить отступ) 0 Outdent (уменьшить отступ) □ Toggle Breakpoint (точка останова) [T| Comment Block (закомментировать блок) Отобразить параметры функции или оператора VBA Завершить текущее ключевое слово VBA Сдвинуть выделенный текст вправо на одну позицию табуляции Сдвинуть выделенный текст влево на одну позицию табуляции Установить или отменить точку останова в исходном коде Превратить выделенный текст в окне Code в комментарий Глава 2. Редактор Visual Basic 37
Окончание табл. 2.3 Кнопка Действие [U Uncomment Block (раскомментировать блок) Щ Toggle Bookmark (закладка) Щ Next Bookmark (следующая закладка) 0 Previous Bookmark (предыдущая закладка) ьГ Clear All Bookmarks (снять все закладки) Удалить символы комментария из выделенного текста в окне Code Установить или отменить уже существующую закладку в ис- ходном коде Переместить курсор вставки в окне Code к следующей закладке Переместить курсор вставки в окне Code к предыдущей закладке Удалить все закладки Окно проектов и обозреватель объектов Для вывода окна проектов на экран в редакторе VBA необходимо выбрать команду меню View^ Project Explore (ВидОкно проектов) либо щелкнуть на кнопке Project Ex- plorer панели Standard или воспользоваться специальной комбинацией клавиш <Ctrl+R>. Окно проектов Project - <имя_проекта> предоставляет пользователю средства быстрого доступа к окнам программного кода, пользовательских форм и других объектов, с кото- рыми можно работать в редакторе VBA. Для ускорения доступа к окнам предназначены две кнопки на панели инструментов окна проектов — это кнопка View Code (Показать программный код), которая позволяет вывести на экран окно программного кода для вы- деленного объекта, и кнопка View Object (Показать объект), которая выводит на экран поверх всех остальных окон сам выделенный объект. Третья кнопка панели инструмен- тов, Toggle Folder (Переключение отображения папок), управляет режимом отображения в самом окне проектов папок среднего уровня иерархии структуры файлов и модулей проектов (рис. 2.3). Рис. 2.3. Окно проектов Project - <имя_проекта> в Excel 2010 Обратите внимание на то, что окно проектов предлагает иерархическое представление состава открытых в данный момент в приложении проектов, отображаемое в виде дре- вовидной структуры. Элементом самого верхнего уровня в отображаемой иерархической структуре является сам проект. Каждый документ, открытый в приложении, автомати- чески представляется в окне Project как отдельный проект, даже если вы еще не вводили 38 Часть 1. Введение в VBA
для этого проекта никакого программного кода и не создавали в нем никаких форм. Имя этого проекта будет совпадать (по умолчанию) с именем породившего его документа, но при желании имя проекта можно изменить в диалоговом окне свойства проекта Project Properties или в окне свойств, речь о котором пойдет ниже. Следующую ступень в иерархии занимают группы объектов — формы, модули про- граммного кода, объекты содержащего документ приложения и ссылки на другие библио- теки объектов. Каждая из этих групп в окне проектов представлена как отдельная папка. Отдельные объекты образуют самый низкий уровень этой иерархии. Для того чтобы про- смотреть содержание любого из разделов в иерархии, достаточно щелкнуть мышью на квадратике, который расположен слева от каждой группы (раздела). В квадратике может отображаться знак “плюс” — это означает, что данная группа закрыта (свернута), или знак ’’минус” — это означает, что данная группа раскрыта (развернута) и в ней видны разделы следующего уровня. Каждый щелчок мыши на квадратике меняет его знак на противоположный. Поэтому, если хотите развернуть группу и увидеть все входящие в нее объекты, следует щелкнуть на расположенном рядом квадратике со знаком “плюс”. Если требуется свернуть раз- вернутую группу, щелкните на соответствующем квадратике со знаком “минус”. Изменить имя проекта, добавить его краткое описание, указать для проекта файл справки или защитить его от любопытных глаз можно с помощью диалогового окна Project Properties (свойства проекта). Для этого либо выберите команду меню Too\s^< имя_ проекта> Properties, либо щелкните правой кнопкой мыши на элементе иерархии, представляющем требуемый проект в окне проектов, а затем выберите в раскрывшемся контекстном меню команду <имя_проекта> Properties. На рис. 2.4 представлено диа- логовое окно <имя_проекта> Project Properties с открытой вкладкой General (Общие). Именно в этом окне можно изменить имя проекта, а также любые другие его параметры по собственному усмотрению. Project Project Properties Genera. j Protection | Project tome; ------------------------------------------------------------------------j groject Desorption; I----------------------------------------------------------------------- Project нею hfib He Name: Context p: Con^Oona! Completion Arguments: Puc. 2.4. Диалоговое окно свойств проекта Project Properties в Word 2010 В поле Project Name (Имя проекта) можно ввести требуемое имя для вновь созданного проекта или изменить имя созданного ранее. Поле Project Description предназначено для ввода краткого описания данного проекта (заполнять это поле необязательно). Поля Help Глава 2. Редактор Visual Basic 39
File Name и Project Help Context ID предназначены для описания файлов со справочной информацией, относящейся к данному проекту. Наконец, в поле Conditional Compilation Arguments вводятся значения ключей условной компиляции для ограничения несанкцио- нированного доступа к исходным текстам проекта. Обозреватель объектов Окно Object Browser (Обозреватель объектов), подобно окну проектов, предоставляет пользователю средства быстрого доступа к объектам, используемым в VBA-программе. Одно из преимуществ обозревателя объектов заключается в том, что он позволяет легко добраться к любым объектам, доступным для этого проекта (т.е. помимо модулей и форм самого этого проекта, в окне обозревателя объектов можно увидеть также все объекты тех проектов или приложений (объекты из соответствующих библиотек), которые доступны или на которые ссылается данный проект). Кроме того, с помощью обозревателя объектов можно познакомиться с методами, событиями, свойствами, а также процедурами из вы- бранной вами библиотеки или проекта. Для вывода окна Object Browser на экран необходимо в редакторе VBA либо выбрать команду меню View^Object Browser (Вид^Обозреватель объектов), либо щелкнуть на кнопке Object Browser на панели инструментов Standard, либо нажать клавишу <F2>. Общий вид окна обозревателя объектов показан на рис. 2.5. В этом окне представлен перечень объектов приложения Excel, а также часть списка свойств и методов класса Ap- plication данного приложения. Рис. 2.5. Окно Object Browser редактора VBA На рис. 2.5 видно, что окно Object Browser разделено на несколько панелей, размеры которых при желании можно изменять, перетаскивая разделительные линии между ними с помощью мыши. В верхней части окна находится панель инструментов, содержащая список Project/Library (Проект/Библиотека) и кнопки, предназначенные для управления обозревателем объектов. Под панелью инструментов расположена еще одна панель с по- лем ввода Search Text (Отыскиваемое значение) для задания критерия поиска и двумя кнопками для запуска поиска и просмотра его результатов. Ниже находятся две большие 40 Часть 1. Введение в VBA
панели со списками Classes (Классы) и Members (Компоненты), предназначенные для отображения перечней объектов и компонентов выбранного объекта соответственно. В нижней части окна расположена информационная панель, на которой отображаются краткие сведения об объекте, выбранном в данный момент на панели классов или ком- понентов (на рис. 2.5 это свойство ActiveCell класса Application). Рассмотрим назначение каждого из основных компонентов окна Object Browser подробнее. Список Project/Library. В этом раскрывающемся списке можно выбрать любой проект или любую библиотеку приложений, доступных в текущем проекте. Напри- мер, при работе с документом Word, помимо проекта этого документа, в списке бу- дут присутствовать библиотеки объектов Word, VBA, Office, шаблона Normal и так далее, а для приложения Excel здесь можно будет дополнительно выбрать библио- теку объектов Excel, OLE-автоматизации и пр. Для того чтобы увидеть перечень объектов всех доступных библиотек и проектов, следует выбрать в списке значение <AII Libraries> (Все библиотеки). Список Classes. В этом списке отображается перечень объектов конкретной би- блиотеки или проекта, выбранных в данный момент в списке Project/Library. На- пример, если выбрать в списке Project/Library библиотеку Word, то в списке Classes будут отображены все объекты этой библиотеки, т.е. полный перечень объектов приложения Word. Список Members. В этом списке отображается перечень компонентов класса, выбранного в данный момент в списке Project/Library. Например, если в списке Project/Library отображается состав библиотеки Word и в данный момент выбран класс Application, то в списке Members будет представлен список всех компонентов (свойств и методов) этого класса. Окна редактирования кода и форм Окно Code (окно программного кода) предназначено для просмотра, редактирования или создания нового программного кода на языке VBA. Чтобы открыть окно программ- ного кода и начать работу с ним, необходимо либо выбрать команду меню View^Code, либо щелкнуть на кнопке View Code окна проектов, либо нажать клавишу <F7>. Общий вид этого окна показан на рис. 2.6. Рис. 2.6. Окно редактирования программного кода Глава 2. Редактор Visual Basic 41
По своей сути окно редактирования кода является простым текстовым редактором — оно используется для ввода и изменения кода процедур создаваемого приложения. Окно редактирования допускает два режима представления кода — просмотр отдельной проце- дуры (Procedure View) и всего модуля в целом (Full Module View). Для переключения ре- жимов представления кода предназначены две кнопки, находящиеся в нижнем левом углу окна редактирования программного кода. Так, на рис. 2.6 нажатой показана кнопка Full Module View, а значит, окно Code находится в режиме отображения кода всего модуля. Для выбора конкретной процедуры, которую в данный момент необходимо просмо- треть или отредактировать в окне программного кода, предназначены два раскрывающих- ся списка, расположенные в верхней части окна Code (см. рис. 2.6). Список General (Общий), расположенный слева, предназначен для выбора из об- щего списка помещенных в форму объектов конкретного элемента управления илй самой формы. В результате такого выбора в окне программного кода будет отобра- жен текст процедуры, выбираемой для данного объекта по умолчанию. На рис. 2.6 в списке General выбран объект Document, в окне кода отображена заготовка для процедуры New. Список Declarations (Объявления), расположенный справа, содержит перечень методов обработки событий, допустимых для выбранного в левом списке объек- та. При выборе в правом списке некоторого события в окне программного кода появится текст процедуры обработки этого события. Если данная процедура еще не описана, будет выведена соответствующая заготовка. Следует заметить, что если двойным щелчком мышью выбрать в форме некоторый элемент управления, а затем щелкнуть на кнопке View Code в окне проектов, то на экране откроется окно редактирования кода, отображающее исходный текст модуля в том месте, где находится процедура, связанная с этим элементом управления. Если необходимо перейти от работы с текстом процедуры обратно к объекту в форме, то быстрее всего это можно сделать, щелкнув в окне проектов на кнопке View Object. Любое окно программного кода, при необходимости, всегда можно разделить на два окна. Если вы одновременно хотите увидеть две различные части исходного текста одно- го и того же модуля или скопировать текст из одной его части в другую, воспользуйтесь для этого маркером разбивки — это маленький бегунок, расположенный в правой части окна, непосредственно над верхней кнопкой вертикальной полосы прокрутки. Поместите указатель мыши на маркер разбивки, нажмите левую кнопку мыши и перетащите появив- шуюся в окне линию разбивки вниз так, чтобы окно оказалось разделенным на две части требуемого размера. Чтобы отменить разбиение окна на две части, просто щелкните два раза мышью на маркере разбивки. Все остальные возможности, доступные в окне про- граммного кода, и методы работы в нем мы обсудим позже, при рассмотрении основ про- граммирования на языке VBA. Окно редактирования форм При разработке приложений VBA для создания диалоговых и других видов окон ис- пользуется программная конструкция, называемая формой. Поэтому одним из основных инструментов при программировании элементов интерфейса пользователя является ре- дактор форм. Для того чтобы добавить в проект новую форму, необходимо выбрать коман- 42 Часть 1. Введение в VBA
ду меню Insert^UserForm (Вставить^Форма пользователя). Для открытия уже созданной формы необходимо выполнить двойной щелчок мышью на ее имени в окне проектов. В результате на экран будет выведено окно UserForm с требуемой формой и плавающая панель инструментов ToolBox (Панель элементов) (рис. 2.7). Эта панель инструментов содержит 15 элементов управления, которые можно поместить в форму при конструиро- вании любых диалоговых окон, используемых в приложении. тц Существует и другой способ быстро открыть окно требуемой формы — щелкните в окне \\ проектов на соответствующем элементе иерархии объектов правой кнопкой мыши и ИЯ выберите в раскрывшемся контекстном меню команду View1^ Object. Рис. 2.7. Окно формы и панель инструментов для построения форм в Word 2010 Процесс построения диалоговых окон в окне формы очень прост: найдите требуе- мый элемент управления на панели элементов и щелкните на нем левой кнопкой мыши. Переместите указатель мыши на то место в форме, где будет находиться выбранный вами элемент, и щелкните левой кнопкой мыши — элемент будет добавлен в форму так, что в указанной точке будет располагаться его верхний левый угол. Элемент управления можно вставить в форму и другим, более точным способом. Поместите на требуемый элемент панели элементов указатель мыши, нажмите левую кнопку и, не отпуская ее, перетащите элемент в требуемое место формы. При этом на экране будет отображаться прямоугольник, указывающий истинный размер данного элемента управления. Отпустите кнопку мыши, когда элемент окажется в требуемом месте формы. После того как вы поместили элемент управления в форму, он автоматически стано- вится выбранным. При этом вокруг него отображается пунктирная рамка с белыми ква- дратиками — маркерами размеров (рис. 2.8). С помощью этих маркеров можно придать данному элементу требуемые размеры и форму. Для этого поместите указатель мыши на маркер и, нажав левую кнопку мыши, перемещайте маркер, пока элемент управления не достигнет требуемых размеров. Отпустите кнопку мыши. Аналогичным образом можно просто перемещать элемент управления в форме, не изменяя его размеров. Отличие со- стоит лишь в том, что указатель мыши помещается не на маркер размера, а на сам объект. Глава 2. Редактор Visual Basic 43
В результате всех этих манипуляций требуемый элемент управления будет помещен в фор- му на отведенное место и ему будут приданы необходимые размеры. Рис. 2.8. Изменение размеров элемента управления в форме Таким образом, размеры форм и содержащихся в них элементов управления можно произвольно изменять. Сами элементы управления можно копировать, вырезать и встав- лять в форму в любой последовательности. Для упрощения и автоматизации работы с от- дельными элементами управления и их группами предназначены команды меню Format (Формат) (подробнее в приложении Б). Окно свойств Окно свойств объектов Properties предназначено для просмотра и изменения свойств любого активного в данный момент объекта (проекта, модуля, формы, элемента управ- IcheckBoxl CheckBox И Alphabetic I Categonzec ’ Рис. 2.9. Окно свойств для флажка опции ления) при работе в редакторе VBA. Чтобы открыть окно свойств и начать с ним работать, либо выберите команду меню View^>Properties Window, либо щелкните на кнопке Proper- ties на панели инструментов Standard, либо нажмите клавишу <F4>. После того как окно свойств будет выведено на экран, для дальнейшей работы с ним следует перейти в окно программ- ного кода или пользовательской формы. Выберите в одном из этих окон требуемый объект, и его свойства будут отображены в окне свойств. Общий вид окна свойств для объекта управления, представляющего собой флажок опции, показан на рис. 2.9. Как видно из рис. 2.9, окно свойств состоит из раскрываю- щегося списка, который находится в верхней части окна, и двух размещенных ниже вкладок — Alphabetic (По алфавиту) и Categorized (По категории). В раскрывающемся списке можно выбрать требуемый объект — саму форму или любой элемент управления, принадлежащий форме. Вкладки отображают один и тот же набор свойств этого объекта, но одна в алфавитном по- рядке, а другая — по категориям. Следует заметить, что проекты и модули имеют только одно свойство — имя, которое можно изменить с помощью окна свойств. Для этого надо выделить 44 Часть 1. Введение в VBA
проект или модуль в окне проектов, перейти в окно свойств, выделить в окне свойств строку со свойством Name и ввести в расположенном справа поле новое значение. После этого вашему проекту (в окне проектов) будет присвоено новое, только что введенное вами имя. Все эти действия можно применять и к формам, вводя с клавиатуры на лю- бой из вкладок свойств новые значения в соответствующие поля. Окно свойств — очень важный инструмент при создании форм, поэтому все остальные его свойства и описания будут подробно рассмотрены в главе 10. Вызов справки В начале этой главы мы ознакомились с различными меню редактора VBA. Одна из последних команд в списке меню редактора VBA — команда Help (Справка). Команды этого меню идентичны командам меню Help в Word, Excel и других приложениях Microsoft Office 2010. Для того чтобы открыть главное окно справочной системы VBA, необходимо выбрать команду меню Help^CnpaBKa: Microsoft Visual Basic или щелкнуть на кнопке с вопросительным знаком на панели инструментов Standard. На экране откроется окно справки с исходной страницей справочной системы редактора VBA. Для того чтобы по- лучить информацию, относящуюся к конкретному аспекту работы с редактором VBA или вашим приложением, необходимо выполнить следующие действия. Выберите команду меню View ^Object Browser или нажмите клавишу <F2>. В раскрывшемся окне обозревателя объектов выберите имя вашего VBA-при- ложения. Выделите требуемый объект на панели классов (левая часть обозревателя объектов). Щелкните на кнопке с вопросительным знаком на панели инструментов обозрева- теля объектов или нажмите клавишу <F1>. В результате на экран будет выведено окно справочной системы с описанием инте- ресующего вас объекта. Пример такой справки (для объекта Application приложения Word) представлен на рис. 2.10. Следует также отметить, что для поиска интересующей вас информации можно в окне справки воспользоваться вкладкой Оглавление, на которой отображается иерархическая структура справочной системы вашего приложения. Кроме того, можно также воспользо- ваться раскрывающимся списком1, расположенным в левом верхнем углу окна справки: введите в него интересующее вас слово, а затем щелкните на кнопке Поиск справа. Таким образом, можно найти любое интересующее вас слово в файлах соответствующей спра- вочной системы. Для вызова контекстно-зависимой справки в редакторе VBA предназначена клавиша <F1>. При ее нажатии на экране откроется тот раздел справочной системы, который относится к активному элементу в окне редактора VBA, т.е. тому объекту, с которым вы в данный момент работаете. Так, в окне программного кода клавиша <F1 > поможет вам вспомнить (если вы забыли), как использовать тот или иной оператор. Для этого доста- точно поместить курсор в соответствующий оператор и нажать клавишу <F1>. В окне пользовательской формы можно получить справку о любом из элементов управления, помещенных в форму. Для этого следует выделить интересующий вас элемент управления 1 Если раскрыть этот список, то в нем будут присутствовать все слова, которые вы раньше искали в справочной системе, причем в хронологическом порядке. Глава 2. Редактор Visual Basic 45
(т.е. щелкнуть на нем), а затем нажать клавишу <F1>. Если вас интересует справка об определенном свойстве некоторого элемента управления, то ее можно получить, выделив этот элемент управления и щелкнув в окне соответствующего свойства (в окне свойств), а затем нажав клавишу <F1>. Аналогичным образом можно получить справку об объектах в окне проектов, окне обозревателя объектов и т.д. Рис, 2,10, Окно справочной системы редактора VBA с описанием объекта Application приложения Word Резюме В этой главе кратко были описаны основные элементы интерфейса пользователя ре- дактора VBA. Обсудив вопрос о способах запуска редактора VBA, мы затем рассмотре- ли его панели инструментов и состав команд меню. Большое внимание было уделено назначению различных окон редактора VBA и основным способам работы в них. Мы ознакомились с окном проектов и окном обозревателя объектов, окном редактирования кода и окном свойств. Особое внимание было уделено окну редактирования форм и тем способам, с помощью которых конструируются диалоговые окна приложений. Наконец, в заключительной части главы кратко обсуждалась справочная система редактора VBA и пояснялось, как можно найти в ней требуемую справочную информацию. Безусловно, приведенное здесь описание окон и инструментов редактора VBA нельзя считать исчер- пывающим, однако этого будет вполне достаточно, чтобы успешно освоить материал по- следующих глав. Тестовые задания Ниже приведено несколько тестовых заданий, предназначенных для закрепления изложенного в этой главе материала. В каждом задании вам предлагается вопрос и 46 Часть 1. Введение в VBA
несколько вариантов ответа на него, один (или несколько) из которых является правиль- ным, а остальные — нет. Укажите правильный ответ. 1. Какие из приведенных ниже окон принадлежат редактору VBA: а) окно проектов; б) окно редактирования кода; в) окно документа; г) окно палитры цвета; д) окно свойств проекта. 2. Для запуска редактора VBA необходимо выполнить следующее: а) щелкнуть мышью в поле документа; б) нажать клавишу <F1>; в) выбрать на ленте вкладку Разработчик и в группе Код щелкнуть на кнопке Visual Basic; г) выбрать соответствующую команду в меню Пуск системы Windows. 3. Для получения справки об интересующем объекте необходимо сделать следующее: а) выделить его и нажать клавишу <F1>; б) переключиться в окно основного приложения и нажать клавишу <F1>; в) нажать комбинацию клавиш <Alt+Ctrl+Delete>; г) обратиться к более опытному коллеге. 4. Для помещения элемента управления в форму следует выполнить следующее: а) скопировать подходящий объект в окне редактора VBA в буфер обмена, а затем вставить его в форму; б) выделить элемент управления на панели элементов и перетащить его в требуемое в) место формы; г) выделить элемент управления на панели элементов, а затем поместить указатель мыши в требуемое место формы и нажать клавишу <Insert>; д) щелкнуть на требуемом элементе управления панели элементов, а затем щелк- нуть в том месте формы, куда он должен быть вставлен. Глава 2. Редактор Visual Basic 47
Глава 3 Создание и выполнение VBA-программ В этой главе... ♦ Общий цикл создания VBA-программы ♦ Общие принципы построения VBA-программы ♦ Написание новых макросов и процедур ♦ Выполнение VBA-программы ♦ Обработка ошибок ♦ Резюме Общий цикл создания VBA-программы Теперь, после того как мы познакомились с возможностями языка VBA и визуальной средой разработки редактора VBA, можно приступать к рассмотрению такого важного аспекта программирования, как процесс разработки и написания программы. Програм- ма — это последовательность недвусмысленных инструкций, которые компьютер вы- полняет одну за другой. Следует заметить, что сам процесс создания программы можно разделить на несколько этапов. Обычно, в каком бы из VBА-приложений вы ни работали, на первом этапе создания VBA-программы следует провести тщательный анализ стоящей перед вами задачи. Далее необходимо перейти к проектированию программы, а имен- но, постараться конкретно представить себе все те элементы, из которых будет состоять будущая программа. Учитывая, что речь здесь идет о VBA-программе, можно с уверенно- стью предположить, что в ней обязательно будет присутствовать хотя бы одно диалоговое окно. А это значит, что вам понадобится разработать, как минимум, одну экранную форму. В форме обязательно будут присутствовать те или иные элементы управления (надписи, поля ввода, списки, командные кнопки и т.д.), а значит, потребуется написать процеду- ры, отвечающие за обработку событий, которые происходят с формой и ее элементами управления. После того как будет разработан детальный проект и составлен подробный план его реализации, можно перейти ко второму этапу работы — реализации проекта. Под этим понимается проектирование внешнего вида требуемых форм с размещением в них необхо- димых элементов управления, построение этих форм в визуальном редакторе с описанием свойств их элементов и подготовкой процедур обработки интересующих событий. Созда- вать новую форму, размещать в ней надписи, поля ввода, командные кнопки и другие эле- менты управления, а также писать программный код необходимых процедур удобнее всего
с помощью визуальной среды разработки, предоставляемой редактором VBA. Например, для создания новой формы потребуется лишь выбрать в меню редактора VBA команду Insert^UserForm, и на экран будет выведено окно новой, пока еще пустой формы. Затем, копируя в форму заготовку элемента управления надпись, можно будет добавить в нее не- обходимые надписи, а с помощью копирования заготовки элемента управления командная кнопка можно будет поместить в форму любые требуемые кнопки — например, ту, после щелчка на которой выполнение вашей программы будет завершаться. Наконец, при вы- боре команды меню View^Code в редакторе VBA будет открыто окно программного кода, предназначенное для записи текста необходимых процедур обработки событий формы и ее компонентов, а также разнообразных вспомогательных процедур. После того как программа, наконец, будет готова, следует перейти к третьему этапу ра- боты — тестированию созданной вами программы. Этот процесс предполагает тщательный анализ функционирования только что созданной программы в самых различных режимах, назначение которого — убедиться, что она работает в полном соответствии с вашими планами. Для этого удобнее всего воспользоваться командой меню редактора VBA Run ... (Выполнить...). При выборе этой команды вновь созданная программа запускается на вы- полнение и появляется возможность проверить, как она реагирует на те или иные события, правильно ли обрабатываются введенные данные (как корректные, так и заведомо оши- бочные), позволяет ли она решить ту задачу, для которой, собственно, и была создана. При обнаружении любых ошибок или просто нежелательных отклонений от нормаль- ной работы вам потребуется перейти к четвертому этапу разработки программы — про- вести ее отладку. Суть этой процедуры состоит в том, что с помощью тех или иных средств выясняется причина появления ошибки в работе программы и принимается решение о способах ее устранения. Теперь потребуется вернуться ко второму этапу и внести в про- грамму необходимые изменения, а затем вновь перейти к третьему этапу и повторить ее тестирование. Этот цикл повторяется до тех пор, пока тестирование не покажет отсутствие каких-либо отклонений от ожидаемого поведения программы. Хочу заметить, что редак- тор VBA предлагает несколько мощных и эффективных средств автоматизации процесса отладки, о чем мы подробно будем говорить в главе 12. Общие принципы построения VBA-программы Следует заметить, что программа не является самостоятельным структурным элемен- том в иерархии объектов языка VBA, и поэтому редактор VBA распознает по именам не программы, а процедуры, модули и проекты. Любая VBA-программа обязательно со- держит хотя бы одну процедуру — по той простой причине, что компилятор языка VBA может выполнять только операторы, помещенные в процедуру. Однако выполняемая программа-процедура может, в свою очередь, обращаться к одной или нескольким другим процедурам, помещенным в один или несколько модулей, входящих в состав одного или нескольких проектов. Другими словами, правильно будет сказать, что в VBA строки про- граммного кода организованы в процедуры, которые размещаются в модулях, а модули размещаются в проектах. Отсюда можно сделать вывод, что программный код VBA со- стоит из следующих “строительных блоков”. Оператор — это наименьшая единица VBA-кода. Он предназначен для определе- ния переменной, установки параметров или выполнения какого-либо действия в программе. Глава 3. Создание и выполнение VBA-программ 49
Процедура — это отдельная единица программного кода VBA, которую можно вы- зывать по имени для выполнения; она может выполняться самостоятельно. Любая процедура содержит один или несколько операторов. Модуль — это именованная единица, состоящая из одной или нескольких процедур и раздела объявлений, в котором объявляются переменные, константы и пользо- вательские типы данных, а также устанавливаются параметры компилятора (о них мы будем говорить ниже в этой главе). Проект — включает в себя все модули, формы и связанные с приложением объ- екты, относящиеся к конкретному документу, причем проект сохраняется вместе с самим этим документом. Написание новых макросов и процедур Мы уже знаем, что макросы представляют собой средство, с помощью которого можно описать произвольную последовательность действий пользователя для ее последующего многократного выполнения. Обычно термин “макрос” применяется к инструкциям, кото- рые автоматически записываются с помощью специальных инструментов в приложениях Microsoft Office 2010, а термин “процедура” применяется к коду VBA, который вы пишете сами. Иначе говоря, процедура — это компьютерная программа, которая выполняет не- которые действия с объектами и сохраняется в модуле VBA. С такой, “программной”, точки зрения макрос — это тоже процедура типа Sub, не имеющая входных параметров. Макросы образуют единственный класс процедур типа Sub, которые можно запускать на выполнение непосредственно вызовом их по имени либо из редактора VBA, либо из само- го VBA-приложения. Написать новый макрос без использования специальных автомати- ческих средств Microsoft Office, т.е. самостоятельно написать соответствующую процедуру типа Sub, можно либо создав в редакторе VBA новый модуль, который будет содержать эту процедуру, либо поместив эту процедуру в уже существующий модуль. Для создания нового модуля необходимо выполнить следующие действия. 1. Убедитесь в том, что вы работаете с нужным проектом. 2. Активизируйте редактор VBA. Проще всего это сделать, нажав клавиши <Alt+Fll>. 3. В окне Project Explorer выделите либо сам проект, либо один из его компонентов. 4. Выберите команду редактора VBA Insert^Module (Добавить1^Модуль) или щелкни- те на кнопке Insert панели инструментов Standard и выберите в раскрывшемся меню команду Module. В результате редактор VBA откроет на экране окно программного кода, предназначен- ное для создания нового модуля. Следует напомнить, что новому модулю при открытии окна программного кода редактор VBA по умолчанию присваивает типовое имя Modulen, где п — порядковый номер модуля, созданного в данном сеансе работы с редактором VBA. Для того чтобы модуль получил некоторое собственное имя, следует переименовать его. 1. Выберите команду меню View=>Properties Window (Вид^Окно свойств) или щелк- ните на кнопке Properties Window в панели инструментов Standard. На экране рас- кроется окно свойств вновь созданного модуля (рис. 3.1). 50 Часть 1. Введение в VBA
2. В текстовом поле Name на вкладке Alphabetic окна Properties введите новое имя модуля. Обратите внимание: модули имеют только одно свойство — Name (Имя). Прежде чем создать новую процедуру в уже существующем модуле, необходимо сначала открыть окно Code для того модуля, в котором предполагается поместить эту процедуру. Для этого щелкните дважды на требуемом модуле в окне Project Explorer либо выделите этот модуль в указанном окне и выберите команду меню View=>Code. Следует напомнить, что модули не хранятся в отдельных файлах, а являются частями некоторого проекта, сохраняемого в некотором документе VBA-приложения. Поэтому для использования одного и того же модуля в разных проектах (читай, VBA-документах) их следует скопировать в них. Для этой цели требуемый модуль можно предварительно экспортировать, создав отдельный файл с его текстом. Для того чтобы экспортировать модуль, выделите его в Project Explorer, после чего выберите команду меню File1^ Export File (Файл«^Экспорт файла). В раскрывшемся на экране диалоговом окне укажите место сохранения экспортируемого файла и, при необходимости, измените его имя (рис. 3.2). Рис. 3.1. Присвоение модулю нового имени Рис. 3.2. Диалоговое окно Export File Убедитесь, что в списке Тип файла выбрано значение Basic Files (*.bas), указывающее, что расширение имени файла определяет копируемый файл как файл исходного кода VBA (* . has). Для завершения операции экспорта файла щелкните на кнопке Сохранить. Для того чтобы импортировать модуль, т.е. добавить экспортированный ранее файл типа .bas в любой из VBA-проектов, выберите в Project Explorer необходимый проект, а затем выберите команду меню File*=>Import File (Файл^Импорт файла). В раскрывшемся диалоговом окне Import File убедитесь, что в списке Тип файла выбрано значение Files of Type (*.frm, *.bas, *.cls), и дважды щелкните на имени того файла, который будет импор- тироваться (рис. 3.3). Если по какой-либо причине потребуется удалить некоторый модуль из VBA- приложения, выполните следующие действия. 1. Щелчком мыши выделите в окне Project Explorer тот модуль, который требуется удалить. Глава 3. Создание и выполнение VBA-программ 51
Рис. 3.3. Диалоговое окно Import File 2. Выберите команду меню File^Remove object_name (Файл>=>Удалить имя_объекта). Другой способ — щелкните в окне Project Explorer правой кнопкой мыши на уда- ляемом модуле и выберите в раскрывшемся контекстном меню кЬманду Remove object_name. В любом случае редактор VBA выведет на экран диалоговое окно с предложением предварительно экспортировать удаляемый модуль (рис. 3.4). 3. Щелкните на кнопке Нет для удаления модуля, если экспортировать его перед удалением не требуется. Если щелкнуть на кнопке Да, на экран будет выведено диалоговое окно Export File, уже обсуждавшееся нами выше. В этом случае модуль будет удален сразу после завершения операции экспорта. Рис. 3.4. Диалоговое окно с запросом выполнения экспорта модуля перед его удалением Поместить исходный код процедуры можно в любом месте модуля, независимо оттого, добавляете ли вы процедуру в новый или уже существующий модуль. Для этого поместите курсор в то место в модуле, где необходимо ввести текст новой процедуры. Ключевыми словами для процедур являются операторы Sub и End Sub, т.е. ваша новая процедура должна начинаться оператором Sub, с указанием имени процедуры, и заканчиваться оператором End Sub, который редактор VBA автоматически добавляет в строку, сразу же после того как вы ввели оператор Sub. Если модуль содержит несколько процедур, то новая процедура должна начинаться после оператора End Sub, предыдущей процедуры или перед оператором Sub, которым начинается следующая процедура в модуле. Следует также отметить, что основными VBA-процедурами являются процедуры типа Sub (под- программы) и процедуры типа Function (функции); более конкретно об этом мы будем говорить в главе 7. 52 Часть 1. Введение в VBA
Давайте попробуем на практике создать процедуру в Word 2010. Предположим, тре- буется написать простейшую процедуру, которая будет выводить на экран приветствие. Текст ее будет выглядеть так. Sub Приветствие () MsgBox "Привет! С началом рабочего дня!" End Sub Создайте новый модуль с именем Приветствие и введите в его окно программного кода этот текст — как показано на рис. 3.5. Для этого выполните следующие действия. 1. Откройте любой документ Word (или рабочую книгу Excel). 2. Активизируйте редактор VBA, для чего нажмите клавиши <Alt+F11 >. 3. В окне Project Explorer выделите проект того документа или рабочей книги, в кото- рой будет создана эта процедура. 4. Для добавления нового модуля к проекту выберите команду Insert^Module. На экране раскроется окно программного кода для вновь созданного модуля. 5. Присвойте новому модулю имя Приветствие и, убедившись, что курсор вставки текста находится в начале первой пустой строки, введите приведенный выше про- граммный текст. Рис. 3.5. Создание процедуры Приветствие в Word 2010 Глава 3. Создание и выполнение VBA-программ 53
Завершив ввод текста процедуры, попробуйте ее выполнить. Для этого выберите ко- манду меню редактора VBA Tools'^ Macros и в диалоговом окне Macros в списке Macro Name выберите процедуру Приветствие, после чего щелкните на кнопке Run (Выпол- нить). Другой вариант: выберите команду меню редактора Run>=>Run Sub/UserForm или просто нажмите <F5>. В любом случае в окне Word 2010 будет выведено диалоговое окно с приветствием, записанным в тексте процедуры (рис. 3.6). Для закрытия этого окна щел- кните на кнопке ОК. Рис. 3.6. Диалоговое окно, выведенное процедурой Приветствие Выполнение VBA-программы Итак, в самом общем случае VBA-программа представляет собой определенную по- следовательность команд, которые выполняются по порядку, одна за другой, при каждом запуске программы. Сама по себе любая VBA-программа является совершенно бесполез- ной последовательностью текстовых строк, пока не будет найден способ запустить ее на выполнение. Мы уже знаем, что VBA-программу можно выполнить в окне редактора VBA, выбрав команду меню Run«=>Run ..., щелкнув на кнопке Run ... панели инструментов Standard или нажав <F5>. Хочу отметить, что это очень удобно при тестировании про- граммы, но совершенно не подходит для повседневной работы с ней. Запускать програм- му, готовую к выполнению, нужно (и гораздо удобнее) из того приложения, в котором вы работаете, причем организовать ее запуск в приложении можно будет с помощью кнопки на панели инструментов, нажатия определенной комбинации клавиш, выбора команды меню и даже предусмотрев ее автоматический запуск при открытии документа. Мы с вами уже выяснили, что макрос — это та же VBA-программа, а макрос, написан- ный самостоятельно (без использования специальных функций Microsoft Office), — это та же процедура. Поэтому выполнить VBA-программу фактически означает выполнить макрос или процедуру. Программа может включать как одну, так и несколько процедур, но только одна из них будет выполняться первой при вызове программы на выполнение — имя этой первой выполняемой процедуры можно считать именем всей программы. Эта первая процедура может вызывать другие процедуры, но для выполнения всей программы вам необходимо и достаточно запускать на выполнение только эту, первую, процедуру, а все остальные будут выполняться автоматически, по мере необходимости, непосредствен- но по ходу решения задачи. При вызове программы на выполнение из диалогового окна Макрос прежде всего сле- дует найти в этом окне ее имя. Откройте диалоговое окно Макрос в том VBA-приложении, в котором будет выполняться ваша программа, для чего перейдите налейте приложения на вкладку Вид, раскройте в группе Макросы меню и выберите в нем команду Макросы. Вид диалогового окна Макрос приложения Word показан на рис. 3.7, однако некоторые детали в нем могут несколько отличаться, в зависимости от используемого VBA-приложения. 54 Часть 1. Введение в VBA
Рис. 3.7. Диалоговое окно Макрос в приложении Word 2010 В диалоговом окне Макрос выберите в списке доступных VBA-программ (или макро- сов) имя требуемой программы и щелкните на кнопке Выполнить. Если в приведенном в окне списке макросов интересующая вас программа (или макрос) отсутствует, откройте раскрывающийся список Макросы из (для Word) и выберите в нем вместо принимаемого по умолчанию значения Активных шаблонов то, которое описывает документ, в котором хранится интересующая вас программа. Для приложения Excel подобный список называ- ется Находится в — по умолчанию в нем выбрано значение Все открытые книги. Создание кнопки запуска VBA-программы Теперь давайте рассмотрим, как организовать более быстрый вызов VBA-программы с помощью кнопки на панели быстрого доступа приложения или специальной комбинации клавиш. Как уже говорилось выше, некоторые приложения Microsoft Office позволяют связать макрос с кнопкой на панели инструментов или с определенной комбинацией клавиш еще при записи самого макроса. Кроме того, выполнить подобные назначения можно и позднее. В Microsoft Word, Excel, PowerPoint и Access назначить VBA-программе определенную кнопку на панели инструментов очень просто. Например, для того что- бы создать кнопку вызова VBA-программы в Word, необходимо выполнить следующие действия. 1. В верхнем левом углу окна приложения щелкните мышью на кнопке Настройка панели быстрого доступа и в раскрывшемся контекстном меню выберите команду Другие команды (рис. 3.8). 2. В раскрывшемся диалоговом окне Параметры Word в списке Выбрать команды из найдите значение Макросы и выберите его щелчком мыши (рис. 3.9). 3. В списке доступных команд (слева) найдите ту программу, для которой требуется создать кнопку на панели быстрого доступа, и выделите ее щелчком мыши. Затем щелкните на кнопке Добавить. В результате выполнения этих действий в список отобранных команд (справа) будет добавлена новая кнопка с именем вашей про- граммы (рис. 3.10). Глава 3. Создание и выполнение VBA-программ 55
Файл Разметка страницы 1Й J ▼______________________________________________ I Главн Настройка панели быстрого доступа Создать =а=£3 Открыть Режим у Сохранить чтения ПОО<6ЛО Электронная почта Быстрая печать Предварительный просмотр Правописание 7 Отменить / Вернуть Нарисовать таблицу Открыть последний файл Другие команды... Разместить под лентой _________________________ ! Настройка панели быстрого доступа Рис. 3.8. Открытие диалогового окна Настройка панели быстрого доступа в приложении Word 2010 Рис. 3.9. Выбор группы команд Макросы в диалоговом окне Параметры Word 56 Часть 1. Введение в VBA
Рис. 3.10. Создание новой кнопки на панели быстрого доступа в диалоговом окне Параметры Word приложения Word 2010 4. Для завершения операции закройте диалоговое окно Настройка панели быстрого доступа щелчком на кнопке ОК. При этом на панели быстрого доступа появится новая кнопка (рис. 3.11). Теперь выполнить вашу программу можно легко и быстро — просто щелкните на вновь созданной кнопке панели быстрого доступа. Веб-документ [~j Линейка fjj Структура [j Сетка Разметка Режим _ страницы чтения 1^1 Черновик ; j Область навигации Рис. 3.11. Кнопка вызова макроса помещена на панель быстрого доступа Word 2010 Глава 3. Создание и выполнение VBA-программ 57
Для того чтобы изменить изображение на только что созданной кнопке, необходимо после ее добавления на панель (п. 3 предыдущего списка) щелкнуть в диалоговом окне Параметры Word на кнопке Изменить. В раскрывшемся диалоговом окне Изменение кнопки (рис. 3.12) выберите из набора предлагаемых готовых изображений наиболее подходящее и щелкните на нем, а затем закройте диалоговое окно, щелкнув на кнопке ОК. (Таким же способом можно изменить изображение и на кнопке, уже созданной ранее.) Изменение кнопки JJX1 Символ: ЗА»*** ж » ♦ © Я1 й « SMSQTYWl А ui 3 . - ® & DВ□В J ua)©5.*a|ax ✓ «<>[:?] л ► ФСЙЭ'Й 1 а ./<4 мд.j-з-4 j Отображаемое имя: (Project.Г^мветствие.Приветствие | ОК ] Отмена Рис. 3.12. Диалоговое окно Изменение кнопки Для того чтобы удалить ненужную кнопку с панели быстрого доступа, щелкните на кнопке Настройка панели быстрого доступа и в раскрывшемся меню выберите коман- ду Другие команды. Далее в раскрывшемся диалоговом окне Параметры Word щелк- ните на строке удаляемой кнопки в правом списке этого диалогового окна, а затем щел- кните на кнопке Удалить. Закройте диалоговое окно Параметры Word. В результате удаляемая кнопка исчезнет с панели быстрого доступа. Назначение комбинации клавиш для запуска программы Если при создании макроса в Microsoft Word комбинации клавиш для его запуска не было назначено, то это можно сделать позднее, в диалоговом окне Параметры Word. Для назначения комбинации клавиш макросу (или VBA-программе) в Word выполните сле- дующие действия. 1. В меню кнопки Файл выберите команду Параметры и в открывшемся окне Параметры Word перейдите в раздел Настройка ленты. Щелкните на кнопке Настройка, расположенной в нижней части окна. 2. В раскрывшемся окне Настройка клавиатуры выберите в списке Категория значе- ние Макросы (рис. 3.13), а затем в списке Макросы выберите имя требуемой про- граммы (или макроса). 3. В поле Новое сочетание клавиш введите назначаемую для вызова программы ком- бинацию клавиш и щелкните на кнопке Назначить, а затем на кнопке Закрыть. Теперь вызывать указанную VBА-программу можно будет с помощью ввода только что назначенной комбинации клавиш. 58 Часть 1. Введение в VBA
Рис. 3.13. Задание комбинации клавиш для вызова VBA-программы в Word 2010 Для задания (или изменения) комбинации клавиш, предназначенной для быстрого вызова VBA-программы или макроса в Microsoft Excel, выполните следующие действия. 1. На ленте приложения перейдите на вкладку Вид и в группе Макросы выберите в меню кнопки Макросы команду Макросы. Откроется диалоговое окно Макрос, показанное на рис. 3.14. В списке Имя макроса выберите требуемую программу и щелкните на кнопке Параметры. 2. В раскрывшемся на экране диалоговом окне Параметры макроса введите клавишу, которая в комбинации с клавишей <Ctrl> будет использоваться для вызова данной VBA-программы (рис. 3.15). Для возвращения в диалоговое окно Макрос щелкните на кнопке ОК. Рис. 3.14. Диалоговое окно Макрос в Excel 2010 Рис. 3.15. Назначение VBA-программе комбинации клавиш в Excel 2010 Глава 3. Создание и выполнение VBA-программ 59
Обработка ошибок При написании кода VBA-программы, безусловно, могут быть допущены ошибки или случайные описки. Многие из подобных случайных ошибок редактор VBA автоматически отслеживает непосредственно во время написания или редактирования программного кода. Более сложные логические ошибки можно обнаружить компилятором при выпол- нении процедуры — он проверяет код процедуры на наличие ошибок непосредственно перед преобразованием программы в форму, понятную для компьютера. Если операция компиляции не будет успешной, появится окно с уведомлением об ошибке. Данный уро- вень проверки намного строже, чем обычная проверка синтаксиса в каждой строке кода, так как на этом этапе проверяется правильность ссылок и тип переменных, а каждый оператор проверяется на корректность всех его параметров. Однако те ошибки, которые все еще остались необнаруженными компилятором, вам придется отыскивать самостоятельно. Самыми простыми ошибками, с которыми вы не- пременно столкнетесь при написании процедур VBA, являются ошибки синтаксиса (syntax error). Если при написании программного кода была допущена синтаксическая ошибка, редактор VBA сообщит об этом сразу, не дожидаясь момента выполнения программы. Всякий раз, когда редактор VBA не сможет понять и корректно интерпретировать в ка- честве того или иного оператора введенную в строку последовательность символов, этот текст будет выделен красным цветом. При попытке перейти с такой строки на другую ре- дактор VBA выдаст сообщение о наличии ошибки с теми или иными разъяснениями. Для того чтобы описанный выше режим был активизирован, следует выбрать команду меню Tools^Options редактора VBA и в раскрывшемся диалоговом окне Options (Параметры) на вкладке Editor (Редактор) установить флажок опции Auto Syntax Check (Автоматиче- ская проверка синтаксиса), как показано на рис. 3.16. Рис. 3.16. Вкладка Editor диалогового окна Options редактора VBA Обнаруживая многие ошибки синтаксиса, редактор VBA информирует о пропущенных запятых, кавычках и т.д. Однако некоторые синтаксические ошибки редактор может обна- 60 Часть 1. Введение в VBA
эужить только тогда, когда программа начнет выполняться, — например, если в операторе была указана ссылка на несуществующую в программе метку. Сообщение о такой ошибке будет выдано, когда начнется выполнение программы. Подобные ошибки следует исправ- лять сразу же, как только редактор VBA их обнаруживает. В некоторых более сложных случаях редактор VBA не может определить, что именно неверно в синтаксисе данного оператора, и только сообщает о наличии неопознанной им ошибки. | Следует также отметить, что в диалоговом окне Options редактора VBA можно также за- < дать другие полезные параметры компиляции. Для этого нужно перейти в окне Options < на вкладку General. В нижнем правом углу вкладки General находятся два флажка для установки параметров компиляции. • Compile On Demand (Компиляция по требованию). Установка этого флажка огра- ничивает код, который будет скомпилирован при открытии формы, т.е. при выпол- нении компиляции будут компилироваться только используемые функции. • Background Compile (Компиляция в фоновом режиме). При установке этого флажка компилируется любой нескомпилированный код. Рис, 3,17, Вкладка General диалогового окна Options редактора VBA Кроме ошибок компиляции, т.е. синтаксических ошибок, существуют еще и логические ошибки — неточности и несоответствия, допущенные при проектировании программы. Другими словами, при наличии подобных ошибок программа делает не то, что было за- планировано, или делает что-то не так, как это ожидалось. Причиной таких несоответ- ствий чаще всего являются ошибки, допущенные при проектировании логики поведения программы. В этом случае не следует искать ошибок в записи операторов; необходимо еще раз тщательно продумать саму структуру программы и уточнить алгоритм ее пове- дения. Когда правильное решение будет найдено, вы обязательно получите требуемый результат. Существует еще один вид ошибок — это ошибки выполнения, которые приводят к останову выполнения программы вследствие непредсказуемых ошибок в обрабатываемых данных или в действиях пользователя, вызывающих возникновение непредусмотренных Глава 3. Создание и выполнение VBA-программ 61
в программе ситуаций. Такие ошибки далеко не всегда можно легко обнаружить и испра- вить. Здесь на помощь разработчику приходят различные методы тестирования программ с последующей отладкой. Подробнее об этом поговорим в главе 12. Чем тщательнее будет проведено тестирование, тем устойчивее и надежнее будет работать написанная вами про- грамма. Резюме Эта глава посвящена вопросам создания и выполнения программ на языке VBA. Прежде всего мы познакомились с основными этапами создания любого программного обеспечения — от самой простой программы до сложнейшего программного комплекса, позволяющего решать ряд практических задач. Чтобы в конечном итоге получить рабо- тоспособное и эффективное приложение, следует тщательно изучить решаемую задачу, подготовить логическую схему будущего приложения и только затем переходить к напи- санию программного кода. Вновь созданная программа обязательно должна быть про- тестирована и полностью отлажена. Только в этом случае можно ожидать, что она будет успешно использоваться теми, для кого была предназначена. Потом в этой главе мы ознакомились с особенностями построения и реализации VBA- программ в различных приложениях, включая вопросы их хранения, запуска и обработки ошибок. Тестовые задания Ниже приведено несколько тестовых заданий, предназначенных для закрепления из- ложенного в этой главе материала. В каждом задании вам предлагается вопрос и несколь- ко вариантов ответа на него, один (или несколько) из которых является правильным, а остальные — нет. Укажите правильный ответ. 1. Общий цикл создания VBA-программ предусматривает такую последовательность действий: а) анализ задачи, написание программного кода, тестирование и отладка; б) проектирование программы, написание программного кода, тестирование и от- ладка; в) анализ задачи, проектирование программы, реализация проекта, тестирование и отладка; г) анализ задачи, проектирование программы, написание программного кода, пере- дача приложения в эксплуатацию. 2. Программными единицами, с которыми может работать редактор VBA, являются: а) проекты, модули, процедуры, операторы; б) проекты, программы, макросы; в) программы, модули, процедуры, операторы; г) проекты, программы, модули, процедуры. 3. Обмен программными модулями между проектами осуществляется с помощью следующих операций: 62 Часть 1. Введение в VBA
а) копирования и вставки; б) экспорта и импорта файлов; в) совместного редактирования и слияния; г) пересылки и считывания. 4. Запуск VBA-программ можно организовать с помощью: а) ярлыка на рабочем столе; б) комбинации клавиш, набираемых в окне VBА-приложения; в) кнопки на панели инструментов; г) команды меню Пуск; д) команды меню VBА-приложения. 5. Редактор VBA позволяет автоматически обнаруживать следующие виды ошибок в программах: а) орфографические; б) синтаксические; в) логические; г) структурные. Глава 3. Создание и выполнение VBA-программ 63

Часть Основы программирования наУВА В этой части... > Глава 4. Типы данных, переменные и константы > Глава 5. Операции и выражения > Глава 6. Управляющие операторы > Глава 7. Процедуры и функции > Глава 8. Объекты и коллекции

Глава 4 Типы данных, переменные и константы В этой главе... ♦ Типы данных ♦ Переменные ♦ Массивы ♦ Константы ♦ Типы данных, определенные пользователем ♦ Комментарии ♦ Резюме Типы данных Перед тем как перейти к рассмотрению переменных, хочу познакомить вас с таким понятием, как типы данных, которыми может оперировать VBA, определяя способ хра- нения информации в виде целого числа, действительного числа, текстовой строки и т.д. В табл. 4.1 перечислены основные типы данных VBA с описанием занимаемого объема памяти в байтах, а также с указанием диапазона значений, которые данный тип может сохранять. Таблица 4.1. Типы данных в VBA Тип Размер Диапазон значений Byte (Байт) 1 байт Целое число от 0 до 255 Boolean (Булев) 2 байта True (Истина) или False (Ложь) Integer (Целое) 2 байта От-32 768 до 32 767 Long (Длинное целое) 4 байта От —2 147 483 648 до 2 147 483 647 Single (С плавающей точкой одинарной точности) 4 байта От-3.402823Е+38 до -1.401298Е-45 (для отрицатель- ных значений); от 1.401298Е-45 до 3.402823Е+38 (для положительных значений) Double (С плавающей точкой двойной точности) 8 байт От -1.79769313486232Е+308 до -4.94065645841247Е- 324 (для отрицательных значений); от 4.94065645841247Е-324 до 1.79769313486232Е+308 (для положительных значений) Currency (Денежный, 8 байт От -922 337 203 685 477.5808 до 922 337 203 685 477.5807 масштабированное целое значение)
Окончание табл. 4.1 Тип Размер Диапазон значений Decimal (Десятичное) 14 байт ±79 228 162 514 264 337 593 543 950 335 без де- сятичной точки или 28 цифр после десятичной точки; минимальное ненулевое значение равно ±0.0000000000000000000000000001 Date (Дата) 8 байт От 1 января 100 года до 31 декабря 9999 года Object (Объектный) 4 байта Любая ссылка на объект String (Строка переменной длины) 10 байт+длина строки От 0 до приблизительно двух миллиардов символов String (Строка фиксированной длины) Длина строки От 0 до приблизительно 65 400 символов Variant (Вариантный числовой) 16 байт Любое числовое значение, вплоть до границ диапазо- на типа Double Variant (Вариантный строковый) 22 байта+длина строки От 0 до приблизительно двух миллиардов символов User-defined (Опреде- ляемый пользователем) Любой Определяется в соответствии с заданным типом данных Теперь давайте немного подробнее познакомимся с каждым из типов данных, при- веденных в табл. 4.1. Числовые данные В языке VBA используется шесть различных типов данных для хранения числовой ин- формации и выполнения над ними различных действий. К таким типам данных относят- ся: Byte, Integer, Long, Single, Double и Currency. Первые три типа данных (Byte, Integer и Long) относятся к целым типам данных, т.е. являются числами, имеющими только целую часть, а следующие три типа данных (Single, Double и Currency) — к типам данных с плавающей точкой, т.е. числам, содержащим целую и дробную части и отличающимся только своей точностью (здесь имеется в виду количество знаков после точки). Тип Byte представляет собой наименьший тип данных среди целых типов данных в языке VBA. Он позволяет хранить числовые значения в диапазоне от 0 до 255. Если для работы необходимо использовать числовое значение, большее 255, то придется ис- пользовать переменную типа Integer, а если не хватит и диапазона типа Integer (он ограничен значением 32 767), то VBA допускает использовать тип с еще большим диа- пазоном — тип Long. Как уже говорилось выше, для задач, требующих более высокой точности вычислений, нужно использовать типы данных с плавающей точкой — Single или Double. Числа, сохраняемые с использованием типа Single, называются числами одинарной точности, а числа, сохраняемые с использованием типа Double, — числами двойной точности. Диа- пазон допустимых значений для чисел этих типов очень велик, но следует помнить, что для чисел, представленных в формате с плавающей точкой, существует вероятность по- явления ошибок округления. Тип данных Currency используется для представления чисел с фиксированной точкой, т.е. положение десятичной точки в них всегда фиксировано — после нее четыре дробные 68 Часть 2. Основы программирования на VBA
цифры. Такой тип данных рекомендуется использовать для вычислений, оперирующих большими числами, когда требуется более высокая точность, чем та, которую обеспечи- вают типы данных с плавающей точкой. Такой тип данных очень удобен для хранения денежных величин. К типам данных, которые работают с числовыми значениями, можно также отнести и тип данных Decimal, но этот тип не является самостоятельным типом данных в данной версии языка VBA, т.е. в нем нельзя объявить переменную типа Decimal. Этот тип су- ществует только в качестве подтипа Variant с использованием функции Cdec. Следует также отметить, что десятичный тип данных при хранении не разделяет числа на дробные и целые, допуская целые величины от -79 228 162 514 264 337 593 543 950 335 до +79 228 16 2 514 264 337 593 543 950 335, если исходное значение не содержит десятичной точки, и в то же время позволяет хранить данные с точностью до 28 десятичных знаков, но в диапазоне значений от -7,9228162514264337593543950335 до+7,9228162514264337593543950335. Булевы значения Тип данных Boolean применяется для логических переменных, используемых при проверке истинности различных условий. Для присваивания значения булевой пере- менной используются логические значения True (Истина) и False (Ложь). В числовом (внутреннем, машинном) представлении это соответствует значениям 1 и 0. Значения типа Boolean генерируются, например, при сравнении двух чисел (сравнение на больше/ меньше) или при сравнении двух строк на совпадение. Тип Date Тип данных Date используется в языке VBA для хранения значений дат и времени. Стартовой датой для языка VBA является 30 декабря 1899 года, причем отрицательные зна- чения указывают на более ранние даты, т.е. на даты до 30.12.1899 года, а положительные — на более поздние. Само число 0 представляет собственно дату 30.12.1899 года, а числу 2.0 соответствует дата 01.01.1900 года. Дата хранится в формате числа с плавающей точкой, причем цифры, стоящие перед точкой, — это количество дней, прошедших с 30 декабря 1899 года до данного дня, а цифры, стоящие после точки, обозначают время как часть дня. Преимущество представления дат и времени в виде числовых значений с плавающей точкой состоит в том, что такие числа можно складывать и вычитать. Например, если необходимо определить количество дней между двумя датами, следует просто вычесть одну из другой — целая часть полученной разности и даст искомый ответ. В этом формате даты могут быть представлены от 1 января 100 года до 31 декабря 9999 года. В языке VBA значения дат и времени указывают, заключая их между знаками # (номер, или диез), как показано ниже. Dim d As Date d = #1/03/2007# Язык VBA также предоставляет широкий набор функций для различных преобразова- ний значений дат и времени; использование этих функций будет рассмотрено в главе 9. хч Следует заметить, что в языке VBA диапазон дат, с которым он работает, значительно шире, чем в Microsoft Excel (в Excel начальная дата — 1 января 1900 года). Поэтому будь- вив те внимательны и следите за тем, чтобы при работе с Excel не использовались значения дат, которые язык VBA позволяет использовать, a Excel — нет. Глава 4. Типы данных, переменные и константы 69
Текстовые данные Для сохранения любых текстовых данных в языке VBA используется тип данных String. Текстовые данные, которые сохраняются в VBА-программе, принято называть строками, потому что текстовые данные обычно рассматриваются как строки символов различной длины. Они могут быть как строками переменной длины (от нуля до двух мил- лиардов символов), в которых могут храниться последовательности символов практически неограниченной длины, так и строками фиксированной длины (от 1 до 65 400 символов). Строковые данные в языке VBA всегда заключаются в кавычки (" "), поэтому очень важ- но правильно понимать отличие между собственно числом и текстовым представлением числа. Например, исходя из формы написания, значение 125 является числом, с кото- рым можно выполнять различные математические действия, а ”125” — это текстовое значение, содержащее цифры и не являющееся числом, над которым можно выполнять какие-либо математические операции. Ниже приведен пример объявления переменной s типа String, которой затем присваивается строковое значение. Dim s As String s = "Это строка длиной 29 символов" Если строке фиксированной длины присвоить текстовое значение, длина которого будет меньше ее размера, то компилятор VBA добавит после символов текстового зна- чения нужное число пробелов, дополняющее результат до полной длины этой строки. Если же текстовое значение будет длиннее ее размера, то лишняя часть текста (справа) будет просто утеряна. Для объявления строки фиксированной длины используется оператор Dim следующей конструкции. Dim имя_переме иной As String * длина_строки Строки переменной длины, в отличие от строк фиксированной длины, могут расши- ряться настолько, насколько этого требуют данные. По умолчанию все строковые данные относятся к этому типу. Для объявления этого типа используется следующий оператор. Dim имя_переменной As String Тип Variant Тип данных Variant — это такой тип данных, который может сохранять в себе данные любых типов из числа допустимых в языке VBA. В переменной типа Variant может быть заключен текст, числовые значения, даты и объекты. В языке VBA тип данных Variant принят по умолчанию, т.е. если переменная была создана без указания типа, то она ав- томатически создается с типом Variant. Переменные этого типа принимают характе- ристики того конкретного типа данных, к которому относятся значения, сохраняемые в них в данный момент. Для числовых данных значение типа Variant принимает характе- ристики числового типа Double, для строковых данных — характеристики типа String и т.д. Благодаря такой гибкости, переменные типа Variant очень удобны, поскольку избавляют программиста от необходимости использовать конкретные типы данных. Нет необходимости думать о том, что именно будет храниться в той или иной перемен- ной, — достаточно просто всем им назначить тип Variant. Однако, несмотря на все свои преимущества, этот тип данных предполагает использование большого объема памяти 70 Часть 2. Основы программирования на VBA
для хранения информации и требует значительных затрат времени при выполнении даже самых простых математических операций или операций сравнения. Поэтому настоятель- но рекомендую, перед тем как приступать к кодированию программы, точно определить, какой из возможных типов данных больше всего подходит для каждой величины, а затем объявлять конкретный тип данных для каждой используемой в программе переменной. Результат будет намного эффективнее, чем при использовании типа Variant для всех без исключения переменных в программе. Ниже приведен пример объявления переменных v и w типа Variant, с последующим присвоением им значений различных типов. Dim v, w As Variant v = "Это строковое значение" ’Присвоение строкового значения w = #31/08/2003# 'Присвоение значения типа даты v = 128 'Замена строкового значения числовым В случае возможного смешения типов в представлении данных (между текстом и чис- лом) в программе для таких данных лучше использовать тип Variant. Переменные Переменная — это поименованная область компьютерной памяти, в которой хранятся данные указанного типа, которые могут изменяться сколь угодно раз по ходу выполнения программы. Это позволяет программе проверять информацию, которая находится в пере- менной, чтобы выяснить, выполняется ли то или иное условие, а затем так или иначе реа- гировать на полученный результат. Например, можно построить программу так, что если проверяемые условия выполняются, программа продолжит работу выполнением одной последовательности операторов, а если не выполняются — другой. Как мы уже знаем, язык VBA содержит обширный набор различных типов переменных, соответствующих данным разного типа. Переменные в операторах VBA представляют числа, текстовую информацию или лю- бую другую информацию, которая при написании оператора (т.е. при программировании) еще неизвестна, но будет доступна при выполнении этого оператора (т.е. когда программа будет выполняться на компьютере). Это можно представлять себе так, как будто при вы- полнении программа, обрабатывая очередной оператор, заменяет все присутствующие в нем имена переменных теми фактическими значениями данных, которые сейчас хранятся в участках памяти, на которые эти переменные ссылаются. Присвоение имени и объявление переменных Прежде чем начать работать с переменной, ей надо присвоить уникальное имя и объявить ее как переменную. Имя для переменной может быть выбрано по вашему усмо- трению, но с соблюдением следующих правил: максимальная длина имени переменной не может превышать 255 символов; имена переменных должны быть уникальными, другими словами, две разные про- цедуры или переменные не могут иметь одно и то же имя; первым символом в имени переменной должна быть буква, за которой могут следо- вать в любой комбинации цифры, буквы или символ подчеркивания Глава 4. Типы данных, переменные и константы 71
имя переменной не может содержать пробелов, точек, восклицательных знаков, а также символов @,#,$,%,&; в качестве имени переменной нельзя использовать ключевые слова языка VBA. При присвоении имени переменным можно использовать как строчные, так и про- писные буквы в любом сочетании, например SumVznos или sumvznos — для компиля- тора VBA это будет одно и то же имя. Если при первом вхождении в текст программы имя переменной было указано как SumVznos, а при втором вхождении оно было записано как sumvznos, то редактор кода VBA автоматически изменит первое вхождение на sumvznos. Полезно также применять для переменных описательные имена, которые поясняют смысл данных, хранящихся в этих переменных, — это сделает вашу программу более читабельной. Перед тем как впервые использовать переменную, поместив ее имя в оператор VBA, можно предварительно объявить ее, т.е. указать компилятору VBA, что требуется создать переменную определенного типа с данным именем. Если переменная создается (т.е. ис- пользуется в операторе) без предварительного объявления (в этом случае говорят, что она объявляется неявно), то такой переменной будет присвоен тип Variant, принимаемый в языке VBA по умолчанию. Для явного объявления переменной используется оператор Dim, с помощью которого в языке VBA резервируется область памяти, предназначенная для хранения данных указанного типа, на которую будет ссылаться переменная. Dim Name As String Dim Namel В первом операторе Name — имя переменной, a String — присвоенный ей тип дан- ных. Во втором операторе конструкция As String (или ей подобная) отсутствует, поэто- му переменной Namel будет присвоен тип Variant. Еще раз напомним, что переменные типа Variant требуют для своего хранения суще- ственно больше памяти, к тому же работа с ними замедляет выполнение программы. С другой стороны, такие переменные не ограничены хранением какого-то одного типа данных. Однако следует отметить, что на практике ситуация, когда в одной переменной требуется хранить данные разных типов, встречается довольно редко, а это и есть усло- вие оптимальности применения типа Variant. В одной строке можно объявить и несколько переменных (через запятую), при этом ключевое слово Dim задается только один раз, а тип данных указывается для каждой переменной. Dim Namel As String, Name2 As String, Name3 As String Кроме того, в одном операторе Dim допускается смешивать объявления переменных различных типов. Dim Name As String, intlnteger As Integer 9 Как правило, используемые переменные описываются в начале процедур. Такая ком- поновка не обязательна, однако большинство разработчиков стараются ее придержи- ваться. Группировка объявлений переменных в начале процедуры позволяет при не- обходимости быстро отыскать эти операторы в теле программы. После объявления переменную можно неоднократно использовать в той части програм- мы, где она будет доступной. Та часть программы, в рамках которой некоторая переменная 72 Часть 2. Основы программирования на VBA
является доступной, называется областью действия данной переменной. Любая переменная может использоваться только в области своего действия, поскольку вне этой области дан- ная переменная считается просто несуществующей и программе о ней ничего неизвестно. Область действия каждой переменной зависит от двух взаимосвязанных факторов — места объявления этой переменной и указанных при ее объявлении ключевых слов. При этом для областей действия переменных можно выделить три уровня. 1. Переменная, объявленная в процедуре, является доступной только в этой процедуре. Если переменная используется без объявления или объявлена внутри процедуры с помощью ключевого слова Dim, то такую переменную можно использовать только внутри этой процедуры. 2. Переменная, объявленная в разделе объявлений модуля с помощью ключевых слов Pri - vate или Dim, является доступной только в пределах этого модуля. Ключевое слово Private в этом случае работает точно так же, как и Dim. Для того чтобы перемен- ная, объявленная с использованием этих ключевых слов, была доступна для всех процедур в данном модуле, ее объявление необходимо поместить в начало модуля, перед кодом всех его процедур. 3. Переменная, объявленная в разделе объявления модуля с помощью ключевого слова Pub- lic, является доступной для всех модулей во всех проектах. При наличии в разделе объявлений модуля оператора Option Private Module переменные, объявлен- ные с использованием ключевого слова Public, будут доступны всем модулям только данного проекта. Рассмотрим следующий пример. Option Private Module Dim a As Integer Private b As Long Public c As Single Public Sub NewSubO Dim x As Single End Sub Здесь переменные а и b доступны в пределах всего модуля, в состав которого входит приведенный выше фрагмент. Переменная с будет доступна для всех модулей, но только данного проекта (поскольку указан оператор Option Private Module). Переменная х будет доступна только внутри самой процедуры NewSub, поскольку она объявлена непо- средственно в ней. Когда переменная объявлена, можно поместить в эту переменную какую-то инфор- мацию, т.е. присвоить ей значение. Это присвоенное значение будет храниться в пере- менной до тех пор, пока ей не будет присвоено другое значение. Значение переменной присваивается специальным оператором, называемым оператором присваивания, в ко- тором имя переменной (слева) соединяется с присваиваемым ей значением (справа) с помощью знака равенства. Например, в операторе присваивания х = 5 переменной х присваивается значение 5. Такие явно указанные значения называются литеральными или просто литералами, однако точно так же можно присваивать значения, вычисляемые на основе значений других переменных. Рассмотрим следующий оператор. Глава 4. Типы данных, переменные и константы 73
CounZap = List * n Здесь переменной CounZap присваивается значение, равное произведению значений переменных List и п. Отсюда следует, что в языке VBA оператор присваивания пред- ставляет собой конструкцию, в которой знак равенства (=) связывает переменную, имя которой указано слева от него, с выражением, определяющим новое значение этой пере- менной и указанным справа от знака равенства. При выполнении оператора присваи- вания языка VBA сначала вычисляется выражение, стоящее справа от знака равенства, а затем полученный результат сохраняется в переменной, имя которой указано слева от знака равенства. Массивы Массив — это набор элементов одинакового типа, имеющих общее имя. Массивы по- зволяют работать с некоторым набором однотипных данных как с единым целым. В языке VBA всякий массив имеет собственное имя и состоит из некоторого количества элемен- тов. Каждый из этих элементов занимает в массиве определенное место. Поэтому, чтобы найти в массиве нужный элемент, достаточно указать имя этого массива и номер (индекс) того элемента, с которым требуется в данный момент работать. Предположим, что у нас есть набор чисел, представляющий собой список телефонных номеров. 2123467 2172219 4101235 3302278 2161710 4401199 Если присвоить этому массиву имя intNumer, то обратиться к его пятому элементу можно будет так: intNumer (5). Такой массив, представляющий собой простой список данных, называется одномерным, а заключенное в скобки число, стоящее рядом с именем массива, называется индексом элемента данного массива. Следует помнить, что в языке VBA нумерация элементов в массиве начинается с нуля, однако с помощью оператора Option Base (подробнее о нем мы будем говорить позже) можно изменить начальный индекс элементов массива. В приведенном выше примере при стандартной нумерации элементов (считая от нулевого) мы обращаемся к пятому элементу от начала массива (т.е. телефонному номеру 4401199), записывая intNumer (5). Ключевое слово Int перед именем массива указывает на то, что в этом массиве хранятся целые числа, поэтому хра- нящееся в intNumer (4) значение также представляет собой целое число. Кроме одномерных массивов, которые очень хорошо подходят для представления в программе простых списков с единственным.индексом, в языке VBA можно создавать и многомерные массивы, имеющие два и более индексов. В случае двух индексов сохраняе- мые в массиве данные можно представить в виде таблицы, состоящей из строк и столбцов. Например, Dim Matrix (1 to 5, 1 to 5)—это матрица размером 5x5 элементов, состоящая из пяти строк и пяти столбцов. Количество размерностей массива в языке VBA не ограничено, т.е. разрешается создавать массивы как одно- или двухмерные, так и ше- стидесятимерные и так далее, но, как показывает практика, в программировании чаще всего используются одно- и двухмерные массивы. 74 Часть 2. Основы программирования на VBA
3 Иногда значение, хранимое в элементе массива, может случайно совпасть (или иметь I сходство) с его индексом, но не путайте эти два понятия. Индекс является средством обнаружения интерпретатором VBA места нахождения соответствующего значения относительно начального адреса массива в оперативной памяти, где все элементы этого массива размещаются последовательно. В оперативной памяти каждому эле- менту отводится определенное его типом количество байтов. Все переменные могут ссылаться только на один адрес в памяти, в том числе и переменные массивов, кото- рые ссылаются на адрес первого элемента. Таким образом, чтобы найти л-й по счету элемент массива, интерпретатор берет значение индекса п, вычитает из него значение нижней границы и умножает на длину данного типа данных. В результате получается смещение адреса в памяти искомого элемента относительно адреса, хранимого в пе- ременной массива. После сложения этих двух величин можно получить абсолютный адрес элемента массива в памяти и извлечь его значение. Статические и динамические массивы Язык VBA поддерживает два типа массивов — статические и динамические. Статиче- скими называют такие массивы, размерность которых была указана непосредственно при их объявлении. В этом случае размер массива остается фиксированным на протяжении всего выполнения программы. Для объявления массивов используются те же операторы Dim и Public, что и при объявлении обычной переменной, причем с теми же правилами определения их области действия. Объявить массив фиксированного размера можно, ука- зав в скобках после его имени конкретные значения для каждого его измерения. ’Одномерный массив из 51 элемента Dim Ml(50) As Integer ’Двухмерный массив из 11 строк по 21 элементу Dim М2(10,20) As Integer В этом примере первый оператор объявляет одномерный массив Ml из 51 целого числа. Так как в языке VBA (по умолчанию) принято нумерацию индексов начинать с нуля, его элементы будут пронумерованы от 0 до 50. Второй оператор объявляет двухмерный массив М2, который будет содержать 11 строк по 21 целому числу, причем индексы его элементов будут изменяться так: первый — от 0 до 10, а второй — от 0 до 20. Напомним, что доступ к элементам объявленного массива осуществляется с помощью указания его индексов, которые являются целыми числами и представляются тем или иным способом. Это может быть литерал, значение целочисленной переменной или же значение указанного элемента массива целых чисел — не имеет значения, важно лишь, чтобы эта указанная величина в данный момент содержала целое число, представляющее собой индекс нужного нам эле- мента массива. Например, для присвоения значения 5 двадцать пятому элементу массива Ml можно воспользоваться любым из трех указанных ниже способов. Ml (24) = 5 х = 24 Ml(х) = 5 Ml(0) = х Ml(Ml (0)) =5 Глава 4. Типы данных, переменные и константы 75
Для того чтобы сослаться на элемент двухмерного массива, необходимо указать два индекса: М2 (9, 12) — в данном случае мы обращаемся к 13 элементу в строке 10. Если вас по какой-либо причине не устраивает вариант нумерации элементов в масси- ве начиная от нуля, можно, до объявления каких-либо массивов, поместить в начало мо- дуля оператор Option Base 1, указывающий, что нумерация индексов массивов долж- на начинаться с 1. Хочу предупредить, что действие этого оператора касается только тех массивов, которые находятся внутри данного модуля. Кроме приведенного выше способа записи размерности массива, существует еще один — с использованием ключевого слова То. Он универсален и позволяет задавать любое начальное значение индексам массива. Dim S3 (10 То 25, 30 То 40) As String В этом примере объявляется двухмерный массив из строковых переменных с именем S3, в котором по первому измерению имеется 16 позиций, а по второму — 11 позиций, т.е. всего 176 строковых переменных. При этом значения первого индекса массива S3 из- меняются от 10 до 25, а второго — от 30 до 40. В отличие от статических массивов, динамические массивы имеют переменное количе- ство элементов, т.е. динамические массивы могут увеличиваться или сокращаться, в за- висимости от того, какое количество элементов требуется в данный момент. Объявлять динамический массив целесообразно в следующих случаях: 1) когда требуемый размер массива неизвестен до момента выполнения программы; 2) если заранее известно, что в ходе выполнения программы размер массива будет меняться; 3) если при выполнении программы после завершения использования массива необходимо освободить занимае- мую им память. При объявлении динамического массива его размерность (индексы) в скобках после имени массива не указывается. Dim DI() As String Прежде чем использовать динамический массив в той или иной процедуре, необходи- мо поместить в нее оператор ReDim, задающий действительную размерность этого масси- ва. Оператор ReDim может быть указан для одного и того же массива сколько угодно раз, при этом всякий раз для него можно задать новую размерность и число элементов. Dim Ml() Dim М2 () Dim М3 () ReDim Ml(5) ’1 измерениеf 6 элементов ReDim М2(5 To 11) ’1 измерение, 7 элементов ReDim M3(l TO 6, 1 To 10) ’2 измерения, 60 элементов При обычном переопределении массива его содержимое полностью уничтожается. Если же при переопределении размерности массива необходимо сохранить уже суще- ствующие в нем данные, укажите необязательное ключевое слово Preserve. Dim М() As Single ReDim М(1 To 10, 1 To 20) ReDim Preserve M(1 To 10, 1 To 50) 76 Часть 2. Основы программирования на VBA
В этой последовательности операторов сначала объявляется динамический массив м, затем он переопределяется как двухмерный массив заданного размера, после чего увели- чивается его размер по второму измерению с сохранением уже имеющихся в этом массиве данных. Следует заметить, что при использовании ключевого слова Preserve имеет ме- сто несколько ограничений. При сокращении размеров массива данные, оказавшиеся за пределами его новых размеров, будут потеряны. Размерность массива (количество измерений) нельзя изменить. В многомерных массивах можно менять размер только последнего измерения. ММЦ Язык VBA позволяет также присваивать значения переменных из одного массива дру- ГОМУ- этого достаточно записать обычный оператор присваивания, но в качестве НКЭ операндов указать в нем имена массивов: МассивДанных = МассивИсходныхДанных В этом случае массив, которому присваиваются значения (слева от знака равенства), должен быть динамическим, и сохраняемые в нем данные должны соответствовать типу данных исходного массива. В противном случае компилятор VBA автоматически перео- пределит тип данных результирующего массива, а также присвоит ему размер и размер- ность исходного массива. Для очистки и удаления массивов в языке VBA применяется оператор Erase. После заполнения элементов массива данные в них хранятся до тех пор, пока программа не присвоит им новые значения или пока VBA не удалит этот массив из памяти. Оператор Erase позволяет очистить все элементы массива при применении его к статическому массиву. В случае динамического массива оператор Erase удаляет из памяти сам массив, освобождая при этом ту область памяти, которая ранее использовалась этим массивом. Чтобы вновь использовать удаленный динамический массив, его следует переопределить с помощью оператора Re Dim. Для статических массивов действие оператора Erase зависит от конкретного типа элементов данного массива. Для любого числового типа оператор Erase записывает во все элементы массива значение нуль. Для строкового типа с переменной длиной строки оператор Erase помещает во все элементы массива строку нулевой длины, а строки фиксированной длины полно- стью заполняются символами пробелов. Для типа Variant оператор Erase устанавливает все элементы массива на Empty. Для типа Ob j ect оператор Erase устанавливает элементы массива на Nothing. Для пользовательского типа оператор Erase устанавливает числовые типы на 0, стро- ковые — на строки нулевой длины, Variant — на Empty, a Object — на Nothing. Константы При написании программы на языке VBA не обязательно всегда использовать только переменные, в некоторых случаях удобнее и правильнее пользоваться значениями, кото- рые не будут меняться на протяжении всего хода выполнения программы. Такие значения Глава 4. Типы данных, переменные и константы 77
принято называть константами. Использование констант делает программы более чита- бельными и упрощает внесение в них исправлений. В языке VBA используются константы двух типов — литеральные и символические. Литеральная константа — это такая кон- станта, действительное значение которой (будь то строка или число) записывается прямо в тексте программы. Такие константы можно изменять только при редактировании про- граммного кода. В языке VBA строчные литеральные константы записываются в двойных кавычках (’’ ’’), а числовые — без специального форматирования. Dim Имя As String Dim Число As Single Имя = "Саша" Число = 12.5 Символическая константа, подобно переменной, имеет присвоенное ей имя, но, в от- личие от переменной, значение символической константы никогда не меняется на всем протяжении выполнения программы. Обычно символические константы применяются для таких значений, которые будут использоваться в программах многократно. Перед тем как символическую константу можно будет использовать в программе, ее следует объя- вить. После объявления символическая константа может использоваться в любом месте программы с учетом обычных правил для области действия символических имен. Иначе говоря, если константа объявлена в процедуре, то областью ее действия будет только дан- ная процедура. Если вы хотите, чтобы константа была доступна всем процедурам модуля, ее следует определить в области определений данного модуля. Для объявления констант используется ключевое слово Const. Const КолВидНачислений = 16 Const ВидНачислений!6 = "Начисление премии" Тип данных при определении констант указывать необязательно. Явно задавать тип данных объявляемой константы нужно только в том случае, когда ее необходимо со- хранить с определенным типом данных. Если при объявлении константы тип данных не указан, то VBA использует тот тип данных, который будет наиболее подходящим для заданного значения. Например, константа, содержащая строку символов, будет по умолчанию сохранена с типом string. Следует также отметить, что язык VBA предоставляет в распоряжение программиста набор внутренних констант, которые были определены разработчиками VBA специально для этой цели. Для того чтобы увидеть полный список внутренних констант, доступных в языке VBA, откройте любой документ Word (или рабочую книгу Excel) и активизируйте редактор VBA, для чего нажмите клавиши <Alt+Fl 1 >, затем откройте диалоговое окно Object Browser и выполните следующие действия. В верхнем раскрывающемся списке окна Object Browser выберите значение VBA. Ниже, в поле списка Classes, выберите значение Constants. В поле списка Mem- bers of ’Constants' (справа) будет отображен полный перечень внутренних констант языка VBA. Для получения информации о конкретной внутренней константе выберите ее имя в поле списка Members of 'Constants', после чего в нижнем поле диалогового окна Object Browser будет выведено имя этой константы и ее значение. Чтобы получить более подробную информацию об этой константе, щелкните на кнопке Help в окне Object Browser (рис. 4.1). 78 Часть 2. Основы программирования на VBA
Рис. 4.1. Просмотр списка внутренних констант языка VBA в диалоговом окне Object Browser Одно из основных преимуществ использования символической константы состоит в том, что для изменения ее значения необходимо отредактировать только объявление символической константы — либо в процедуре, которая ее использует, либо в области объявления модуля, если эта константа используется в нескольких процедурах модуля. Типы данных, определенные пользователем Язык VBA позволяет создавать собственные, определенные пользователем типы дан- ных, состоящие из одного или нескольких элементов. Определив пользовательский тип данных, вы получаете возможность использовать переменные соответствующего типа, которые по своей структуре напоминают записи в базе данных. База данных — это набор записей с одинаковой структурой, состоящих из нескольких элементов. Элементы такой записи представляют собой поля, в которых хранятся данные различных типов. В языке VBA для работы с записями подобной базы данных удобнее всего объявить массив данных пользовательского типа. Для объявления пользовательского типа данных используется оператор Туре ... End Туре. Туре Сотрудник ТабНомер As Integer Фамилия As String Имя As String Отчество As String Оклад As Currency Адрес As String End Type Глава 4. Типы данных, переменные и константы 79
В этом примере объявляется новый пользовательский тип данных Сотрудник, ко- торый состоит из целого значения (ТабНомер), четырех строковых значений (Фамилия, Имя, Отчество, Адрес) и значения типа Currency (Оклад), используемого для хранения денежных величин. Тип данных, определенный пользователем, можно определить только на уровне моду- | В ля — в самом его начале, в разделе объявлений. Внутри процедуры объявить пользова- тельский тип нельзя. Как только тип данных пользователя определен, он становится доступным для опреде- ления переменных и массивов. Например, объявить переменную пользовательского типа можно с помощью обычного оператора Dim. Dim Экономист As Сотрудник При объявлении переменной пользовательского типа не требуется объявлять или пере- числять все элементы, входящие в состав этого типа, так как имена и другие свойства этих элементов зафиксированы в объявлении соответствующего пользовательского типа. При объявлении переменных пользовательского типа можно использовать и такие ключевые слова, как Public или Private. Оператор Public служит для описания пере- менных определяемых пользователем типов, которые должны быть доступны для всех процедур во всех модулях всех проектов, а оператор Private используется для описания переменных определяемых пользователем типов, которые должны быть доступны только в том модуле, в котором они объявляются. В следующем примере массив пользователь- ского типа данных объявляется с помощью оператора Private. Private Экономист(1 То 10) As Сотрудник Для того чтобы получить доступ к элементу, входящему в состав пользовательского типа данных, необходимо идентифицировать этот элемент указанием имени переменной, после которой ставится точка, а затем указывается имя требуемого элемента. Экономист.Фамилия = "Иванов" Экономист.Имя = "Иван" Экономист.Отчество = "Иванович" Для сокращения записи подобных операторов можно использовать оператор With ... End With. With Экономист .Фамилия = "Иванов" .Имя = "Иван" .Отчество = "Иванович" End With Следует также заметить, что при работе с переменными пользовательского типа дан- ных можно присваивать содержимое одной переменной, хранящей полный набор данных, другой переменной такого же типа. Экономист(2) = Работник Здесь содержимое переменной Работник присваивается второй ячейке в массиве Экономист. 80 Часть 2. Основы программирования на VBA
Комментарии По ходу выполнения проекта вам неоднократно придется возвращаться к написанным ранее программам, чтобы проверять и изменять их. Поэтому каждая программа должна быть написана таким образом, чтобы в ней легко можно было находить (причем не только ее создателю, но и другим программистам) места, в которые требуется внести те или иные изменения. Иначе говоря, текст программы должен быть написан максимально понятно для любого человека, которому впоследствии потребуется в ней разобраться, включая и самого ее автора. Эту мысль можно выразить более кратко — ваша программа должна быть читабельна. При написании программы следует выбрать для себя правила использования отсту- пов и обязательно придерживаться их. Для того чтобы взаимосвязь между связанными по смыслу операторами была зрительно очевидной, необходимо использовать для таких операторов одни и те же отступы. Do 'Общий цикл программы switch = False For i = 1 То m 'Цикл в пределах массива If b(i) > b(i + 1) Theh 'Оператор If dum = b(i) b(i) = b(i + 1) b(i + 1) = dum switch = True End If 'Конец оператора If Next i 'Конец цикла в пределах массива Loop 'Конец общего цикла программы Здесь наглядно видно, что операторы внутри конструкции If ... Then ... End If — это одна группа, поэтому для них установлен один и тот же отступ. В данной программе оператор switch = False и структура For ... Next выполняются при каждом проходе структуры Do ... Loop, поэтому у них другой отступ. Это позволяет с первого взгляда четко определять саму структуру и содержащиеся в ней подчиненные операторы. Для до- бавления отступа в строке можно использовать клавишу пробела или клавишу <ТаЬ>, по- зволяющую сдвинуть курсор вправо. Если вы решили установить отступ табуляции, рав- ный пяти, выберите команду меню редактора VBA Tools ^Option, а затем в раскрывшемся диалоговом окне Options на вкладке Editor в поле Tab Width введите значение 5 (рис. 4.2). По умолчанию знак табуляции соответствует четырем пробелам. z-x Для организации в строке кода отступа можно также воспользоваться кнопкой Indent Ly (Добавить отступ) панели инструментов Edit Кнопка Outdent (Удалить отступ) этой панели позволяет убрать отступ в текущей строке. При написании программы очень удобно, когда записываемый оператор виден в окне программного кода целиком. Если создаваемый оператор оказался слишком длинным, можно воспользоваться символом подчеркивания (_). Данный символ, поставленный в конце строки, сообщает редактору VBA о том, что следующая строка должна быть присоединена к текущей с образованием единого оператора. В этом случае символ под- черкивания называется символом продолжения строки, однако чтобы он воспринимался редактором как таковой, перед ним обязательно должен стоять пробел. Так, приведенные ниже две строки программного кода вместе определяют один оператор. Глава 4. Типы данных, переменные и константы 81
Set Пункт = Новое_меню.Controls.Add (Type:= msoControlPopup) Рис. 4.2. Определение величины отступа для клавиши < Tab > в диалоговом окне Options При работе с программой также очень удобно использовать комментарии — текст, предназначенный для прочтения человеком и не являющийся программным кодом, а по- тому игнорируемый компилятором. Внесение в текст программы комментариев, словес- но описывающих выполняемые в ней действия, является хорошей практикой. В языке VBA комментарии записываются после символа апострофа, который можно поместить в любом месте строки, причем все символы после апострофа (до конца строки) будут вос- приниматься компилятором как комментарии. Комментарии можно размещать как на от- дельных строках, так и после операторов программы. Очень важно использовать коммен- тарии при написании сложных программ, в каждой строке желательно кратко пояснять, что и как делает данная программа. Это поможет вам при отладке программы, а также при добавлении в нее новых фрагментов, когда требуется четко знать, в какой процедуре и где именно следует поместить новый фрагмент. Поскольку каждая написанная процедура может использоваться многократно, для удобства ее дальнейшего применения целесообразно в начало каждой процедуры помещать комментарии, описывающие назначение и способ использования этой процедуры. Эти же рекомендации справедливы и в отношении комментариев, помещаемых в начало модулей. Комментарии также можно использовать для описания назначения переменных — чтобы другие пользователи (да и вы сами через некоторое время) могли понять их смысл и способ применения. Ниже приведен самый простой пример использования комментариев. ’ Вычисление значения Sub Вычисления() а = 15 ’ переменная а равна 15 Ь = 20 ’ переменная Ь равна 20 ’ Отображение результата на экране MsgBox а + Ь End Sub 82 Часть 2. Основы программирования на VBA
Умение кратко и понятно описывать выполняемые в программе действия обыч- но приходит с опытом, однако следующие рекомендации по поводу использования комментариев, безусловно, помогут вам. Будьте кратки, насколько это возможно. Грамматически корректно формируйте фразы и предложения. Используйте наиболее понятные описания. Правильно используйте знаки пунктуации. Комментируйте передаваемые аргументы. Комментируйте версии фрагментов программы — кто и когда выполнил изменения и для чего это было сделано. Вносите комментарии непосредственно при вводе текста программы, пока поста- новка задачи еще свежа в памяти. Следует также отметить, что панель инструментов редактирования редактора VBA со- держит кнопки комментирования фрагментов программы, с помощью которых можно быстро отключать и включать фрагменты вашего кода. Вначале отобразите на экране панель инструментов редактирования. Для этого выберите команду меню редактора VBA Wiew^ Toolbars1^ Edit. Выделите фрагмент текста программы, а затем щелкните на кнопке Comment Block (Закомментировать фрагмент) данной панели инструментов (рис. 4.3). Рис. 4.3. Быстрое комментирование, выполненное одним щелчком мыши Глава 4. Типы данных, переменные и константы 83
Для того чтобы снять комментарий, щелкните на кнопке Uncomment Block панели инструментов редактирования. Резюме В этой главе мы ознакомились с базовыми понятиями языка VBA — типами данных, которые в нем поддерживаются, а также переменными и константами. Понятно, что на- значение любой из программ состоит в манипулировании теми или иными данными, поэтому логично будет начать изучение ^нового языка программирования именно с рас- смотрения тех типов данных, которые в нем поддерживаются. Язык VBA предоставля- ет в ваше распоряжение весьма обширный набор типов данных, позволяющий решать задачи практически любых типов. Для начинающего программиста очень важно знать возможности языка VBA и уметь ими пользоваться. Для хранения данных в программе используются переменные и константы, каждая из которых объявляется с тем или иным типом данных. Язык VBA позволяет строить массивы — поименованный набор данных одного типа, к элементам которого можно обращаться посредством указания их поряд- кового номера — индекса. Массивы могут быть одномерными и многомерными, статиче- скими и динамическими. В последнем случае истинный размер массива задается только при выполнении программы и может многократно переопределяться. Завершается глава обсуждением типов данных, определенных пользователем. Это весьма гибкий механизм, позволяющий эффективно работать с информацией, обладающей некоторой фиксиро- ванной структурой, — описанием товара, адресами, личными данными работников и т.д. Тестовые задания Ниже приведено несколько тестовых заданий, предназначенных для закрепления из- ложенного в этой главе материала. В каждом задании вам предлагается вопрос и несколь- ко вариантов ответа на него, один (или несколько) из которых является правильным, а остальные — нет. Укажите правильный ответ. 1. В языке VBA тип данных определяет следующие характеристики некоторого эле- мента информации: а) назначение элемента и смысл сохраняемой в нем информации; б) способ представления в памяти; в) скорость выполнения операций; г) набор допустимых операций; д) категорию информации и ее владельца. 2. Язык VBA поддерживает следующие типы числовых данных: а) размеры в метрических и дюймовых единицах измерения; б) целочисленные; в) дата и время; г) количественные; д) с плавающей точкой; е) комплексные. 84 Часть 2. Основы программирования на VBA
3. Язык VBA поддерживает следующие типы нечисловых данных: а) строки символов фиксированной и произвольной длины; б) текстовые; в) графические; г) логические; д) валюта. 4. Массивы в языке VBA могут быть следующих типов: а) линейные и плоские; б) одномерные; в) статические; г) переменной длины; д) циклические. 5. Комментарии в программу помещаются для следующих целей: а) для повышения читабельности кода; б) для пояснения смысла выполняемых действий; в) для защиты авторских прав; г) для описания назначения переменных и функций. Глава 4. Типы данных, переменные и константы 85
Глава 5 Операции и выражения В этой главе... ♦ Выражения в языке VBA ♦ Совместимость типов данных ♦ Оператор присваивания ♦ Арифметические операторы ♦ Логические операторы ♦ Операторы сравнения ♦ Строковые операторы ♦ Приоритеты выполнения операций ♦ Резюме Выражения в языке VBA Для манипуляции данными, константами и переменными в языке VBA используются выражения. Выражение — это отдельное значение или несколько значений, соединенных знаками операций. Иными словами, выражение — это то, что может быть вычислено, причем полученный результат должен иметь допустимый тип данных. Выражение может содержать любую комбинацию чисел, символов, констант, переменных, свойств объектов, встроенных функций и процедур типа Function, связанных между собой допустимыми знаками операции. В сложном выражении, состоящем из нескольких компонентов, каж- дый из них также может рассматриваться как некоторое промежуточное выражение со своим собственным значением. Отсюда следует, что в языке VBA выражение может пред- ставлять собой как единственную константу, так и сколь угодно сложную конструкцию, однако в любом случае оно в конечном итоге дает единственное значение. При записи выражения отдельные его элементы соединяются знаками операций, обо- значающих те арифметические, логические или иные действия, которые должны быть вы- полнены над соответствующими операндами. При выполнении программы любое выраже- ние вычисляется до получения конечного результата, причем тип данных этого результата принимается как тип данных всего выражения. В зависимости от типа данных результата, выражения могут быть числовыми, строковыми, логическими, объектными и с типом даты. ЦВМ Помимо допустимых значений тех типов данных, речь о которых шла в предыдущей тгА главе, результатом вычисления выражения может быть одно из специальных значе- МИ ний, обозначаемых ключевыми словами Empty и Nul1. Значение Empty в языке VBA представляет неинициализированную переменную типа Variant; также это результат вычисления любого выражения, в котором принимает участие подобная неинициали- зированная переменная. Значение Null указывает, что эта переменная не содержит корректных данных.
Выражения в программе строятся для выполнения различных вычислений, построе- ния и сравнения значений, представления изменяемых величин. Они могут использовать- ся как для присвоения значения переменным, так и для передачи значений аргументов функциям и процедурам. Совместимость типов данных В предыдущей главе мы довольно подробно останавливались на описании тех типов данных, которые поддерживает VBA. Из сказанного очевидно, что не все типы данных вза- имно совместимы, и поэтому нельзя использовать несовместимые типы данных в одном выражении. При обработке выражения, содержащего различные типы данных, компи- лятор VBA сначала пробует самостоятельно устранить любое различие типов. Для этого он пытается преобразовать значения в выражении в совместимые типы данных, и только если не удается автоматически устранить различия в типах данных, компилятор VBA вы- дает ошибку несовпадения типов. Аналогичную ошибку — несовпадение типов — можно получить, если присваивать результат вычисления какого-нибудь выражения переменной, тип которой несовместим с типом этого результата. То же самое можно сказать о функции или о процедуре — ошибка несовпадения типов возникнет в том случае, если использо- вать результат вычисления неподходящего по типу выражения в качестве их аргумента. В языке VBA есть ряд встроенных функций, предназначенных для преобразования одних типов данных в другие (эти функции будут подробно рассмотрены в главе 9). Важно знать, что всегда, когда только это возможно, компилятор VBA автоматически конвертирует данные в подходящий тип. Если переменной целого типа присвоить значение с дробной частью, то компилятор VBA автоматически округлит это значение до ближайшего целого числа. В языке VBA многие типы данных совместимы, что позволяет использовать их в одном выражении — например, смешивать при вычислениях различные числовые типы данных. Компилятор VBA автоматически выполняет необходимые преобразования при использовании в выражении различных числовых типов. Автоматическое преобразование типов компилятор VBA выполняет гораздо быстрее, Ж. когда выражение содержит переменные типа Variant, поскольку переменная такого типа может хранить данные любого из допустимых в VBA типов, включая числовые зна- чения, строки, даты и объекты. Оператор присваивания Оператор — это наименьшая единица программного кода. Каждый (выполнимый) оператор содержит инструкцию, указывающую, какие именно манипуляции данными или изменения в ходе программы должны быть осуществлены при его выполнении. Оператор присваивания представляет собой связанную знаком равенства конструкцию, в которой значение выражения, находящегося справа, присваивается переменной, имя которой указано слева. Например, после выполнения следующей пары операторов переменной z будет присвоено значение а + Ь. х = а z = х + b Глава 5. Операции и выражения 87
Оператор присваивания допускается использовать и для манипуляции объектами. Однако если переменной присваивается значение ссылки на объект, то в операторе при- сваивания следует указать ключевое слово Set. Set objA = objB Здесь предполагается, что ob j А и ob j В были объявлены как переменные объектного типа и переменная ob j В в данный момент содержит ссылку на некоторый объект. В результате выполнения приведенного выше оператора переменной objA присваивается значение ссылки на тот же объект. Следует заметить, что если переменной с определенным типом данных присваивается результат вычисления некоторого выражения, тип данных этого результата должен совпа- дать с типом переменной, получающей новое значение. В противном случае компилятор VBA автоматически предпримет попытку преобразовать тип данных результата вычисле- ния выражения в тип, совместимый с типом указанной переменной. Арифметические операторы В языке VBA арифметические операторы позволяют выполнить любые арифметиче- ские операции в полном соответствии с правилами арифметики. В табл. 5.1 приведены знаки операций, которые в языке VBA могут использоваться при написании арифмети- ческих выражений. Таблица 5.1. Знаки арифметических операций, используемые в языке VBA Знак операции_________________Описание_____________________________________ + Сложение Вычитание * Умножение / Деление \ Деление без остатка Возведение в степень mod Остаток от деления по модулю Нет смысла подробно обсуждать здесь использование таких тривиальных знаков опера- ций, как или но несколько полезных замечаний все же следует сделать: знак операции сложения можно использовать при построении арифметических выражений с данными типа Date; если в операции сложения используются данные типа Integer и Long, результат вычисления выражения будет иметь тип данных Long; если в операции вычитания один из операндов имеет тип данных Date, то результат вычисления выражения будет иметь тип данных Date; если оба операнда в операции вычитания имеют тип данных Date, то результат вычисления выражения будет иметь тип данных Double; если в операции умножения используются данные различных типов, то результат вычисления выражения будет иметь тип данных, соответствующий типу данных того из сомножителей, который имеет наибольшую точность; 88 Часть 2. Основы программирования на VBA
при умножении значения переменных с типом данных Variant, содержащих в данный момент значения типа Date, последние будут преобразованы в числовые значения; если при выполнении деления делитель окажется равным нулю, будет выдано со- ответствующее сообщение об ошибке; для результата вычисления операции деления чисел с плавающей точкой обычно используется тип данных Double, а для чисел типа Integer — Single. Результатом операции деления без остатка будет целое число без округления, при этом дробная часть результата просто отбрасывается. Например, после вычисления выражения 17\5 получим 3. Тип данных результата операции деления без остатка — либо Integer, либо Long, при этом язык VBA использует наименьший тип данных, позволяющий пред- ставить значение вычисленного результата. Если в операции деления любого типа один из операндов имеет значение Null (отсутствие конкретного значения), то результатом операции также будет значение Null. И вообще, если в выражении присутствует переменная, имеющая значение Null, то результатом вычисления всего выражения также будет значение Null. Операция возведения в степень (А) предполагает возведение значения первого опе- ранда выражения в степень, равную значению второго операнда (например, выражение 5А4 означает “пять в четвертой степени” и после вычисления дает значение 625). При этом оба операнда должны быть либо числовыми выражениями, либо строками, которые компилятор VBA сможет преобразовать в числовое значение. Отрицательное число мо- жет быть возведено только в целочисленную степень. Результат операции возведения в степень всегда имеет тип Double, за исключением случая, когда один из операндов равен Null (здесь результатом возведения в степень также будет Null). При выполнении операции деления по модулю осуществляется деление первого операнда на второй, и в качестве результата возвращается целочисленный остаток этого деления. Если при выполнении операции Mod используются числа с плавающей точкой, они округляются до ближайших целых до выполнения операции. Тип данных результата операции деления по модулю может быть Integer или Long, при этом в каждом случае используется наименьший тип данных, который соответствует полученному результату. Логические операторы Логические операторы в языке VBA используются для манипулирования логическими значениями — True (в числовом представлении это 1) и False (в числовом представ- лении это 0). При выполнении этих операторов логическим переменным присваивается результат вычисления логических выражений, указанных в правой части операторов. О бычно результатом логических операций является значение типа Boolean. В табл. 5.2 кратко описаны логические операторы, поддерживаемые в языке VBA. В табл. 5.2 логический оператор And обозначает операцию конъюнкции, результатом выполнения которой будет значение True тогда и только тогда, когда оба операнда име- ют значение True. В остальных случаях результатом выполнения этой операции будет значение False. (3 > 2) And (3 > 6) And (4 > 3) (4 > 3) Глава 5. Операции и выражения 89
Таблица 5.2. Допустимые логические операторы языка VBA Оператор Описание And Or Not Хог Конъюнкция (Логическое И) Дизъюнкция (Логическое ИЛИ) Отрицание (Логическое НЕТ) Исключение (Логическое исключающее ИЛИ) Eqv Imp Логическая эквивалентность Логическая импликация Результатом вычисления первого выражения будет значение True, так как оба опе- ранда имеют значение True. Результатом вычисления второго выражения будет значение False, поскольку первый операнд имеет значение False. Логический оператор Or обозначает операцию дизъюнкции, результатом выполнения которой будет значение True, если хотя бы один из операндов имеет значение True. Результат будет иметь значение False тогда и только тогда, когда оба операнда имеют значение False. (3 > 5) Or (4 > 2) (2 > 3) Or (2 > 4) Результатом вычисления первого выражения будет значение True, так как один из операндов (второй) имеет значение True. Результат вычисления второго выражения будет иметь значение False, так как оба операнда имеют значение False. Логический оператор Not обозначает операцию логического отрицания и имеет только один операнд. Результатом выполнения этой операции будет значение True, если ис- ходно операнд имеет значение False, и, наоборот, результатом будет значение False, если операнд имеет значение True. D1 = ((2 > 5) Or (7 > 3)) And Not ((3 > 1) Or (8 < 10)) После вычисления приведенного выше выражения переменной D1 будет присвоено значение False, поскольку, хотя оба помещенные в скобки логические выражения Or имеют значения True, оператор Not превращает второе значение True в False, а значит, и результатом всего оператора And будет значение False. Логический оператор Хог обозначает логическую операцию “исключающее ИЛИ”, результатом выполнения которой будет значение True, если операнды имеют различные значения, и значение False, если оба операнда имеют одинаковые значения (оба — True или оба — False). D2 = ((2 > 5) Хог (7 > 3)) And ((3 > 1) Хог (8 < 10)) В приведенном выше примере переменной D2 буд^т присвоено значение False, по- скольку, хотя первый помещенный в скобки оператор Хог дает значение True, второй оператор Хог дает значение False, а значит, результатом всего оператора And будет зна- чение False. Логический оператор Eqv обозначает логическую операцию эквивалентности двух выражений, результатом выполнения которой будет значение True, если оба операнда имеют одинаковые значения (оба — True или оба — False), и значение False, если только один из операндов имеет значение False. 90 Часть 2. Основы программирования на VBA
Логический оператор Imp обозначает логическую операцию импликации (следования) двух выражений, результатом выполнения которой будет значение False, если первый операнд имеет значение True, а второй операнд имеет значение False, и значение True — во всех остальных случаях. Следует отметить, что логические операторы чаще всего используются в операторах сравнения. Операторы сравнения Операторы сравнения используются в языке VBA для сравнения числовых и строко- вых значений переменных, констант и результатов вычисления выражений. В результате выполнения операции сравнения всегда получается значение типа Boolean: либо True (Истина), либо False (Ложь). В табл. 5.3 описаны операторы сравнения, поддерживае- мые в языке VBA. Таблица 5.3. Операторы сравнения в языке VBA Оператор Описание = Равно > Больше Меньше >= Больше или равно о Меньше или равно Не равно Is Like Сравнение двух операндов, содержащих ссылки на объекты Сравнение двух строковых выражений Если в выражении оба операнда имеют один и тот же тип данных, в языке VBA выпол- няется простое сравнение для этого типа данных. Если один или оба операнда являются переменными типа Variant, то компилятор VBA преобразует тип Variant в какой-либо совместимый тип данных, иначе на экран будет выведено сообщение об ошибке времени выполнения. Знаки операции сравнения можно использовать как для чисел, так и для строковых значений. При сравнении строковых значений компилятор VBA последовательно срав- нивает отдельные символы слева направо, определяя старшинство в соответствии с алфа- витным порядком для букв и в соответствии с двоичным значением кода ASCII для любых прочих символов. В языке VBA при сравнении строк одна строка будет признана равной другой, если обе строки имеют одну и ту же длину и содержат одинаковые символы, рас- положенные в одинаковом порядке. Результатом такого сравнения будет значение True. Если же хоть одно из перечисленных условйй не будет выполнено, результатом сравнения строк будет значение False. Язык VBA предоставляет два способа сравнения символов различных регистров. Сравнение строк в двоичном режиме (метод сравнения по умолчанию). При сравне- нии строковой информации по этому методу для анализа используется действитель- ный двоичный эквивалент кода каждого символа. Буквы верхнего регистра имеют меньший двоичный код, чем буквы нижнего регистра. Например, для буквы “А” код символа верхнего регистра (А) меньше кода символа нижнего регистра (а). Глава 5. Операции и выражения 91
”а” > "A” True. Сравнение строк в текстовом режиме. Согласно этому методу сравнение строк будет выполняться по алфавиту, но без учета регистра букв. При сравнении в текстовом режиме строка “ASD” равна строке “asd”. Для того чтобы перейти в текстовый ре- жим сравнения, необходимо в начало модуля перед объявлениями переменных или процедур поместить оператор Option Compare Text, устанавливающий данный режим сравнения для этого модуля. Для сравнения выражений, содержащих ссылки на объекты, в языке VBA используется оператор сравнения Is. Результатом выполнения оператора Is является значение True, если оба выражения типа Object ссылаются на один и тот же объект, и значение False — в противном случае. objl Is obj2 Оператор Like позволяет сравнивать строку с заданным шаблоном (некоторым спе- циальным образцом) и может использоваться только для сравнения двух строковых выра- жений. С помощью оператора Like осуществляется поиск в тексте некоторого слова или фразы, отвечающих условиям, которые описаны заданным шаблоном. При этом оператор Like возвращает значение True, если в тексте присутствует слово или фраза, соответ- ствующие заданному шаблону, или значение False — в противном случае. Синтаксис оператора следующий. Strzapl Like Strzap2 Здесь strzapl — любое строковое выражение (сравниваемая строка, в которой выполняется поиск), a Strzap2 — комбинация специальных символов, определяющая шаблон для сравнения. Перечень допустимых символов шаблона с их кратким описанием приведен в табл. 5.4. Таблица 5.4. Специальные символы шаблона для оператора Like Символ шаблона Чему соответствует Одному любому символу ★ Любому количеству символов от 0 и больше # Любой цифре от 0 до 9 (List) Списку (List) определенных символов. Для обозначения диапазона исполь- зуется знак дефиса (-) (!List) Любому символу, не входящему в список (List) Результат сравнения в операторе Like прописных (верхний регистр) и строчных (нижний регистр) букв зависит от установленного режима Option Compare... . Если задано двоичное сравнение строк, то оператор Like различает буквы верхнего и нижнего регистров. Если установлен режим текстового сравнения, то оператор Like не реагирует на значение регистров. Строковые операторы В языке VBA для строковых значений поддерживается единственный оператор конка- тенации, выполняющий операцию слияния двух строк в одну. Для обозначения операции 92 Часть 2. Основы программирования на VBA
конкатенации используется знак “ & Результат операции конкатенации строк всегда имеет тип данных String. Например, рассмотрим результат выполнения следующего оператора. MyFIOString = "Иванов” & " " & "Иван" & " ” & "Иванович” Здесь в переменную MyFIOString будет помещена строка "Иванов Иван Иванович". (Обратите внимание: пробелы между словами в эту строку добавлены как отдельные операнды-строки.) Все возможные операции со строками подробно рассматриваются в главе 9. Если в операции конкатенации используются числовые операнды, то перед ее выпол- нением компилятор VBA автоматически преобразует числовые выражения в операндах в строки символов, соответствующие их текущему значению. Приоритеты выполнения операций Если выражение содержит больше одного оператора, то вычисление значения таких многоэлементных выражений регулируется правилами о приоритете выполнения опера- ций, принятыми в языке VBA. Приоритеты основных операторов представлены в табл. 5.5. Операторы, имеющие одинаковый приоритет, выполняются в выражении последователь- но, слева направо. Изменить стандартный порядок выполнения операций в выражениях языка VBA можно с помощью скобок. Таблица 5.5. Приоритеты операторов VBA Оператор Название Приоритет л Возведение в степень 1 *, / Умножение, деление 2 Деление без остатка 3 Mod Остаток 4 +. - Сложение, вычитание 5 & Слияние строк 6 Операторы с меньшим значением приоритета, согласно табл. 5.5, выполняются первы- ми. Рассмотрим следующий пример. 7 + 5*3 В данном примере сначала будет выполняться операция умножения, так как она имеет более высокий приоритет, а затем операция сложения, т.е. результат вычисления всего выражения будет равен 22. Следует также отметить, что если в сложных выражениях встречаются части выражений, заключенные в скобки, они всегда вычисляются в первую очередь, независимо от приоритета операторов. (7 + 5) * 3 В этом примере первой будет выполнена операция сложения, заключенная в скобки, а лишь затем операция умножения, т.е. результат вычисления всего выражения будет равен 3 6. В выражении можно использовать сколько угодно уровней скобок, но все они должны быть парными. Если скобки в выражении вложены одна в другую, то вычисления начина- ются с самого внутреннего уровня скобок. Глава 5. Операции и выражения 93
Резюме В этой главе мы продолжили изучение основных концепций языка VBA и ознакоми- лись с выражениями и различными типами операций, поддерживаемых в нем. Выраже- ния — это последовательность значений, соединенных знаками операций. При выполне- нии программы любое выражение вычисляется и приводится к единственному значению того или иного типа данных. При построении выражений значения соединяются знаками операций, набор которых задается всей совокупностью операторов, поддерживаемых в языке VBA, — арифметических, логических, строковых и операторов сравнения. Вы- ражения входят в состав любых выполнимых операторов языка VBA, простейшими из которых являются операторы присваивания. С их помощью результат вычисления вы- ражения помещается в указанную переменную. При этом очень важное значение имеет совместимость типов данных переменной и вычисленного выражения. Тестовые задания Ниже приведено несколько тестовых заданий, предназначенных для закрепления из- ложенного в этой главе материала. В каждом задании вам предлагается вопрос и несколь- ко вариантов ответа на него, один (или несколько) из которых является правильным, а остальные — нет. Укажите правильный ответ. 1. В языке VBA выражением является: а) последовательность символов, разделяемая пробелами и знаками операций; б) отдельное значение или несколько значений, соединенных знаками операций; в) последовательность операторов, ограниченная операторами Sub — End Sub; г) несколько переменных и/или констант, разделяемых знаками арифметических и логических операций. 2. Язык VBA поддерживает автоматическое преобразование следующих типов данных: a) Integer в Double; б) String в Object; в) Boolean в String; г) Byte в Date. 3. Язык VBA поддерживает следующие арифметические операторы: а) умножения; б) извлечения квадратного корня; в) взятия модуля числа; г) сложения; д) преобразования двоичного значения в десятичное. 4. Язык VBA поддерживает следующие строковые операторы: а) сложения; б) преобразования в двоичное значение; в) конкатенации; г) суммирования. 94 Часть 2. Основы программирования на VBA
5. В сложных выражениях операции выполняются по следующим правилам: а) согласно скобок, а если их нет — слева направо; б) сначала числовые, затем строковые и последними — логические; в) от простых к сложным; г) согласно приоритету операций, слева направо, с учетом скобок. Глава 5. Операции и выражения 95
Глава 6 Управляющие операторы В этой главе,,, ♦ Оператор перехода GoTo ♦ Оператор условного перехода If.. .Then ♦ Оператор Select Case ♦ Операторы циклов ♦ Резюме После запуска написанной вами программы интерпретатор языка VBA начинает выпол- нять ее шаг за шагом, оператор за оператором, от первого к последнему. Однако в некоторых случаях возникают такие ситуации, когда необходимо управлять последовательностью вы- полнения операторов программы — например, выполнить некоторую последовательность операторов несколько раз подряд либо пропустить некоторые операторы, не выполняя их, или же выбрать следующий выполняемый оператор в зависимости от некоторых условий. Для решения подобных проблем в языке VBA реализованы и широко используются управ- ляющие операторы — такие операторы программного кода, с помощью которых опреде- ляется порядок выполнения других операторов. Решение о том, какой именно оператор будет выполняться следующим, принимается исходя из результатов проверки некоторого условия непосредственно во время выполнения программного кода. К управляющим операторам относятся операторы условного перехода и операторы безу- словного перехода. Операторы условного перехода — это операторы, определяющие действи- тельную последовательность выполнения операторов программы на основе анализа одного или нескольких условий. В зависимости от того, какое значение (True или False) будет получено при проверке некоторого заданного условия, VBA определит в операторе услов- ного перехода, какую из ветвей программного кода надо выполнять. Оператор безусловного перехода — это оператор, который просто указывает программе следующий оператор, кото- рый должен быть выполнен после данного оператора безусловного перехода. Оператор перехода GoTo Оператор GoTo — это оператор безусловного перехода, который относится к группе операторов управления ходом выполнения программы. Оператор безусловного перехода всегда изменяет порядок выполнения операторов в программе — при этом VBA не про- веряет никаких условий, а просто переходит к дальнейшему выполнению программы с того места, которое будет указано в этом операторе. Оператор GoTo имеет следующий синтаксис. GoTo Labi
Здесь Labi — метка, определяющая оператор (или группу операторов), с которого будет продолжено выполнение программы. Метка — это любой допустимый идентификатор VBA, за которым обязательно должно следовать двоеточие. Программа, написанная на языке VBA, может содержать любое количество меток, однако оператор GoTo не может указывать на метку, находящуюся вне той процедуры, в которой он находится. Иначе говоря, метка, на которую ссылается оператор GoTo, должна быть обязательно расположена в той же процедуре, что и этот оператор. Sub Password() Пароль = InputBox("Введите ваш пароль") If Пароль о "ABC" Then GoTo Неверный_пароль MsgBox ("Добро пожаловать, АВС!") ’ - [Другие операторы] - Exit Sub Неверныи_пароль: MsgBox "Вы не можете работать на этой машине" . End Sub В начале выполнения этой процедуры на экран будет выведено диалоговое окно, в котором предлагается ввести пароль (рис. 6.1, а). Далее в этой процедуре используется оператор GoTo для перехода в особую ветвь программы, предназначенную для обработки ситуации, когда пользователь вводит неверный пароль (рис. 6.1, б). Если же пароль будет введен верно ("АВС"), то после вывода приветствия программа предоставит пользователю доступ к приложению для продолжения работы (рис. 6.1, в). Введите ваш пароль 2d I °* I Cancel | х| Вы не можете работать на этой машине Добро пожаловать, ABQ Рис. 6.1. Возможные результаты выполнения процедуры GoTo Глава 6. Управляющие операторы 97
Следует заметить, что оператор GoTo не пользуется “большой популярностью” у про- граммистов, поскольку его использование противоречит нормам структурного програм- мирования и потенциально может способствовать появлению ошибок в логике програм- мы. Поэтому оператор GoTo следует применять только в том случае, когда без него никак нельзя обойтись. Обычно в языке VBA оператор GoTo используется только при обработке ошибок. Оператор условного перехода If...Then Итак, мы уже знаем, что операторы условного перехода влияют на последовательность выполнения программы исходя из результатов проверки некоторых условий. В языке VBA имеются два условных оператора перехода — I f ...Then и Select Case. Оператор If...Then — один из важнейших управляющих операторов. Он организует выполнение заданного блока операторов, если при вычислении указанного условного вы- ражения будет получено значение True, и не делает ничего, если будет получено значение False. Синтаксис этого условного оператора следующий. If условие Then (операторы) Здесь условие — это условное выражение, которое VBA должен вычислить для проверки выполнения условия. Если вычисленное значение равно True, выполняется оператор (или блок операторов), следующий за ключевым словом Then, до конца строки. Если в операторе if...Then выполняется только один оператор, когда проверяемое условие принимает значение True, мы будем говорить об однострочном операторе. Такая конструкция If...Then записывается в одной строке, и завершающий оператор End If для нее не требуется. If intBospacT < 15 Then MsgBox ’’Ребенок" Однако в операторе I f ...Then может выполняться не только один оператор, но и блок последовательно следующих операторов. В этом случае проверяемое условие и выпол- няемые операторы записываются в отдельных строках. Если условное выражение имеет значение True, выполняемая группа операторов начинается с первого оператора, стоя- щего после ключевого слова Then, и включает все последующие операторы, вплоть до оператора завершения End I f. If условие Then (операторы) End If Таким образом, если в представленном примере значение условного выражения условие равно True, будет выполняться блок операторов (операторы), в противном случае выполнение программы продолжится начиная с оператора (если такие будут), сле- дующего за оператором End If. Для более сложных ситуаций, когда на основании некоторого условия необходимо выбрать одну из двух различных последовательностей операторов, используется опера- тор If...Then...Else. Как и оператор If...Then, конструкция lf...Then...Else может быть однострочной, и ее можно записать так. If intYron <= 90 Then MsgBox "Острый угол" Else MsgBox "Тупой угол" 98 Часть 2. Основы программирования на VBA
В этом выражении VBA сначала проверяет заданное условие If 1пЬУгол <= 90, и если результат будет равен True, выполняется оператор MsgBox, отображающий со- общение “Острый угол”. Если величина угла окажется больше 90 градусов (значение raise), то будет выполнен оператор MsgBox, следующий за ключевым словом Else и отображающий сообщение “Тупой угол”. Однострочный оператор lf...Then...Else не всегда удобен при написании программы, поэтому лучше воспользоваться блочным оператором lf...Then...Else, в котором условие и операторы записываются в отдельных строках. В этом случае синтаксис оператора ! f...Then...Else следующий. If условие Then (операторы!) Else (опера торы2) End If Здесь условие — это проверяемое условное выражение. Если значение этого условного выражения равно True, то VBA выполняет операторы блока (операторы!), а затем, пропустив все остальные операторы структуры lf...Then...Else, переходит к строке, следующей за оператором End If. Если значение условного выражения равно False, выполняются операторы блока (операторы2), расположенные после ключевого слова Else, вплоть до оператора End If. После этого VBA продолжит выполнение программы начиная с первого оператора, следующего за оператором End If. Sub Возраст () If intBospacT <= 7 Then MsgBox "Дошкольник" Else MsgBox "Школьник или взрослый" End If End Sub Часто при написании программ возникают такие ситуации, когда приходится прове- рять не одно, а два или больше условий. В этом случае можно поместить один оператор I f... Then внутри другого оператора I f ...Then (или оператор I f ...Then...Else внутри оператора lf...Then...Else), что называется вложением операторов. Вложенные операторы следует использовать тогда, когда для принятия решения необходимо проверить дополнительное условие, но при этом первое условие должно оказаться истинным. Если же первое условие не выполнено, то будут выполняться операторы, следующие за ключевым словом Else. Sub Возраст1() intBospacT = InputBox("Укажите возраст") If intBospacT > 7 Then If intBospacT <= 17 Then MsgBox "Школьник" Else MsgBox "Взрослый" End If Else MsgBox "Дошкольник" End If End Sub Глава 6. Управляющие операторы 99
Эквивалентом вложенных операторов является оператор lf...Then...Elself, в кото- ром используется ключевое слово Elsel f. С помощью ключевого слова Else If в одном условном операторе можно проверить несколько условий. Синтаксис этого условного оператора выглядит следующим образом. If условие 1 Then (операторы!) Elself условие2 Then (операторы2) Elself условие3 Then (операторыЗ) Else ’Это необязательный элемент конструкции (операторы!!) End If При выполнении оператора lf...Then...ElseIf первым проверяется значение услов- ного выражения условие!, и если оно равно True, то выполняется блок операторов (операторы!) (между ключевыми словами Then и Elself), а затем все остальные опе- раторы структуры пропускаются и выполняется первый из операторов, следующих за опе- ратором End If. Если значение условного выражения условие! будет равно False, то проверяется значение условие2. Если значение условие2 будет равно True, то выпол- няется блок операторов (опера торы2), а затем все остальные операторы структуры про- пускаются и выполняется первый из операторов, следующих за оператором End If. Если значение условие2 будет равно False, то проверяется значение условие3 — и т.д. Если в конструкцию оператора lf...Then...ElseIf включен оператор Else и все условные вы- ражения условие!, условие2,... окажутся равны False, то будут выполнены операторы, расположенные после оператора Else, и только после этого — первый из операторов, рас- положенных после оператора End If. Ключевое слово Else является необязательным, но если оно все же присутствует, то должно быть записано в конструкции оператора последним. Sub Возраст2() intBoapacT = InputBox("Укажите возраст") If intBoapacT < 7 Then MsgBox "Дошкольник" Elself intBoapacT < 17 Then MsgBox "Школьник" Elself intBoapacT < 23 Then MsgBox "Студент" Elself intBoapacT < 55 Then MsgBox "Специалист" Else MsgBox "Пенсионер" End If End Sub Из приведенной выше процедуры видно, что ключевое слово Elself может повто- ряться в конструкции сколько угодно раз. При этом выполнение заданных условий про- веряется строго последовательно, в том порядке, в каком они записаны. И как только истинное условие (True) будет найдено, выполняется соответствующий ему блок опера- торов, после чего выполнение данного условного оператора прекращается. 100 Часть 2. Основы программирования на VBA
Если в окне программного кода вы наберете эту процедуру и запустите ее, то вначале, при выполнении этой процедуры, на экран будет выведено диалоговое окно (рис. 6.2, а), в кото- ром предлагается ввести ваш возраст. Затем, в зависимости от введенного вами значения, на экран будет выведено диалоговое окно с одним из пяти возможных сообщений (рис. 6.2, б-е). а) б) г) е) Рис. 6.2. Возможные результаты выполнения процедуры с использованием конструкции оператора If...Then...ElseIf Глава 6. Управляющие операторы 101
Оператор Select Case Кроме рассмотренных выше условных операторов, в языке VBA имеется еще один условный оператор перехода Select Case. Этот условный оператор используется в том случае, когда необходимо проверять одно и то же значение, сравнивая его с различны- ми выражениями. После исходного оператора Select Case за проверяемым значением может следовать произвольное количество операторов проверки условия Case, причем в каждом из них проверяется выполнение различных условий. В любом случае выполня- ется либо только одна из ветвей Case (та, в которой было обнаружено первое истинное условие), либо ни одной (если все условия оказались не выполненными). После каждого оператора проверки условия Case можно записывать любое количество выполняемых операторов. Если выполняется только один оператор, то он записывается в одной строке с оператором Case. Общий синтаксис оператора Select Case будет таким. Select Case значение Case условие! (операторы!) Case условие2 (операторы2) Case условиеЫ (операторы!!) Case Else ’ Это необязательный оператор конструкции (операторы_else) End Select Сначала вычисляется выражение значение, которое может быть любым числовым или строковым выражением, а затем полученный результат сравнивается с каждым из условий в операторах Case, начиная с первого условие!. Если результат вычисления выражения значение совпадает со значением выражения условие!, будут выполнены операторы блока (операторы!), после чего выполнение программы продолжится начи- ная с оператора, следующего за оператором End Select. Если результат вычисления вы- ражения значение не совпадает ни с одним из значений выражений, начиная с выраже- ния условие! и заканчивая выражением условиеЫ, то будет выполнен блок операторов операторы_е1ге, следующий за ключевым словом Case Else. Оператор Case Else всегда находится в конце конструкции Select Сазеине является обязательным — он и соответствующий ему блок операторов операторы_е!ге могут быть опущены. Следует заметить, что в каждом операторе Case выражение условие можно предста- вить следующим образом. Любое выражение (числовое, строковое или логическое). В этом случае результат вычисления выражения значение должен в точности совпадать с результатом вы- числения значения выражения условие. Выражение, задающее диапазон значений. В этом случае указываются граничные зна- чения диапазона, разделяемые ключевым словом То. Например, запись 10 То 20 означает, что проверяемое выражение должно попасть в диапазон чисел от 10 до 2 0. Конструкция с ключевым словом Is, помещенным перед оператором сравнения. После оператора сравнения записывается то выражение, со значением которого проводится сравнение. Например: Is > 20. 102 Часть 2. Основы программирования на VBA
В одном операторе Case можно указать несколько выражений условие, которые в этом случае разделяются запятыми. Case 1 То 10, 15, Is > 30 В листинге 6.1 приведен пример использования оператора Select Case, построен- ного без применения ключевого слова Case Else. Листинг 6.1. Пример использования оператора Case Else Sub SelectCaseO Dim a As Single a = InputBox("Введите ваш рост в сантиметрах") Select Case а Case Is < 150 MsgBox "У вас очень маленький рост" Case 151 То 178 MsgBox "Вы человек среднего роста" Case Is > 178 MsgBox "Вы высокий человек" End Select End Sub При выполнении этой процедуры на экран будет выведено диалоговое окно, в котором предлагается ввести ваш рост в сантиметрах (рис. 6.3). Рис. 6.3. Окно запроса, выводимое при выполнении процедуры Select Case В зависимости от введенного вами числового значения, на экран будет выведено диа- логовое окно с одним из трех возможных сообщений (рис. 6.4, а—в). Рис. 6.4. Возможные результаты выполнения процедуры Select Case Глава 6. Управляющие операторы 103
Операторы циклов Цикл — это фундаментальный компонент любого языка программирования (в том числе и VBA). Под циклом мы будем понимать такой оператор или последовательность операторов, которые по ходу выполнения программы могут при необходимости выпол- няться многократно. Для организации циклов язык VBA предоставляет несколько мощ- ных и гибких структур, называемых структурами организации циклов. Некоторые из этих структур цикла построены таким образом, что всегда выполняются заданное количество раз. К таким структурам можно отнести операторы For...Next и For...Each...Next. Другие циклические структуры повторяются переменное количество раз, в зависимости от вы- полнения некоторого условия. К таким структурам относится оператор Do...Loop. Оператор For...Next Оператор For...Next относится к операторам создания циклов простейшего типа и является одним из самых распространенных видов цикла, реализованных практически в любом языке программирования. В программе на языке VBA с его помощью блок опе- раторов выполняется заданное количество раз, известное до начала выполнения цикла. Синтаксис оператора For...Next имеет следующий вид: For счетчик = начало То конец [Step шаг] (операторы) Next счетчик Здесь счетчик — любая числовая переменная, в которой сохраняется информация о количестве выполненных проходов цикла (счетчик цикла). Параметры начало и конец — это числовые выражения, задающие начальное и конечное значения счетчика и определяющие количество проходов цикла. Числовая переменная шаг задает приращение, на которое увеличивается счетчик цикла при каждом проходе. Вся фраза с ключевым словом Step необязательна. При ее отсутствии интерпретатор VBA (по умолчанию) увеличивает переменную счетчик на единицу при каждом выполнении блока операторов цикла. При необходимости изменить этот стандартный шаг следует использовать фразу Step шаг, где шаг — это любое числовое выражение, определяющее приращение, которое будет использоваться для изменения переменной счетчик. В операторе Next счетчик, завершающем цикл For...Next, имя переменной счетчик указывать необязательно, так как при обнаружении ключевого слова Next VBA автоматически вычисляет следующее значение переменной счетчик и возвращает управление в начало конструкции. Старайтесь всегда указывать имя переменной счетчик в операторе Next, так как при этом значительно улучшается читабельность программы и в случае нескольких вложенных циклов For...Next сразу видно, какому именно циклу принадлежит данный оператор Next. Теперь разберем пошаговую процедуру выполнения оператора For...Next. 1. Переменной счетчик присваивается значение параметра начало. 2. Выполняются все операторы, входящие в блок, обозначенный как (операторы), вплоть до ключевого слова Next. 3. Значение переменной счетчик увеличивается на величину, заданную в фразе Step шаг, или на 1, если фраза Step не указана. 104 Часть 2. Основы программирования на VBA
4. Управление возвращается в начало цикла, и выполнение программы продолжается со сравнения текущего значения переменной счетчик со значением параметра конец. Если значение счетчика меньше или равно значению параметра конца цикла, то выполнение программы будет продолжено с п. 2. Если значение переменной счетчик окажется больше значения параметра конец, программа продолжит свое выполнение с оператора, следующего за оператором Next. Рассмотрим конкретный пример. Приведенная в листинге 6.2 программа выводит на экран окно сообщения со строкой нечетных чисел. Листинг 6.2. Пример программы с циклом For... Next Sub NnumberO Dim AddNNum As String For a = 1 To 21 Step 2 AddNNum = AddNNum & a & • ” ” Next a MsgBox ’’Это последовательность нечетных чисел:’’ & _ Chr(13) & AddNNum End Sub Данный цикл создает строку нечетных чисел в диапазоне от 1 до 21 (значения параметров начала и конца цикла). Вывод именно нечетных чисел достигается вы- бором шага, равного 2, — это значение указано после ключевого слова Step и, сле- довательно, на эту величину увеличивается переменная а при каждом проходе цикла. В рассмотренном примере значение переменной а всегда будет нечетным, потому что ее начальное значение 1. Следует также заметить, что числовое значение во фразе Step может быть дробным, т.е. приращение значения счетчика цикла не обязательно должно быть целым числом. Однако в этом случае переменная счетчика цикла должна иметь тип с плавающей точкой. Пример подобного цикла приведен в листинге 6.3. Эта программа строит таблицу перевода дюймов в сантиметры и выводит ее в окне сообщения (рис. 6.5). Листинг 6.3. Пример цикла с дробным значением приращения счетчика Sub PNnumber() Dim AddNNum As String Dim a As Single b = 0 For a = 2.51 To 14 Step 2.51 b = b + 1 AddNNum = AddNNum & b a & ” cm’’ & Chr(13) Next a MsgBox ’’Таблица перевода дюймов в сантиметры:’’ & _ Chr(13) & AddNNum End Sub Глава 6. Управляющие операторы 105
Таблица перевода дюймов в сантиметры: 1" = 2,51 см 2" = 5,02 см 3" = 7,53 см 4” = 10,04 см 5" = 12,55 см Рис. 6.5. Использование цикла с дробным приращением для построения таблицы перевода дюймов в сантиметры Следует также заметить, что наряду с использованием цикла For...Next с возрастаю- щим счетчиком можно (а другой раз и весьма полезно) записывать такой цикл с убываю- щим значением счетчика. Для того чтобы счетчик не возрастал, а убывал, нужно в фразе Step указать для шага приращения отрицательное значение. В этом случае значение параметра начало должно быть больше, чем значение параметра конец, и цикл прекра- тится, когда значение переменной счетчик станет меньше значения параметра конец. Помните, что цикл For...Next при уменьшении счетчика цикла будет выполняться до тех пор, пока значение счетчика будет больше значения параметра конец или равно ему. Если же счетчик цикла увеличивается, то цикл Fo г ...Nex t будет выполняться, пока зна- чение счетчика будет меньше значения параметра конец или равно ему. Циклы For...Next в одной и той же процедуре можно использовать сколько угодно раз, при этом, подобно другим операторам циклов языка VBA, циклы For...Next можно вкладывать один в другой. Следует отметить, что циклы For...Next особенно полезны при работе с массивами. С помощью цикла For...Next совсем не сложно заполнить массив множеством вычисленных значений. Ниже приведен пример, где два вложенных цикла используются для присвоения значения 2 каждому элементу двухмерного массива размер- ностью 5x5. После выполнения этой процедуры все элементы массива будут равны 2. Sub ВложЦиклы() Dim А(1 То 5, 1 То 5) (операторы1) For х = 1 То 5 For у = 1 То 5 А(х, у) = 2 Next у Next х (операторы2) цикла End Sub ' Объявление массива ' Операторы, выполняемые до начала цикла ' Цикл 1 - по строкам ' Цикл 2 - по ячейкам строки ' Ячейка заполнена ' Конец заполнения строки ' Операторы, выполняемые после завершения Иногда в программе по тем или иным причинам может потребоваться немедленно пре- кратить выполнение цикла For...Next еще до того, как значение переменной счетчик до- стигнет заданного конечного значения. Для этой цели предназначен оператор Exit For. В цикле этот оператор обычно указывается в одной из ветвей выполнения условного опе- 106 Часть 2. Основы программирования на VBA
ратора If...Then или Select Case, вложенного в цикл For...Next. В одном цикле может быть записано любое количество операторов Exit For, выполнение цикла немедленно прекратится, как только будет выполнен хотя бы один из них, и программа перейдет к выполнению операторов, расположенных в тексте после данного цикла. Очень удобно использовать оператор Exit For при проверке массивов на наличие в них недопустимых значений — если в массиве обнаружены неправильные данные, выполнение цикла про- верки досрочно завершается. Оператор For Each...Next В отличие от цикла For...Next, цикл For Each...Next не использует счетчика циклов. Цикл For Each...Next применяет заданный в нем блок операторов по отношению ко всем объектам некоторой коллекции (подробно о коллекциях будем говорить в главе 8). Синтаксис оператора For Each...Next следующий. For Each элемент In группа (операторы) Next элемент Переменная элемент используется для итерации по всем членам коллекции. Параметр группа — это имя коллекции, с которой предстоит работать. Это имя может задавать либо объект коллекции, либо массив. Если параметр группа определяет объект коллекции, то переменная элемент должна быть объявлена с типом Variant, Object или с конкретным объектным типом, совпадающим с типом коллекции. Если же параметр группа опреде- ляет массив, то переменная элемент должна быть объявлена с типом Variant. В примере, показанном в листинге 6.4, с помощью цикла For Each...Next обрабатывается коллекция объектов класса Employee (Работник), содержащих сведения о сотрудниках некоторой фирмы. Если свойство Status объекта имеет значение “Уволен”, этот объект удаляет- ся. Иначе говоря, конструкция I f ...Then используется для нахождения объектов класса Employee с отметкой “Уволен” среди всех объектов этого класса, помещенных в коллек- цию Employees. После того как такой объект найден, он удаляется и выполнение цикла продолжается, пока не будет обработана вся коллекция. Листинг 6.4. Пример использования цикла For Each...Next Dim Employees As New Colection ' Объявление коллекции объектов Dim objA As Employee ' Объявление переменной объектного типа For Each objA In Employees If objA.Status = "Уволен" objA.Delete End If Next objA Использование оператора прерывания цикла Exit For в конструкции For Each... Next ничем не отличается от использования этого оператора в конструкции For...Next. Если в цикл из листинга 6.4 после оператора objA. Delete включить оператор Exit For, то выполнение цикла завершится после обнаружения первого же уволенного работника. Глава 6. Управляющие операторы 107
Цикл Do...Loop Существует несколько видов операторов циклов типа Do...Loop. Операторы циклов Do...Loop (в отличие от операторов For...Next) выполняются не заданное количество раз, а сколь угодно долго — до тех пор, пока не будет выполнено некоторое логическое усло- вие. Язык VBA включает несколько вариантов организации такого цикла. В первом варианте логическое условие проверяется до начала выполнения цикла. В этом случае после оператора цикла Do записывается ключевое слово While (Пока), и цикл имеет следующий синтаксис. Do While условие (операторы) Loop При выполнении программы, обнаружив оператор Do While, VBA прежде всего про- веряет текущее значение логического выражения условие. Если вычисленное значение выражения условие равно True, VBA выполняет блок (операторы) и, достигнув опе- ратора Loop, опять возвращается к оператору Do While, чтобы вновь проверить условие цикла. Если вычисленное значение выражения условие равно False, VBA игнорирует все операторы внутри цикла и сразу переходит к выполнению оператора, следующего за оператором Loop. Еще одной формой записи оператора, проверяющего значение логического условия до выполнения цикла, является оператор Do Until со следующим синтаксисом. Do Until условие (операторы) Loop При выполнении цикла Do Until VBA сначала проверяет текущее значение логиче- ского выражения условие и, если оно равно False, выполняет блок (опера торы), пока не будет достигнут оператор Loop. Далее управление опять возвращается к оператору Do Until и значение выражения условие проверяется вновь. Если вычисленное значение будет равно True, VBA игнорирует операторы внутри цикла и переходит к выполнению оператора, следующего за оператором Loop. Легко заметить, что в обоих случаях цикл в программе может оказаться ни разу не выполненным, если первая же проверка условия даст результат, при котором цикл вы- полнять не следует. Учитывайте это при выборе типа цикла, используемого в каждом конкретном случае. Во втором варианте цикла Do...Loop логическое условие проверяется в конце тела цикла после того, как он будет пройден хотя бы один раз. В этом случае анализируемое логическое выражение записывается после ключевого слова в операторе Loop с помощью конструкции While условие. Его синтаксис таков. Do (операторы) Loop While условие В конструкции Do...Loop While цикл всегда выполняется по крайней мере один раз. Сначала программа проходит весь блок операторов, а затем вычисляет текущее значение логического выражения условие. Если оно равно True, VBA повторяет выполнение опе- 108 Часть 2. Основы программирования на VBA
раторов цикла, если нет — продолжает выполнение программы с оператора, следующего за строкой Loop While условие. В этом варианте цикла можно также использовать конструкцию Do...Loop Until. Рассмотрим ее синтаксис. Do (операторы) Loop Until условие В этом случае (как и в предыдущем) программа сначала проходит весь блок операторов и лишь затем вычисляет текущее значение логического выражения условие. Если оно равно False, VBA выполняет цикл еще раз, а если True — VBA продолжит выполнение программы с оператора, следующего за строкой Loop Until условие. Из сказанного выше вполне очевидно, что во всех перечисленных вариантах построе- ния цикла значение логического выражения условие автоматически вычисляется и про- веряется либо в начале, либо в конце цикла. Для того чтобы проверить некоторое условие внутри цикла, можно использовать оператор Do...Loop, но без указания фразы While... или Until...; при этом потребуется вложить в цикл либо оператор If, либо Select Case, одна из ветвей которого будет включать оператор принудительного завершения цикла Exit Do. Циклы такого типа могут содержать и несколько операторов Exit Do — про- грамма завершит выполнение цикла при достижении любого из них. Вот пример синтак- сиса подобного оператора цикла. Do (операторы!) If условие Then Exit Do End If (опера торы2) Loop В этом примере блок (операторы!) в цикле будет выполняться всегда, независимо от выполнения или невыполнения условия завершения цикла, тогда как блок (опера торы2) будет выполнен только в случае, если выражение условие имеет значение False. Теперь рассмотрим на примере (листинг 6.5) цикл Do...Loop, используемый пользователем для ввода данных и проверки их правильности. Листинг 6.5. Пример использования цикла с проверкой условия выхода внутри цикла Sub DoLoopO Dim Kat As String Kat = InputBox("Введите значения для категории (от 1 до 3)") Do If Kat = ’’” Then Kat = InputBox (’’Значение категории не может быть пусто.’’ _ & Chr(13) & ’’Введите правильное значение (от 1 до 3)’’) Elself Len(Kat) > 1 Then Kat = InputBox (’’Значение категории задается одной цифрой. ’’ _ & Chr(13) & ’’Введите правильное значение (от 1 до 3)’’) Elself Kat < 1 Or Kat > 3 Then Глава 6. Управляющие операторы 109
Kat = InputBox (’’Ошибка. Неверное значение” _ & Chr(13) & "Введите правильное значение (от 1 до 3)’’) Else Exit Do ’ Введено правильное значение. Выход из цикла End If Loop End Sub При выполнении этой процедуры на экран будет выведено диалоговое окно, в котором предлагается ввести значение категории работника (рис. 6.6). Рис. 6.6. Окно запроса, выводимое при выполне- нии процедуры DoLoop Следует отметить, что в этой процедуре цикл Do...Loop будет повторяться до тех пор, пока пользователь не введет правильное значение категории работника (она может быть равна либо 1, либо 2, либо 3). В противном случае на экран будет выведено одно из сле- дующих предусмотренных в процедуре сообщений (рис. 6.7, а-в). а) Ошибка. Неверное значение I ок | Введите правильное значение (от 1 до 3) ’ ’.* Cancel I б) в) Рис. 6.7. Возможные сообщения при обнару- жении неправильно введенной информации 110 Часть 2. Основы программирования на VBA
Резюме В этой главе был представлен важнейший класс операторов языка VBA, которые управляют операторами, предназначенными для изменения строго последовательного хода выполнения программы. Были подробно рассмотрены все четыре типа управляющих операторов языка VBA: оператор безусловного перехода GoTo, оператор условного пере- хода If...Then, оператор выбора Select...Case и различные варианты операторов циклов, к которым в языке VBA относятся операторы For...Next и Do...Loop. Каким образом и для чего могут использоваться управляющие операторы различных типов, было показано на конкретных примерах. Тестовые задания Ниже приведено несколько тестовых заданий, предназначенных для закрепления из- ложенного в этой главе материала. В каждом задании вам предлагается вопрос и несколь- ко вариантов ответа на него, один (или несколько) из которых является правильным, а остальные — нет. Укажите правильный ответ. 1. Метка в операторе безусловного перехода GoTo определяет: а) имя процедуры, к которой принадлежит данный оператор; б) оператор, с которого будет продолжено выполнение программы; в) оператор, который должен быть выполнен перед данным оператором; г) имя процедуры, которой должно быть передано управление. 2. Если исходно значение переменной а было равно 5, а переменной ь — 3, то какое значение будет иметь переменная а после выполнения оператора: If (а - Ь) >0 Then а = а - b Else а = а + Ь а) 2; б) 8; в) 5; оператор содержит ошибку, и программа не сможет его выполнить. 3. Если значение переменной а равно 8, то какой из операторов будет выполнен по- сле выполнения оператора: Select Case а Case 5 b = 1 Case 3 To 15 b = 2 Case Is >5 b = 3 Case 2, 4, 6, 8, 10 b = 4 End Select a)b = 1; 6)b = 2; Глава 6. Управляющие операторы 111
в) b = 3; г) b = 4; д) оператор, следующий после оператора End Select; е) оператор содержит ошибку, и программа не сможет его выполнить. 4. Сколько раз будет выполнен оператор а = а + 1 при выполнении следующего цикла: Dim i As Single For i=10,3 To 1.23 Step -1.18 a = a + 1 Next i a) 10; 6)9; b)8; r)7; д) ни одного. 5. Какой тип цикла следует использовать, чтобы операторы в теле цикла были вы- полнены хотя бы один раз: a) Do While ... Loop; б) Do ... Loop While; в) Do Until ... Loop; r) Do ... Loop Until. 112 Часть 2. Основы программирования на VBA
Глава 7 Процедуры и функции В этой главе... ♦ Основные понятия о процедурах VBA ♦ Аргументы процедур ♦ Выполнение процедур ♦ Функции языка VBA ♦ Ошибки выполнения ♦ Резюме В начале этой книги мы уже встречались с примерами процедур и функций в языке VBA. Хочу напомнить, что процедура — это сохраняемая в модуле VBA компьютерная про- грамма, которая имеет собственное имя и представляет собой некоторую последователь- ность операторов, выполняющих определенные действия с теми или иными объектами. Обычно программный код VBA организуется в виде совокупности процедур, каждая из которых предназначена для решения определенной задачи. Наряду с процедурами, в язы- ке VBA также могут быть созданы и собственные функции, которые затем будут исполь- зоваться в процедурах. Очень важно четко представлять себе разницу между процедурой и функцией — в отличие от процедуры, функция, оперируя одним или несколькими ис- ходными значениями, всегда возвращает единственное результирующее значение, которое при выполнении программы подставляется в то самое место, где было указано имя функ- ции. Все эти вопросы будут подробно рассмотрены в данной главе. Основные понятия о процедурах VBA Дополняя приведенное выше определение, можно также сказать, что процедура — это наименьшая единица программного кода, которая содержит операторы программ VBA. Любая написанная процедура сохраняется в модуле VBA, который, в свою очередь, может содержать любое количество процедур. Доступ к процедуре (например, для ее выполне- ния) можно получить с помощью редактора VBA, воспользовавшись одним из предлагае- мых им способов вызова процедур (подробно об этом будет сказано ниже). В языке VBA существует несколько типов процедур. Процедура типа Sub (процедура-подпрограмма) — это часть программы, которая может выполняться независимо; при этом одна процедура типа Sub может вызы- вать другую. Процедура типа Function (процедура-функция) — этот класс процедур отли- чается от прочих тем, что в результате выполнения функции всегда вычисляется
единственное возвращаемое значение, которое присваивается переменной с име- нем данной функции. Процедура типа Property (процедура свойств) используется для доступа к свой- ствам объекта определенного пользователем класса. Подробно процедуры свойств будут рассматриваться в главе 9. Процедура обработки события (event procedure) — это процедура специально- го назначения, которая выполняется при возникновении некоторого события. Приступая к написанию новой процедуры, потребуется либо создать в редакторе VBA новый модуль, который будет содержать эту процедуру, либо добавить эту процедуру в уже существующий модуль (подробно об этом читайте в разделе “Написание новых макро- сов и процедур” в главе 3). Каждая процедура содержит один или несколько операторов, помещенных между двумя специальными операторами — оператором объявления про- цедуры (например, Sub) и оператором End. Текст процедуры начинается с ее объявления с помощью оператора Sub, Function, Property или Event, определяющего имя про- цедуры и список ее параметров. Синтаксис процедуры типа Sub следующий. Sub Имя [(аргументы) ] ... (операторы) End Sub Здесь Sub — обязательное ключевое слово, указывающее на начало процедуры- подпрограммы. Имя — это уникальное имя процедуры, составленное согласно правилам языка VBA. Список аргументов аргументы— это необязательный параметр, заключенный в круглые скобки. Он представляет собой перечень входных данных (аргументов), передаваемых процедуре. Если в процедуре используется несколько аргументов, то между собой они разделяются запятыми. Если же аргументы у процедуры отсутствуют, то после имени процедуры ставится пустая пара скобок. В конце процедуры обязательно должен присутствовать оператор End Sub, указывающий компилятору VBA на необходимость прекращения выполнения ее программного кода. Как и переменные, процедуры имеют определенную область действия, в пределах которой данную процедуру можно вызвать из других программ (процедур). Область дей- ствия каждой процедуры определяется указанием при ее объявлении соответствующих ключевых слов — Private или Public. При этом можно выделить три типа области действия процедур. 1. Процедура, объявленная с помощью ключевого слова Private, доступна для всех процедур в данном модуле и недоступна процедурам, находящимся в других модулях. Private Sub Имя [(аргументы)] (операторы) End Sub 2. Процедура, объявленная с помощью ключевого слова Public, доступна для всех модулей во всех проектах. Эта область действия процедуры принята по умолчанию, поэтому ключевое слово Public использовать при объявлении процедуры не обя- зательно. Public Sub Имя [(аргументы) ] (операторы) End Sub 114 Часть 2. Основы программирования на VBA
3. При наличии в модуле оператора Option Private Module процедуры, объявлен- ные с использованием ключевого слова Public, будут доступны всем программам данного проекта и недоступны для других проектов. В пределах процедуры переменные можно создавать без всяких ограничений. В гла- ве 4 в разделе “Присвоение имени и объявление переменных” мы уже говорили о том, что переменная, объявленная в процедуре, будет доступна только в пределах этой про- цедуры. Такие переменные называются локальными — они заново создаются при каждом вызове процедуры и уничтожаются по завершении ее работы. Однако может возникнуть ситуация, когда переменная должна сохранять свое значение и между двумя вызовами процедуры. В этом случае при ее объявлении вместо ключевого слова Dim следует ука- зать ключевое слово Static, которое специально предназначено для определения по- добных переменных, называемых статическими. Если указать ключевое слово Static непосредственно при объявлении процедуры, то все переменные этой процедуры будут статическими, поэтому значения этих переменных будут сохраняться и после завершения выполнения процедуры. Static Sub Имя [(аргументы)] (операторы) End Sub Аргументы процедур Аргументы процедуры — это элементы данных, передаваемые процедуре при ее вызове и используемые ею при выполнении. При объявлении процедуры аргументы указываются в виде списка аргументов. Этот список заключается в скобки и записывается непосред- ственно после имени процедуры, причем отдельные элементы списка отделяются запя- тыми. Для каждого из аргументов указывается его имя и тип данных, записываемый после ключевого слова As. (Аргумент! f Аргумент2 As type,...) Тип аргумента может быть любым стандартным типом языка VBA или объявленным классом. Если указано только имя аргумента без указания его типа, то VBA приписывает такому аргументу тип Variant. В языке VBA процедура может иметь и переменное число аргументов. Для создания процедуры с переменным числом аргументов используется ключевое слово ParamArray, определяющее массив, который будет содержать необходимое количество значений- аргументов. Ключевое слово ParamArray указывается в объявлении процедуры только один раз и обязательно для того аргумента, который в списке стоит последним. В этом случае тип аргументов не указывается, так как соответствующий массив всегда должен иметь тип Variant. Рассмотрим пример. Sub А (В As Integer, ParamArray СО) End Sub В этом примере процедуре А при каждом вызове может передаваться переменное коли- чество аргументов, но не менее одного — параметр В, целого типа, должен присутствовать обязательно. Остальные аргументы передаются как элементы массива С, которых в каж- дом конкретном случае может быть произвольное количество. Глава 7. Процедуры и функции 115
Аргументы процедуры могут быть обязательными или необязательными, причем допу- стима и такая ситуация, когда все аргументы процедуры будут необязательными. Необя- зательный аргумент можно передавать при вызове процедуры, а можно и опускать. Если аргумент необязателен, то для него задается значение, принимаемое по умолчанию. Оно передается процедуре, если при ее вызове данный аргумент будет опущен. Для указания того, что аргумент является необязательным, используется ключевое слово Optional. Optional Аргумент As type = defaultvalue Здесь defaultvalue — это значение данного аргумента, которое будет использоваться по умолчанию. Все необязательные аргументы должны указываться после обязательных, те. в конце списка аргументов. Следует отметить, что ключевые слова ParamArray и Optional взаимоисключающие — в списке параметров может присутствовать только одно из этих ключевых слов. Передача аргументов при вызове процедуры Процедура может иметь аргументы или не иметь их. Однако если у процедуры есть аргу- менты, то при вызове такой процедуры на выполнение они будут обязательно запрашивать- ся. Это означает, что в операторе, вызывающем процедуру, также должен быть задан соот- ветствующий список аргументов, разделенных запятыми, причем передаваемые значения в этом случае должны быть указаны в том же порядке, что и при объявлении процедуры. В качестве значений аргументов при вызове процедур могут использоваться переменные, константы, символьные строки, массивы и объекты. Ниже приведен пример объявления процедуры А и несколько операторов вызова этой процедуры из тела другой процедуры — W. Sub А(В As Integer, С As String) End Sub Sub W() Dim E As Integer, F As String Call A(E, "Value") Call A(12, F) Call A(E, F) End Sub Для предыдущего примера следует дать некоторые дополнительные пояснения. Для со- К. крашения объема листингов в приводимых в этой книге примерах часто дается не пол- “ ный текст программы, а лишь отдельные ее фрагменты, которые важны для понима- ния излагаемого материала, а остальные, несущественные в данном случае операторы опускаются. При этом, вместо пропущенных операторов, в текст примера вставляется строка с многоточием, обозначающая, что в этом месте листинга может находиться произвольная последовательность любых операторов, которые выполняют действия, не имеющие особого значения для обсуждаемой в данный момент темы. Понятно, что это могут быть операторы ветвления и цикла, безусловного перехода, присвоения и пр. Поэтому в примерах отделяемые строкой с многоточием операторы НИКОГДА не вы- полняются непосредственно один за другим. 116 Часть 2. Основы программирования на VBA
Если аргумент является необязательным и опускается, то передаваемое значение не указывается, но отделяющая его запятая сохраняется. Пусть процедура X имеет четыре аргумента, два последних из которых необязательны. В этом случае вызов данной про- цедуры с передачей ей значений первого, второго и четвертого аргументов будет выглядеть следующим образом. Call X(Аргумент!, Аргумент2г г Аргумент!) Запятые для отсутствующих аргументов могут не указываться только в том случае, если опущен не только данный аргумент, но и все последующие. Так, если при вызове упо- мянутой выше функции X ей передаются только первый и второй аргументы, то оператор вызова может иметь следующий вид. Call X(Аргумент!f Аргумент2) Указанный выше способ записи параметров в виде списка удобен только в том случае, если процедура имеет относительно немного аргументов. Если в процедуре присутствует много аргументов, в том числе и необязательных, то может оказаться удобнее способ за- писи оператора вызова с именованными аргументами. В этом случае при вызове процедуры не обязательно указывать полный список аргументов, в том числе и опущенных, — до- статочно указать только те аргументы, значения которых действительно передаются, но каждому значению должно предшествовать имя соответствующего аргумента из оператора объявления процедуры, за которым следует оператор присваивания : =. Иначе говоря, для записи именованных аргументов в операторе вызова процедуры используется следующий синтаксис. аргумент := value Здесь аргумент — это имя аргумента в объявлении процедуры, := — оператор присваивания, a val ие — это значение, присваиваемое данному аргументу. Следует также уточнить, что указывать аргументы по их имени можно независимо от того, обязательные они или необязательные, причем порядок их указания в списке аргументов оператора вызова в данном случае не имеет никакого значения. В языке VBA допускается комбинировать оба способа записи аргументов при вызове Ж. процедур. При этом сначала указывается некоторая начальная часть списка аргумен- тов, а затем в произвольном порядке следуют необходимые именованные аргументы. Рассмотрим пример, включающий две процедуры. В процедуре А с помощью опера- тора Call три раза вызывается процедура В, причем этот вызов осуществляется в цикле For...Next. Сначала в процедуре А создается трехэлементный строковый массив Файл, а затем с помощью цикла каждый элемент этого массива передается в качестве аргумента процедуре В, имеющей единственный аргумент строкового типа. После выполнения этой процедуры управление возвращается оператору, следующему за оператором Call. Sub А() Файл(1) = "Uexl.xls" 'Создание массива имен файлов Excel Файл(2) = "Цех2.х1з" Файл(З) = "Hex3.xls" For i = 1 То 3 Call В(Файл(i)) 'Открытие и обработка очередного файла Next i Глава 7. Процедуры и функции 117
End Sub Sub B(S As String) Workbooks.Open FileName:=S 'Открытие указанного файла в Excel End Sub Здесь Workbooks. Open FileName:=S означает вызов метода (подпрограммы) Open объекта Workbooks, открывающего файл, имя которого передается методу в качестве аргумента (подробнее речь об объектах пойдет в следующей главе). Это пример использования обычного способа передачи аргументов вызываемой процедуре в виде списка, а особенность его состоит в том, что он демонстрирует передачу в качестве аргумента отдельных элементов массива. Рассмотрим еще один пример. Пусть процедура А имеет четыре аргумента, из которых три последних являются необязательными. В процедуре N приведены примеры различных операторов вызова процедуры А, в которых использованы различные типы записи списка из трех передаваемых аргументов — в, С, Е. Sub А(В, Optional С, Optional D, Optional Е) End Sub Sub N() Dim X, X, Z Call A(X, Y, , Z) 'Передача аргументов списком Call A(X, E:=Z, C:=Y) 'Исп. списка и именованных аргументов Call A(C:=Y, E:=Z, B:=X) 'Исп. только именованных аргументов End Sub Здесь при первом вызове все аргументы передаются списком; при втором — первый операнд В передается списком, а остальные два как именованные аргументы; наконец, в последнем вызове все передаваемые аргументы являются поименованными. Способы передачи аргументов в процедуру Передавать аргументы процедуре можно двумя способами — либо как ссылку, либо как значение. При передаче аргумента по ссылке (т.е. указывая адрес его размещения в памяти) процедура получает непосредственный доступ к этому аргументу. В результате при выполнении она может изменить значение переданного по ссылке аргумента. Рассмотрим пример. Sub test() 'Вызывающая подпрограмма Dim f f = 5 'Исходное значение переменной Call testl(f) 'Передача переменной по ссылке MsgBox f 'Отображение значения переменной End Sub 118 Часть 2. Основы программирования на VBA
Sub testl(к) 'Вызываемая подпрограмма к = к * 10 'Модификация полученного значения аргумента End Sub Здесь в процедуре test (вызывающей) переменной f присваивается значение 5, а затем вызывается процедура testl (вызываемая), причем переменная f передается ей в качестве аргумента. В процедуре testl полученный аргумент умножается на 10, после чего управление возвращается процедуре test. В завершение процедуры test значение переменной f отображается с помощью оператора MsgBox, который выводит на экран диалоговое окно с ее текущим значением (рис. 7.1). Как видите, после выполнения этих процедур значение переменной f оказывается равным 50, а не 5, как на первый взгляд следует из текста процедуры test. При передаче аргумента по значению процедура получает копию передаваемого аргу- мента, и поэтому изменение аргумента внутри процедуры уже не оказывает влияния на исходную переменную. Другими словами, значение аргумента, переданного вызываемой процедуре по значению, всегда остается в вызывающей процедуре неизменным, незави- симо от действий, выполняемых в вызываемой процедуре. Для организации передачи ар- гумента по значению используется ключевое слово ByVai, которое ставится перед именем этого аргумента в объявлении вызываемой функции. В этом случае вызываемая процедура всегда будет получать лишь копию значения переменной. Для того чтобы в этом убедить- ся, добавим ключевое слово В у Vai в рассмотренный выше пример. Sub test2 () Dim f f = 5 Call test3 (f) MsgBox f End Sub Sub test3(ByVai k) k = k * 10 End Sub В результате выполнения этого примера значение переменной f в вызывающей проце- дуре test не изменится и оператор MsgBox выведет на экран диалоговое окно, в котором значение переменной f действительно будет равно 5 (рис. 7.2). Рис. 7.1. Результат выпол- нения процедуры test Рис. 7.2. Результат выполнения процедуры test2 при передаче аргумента по значению Следует заметить, что в большинстве случаев используется способ передачи аргумен- тов по ссылке, который принят в VBA по умолчанию. Однако если в вызывающей про- цедуре некоторые переменные используются как аргументы и в то же время участвуют в Глава 7. Процедуры и функции 119
тех или иных вычислениях, то надежнее будет использовать способ передачи аргументов по значению. В этом случае любые изменения значения переменной-аргумента внутри вызываемой процедуры никак не скажутся на переменной вызывающей процедуры. Итак, чтобы более четко понять, как обрабатываются аргументы, передаваемые по ссылке или значению, следует вспомнить, что любые переменные в программе представ- ляются двумя величинами. Первая определяет положение переменной в памяти (адрес), а вторая — собственно значение переменной. При передаче аргумента по значению (ByVai) в подпрограмму передается только ее значение в виде копии содержимого исходной переменной. Это бывает полезно, если ис- ходная переменная используется в расчетах многократно — например, в ней хранится процент скидки для оптового покупателя. Понятно, что если значение этой переменной после вызова подпрограммы расчета стоимости одной позиции заказа клиента окажется разрушенным, общая сумма будет неверной. Поэтому, для того чтобы исключить всякую возможность даже случайной модификации в подпрограммах важных для работы про- граммы величин, их следует передавать именно по значению. При передаче аргумента по ссылке в подпрограмму передается адрес переменной, а при ее выполнении в вычислениях непосредственно используется размещенное по этому адресу исходное значение. Передача по ссылке полезна в том случае, если само назначе- ние подпрограммы состоит в модификации полученного на входе значения — например, она должна вставить в формируемый почтовый адрес полное название улицы, заменив им укороченное кодовое название, присутствующее в исходных данных. Если в качестве аргумента используется переменная, тип данных которой определен £ пользователем, то такой аргумент можно передавать только в виде ссылки. Выполнение процедур Для выполнения или, как еще говорят, для вызова процедур в VBA существует несколь- ко способов. Вызвать процедуру на выполнение (в случае простой процедуры типа Sub, не требующей аргументов) можно непосредственно в редакторе VBA — с помощью команды Run^Run Sub/llserForm (или нажатием клавиши <F5>). После выбора указанной ко- манды редактор VBA автоматически выполнит предварительное тестирование процедуры, поэтому этот способ чаще всего применяется при проверке или тестировании процедур. 9 При выборе команды Run^Run Sub/UserForm следует обращать внимание на теку- щее положение текстового курсора в окне Code. При вызове интересующей вас про- цедуры курсор должен находиться на любой строке этой процедуры. В противном случае, когда курсор находится вне кода требуемой процедуры, вам не удастся вызвать именно эту процедуру. Если курсор находится вообще вне какой-либо процедуры, от- кроется диалоговое окно Macros, предоставляя вам возможность выбрать ту или иную процедуру. Вызвать процедуру можно также из диалогового окна Макрос, в котором будет представлен список всех доступных в данный момент процедур (см. раздел “Выполне- ние макросов” в главе 1), с помощью назначенной для данной процедуры комбинации клавиш или кнопки панели инструментов, если там имеется соответствующая кнопка, а также из меню пользователя, когда в это меню была вставлена специальная команда, 120 Часть 2. Основы программирования на VBA
предназначенная для вызова данной процедуры (все эти способы подробно рассматрива- ются в разделе “Выполнение VBA-программы” в главе 3). Любую процедуру можно вызвать или выполнить из другой процедуры, независимо от того, имеет она аргументы или нет. Если процедура типа Sub не имеет аргументов, то ее можно вызвать, просто указав имя этой процедуры в отдельной строке программы. Sub Сводка() (операторы!) Отчет (операторы2) End Sub Sub Отчет () (опера торыЗ) End Sub В этом примере сначала выполняются операторы блока операторы! процедуры Сводка, затем вызывается процедура Отчет, в которой выполняются операторы блока опера торыЗ. После выполнения этих операторов опять продолжит свою работу проце- дура Сводка, и будут выполнены операторы блока опера торы2. Вызвать процедуру из другой процедуры можно также с помощью специального опера- тора вызова, состоящего из ключевого слова Call, после которого указывается имя про- цедуры, а передаваемые этой процедуре аргументы записываются в круглых скобках. Если аргументов несколько, они разделяются запятыми. Ниже приведен пример, в котором с помощью оператора Call вызывается процедура Отчет и ей передается один аргумент. Sub Сводка() ’Вызывающая процедура Номер—Квартала = InputBox("Введите номер квартала: ’’) Call Отчет(Номер_квартала) ’Вызов процедуры Отчет End Sub Sub Отчет(Квартал) ’Вызываемая процедура End Sub Любая вызываемая процедура должна быть известна и доступна редактору. Поиск вызываемой процедуры может выполняться на двух уровнях — уровне модуля (по умол- чанию) и уровне приложения. При обычном обращении к процедуре сначала предпо- лагается, что она является процедурой уровня модуля, т.е. вызывающая и вызываемая процедуры находятся в одном модуле. Если при вызове процедуры VBA не может найти вызываемую процедуру в текущем модуле, тогда просматриваются процедуры уровня при- ложения, т.е. доступные процедуры в других модулях этого же проекта. Следует помнить, что в одном и том же модуле не может быть двух процедур с одинаковым именем, однако в разных модулях это допускается. Если в разных модулях проекта имеются процедуры с одинаковыми именами, то для вызова процедуры из определенного модуля, отличного от модуля вызывающей процедуры, необходимо перед ее именем указать имя требуемого мо- дуля, не забыв при этом поставить между ними точку. Например, пусть (различные) про- цедуры с именем Сводка присутствуют в двух модулях проекта — Modulel и Module2, Глава 7. Процедуры и функции 121
а процедура Отчет принадлежит модулю Module2. Какие именно процедуры вызываются в приведенном ниже коде? Sub Отчет() Module1.Сводка ’Вызов 1 Call Сводка ’Вызов 2 Call Modulel.Сводка ’Вызов 3 End Sub Учитывая сказанное выше, можно сделать вывод, что в первом и третьем случаях вы- зывается процедура Сводка из Modulel, тогда как во втором примере вызывается про- цедура с этим же именем, но из модуля Module2. Функции языка VBA Функции представляют собой необходимый элемент любых языков программирова- ния, не является исключением и язык VBA. В некоторых примерах мы уже использовали такие функции, как InputBox () и MsgBox (), но при этом не останавливались подробно на их описании. Теперь пришло время детальнее ознакомиться с функциями и их исполь- зованием. В теоретическом плане функция — это “встроенная формула”, которая выполняет требуемые действия и генерирует значение, вычисляемое на основании указанных в ней выражений. На практике в языке VBA функция представляет собой особый вид процедур, отличающийся от прочих тем, что она всегда возвращает вычисленное значение. Это по- зволяет обращаться к функции не с помощью оператора вызова Call, а непосредственно из выражений, при построении которых в месте обращения к функции подразумевается использование вычисленного с ее помощью значения. Иначе говоря, оперируя одним или несколькими значениями, переданными функции в качестве аргументов, последняя всегда возвращает единственное результирующее значе- ние, которое VBA вставляет в текущий оператор программы в то самое место, где было указано имя этой функции. Поэтому при построении выражений имя функции вместе с требуемыми значениями ее аргументов записывается в операторе непосредственно в том месте, где требуется использовать вычисленный при выполнении данной функции результат. Отсюда следует, что возвращаемое функцией результирующее значение можно непосредственно использовать как часть выражения, присваивать какой-либо перемен- ной, а также указывать как аргумент другой процедуры или функции. Процедуры типа Function Функции в языке VBA создаются как процедуры специального типа Function. Про- цедура типа Function выполняется аналогично процедуре типа Sub. Но, в отличие от процедуры Sub, процедура типа Function обязательно возвращает в вызывающую про- цедуру (в точку вызова) результирующее значение, которое и будет использоваться в даль- нейших вычислениях. Кроме того, вместо уже знакомых нам ключевых слов Sub и End Sub, используемых при объявлении обычных процедур VBA, при объявлении процедур 122 Часть 2. Основы программирования на VBA
типа Function используются ключевые слова Function и End Function. Синтаксис процедуры типа Function следующий. Function Имя(аргументы) As тип (операторы) Имя = возвращаемое_значение End Function Здесь ключевое слово Function определяет процедуру типа Function, за ним следует уникальное Имя процедуры-функции, составленное согласно правилам языка VBA. После имени функции указывается список ее аргументов аргументы, который описывает передаваемые функции данные. Значение тип определяет тип данных величины возвращаемое_значение, возвращаемой функцией в точку вызова посредством помещения ее в теле функции в переменную с именем Имя. Возвращаемое функцией значение может иметь любой тип данных, существующий в языке VBA. Z4; Если тип данных возвращаемого функцией значения при объявлении опущен, то он JI принимается как тип Variant. Следует помнить, что значения, сохраняемые или об- рабатываемые как тип данных Variant, занимают больше памяти, чем любой дру- гой тип данных, и на их обработку требуется больше времени. Поэтому в объявлении функции всегда следует указывать тип возвращаемого ей результата. Для того чтобы передать в вызывающую процедуру возвращаемое функцией результи- рующее значение, следует внутри ее тела присвоить это значение переменной с именем функции. Процедура типа Function может включать один или несколько операторов присваивания значения переменной с именем функции, а также может не иметь их со- всем. Тип данных результата вычисления выражения в правой части такого оператора присваивания должен совпадать с объявленным типом функции. Если возвращаемое значение будет иметь тип данных, несовместимый с объявленным типом функции, то VBA выдаст сообщение об ошибке несовпадения типов. Однако если тип возвращаемого значения отличается от объявленного типа функции, но совместим с ним, он будет пре- образован в тип, указанный в объявлении процедуры. Если процедура типа Function не имеет оператора присваивания функции, то VBA возвращает следующие значения: 0 — для функций, возвращающих любой числовой тип; пустая строка null — для функций, возвращающих строковый тип; значение Empty — для функций, возвращающих результат типа Variant; значение Nothing — для функций, возвращающих результат типа Object. Если функция возвращает значение типа Ob j ect, то присваивать это значение в теле функции следует с помощью оператора Set. Set Имя_функции = Возвращаемое_значение Л"\ Можно рекомендовать выбирать для процедур типа Function такой тип возвращае- V/ мого результата, который требует наименьшего объема памяти и одновременно вме- щает полный диапазон значений, которые может возвращать эта функция. Процедуру типа Function можно выполнить, только вызвав ее из другой процедуры. Обычно это осуществляется присваиванием некоторой переменной “значения”, пред- ставляющего собой имя данной функции. Глава 7. Процедуры и функции 123
Sub Корень() 'Вычисление квадратного корня Dim A, Sqrt А = 4 'Исходное значение Sqrt = Sqr(А) 'Вычисление квадратного корня MsgBox (Sqrt) 'Вывод окна с результатом End Sub В этом примере в переменную Sqrt помещается значение, вычисленное с помощью стандартной функции Sqr (), возвращающей значение квадратного корня из числа, пере- данного ей в качестве аргумента. Вычисленное значение квадратного корня затем с по- мощью функции MsgBox () выводится на экран в окне сообщения (рис. 7.3). Однако главное удобство использования функций состоит в том, что они могут вы- зываться в любом месте программного кода, где может быть явно указано возвращаемое ими значение. В частности, мы можем усложнить приведенный выше пример. Вначале выведем на экран диалоговое окно, в котором предложим пользователю ввести число, из которого будет извлекается квадратный корень (для этого напишем специальную функ- цию КвКорень ()). Следует отметить, что в данном случае общий результат оказался даже компактнее предыдущего, поскольку в функции КвКорень () запрос и вычисления выполняются в одной строке. В этой же строке организуется и возврат вычисленного значения. Sub ВычКвКорня() ' Вычисление квадратного корня MsgBox (КвКорень()) 'Вывод рез-та, возвр. функцией КвКорень() End Sub Function КвКорень() КвКорень = (Sqr(InputBox("Введите значение:"))) End Function После запуска процедуры ВычКвКорня () в раскрывшемся диалоговом окне (рис. 7.4) в поле ввода введем нужное нам число и щелкнем на кнопке ОК. В результате выполне- ния этих действий на экран будет выведено диалоговое окно с вычисленным значением (рис. 7.5). Рис. 7.4. Диалоговое окно для ввода числа, из Рис. 7.5. Результат вычис- которого извлекается квадратный корень ления квадратного корня Рис, 7.3. Вычисление квадратного корня Возьмите для себя за правило, что функция никогда не должна изменять данные, пе- редаваемые ей в качестве аргументов. Принимая решение о типе вновь создаваемой процедуры, помните, что главное назначение функции — возвращение вычисленного значения. В частности, целесообразно написать специальную функцию, если одни и те же математические вычисления требуется выполнять в разных местах программы. В любом случае функции не должны выполнять никаких иных действий, кроме абсо- лютно необходимых для получения требуемых возвращаемых результатов. 124 Часть 2. Основы программирования на VBA
При работе над большим проектом часто используется достаточно много процедур- функций, и сразу трудно вспомнить, в каком из модулей находится нужная вам функция. В этом случае для быстрого поиска и отображения исходного VBA-кода интересующей вас в данный момент процедуры или функции можно воспользоваться окном Object Browser (рис. 7.6). Рис, 7.6, Поиск нужной процедуры или функции в окне Object Browser Упростить работу с процедурой-функцией как самому себе, так и другим программи- стам, которым потребуется эта функция, можно с помощью ввода описания, кратко осве- щающего ее назначение и особенности. Для добавления к процедуре или функции опи- сания воспользуйтесь окном Object Browser, найдите в нем нужную процедуру-функцию и щелкните на ней правой кнопкой мыши. В раскрывшемся контекстном меню выберите команду Properties, и на экран будет выведено диалоговое окно Member Options (Параме- тры компонента), показанное на рис. 7.7. Введите описание данной процедуры-функции в поле Description (Описание ) и щелкните на кнопке ОК. Рис. 7.7. Добавление описания для процедуры или функции Глава 7. Процедуры и функции 125
Аргументы функций Аналогично аргументам процедур, аргументы функций могут быть константами, пере- менными (включая массивы), текстовыми строками или объектами. Некоторые функции могут не иметь аргументов. Такие функции, не требующие аргументов, выбирают воз- вращаемое значение из системных переменных Windows. Например, функция Timer возвращает значение, которое представляет собой количество секунд, прошедших с на- чала суток, и вычисляется с точностью до сотых долей секунды. Для вызова функции, не имеющей аргументов, достаточно указать ее имя. Timl = Timer MsgBox (Timl) Для работы других функций необходимо при вызове передать им один или несколько аргументов, которые в теле процедуры-функции выполняют практически ту же роль, что и другие переменные, объявленные самым обычным образом. При объявлении процедуры- функции в списке аргументов необходимо указать имя каждого аргумента, который дол- жен быть передан функции при вызове. Весь список аргументов заключается в круглые скобки, и, если в нем присутствует больше одного аргумента, они отделяются запятой. Указанные в списке аргументов имена ссылаются на значения, передаваемые при вызо- ве функции, и доступны только внутри этой процедуры-функции. В приведенных выше примерах была использована функция InputBox (), которая выводит диалоговое окно с указанным запросом, а затем ожидает, пока пользователь введет требуемое значение. Полученное значение возвращается вызывающей процедуре. MsgBox (Sqr(InputBox("Введите значение:"))) В этом примере для сокращения записи используется механизм вложения функций — вызов одной функции организуется непосредственно в списке аргументов другой функ- ции. Смысл выполняемых действий очевиден: возвращаемое первой функцией значение используется в качестве аргумента для следующей функции и т.д. Отметим, что в VBA уровень подобного вложения функций практически не ограничивается. Поскольку функции в VBA являются специализированным видом процедур, к ним также относятся все те правила записи и передачи аргументов, которые уже обсуждались выше, в разделе “Аргументы процедур”. Например, в объявлениях процедур VBA, а зна- чит и функций, могут присутствовать как обязательные, так и необязательные аргументы, причем число обязательных аргументов в каждой функции фиксированно — от 1 до 60. Еще раз обратимся к уже знакомой нам функции InputBox (подробно об этой функции мы будем говорить в главе 9) и рассмотрим ее синтаксис. InputBox(Prompt [, Title] [, Default] [, Xpos] [, Ypos]_ [, HelpFile, Context]) Здесь Prompt — единственный обязательный аргумент для функции InputBox, а все остальные являются необязательными, т.е. при вызове функции могут не указываться. Поскольку необязательные аргументы при вызове функции могут указываться или не указываться, иногда полезно присвоить определенным необязательным аргументам значение по умолчанию. Напомним, что при объявлении процедуры-функции необходимо указывать тип данных для каждого аргумента функции. Для тех аргументов, тип которых в определении функции не был указан явно, VBA передает значения как тип Variant. 126 Часть 2. Основы программирования на VBA
При вызове процедур-функций также можно использовать способ задания именован- ных аргументов. Обратите внимание на то, что при вводе имени встроенной функции VBA или доступной собственной процедуры/функции редактор кода автоматически отобра- жает окно подсказки с перечнем ее именованных аргументов. При этом имя очередного ожидаемого аргумента будет выделено полужирным шрифтом (рис. 7.8). | (General) Function КаКорень() КаКорень » (Sqr( End Function SqriNumber As Double As Double | Рис. 7.8. Вывод окна подсказки с указанием списка аргументов функции Функция вывода окна подсказки с перечнем аргументов процедур в редакторе VBA бу- дет активна только в том случае, если на вкладке Editor диалогового окна Option будет установлен флажок опции Auto Quick Info (Автоматический вывод кратких сведений). Если на этой вкладке будет также установлен флажок опции Auto Syntax Check, то при вызове процедуры с аргументами редактор заставит вас указать значения для всех ее обязательных аргументов, автоматически контролируя получение процедурой всех тех значений, которые ей требуются. Ошибки выполнения При выполнении написанных вами процедур или процедур-функций могут возникнуть ошибки, отличные от синтаксических, — ошибки выполнения. Такие ошибки можно обна- ружить только в процессе выполнения процедуры. Они возникают по разным причинам: из-за просчетов в логике, пропуска аргументов при вызове процедуры или функции, не- верного указания типа данных аргументов, из-за пропуска ключевых слов в объявлениях, при попытках доступа к несуществующим папкам каталога и т.д. Обычно такие ошибки выполнения приводят к остановке процедур VBA. При этом отображается диалоговое окно с сообщением, в котором указывается номер*ошибки и краткое ее описание (рис. 7.9). Рис. 7.9. Диалоговое окно с сообщением об ошибке выполнения В этом окне кнопка Continue (Продолжить) используется для продолжения выполне- ния процедуры или процедуры-функции (для большинства ошибок эта кнопка неактив- на). Щелчок на кнопке End (Закончить) прекращает выполнение процедуры. Щелчок на кнопке Debug (Отладка) переводит выполняющуюся процедуру в режим прерывания, что Глава 7. Процедуры и функции 127
позволяет в окне кода редактора VBA внести исправления в тот оператор, где возникла данная ошибка выполнения, а затем продолжить выполнение программы. Щелчок на кнопке Help предоставляет доступ к справочной системе VBA с выводом страницы, где описывается обнаруженная ошибка выполнения. Напомним, как можно быстро получить справку по конкретному ключевому слову или процедуре. Для этого достаточно в окне кода поместить курсор на интересующее вас слово или оператор процедуры и нажать клавишу <F1 >. Следует заметить, что написать процедуру, функцию или большую программу без оши- бок совсем не просто — от случайных ошибок и описок никто не застрахован. К тому же практически невозможно предусмотреть и соответствующим образом учесть в логике про- граммы все те ситуации, которые могут иметь место впоследствии, при ее многократном выполнении. Поэтому программа считается хорошо написанной, если в ней присутствуют специальные подпрограммы обработки ошибок, с помощью которых ошибки выполнения автоматически обнаруживаются и обрабатываются, что позволяет программе тем или иным способом выходить из нестандартных ситуаций. В языке VBA есть много инстру- ментов, которые можно использовать для обработки и предотвращения ошибок, — под- робно об этом мы будем говорить в главе 13. Резюме В этой главе мы познакомились с важнейшим разделом программирования на языке VBA — использованием процедур и функций. Процедуры и функции — это небольшие самостоятельные программы, сохраняемые в модуле VBA. Они имеют собственное имя и предназначены для выполнения определенных действий с теми или иными объектами. Различие между процедурами и функциями состоит в том, что последняя всегда возвраща- ет единственное значение, которое при выполнении программы подставляется в то самое место, где было указано имя функции. При выполнении процедуре могут потребоваться некоторые исходные данные, которые ей должны быть переданы при вызове. Такие дан- ные называются аргументами и описываются в объявлении процедур. Аргументы могут быть обязательными и необязательными, в последнем случае при необходимости им мо- жет присваиваться значение по умолчанию. Аргументы могут передаваться в процедуру по ссылке или по значению, причем в первом случае процедура изменяет исходное значение аргумента, а во втором — нет. Процедуру можно вызвать на выполнение из другой про- цедуры, а также из окна редактора кода VBA или самого приложения. Функции являются особым видом процедур и предоставляют в распоряжение программиста некоторые до- полнительные возможности. В завершение мы обсудили понятие ошибок выполнения, которые иногда имеют место при выполнении функций или процедур. Тестовые задания Ниже приведено несколько тестовых заданий, предназначенных для закрепления из- ложенного в этой главе материала. В каждом задании вам предлагается вопрос и несколь- ко вариантов ответа на него, один (или несколько) из которых является правильным, а остальные — нет. Укажите правильный ответ. 128 Часть 2. Основы программирования на VBA
1. Процедуры в языке VBA представляют собой: а) особый тип операторов языка; б) небольшие самостоятельные программы, сохраняемые в модуле VBA; в) произвольную поименованную последовательность операторов; г) специальный тип данных языка VBA. 2. Главное отличие между процедурами и функциями состоит в том, что: а) для их определения используются разные операторы; б) функции и процедуры имеют различное количество аргументов; в) вызов функций осуществляется иначе, чем вызов процедур; г) функция всегда возвращает единственное значение. 3. Аргументы могут быть следующими: а) обязательными; б) необязательными; в) позиционными; г) опущенными; д) возвращаемыми; е) именованными. 4. Механизм вложения функций позволяет: а) указывать вызов одной функции в качестве аргумента для другой функции; б) последовательно выполнять функции, перечисленные в списке; в) вставлять в текст одной функции определение другой функции; г) размещать функции в пределах одного модуля. 5. Возникновение ошибки времени выполнения сопровождается: а) немедленным прекращением выполнения главной программы; б) прекращением выполнения VBA-программы; в) выводом окна сообщения об ошибке; г) перезагрузкой компьютера; д) игнорируется системой. Глава 7. Процедуры и функции 129
Глава 8 Объекты и коллекции В этой главе... ♦ Что такое объект ♦ Свойства и методы объекта ♦ Коллекции и контейнеры ♦ События и их обработка ♦ Понятие о классах и иерархии объектов ♦ Создание и идентификация объектов ♦ Работа с объектами в программе ♦ Окно Object Browser ♦ Резюме Что такое объект Одним из основных преимуществ языка VBA является то, что он относится к языкам объектно-ориентированного программирования, т.е. в основу программирования на VBA положено такое понятие, как объект. Любое программное приложение, поддерживающее среду программирования VBA, должно состоять из совокупности объектов, каждый из которых имеет собственные специфические свойства. Объектом называют программную конструкцию, которая позволяет инкапсулировать данные, описывающие некоторый компонент прикладной области, вместе с кодом, предназначенным для обработки этих данных, т.е. позволяет объединить их в нечто целое. Инкапсуляция — одно из базовых понятий объектно-ориентированного программиро- вания. В наиболее простом толковании инкапсуляцию можно понимать как сокрытие объектом принадлежащих ему свойств таким образом, чтобы доступ к ним из внешне- го мира был возможен только через специальные функции, предоставляемые самим этим объектом1. Например, если объект имеет свойство цвета, то его никак не удастся “покрасить” в другой цвет, кроме как воспользовавшись специальными функциями (в объектной терминологии — методами), предоставляемыми объектом для этой цели. Такой под- ход дает большие преимущества: прикладной программист не должен заботиться о том, чтобы запрограммировать процедуру “покраски” объекта, —- об этом позаботился 1 Простейшая аналогия — автомат разлива кофе. Покупатель не может забраться внутрь аппарата, чтобы насыпать себе в стаканчик черный кофе или капуччино. Для выбора типа напитка автомат предлагает кнопки: нажмешь одну, получишь черный кофе, другую — кофе с молоком. Как и от- куда аппарат засыпает смеси в стаканчик для заваривания, покупателя не касается, его дело лишь нажимать кнопки.
разработчик объекта. А тот со своей стороны может не беспокоиться, что функцио- нирование его объекта будет нарушено, если прикладному программисту потребуется сделать объект зеленым и он по незнанию или ошибке сделает это неправильно. В каждом VBA-приложении присутствует свой уникальны^ набор объектов с их соб- ственными свойствами и методами. Например, в Excel существуют объекты, связанные с такими понятиями, как ячейки, в которых хранятся данные, рабочие листы в файлах, рабочие книги, в то время как в Access объекты представляют различные компоненты баз данных и позволяют манипулировать информацией, сохраняемой в этих базах. Во всех VBA-приложениях присутствуют объекты, представляющие экранные формы и обеспечи- вающие отображение информации, а также объекты отдельных компонентов этих форм, предоставляющие средства обработки отображаемой информации, — панели инструмен- тов и отдельные кнопки на этих панелях, меню, переключатели, поля ввода и т.д. С точки зрения программы, сам по себе объект не представляет большого интереса, гораздо важнее то, какие действия можно совершить над этим объектом и какими свой- ствами он обладает. Действия, выполняемые над объектом, определяются набором его методов, а свойства данного объекта определяют те или иные его характеристики. Управ- лять состоянием объекта, т.е. его текущими характеристиками, программа может только с помощью его же методов, предоставляющих доступ к свойствам данного объекта. Свойства и методы объекта Свойства представляют собой самые простые для понимания характеристики объекта. Они предназначены для хранения информации о текущем состоянии некоторого аспекта рассматриваемого объекта. С помощью свойств можно управлять внешним видом и по- ведением объекта. Для изменения характеристик объекта необходимо (и достаточно) из- менить значения его свойств. С другой стороны, чтобы узнать о текущих характеристиках и возможном поведении объекта, необходимо (и достаточно) извлечь информацию о те- кущем состоянии его свойств. Следует еще раз уточнить, что доступ к каждому свойству, характеризующему состояние некоторого аспекта объекта, возможен только с помощью методов доступа именно к данному конкретному свойству, т.е. с помощью специализиро- ванных команд обработки данного свойства. Некоторые свойства объекта при необходимости можно изменять — такие свойства мы будем называть доступными для чтения и записи. В качестве примера такого свойства можно привести значение, сохраняемое в поле ввода, — в процессе работы программы оно может многократно изменяться, в зависимости от того, что пользователь будет вво- дить в это поле. Другие же свойства позволяют только считывать свои значения, но не предоставляют возможности изменять эти значения. Такие свойства объекта называются доступными только для чтения. Следует помнить, что, с точки зрения программы, данные в свойствах, описывающие различные аспекты объекта, — это обычные данные, ничем не отличающиеся от тех данных, которые помещаются в обычные переменные языка VBA. Другими словами, свойства представляют собой переменные, инкапсулированные (сокрытые) внутри данного объекта, которые по этой причине не требуется объявлять. Использовать свойства объекта можно двумя способами — либо получить текущее значение свойства, либо установить новое значение свойства. Чтобы получить текущее значение свойства, нужно указать имя этого свойства в некотором выражении — по тому Глава 8. Объекты и коллекции 131
же принципу, который используется при вызове выстроенных функций или собственных процедур типа Function. Иначе говоря, следует присвоить это свойство некоторой пере- менной в операторе программного кода. Для этого используйте следующий синтаксис. Переменная = Object. Имя Здесь Переменная — любая допустимая переменная, Object — ссылка на требуемый объект, а Имя — имя свойства того объекта, на который выполняется ссылка. Присваиваются значения свойствам точно так же, как и переменным, — слева от знака равенства указывается имя свойства, а справа — его значение. Иначе говоря, для того что- бы задать (установить) новое значение свойства объекта, нужно присвоить этому свойству новое значение, используя следующий синтаксис. Object.Свойство = ЗначениеСвойства Здесь Object — ссылка на требуемый объект, Свойство — то свойство объекта, которо- му присваивается новое значение, ЗначениеСвойства — любое допустимое выражение VBA соответствующего типа. Рассмотрим конкретный пример. В Excel существует объект, соответствующий теку- щей активной ячейке, — ActiveCell. Он обладает многими свойствами, среди которых есть свойство Interior — и это свойство тоже объект! — определяющее внешний вид активной ячейки. В свою очередь, у объекта Interior, среди прочих, есть свойство Col- orindex, устанавливающее цвет фона ячейки, задаваемый числовым кодом — от 0 до 56. Предположим, нам надо изменить цвет активной ячейки на желтый (код = 6). Мы уже выяснили, что цвет активной ячейки определяется значением “двухступенчатого” свой- ства Interior. Color Index объекта ActiveCell, поэтому изменение цвета ячейки на желтый можно записать следующей строкой кода. ActiveCell.Interior.Colorindex = 6 Таким образом, изменение выполняющейся программой значения свойства Interi- or . Colorindex объекта ActiveCell во “внешнем мире” приводит к изменению цвета активной ячейки. Проверим это на практике. Напишем процедуру PaintCell, которая будет менять цвет активной ячейки на заданный пользователем (листинг 8.1). Листинг 8.1. Изменение значения цвета фона активной ячейки Sub PaintCell() ’ Изменение цвета активной ячейки Dim n As Integer n = (InputBox("Введите код цвета:")) ’ Запрос кода цвета ActiveCell.Interior.Colorindex = n ’ Изменение значения свойства End Sub Создайте в Excel 2010 новую книгу, откройте окно редактора VBA и выберите в нем команду меню Inserts Module. Далее откройте окно редактора кода (<F7>) и введите при- веденный выше код (можно без комментариев). Завершив ввод, выполните процедуру, для чего просто нажмите <F5>. Теперь активизируется окно Excel с выведенным окном запроса, предлагающим задать требуемый код цвета (рис. 8.1, а). Введите в поле требуемое целое число (от 0 до 56) и щелкните на кнопке ОК. Вновь сделайте активным окно Excel и убедитесь, что цвет активной ячейки изменился (рис. 8.1, б). 132 Часть 2. Основы программирования на VBA
Вставка Разметка страницы Формулы Данн, Я: Ы Книга! Visual Макросы Надстройки Надстройки для Baste модели СОМ Вставить Режим конструктора Разметка страницы Формулы Данн Главная Рис. 8.1. Изменение цвета активной ячейки с помощью изменения значения свойства объекта Visual Макросы Bask Надстройки Надстройки для Вставить Режим модели СОМ конструктора 3 а Кроме того, следует отметить, что одно и то же свойство можно изменять сразу у всех объектов одной группы, для которой определено собственное имя. Worksheets.Visible = False Здесь значение False присваивается свойству Visible всех объектов, принадлежащих группе2 Worksheets, т.е. все рабочие листы активной книги в результате станут скры- тыми (невидимыми). Если хотите проверить это утверждение на практике, измените в подпрограмме PaintCell (см. листинг 8.1) имя объекта ActiveCe 11 на имя коллекции Cells (ячейки) и вновь выполните пример. Не правда ли, результат впечатляет?! \ При многократном использовании в программе рдного и того же значения некоторого свойства объекта это значение лучше предварительно сохранить в обычной перемен- ной, так как VBA извлекает значение обычной переменной значительно быстрее, чем значение свойства объекта. Любые свойства, как и переменные, хранят данные определенного типа — чаще всего это один из числовых типов, строковый тип или тип Boolean. Многие объекты имеют свой- ства, значения которых принимаются по умолчанию, — они присваиваются этим свойствам при создании объекта, когда для них не задается какое-либо конкретное значение. Доступ к свойствам (как мы уже говорили выше) возможен только с помощью их соб- ственных методов, т.е. команд обработки именно этих конкретных свойств. Методы пред- ставляют собой обычные подпрограммы-процедуры на языке VBA, “спрятанные” внутри объекта и выполняющие те или иные действия над данными, хранимыми в объектах, — например, изменение значений свойств этих объектов. И хотя методы представляют собой обычные процедуры, они жестко связаны с конкретным объектом, поэтому обратиться к ним можно только через соответствующий объект. Метод считается частью объекта и 2 Такие группы однотипных объектов в объектном программировании называются “коллекциями”. В VBA их имена обычно образуются из имени входящих в коллекцию объектов с добавлением буквы s: объект Worksheet (рабочий лист) — коллекция Worksheets (рабочие листы). Глава 8. Объекты и коллекции 133
способен оказывать воздействие только на тот объект, через который осуществляется об- ращение к этому методу. Для вызова метода используется следующий синтаксис. Object.Метод Если метод имеет аргументы, используется следующий синтаксис. Object. Метод Аргумент!, Аргумент?, Аргумент?... В обоих случаях Ob j ect — это имя объекта, которому принадлежит вызываемый метод, Метод — имя метода, а Аргумент!, ... — список аргументов метода. Как и в случае обыч- ных процедур, методы могут иметь аргументы или не иметь их совсем, при этом аргу- менты методов могут быть как обязательными, так и необязательными. Если метод имеет несколько аргументов, то такие аргументы в списке разделяются запятой и перечисляются в определенном порядке. Некоторые объекты имеют методы, которые возвращают результирующее значение, т.е. ведут себя как функции. Например, добавить рабочий лист в открытую рабочую книгу Excel можно, записав следующий код (здесь параметр Before задает номер уже существу- ющего рабочего листа в коллекции Worksheets, перед которым будет добавлен новый). Worksheets.Add Before:= Worksheets (1) Но метод Worksheets . Add ведет себя как функция, т.е. создает новый объект, ссыл- ка на который возвращается как результирующее значение. Поэтому для вызова данного метода необходимо указать его в операторе присвоения значения переменной или же ис- пользовать в некотором выражении. Set MyWorksheet = Worksheet.Add (Before:= Worksheets (1)) Обратите внимание: в этой записи список аргументов метода помещен в круглые скоб- ки — как при обращении к обычным функциям. Если при перечислении аргументов скобки отсутствуют, возвращаемый методом результат игнорируется. Следует также помнить, что в списке аргументов метода обязательно нужно указывать запятые, от- мечающие места пропущенных необязательных аргументов. Проверим работу методов на практике: напишем процедуру AddSheet, позволяющую добавлять в открытую рабочую книгу Excel новый рабочий лист, указав, перед каким из существующих листов он должен быть добавлен (листинг 8.2). Листинг 8.2. Добавление нового рабочего листа Sub AddSheet() ’ Добавление рабочих листов в книгу Dim n As Integer ’ Переменная для номера листа Dim MyWorksheet As Worksheet ’ Переменная объектного типа n = (InputBox ("Укажите номер предыдущего листа:’’)) Set MyWorksheet = Worksheets.Add(Before:=Worksheets(n)) End Sub у—. Обратите внимание: присвоение значения переменным или аргументам в методах вы- полняется с помощью оператора : =, а не =, как это делается при присвоении значения в свойствах. 134 Часть 2. Основы программирования на VBA
Наберите код из листинга 8.2 (можно без комментариев) в окне редактора кода Excel 2010 и нажмите <F5>. Активизируется окно Excel с выведенным окном запроса, пред- лагающим задать номер уже существующего рабочего листа, перед которым должен быть вставлен новый (рис. 8.2, а). Введите в поле требуемое значение и щелкните на кнопке ОК. Вновь сделайте активным окно Excel и убедитесь, что в книге появился новый рабочий лист, помещенный в указанное место (рис. 8.2, б). б) Рис. 8.2. Добавление в книгу нового листа обращением к методу объекта Коллекции и контейнеры Коллекция объектов (collection) — это группа связанных объектов, которые при работе могут использоваться как некое единое целое3. Каждый объект в такой коллекции назы- вается элементом (element) этой коллекции. Коллекции используются во всех тех случаях, когда в программе необходимо манипулировать более чем одним экземпляром объектов какого-либо типа. Понятно, что коллекции — очень важный и мощный инструмент в объектной модели Office. Даже само приложение Excel является объектом. Этот объект называется Application. В него входит коллекция Workbooks, в которой хранятся объ- екты Workbook для всех открытых книг. Каждый объект Workbook содержит коллекцию Worksheets, в которой хранятся объекты Worksheet для рабочих листов этой книги. Напомним, что приложение Excel может поддерживать работу с более чем одной откры- той рабочей книгой, а каждая такая книга может иметь несколько рабочих листов. Как уже упоминалось выше, имя объекта-коллекции обычно образуется как множе- ственное число от имени образующих ее объектов. Поскольку коллекция сама по себе — это тоже объект, она может иметь собственные методы и свойства. Практически каждая коллекция имеет метод Add, позволяющий добавлять в нее новые объекты-члены4, и метод Item, позволяющий получить доступ к требуемому элементу коллекции. Также типичным является наличие свойства Count, значение которого определяет текущее ко- личество объектов-членов коллекции. При необходимости сослаться на член коллекции можно указать его позицию в коллек- ции (в этом случае указывается номер индекса начиная с 1) или имя требуемого экземпляра объекта (текст в кавычках). Например, если в Excel открыта только одна рабочая книга, ко- торая называется Bookl.xls,к ней можно обратиться с помощью следующих операторов. 3 В первом приближении можно понимать коллекцию как объект, предоставляющий доступ к мас- сиву из объектов. 4 Существуют и коллекции, доступные только для чтения, у которых метод Add отсутствует. Глава 8. Объекты и коллекции 135
Workbooks.Item(1) Workbooks . Item (’’Bookl.xls”) Если в активной книге открыты четыре листа — Сервер, Юг, Восток и Запад, обра- титься к объекту третьего листа можно одним из следующих способов. Worksheets.Item(3) Worksheets . Item (’’Восток”) Проверим это утверждение на практике. Напишем несложную процедуру SheetName, которая будет выводить имя заданного рабочего листа в окне сообщения (листинг 8.3). При запуске этой процедуры на выполнение выводится диалоговое окно с запросом (рис. 8.3, а). После указания номера требуемого листа и щелчка на кнопке ОК процедура выводит окно сообщения с именем требуемого рабочего листа (рис. 8.3, б). Листинг 8.3. Пример организации доступа к объектам-членам коллекции Sub SheetName() ’ Вывод имени указанного рабочего листа Dim n As Integer n = (InputBox ("Укажите номер требуемого листа:’’)) MsgBox ("Имя листа №’’ + Str(n) +’’ = ’’+ Worksheets. Item (n) .Name) End Sub a) Рис. 8.3. Пример использования коллекций 19 CSSSSISEB" *1 21 22 Имя листа № 3 = Восток 25 26 27 и < ► И Сервер Юг Восток s Запад ' Готово I б) Обычно все объекты коллекции имеют один и тот же тип (принадлежат одному и тому же классу), например коллекция Documents будет включать несколько объектов класса Document. Подробнее о классах мы будем говорить в следующем разделе. Однако есть и такие коллекции, которые предназначены для хранения объектов любых типов, в любой комбинации. В частности, в языке VBA объектом подобного типа высту- пает родовой объект Collection, позволяющий сохранять объекты любых типов в про- извольной комбинации. Единственное свойство родового объекта Collection — Count (количество). Это свойство хранит сведения о текущем количестве элементов в коллекции и доступно только для чтения, т.е. в программе его значение можно только получить, но не изменить. Мы уже знаем, что объекты VBA находятся в иерархической зависимости один от другого, т.е. объекты высших ступеней иерархии служат контейнерами для одного или целого множества подчиненных объектов. Таким образом, можно сказать, что контейнер (container) — это любой объект, содержащий один или несколько других вложенных в него объектов. Вся система подобных иерархических отношений между объектами кон- кретного VBA-приложения называется объектной моделью этого приложения. Объектная 136 Часть 2. Основы программирования на VBA
модель описывает последовательность вложения одних объектов в другие и обычно пред- ставляется в графическом виде. Так, на рис. 8.4 представлен фрагмент объектной модели приложения Microsoft Excel (на этой диаграмме белыми прямоугольниками обозначены объекты-коллекции, а серыми — обычные объекты). Здесь объект Application содер- жит коллекцию Workbooks, в которой каждый объект Workbook соответствует одной открытой рабочей книге. Каждый из объектов Workbook, в свою очередь, содержит коллекцию Worksheets, которая включает по одному объекту Worksheet для каждого рабочего листа данной рабочей книги, коллекцию Chatrs (диаграммы) и т.д. | Application [ *~jWorkbooks (Workbook» | -[Worksheets «Worksheet» | -[Charts (Chart» | ►— ~| Documentproperties (Documentproperty» | -jVBProject Puc, 8.4. Начальный фрагмент объектной модели приложения Microsoft Excel Для доступа к свойствам вложенных объектов используется стандартный синтаксис, при котором имена объектов (в том числе и коллекций) соединяются вместе с помощью разделителя-точки (.) — см. листинги выше. В результате образуется единое объектное выражение, которое и используется при написании программы. Например, для доступа к счетчику элементов (свойство Count) коллекции Worksheets (см. рис. 8.4) можно ис- пользовать следующее выражение. Application.Workbooks.Worksheets.Count События и их обработка Некоторые действия пользователя или действия других функционирующих в системе программ, распознаваемых объектом, называются событиями. Многие из объектов могут откликаться на определенные события, для которых этот отклик предварительно следует запрограммировать. События могут быть инициированы системой или возникать в ре- зультате действий пользователя (например, щелчок мыши или нажатие клавиши) либо программы. Отклик на конкретное событие реализует имеющаяся у некоторого объекта процедура. Если ни один из объектов в системе не имеет процедуры для обработки данного события, система не среагирует на данное событие и оно останется безответным. Другими словами можно сказать, что действия, происходящие в системе, являются событиями, а отклики на них обеспечиваются процедурами обработки этих событий у объектов. Про- цедуры, генерирующие отклик на событие, называются процедурами обработки событий. Каждая из таких процедур представляет собой специально созданную программу, которая автоматически выполняется, когда происходит связанное с ней событие, и определяет, что должен делать объект в ответ на распознаваемое событие. При наступлении соответствую- щего события объект автоматически предпринимает запрограммированные в процедуре действия, при этом саму процедуру обработки событий вызывать из каких-либо других Глава 8. Объекты и коллекции 137
процедур или функций не требуется. Если программа не должна отвечать на некоторое со- бытие, достаточно просто не создавать в ее объектах процедуру обработки этого события. В среде Office события происходят на уровне документа или на уровне объектов в доку- менте, например к событиям можно отнести открытие и закрытие документа, добавление и удаление страниц (такие события в Word распознаются объектами Application и Doc- ument). А в некоторых случаях события происходят на уровне приложения. Подробнее о событиях мы будем говорить при рассмотрении компонентов экранных форм, в главе 10. В среде Windows управление состоянием элемента (а точнее — представляющего его объекта) осуществляется с помощью посылаемых ему сообщений, указывающих на не- обходимость выполнить тот или иной метод для достижения требуемого результата. Сами сообщения генерируются системой в ответ на действия пользователя. Понятие о классах и иерархии объектов Одним из важнейших понятий объектно-ориентированного программирования явля- ется класс. Это понятие описывает типовую структуру сходных по назначению элементов, представляемых объектами. В системе хранится программное описание каждого известно- го ей класса, на основании которого при необходимости создаются экземпляры объектов, представляющие собой конкретные элементы программной среды. Экземпляры объектов данного класса содержат реальные данные. Например, в программе может быть описан класс кнопки, отображаемой в окнах приложения. Каждая отдельная кнопка (экземпляр объекта этого класса) в любом окне приложения создается на основании этого общего описания, но отличается от других значением своих свойств (размером, расположением в окне, цветом, надписью, выполняемой по щелчку операцией и т.д.). В частности, сами приложения Microsoft Word, Excel, Access, PowerPoint также представлены в среде Windows объектами, принадлежащими к общему классу объектов — классу приложений VBA (объ- ект Application — см. рис. 8.4). Класс определяет назначение объекта, набор его свойств и те действия, которые мо- гут быть выполнены этим объектом и над ним. Каждый класс объектов может содержать один или несколько подклассов, описывающих свойства-объекты, вложенные в него. Объекты, принадлежащие к определенному классу объектов, называются членами этого класса. На основании одного класса можно создать сколько угодно самостоятельных объектов для дальнейшего использования каждого из них в различных целях. Например, при открытии или создании документа в приложении Word создается экземпляр объекта класса Document — Document 1, при открытии следующего документа будет создан еще один экземпляр объекта этого же класса — Document2 и т.д. Все эти экземпляры объек- тов Document 1, Document2, ... будут принадлежать к одному и тому же классу Docu- ment приложения Word и являться членами коллекции Documents (рис. 8.5). Обобщим сказанное выше. В VBA класс представляет собой шаблон, по которому соз- даются подобные объекты, — именно этот шаблон описывает программист при разработ- ке приложения. Чтобы использовать класс как шаблон, необходимо создать на его основе объект или, как принято говорить, экземпляр объекта. После того как класс определен и зарегистрирован в системе, на его основе можно создать произвольное количество объ- ектов (экземпляров), каждый из которых будет полностью независим от других. Следует понимать, что объекты в памяти компьютера создаются не при написании программы, а при ее выполнении, и уничтожаются при ее завершении. 138 Часть 2. Основы программирования на VBA
[Application ~| -[Documents | -[Document 1 | |-|Document 2 | —[Dialogs | Hoijlog | > Puc. 8.5. Фрагмент объектной модели приложения Microsoft Word Язык VBA предоставляет пользователю возможность создавать свои собственные клас- сы объектов, что достигается с помощью добавления модуля класса в проект. Добавляемый модуль класса должен содержать определения всех свойств и методов объектов данного типа. После создания и регистра- ции класса его можно использовать как в данной программе, так и в других программах, причем заново программировать реализацию его свойств и методов уже не потребуется, доста- точно лишь знать их имена. Это одно из полезнейших след- ствий инкапсуляции, благодаря которому функциональные возможности класса будут доступны даже в том случае, когда мы ничего не знаем о способе их реализации. Модули классов Как мы уже говорили выше, в VBA класс существует в собственном модуле класса, а поэтому, чтобы создать но- вый класс, необходимо прежде всего создать новый модуль класса в VBA-проекте. Для этого выберите команду меню Inserts Class Module — раскрывшееся окно модуля класса выглядит и работает так же, как и обычное окно программ- ного кода. Когда модуль некоторого класса активен, его свойства отображаются в окне Properties. Вновь созданный модуль класса содержит два свойства (рис. 8.6): Name — название класса, которое должно быть присвоено при его создании (желательно, чтобы оно так или иначе описывало функцию этого класса), и Instancing — это свойство опреде- ляет область использования создаваемого класса (по умол- чанию принимается значение 1, эквивалентное объявлению Private в других модулях, т.е. класс можно будет использо- вать только в пределах данного проекта). После присвоения классу имени можно приступать к написанию программно- го кода, т.е. к добавлению в созданный вами класс свойств, содержащих данные, а также методов, выполняющих те или иные действия. Normal Й Project (Документ!) S €3 Microsoft Word Objects ThsDocument Й Class Modules Classi ffi Ll’ References Рис. 8.6. Представление вновь созданного класса в окне свойств Глава 8. Объекты и коллекции 139
Если класс является частью проекта, то описываемый им тип данных будет доступ- FA ным во всем проекте, а его имя будет доступно в автоматически формируемых списках VBA, так же как его методы и свойства. Пусть в рамках создаваемого в Microsoft Word приложения необходимо работать с дан- ными о книгах. При обработке потребуются такие сведения, как наименование книги, автор, год издания и издательство. Подготовим для этой цели соответствующий объект Book с четырьмя свойствами: Title, Author, PublishYear и Publisher соответствен- но. Создайте новый модуль класса, как описано выше, и в окне свойств дважды щелкните в поле значения свойства Name, введите в нем значение Book и нажмите <Enter> или щелкните мышью в любом месте окна редактора кода. Нашему вновь созданному классу присвоено имя Book. Теперь необходимо сделать объявления всех констант и переменных, которые будут использоваться в теле описания класса. В нашем случае это внутренние (закрытые) пере- менные, предназначенные для хранения значений свойств объекта, и константа, пред- ставляющая собой стандартное значение для отсутствующих свойств. Const Omitted = "Отсутствует" Dim bookTitle As String ’Переменная класса для свойства Title Dim bookAuthor As String ’Переменная класса для свойства Author Dim bookYear As Date ’Переменная класса для свойства PublishYear Dim bookPublisher As String ’Переменная класса для свойства Publisher Обратите внимание: при создании нового модуля класса в него автоматически заносит- ся первая строка Option Explicit. Этот оператор устанавливает для модуля режим обязательного объявления всех используемых переменных — т.е. в модулях классов ис- пользовать переменные без их предварительного объявления запрещается. Теперь опишем для нашего класса необходимые свойства. Создание свойств класса Создание свойства класса предусматривает программную реализацию хранения его значения и доступа к нему. Для этого можно воспользоваться двумя способами. Самый простой — определить в модуле класса свойство как открытую переменную (тип Public). В результате в© всех модулях, для которых описание данного класса будет видимым, будет доступно свойство с тем же именем, что и у объявленной переменной. Причем доступ к этому свойству будет разрешен всем как для чтения, так и записи, и объект не будет иметь возможности контролировать этот доступ и вносимые изменения. Например, можно подобным образом определить в нашем классе Book переменную bookcover логического типа, описывающую тип переплета — твердый (значение True) или мягкий (значение False). Public Hardcover As Boolean В данном случае доступ к этому свойству класса Book очень прост. Пусть в приложе- нии существует объект класса Book с именем FirstBook. Тогда для присвоения нового значения его свойству Hardcover достаточно записать следующее. FirstBook.Hardcover = False ’ Переплет мягкий 140 Часть 2. Основы программирования на VBA
Как видите, данный метод описания свойств очень прост, но имеет существенные не- достатки: нельзя запретить изменение значения свойства извне, нельзя предварительно проконтролировать или изменить со стороны самого объекта вновь присваиваемое его свойству значение и т.д. Все это идет вразрез с основными постулатами инкапсуляции, поэтому данный метод определения свойств класса использовать не рекомендуется. Описание свойств с использованием процедур доступа Второй способ более строгий и предполагает создание не только переменной класса, где будет храниться собственно значение свойства, но и специальных процедур (подпро- грамм) для доступа к нему. Существует три типа таких процедур: в Property Let — присваивает свойству новое значение, т.е. с ее помощью в про- грамме (вне класса) можно будет задать новое значение свойства; в Property Get — возвращает текущее значение свойства, т.е. с ее помощью в про- грамме (вне класса) можно будет получить текущее значение свойства; в Property Set — помещает в свойство ссылку на указанный объект, т.е. с ее по- мощью в программе (вне класса) можно будет задать новое значение свойства, если оно представляет собой ссылку на объект. Если для свойства подготовить пару процедур: Let и Get (или Let и Set для свойства объектного типа), то доступ к данному свойству извне будет возможен как для чтения, так и для записи. Если же подготовить только процедуру Get, то доступ к данному свойству извне будет возможен только для чтения, и никто, кроме внутренних подпрограмм самого объекта, не сможет изменить его значение. Процедуры Property Let, Property Set и Property Get — это процедуры свойств, обеспечивающие доступ к свойству объекта. Процедура Property Let (или Set) уста- НКЗ навливает новое значение свойства, т.е. присваивает переданное ей в виде аргумента значение переменной, представляющей данное свойство в объекте. Процедура Property Get возвращает в программу значение свойства. Синтаксис этой процедуры подобен синтаксису процедур типа Function, т.е. значение, которое долж- но быть возвращено, присваивается имени процедуры, которое в данном случае явля- ется именем свойства. Типовой синтаксис записи процедуры типа Let выглядит следующим образом. Property Let имя ([аргументы, ] значение) (операторы) End Property Здесь параметр имя задает свойство, значение которого изменяет данная процедура, а параметр значение — это переданная извне величина, определяющая новое значение свойства. Необязательный параметр аргументы представляет дополнительные данные, которые могут передаваться в процедуру изнутри класса для предварительной обработки или контроля величины значение. Выражение (операторы) представляет произвольную последовательность операторов языка VBA, с помощью которой необходимым образом контролируются и обрабатываются поступившие на вход подпрограммы данные и, в ко- нечном итоге, помещается требуемое значение в переменную класса, представляющую данное свойство. Рассмотрим конкретный пример — процедуру Let для свойства Title. Глава 8. Объекты и коллекции 141
Property Let Title(NewTitle As String) bookTitle = NewTitle ’ Сохранение нового значения свойства End Property Эта процедура обеспечивает присвоение свойству Title объекта класса Book нового значения, передаваемого извне в переменной NewTitle и сохраняемого в переменной класса bookTitle. Типовой синтаксис записи процедуры типа Get выглядит следующим образом. Property Get имя [{аргументы)] [As тип] {опера торы) End Property Здесь параметр имя задает свойство, значение которого считывает данная процедура. Необязательный параметр аргументы представляет дополнительные данные, которые могут передаваться в процедуру изнутри класса для предварительной обработки возвра- щаемого значения свойства, а необязательный параметр тип может задавать тип возвра- щаемого подпрограммой значения. Выражение (операторы) представляет произвольную последовательность операторов языка VBA, с помощью которой сохраняемое в перемен- ной класса значение свойства необходимым образом обрабатывается перед тем, как будет передано за пределы класса. Рассмотрим конкретный пример — процедуру Get для того же свойства Title. Property Get Title () As String Title = bookTitle ' Считывание текущего значения свойства End Property Эта процедура возвращает текущее значение свойства Title объекта класса Book, со- храняемого в переменной класса bookTitle. Как видите, если для некоторого свойства класса (в нашем примере это свойство Title, значение которого сохраняется в переменной класса bookTitle) описать обе процедуры Get и Let, извне класса можно будет как счи- тывать, так и устанавливать новое значение этого свойства. Если же описать только проце- дуру Get, значение свойства можно будет только считывать, поскольку переменная класса bookTitle, в которой в действительности хранится значение данного свойства, вне класса не видна, а значит, недоступна. Однако в пределах класса она будет вполне доступна и его внутренние подпрограммы при необходимости смогут поместить в нее новое значение. Хотя в нашем классе Book нет свойств объектного типа, для полноты картины при- ведем синтаксис процедуры помещения нового значения в подобные свойства (процедура Set). Property Set имя [{аргументы, ] ссылка) {операторы) End Property Здесь смысл параметров имя и аргументы тот же, что и для процедуры Let, а параметр ссылка — это передаваемая извне ссылка на объект, который следует поместить в данный объект как значение его свойства объектного типа. Для изменения значения свойств объектного тина VBA позволяет использовать как vQ процедуры Let, так и Set, тем не менее для таких свойств рекомендуется всегда ис- ЬМ пользовать именно процедуры Property Set. 142 Часть 2. Основы программирования на VBA
Полный текст процедур для класса Book Закончив с теорией, попробуем собственными силами определить все необходимые процедуры нашего класса Book. Для добавления нового свойства в модуль класса выпол- ните следующие действия. 1. В окне Project щелкните мышью на имени требуемого класса и в окне кода по- местите курсор ввода сразу после уже введенного определения констант и пере- менных класса. 2. Выберите команду меню Inserts Procedure (рис. 8.7). Рис. 8.7. Добавление в код класса новой процедуры 3. В раскрывшемся диалоговом окне Add Procedure (рис. 8.8) установите переключа- тель Туре в положение Property (свойство) и введите имя свойства в поле Name — именно это имя будет использоваться для доступа к свойству. Переключатель Scope установите в положение, определяющее требуемую область видимости данного свойства (по умолчанию выбрано Public). Щелкните на кнопке ОК. 4. В текст модуля будут включены заготовки процедур Property Get и Property Let, как показано на рис. 8.9. Глава 8. Объекты и коллекции 143
Рис, 8.8. Добавление свойства в диалоговом окне Add Procedure Рис. 8.9. В текст модуля класса добавлены заготовки процедур свойств 5. Измените текст заготовок процедур так, как было показано выше в примерах для этого свойства. Теперь вся подготовительная работа по определению свойства Title закончена. 6. Аналогичным образом создайте процедуры Get и Let для трех остальных свойств класса. Полный текст модуля класса Book на данный момент показан в листинге 8.4. Листинг 8.4. Описание процедур свойств в модуле класса Book Option Explicit ’ Описание класса Book, представляющего информацию о книге Const Omitted = "Отсутствует" 144 Часть 2. Основы программирования на VBA
Dim bookTitle As String ’Переменная класса для свойства Title Dim bookAuthor As String ’Переменная класса для свойства Author Dim bookYear As Date ’Переменная класса для свойства PublishYear Dim bookPublisher As String ’Переменная класса для свойства Publisher Public Property Get Title() As String Title = bookTitle ’ Считывание текущего значения свойства End Property Public Property Let Title(NewTitle As String) bookTitle = NewTitle ’ Сохранение нового значения свойства End Property Public Property Get Author() As String Author = bookAuthor ’ Считывание текущего значения свойства End Property Public Property Let Author(NewAuthor As String) bookAuthor = NewAuthor ’ Сохранение нового значения свойства End Property Public Property Get PublishYear() As Date PublishYear = bookYear ’ Считывание текущего значения свойства End Property Public Property Let PublishYear(NewYear As Date) bookYear = NewYear ’ Сохранение нового значения свойства End Property Public Property Get Publisher() As String Publisher = bookPublisher ’ Считывание текущего значения свойства End Property Public Property Let Publisher(NewPublisher As String) bookPublisher = NewPublisher ’ Сохранение нового значения свойства End Property Обратите внимание на то, что в листинге 8.4 все процедуры свойств класса Book объяв- лены как открытые (Public), поэтому они будут доступны извне класса, что нам и тре- бовалось. Все эти процедуры очень просты и фактически состоят из одного оператора, но это сделано лишь для упрощения примера. Ничто не мешает сделать любую из процедур сколь угодно сложной. Например, для процедуры Let свойства PublishYear полезно было бы добавить операторы проверки записываемого значения — оно не должно быть больше текущей даты. Иначе говоря, книга не может быть издана “завтра”, такая дата — явная ошибка, и запись подобных значений в свойство имеет смысл блокировать. Создание методов класса Как уже говорилось, метод — это не что иное, как процедура внутри модуля класса. В классе могут быть созданы методы, возвращающие значение (процедуры-функции) или Глава 8. Объекты и коллекции 145
не возвращающие значение (процедуры типа Sub). Все, что было сказано в главе 7 о про- цедурах, в полной мере относится также и к методам — так, для создания метода в модуле класса используется та же команда Insert Procedure и соответствующее диалоговое окно. При создании методов не забывайте: чтобы этот метод был доступен вне класса, он должен быть объявлен с ключевым словом Public — именно этот вариант принимается по умолчанию в диалоговом окне Add Procedure. Чтобы сделать метод доступным только в пределах данного класса, т.е. чтобы он мог вызываться только из других методов этого класса, но был недоступен вне его, замените в объявлении ключевое слово Public на Private. Обратите внимание на сходство между методами-функциями и процедурами Property Get. И те, и другие возвращают значение вызывающей программе. Фактически, с точ- ки зрения программиста, они просто неразличимы. Например, в выражении х = Ob j ect 1. Value невозможно определить, чем является Value — свойством или функ- цией. На самом деле это и неважно — для данных, которые возвращаются из объекта (особенно данных, доступных только для чтения), можно использовать как процедуру свойства, так и некоторую функцию (метод). Итак, с точки зрения написания кода, методы класса отличаются от обычных процедур и функций только тем, что размещаются в модуле класса, а не в обычном программном модуле. Поэтому не углубляясь больше в теорию, просто создадим метод Showinfo для нашего класса Book. Его назначение — собрать в одну строку текущие значения свойств класса в виде последовательности автор, заголовок, издательство, год издания и вывести эту строку в окне сообщения. Поскольку этот метод не возвращает значения, он является процедурой типа Sub. Чтобы добавить его в модуль класса, создайте новую процедуру с именем Showinfo, как описано выше (см. рис. 8.7 и 8.8), но при этом переключатель Туре в окне Add Procedure установите в положение Sub. Текст метода скопируйте в окно кода из листинга 8.5. Листинг 8.5. Текст метода Showinfo Public Sub Showinfo() ’Метод класса - вывод строки описания книги Dim strinfo As String strinfo = "Сведения о книге: " strinfo = strinfo & bookAuthor & ", ’" strinfo = strinfo & bookTitle & "’, " strinfo = strlnfo & bookPublisher & ", " If bookYear > #12:00:00 AM# Then ’ Свойство заполнено? strlnfo = strlnfo & Format(bookYear, "yyyy") Else ’ Нет, выводится заменяющее значение strlnfo = strlnfo & Omitted End If MsgBox (strlnfo) ’ Вывод строки описания на экран End Sub Как видите, текст метода очень прост. Сначала объявляется строковая переменная strlnfo, затем ее значение формируется из текущих значений свойств объекта, после чего полученная строка выводится в окне сообщений. 146 Часть 2, Основы программирования на VBA
События класса В VBA с собственно классами связаны два стандартных события — Initialize и Terminate. Событие Initialize генерируется при инициализации (т.е. создании) нового экземпляра данного класса. Процедуру обработки этого события можно исполь- зовать для задания требуемых исходных значений свойств и других переменных объекта. Иначе говоря, эта процедура позволяет привести переменные класса в требуемое исходное состояние. Событие Terminate генерируется непосредственно перед уничтожением данного экземпляра объекта. В процедуру обработки этого события можно поместить код, осу- ществляющий очистку используемых объектом переменных или же сохранение данных уничтожаемого объекта в некотором файле. Тем не менее чаще всего процедура обработки этого события остается нереализованной. В качестве примера определим в нашем классе процедуру обработки события Ini- tialize, которое VBA генерирует при создании любого объекта любого класса и пере- дает этому же вновь созданному объекту. Если в этом объекте имеется подпрограмма обработки данного события, она выполняется, если нет — событие просто остается необ- работанным. Воспользуемся этим событием для того, чтобы привести значения свойств вновь созданного объекта класса Book в исходное состояние. Общий синтаксис записи процедур обработки событий в модулях классов следующий. Private Sub объект_событие() (операторы) End Sub Здесь параметр объект представляет имя класса, в котором создается данная процедура, а параметр событие — название события, которое обрабатывается данной процедурой. И как всегда, параметр (операторы) представляет произвольную последовательность VBA- операторов, выполняющих необходимую обработку. В нашем примере процедура обработ- ки события Initialize в классе Book будет выглядеть так, как показано в листинге 8.6. Ее текст совсем несложен — в ней четыре оператора, с помощью которых строковым свойствам класса присваивается значение "Отсутствует” (для этой цели используется специально определенная именованная константа класса Omitted), а свойству даты пу- бликации — значение “нулевой” даты в формате VBA. Листинг 8.6. Процедура обработки события Initialize для класса Book Private Sub Class_Initialize() bookTitle = Omitted ’ Инициализация свойства Title bookAuthor = Omitted ’ Инициализация свойства Author bookYear = #12:00:00 AM# ’ Инициализация свойства PublishYear bookPublisher = Omitted ’ Инициализация свойства Publisher End Sub Вставка процедуры обработки события в модуль класса выполняется очень просто. В окне кода в верхнем левом списке выберите значение Class (рис. 8.10, а) — при этом в правом списке появится перечень описанных для данного класса событий. Выберите в правом списке значение Initialize, и редактор кода автоматически добавит в модуль класса заготовку для процедуры обработки этого события (рис. 8.10, б). Скопируйте в заготовку процедуры Class_Initialize текст из листинга 8.6. Глава 8. Объекты и коллекции 147
strinfo = "Сведения о книге: " strinfo strinfo & bookAuthor & ", strinfo ” strlnfc & bookTitle 4 " strinfo « strlnfc & bookPublisher L ", " If bookYear > #12:00:00 AM# Then ’ Свей сова заполнено? strinfo - strlnfc & Format(bookYear, "yyyy*> Else • Нет, выводится заг-жняюаее значение strlnfc = strlnfc i Omitted End If MsgBox (strlnfc) ‘ Вывел строки описания на экран End Sub а) б) Рис. 8.10. Добавление в модуль класса подпрограммы обработки события В VBA при создании подпрограмм обработки событий нельзя применять именованные и необязательные параметры, а также параметры типа ParamArray. Помимо стандартных системных событий, в языке VBA возможно определение и поль- зовательских событий. Определять такое событие в классе имеет смысл тогда, когда требуется обеспечить реакцию класса на изменение его состояния или некоторую внеш- нюю ситуацию. При этом, помимо описания данного события, в модуле класса потребуется позаботиться о генерации этого события в одной из подпрограмм данного класса. Описание собственного события класса выполняется с помощью оператора Event. 148 Часть 2. Основы программирования на VBA
[Public] Event имя_события[(список_аргументов)] Здесь имя_ события задает имя определяемого события, а параметр список_аргументов позволяет указать, какие параметры и какого типа должны быть переданы при генерации события в процедуру его обработки. Генерация пользовательского события осуществляется с помощью специального опе- ратора RaiseEvent, имеющего следующий синтаксис. RaiseEvent имя_события[(список_аргументов)] Здесь параметр имя_события представляет собой имя генерируемого пользовательского события, а необязательный параметр список_аргументов задает список аргументов, передаваемых в процедуру обработки этого события. В качестве примера определения пользовательского события воспользуемся обсуждав- шейся выше, но пока не реализованной идеей — обеспечим проверку на допустимость значения, передаваемого в свойство Publish Yea г класса. Речь идет о предотвращении записи в это свойство года, превышающего текущий, — книга не может быть изданной в году, который еще не наступил. Для реализации проверки нам потребуется вставить в процедуру Let свойства PublishYear условный оператор, сравнивающий переданное значение с годом текущей даты. Если значение меньше или равно, все в порядке, ошибки нет. В противном случае генерируется событие Ye ar Mi stake и ошибочное значение от- брасывается, а свойство PublishYear остается без изменения (листинг 8.7). Листинг 8.7. Расширенная версия процедуры Property Let для свойства PublishYear Public Property Let PublishYear(NewYear As Date) If Format(NewYear, "yyyy") <= Format(Date, "yyyy") Then bookYear = NewYear ’ Сохранение нового значения свойства Else ' Генерация события извещения об ошибке RaiseEvent YearMistake(NewYear) End If End Property Далее необходимо добавить в модуль какого-то другого класса из данного проекта про- цедуру обработки события YearMistake и обеспечить его перехват объектом этого класса. Для решения последней задачи используется специальное ключевое слово WithEvents: в раздел объявлений перехватывающего класса помещается следующий оператор. Private WithEvents имя_переменной As класс_отправитель Здесь параметр имя_переменной задает имя переменной объектного типа, а параметр кла с с_ отправит ель — имя класса объекта, генерирующего перехватываемое событие. Добавляется процедура обработки события так же, как и процедура обработки события Initialize. После ввода оператора Private WithEvents выберите указанное в нем значение имя_переменной в левом верхнем списке окна кода, и в правом списке будут представлены все события, объявленные в классе класс_отправитель. Выберите требуемое событие, и в модуль класса будет вставлена заготовка соответствующей про- цедуры обработки. Чтобы не усложнять наш пример созданием еще одного класса, при- ведем лишь схематический код процедуры, перехватывающей и обрабатывающей событие YearMistake (листинг 8.8), которая просто выводит сообщение об ошибке. Однако, Глава 8. Объекты и коллекции 149
помимо вывода сообщения, в подобных процедурах можно выполнять и любые другие действия, необходимые для продолжения работы программы. На этом в обсуждении соб- ственных событий и ограничимся. Листинг 8.8. Процедура обработки события YearMistake Public Sub переменной—YearMistake (MisDate As Date) MsgBox ("Значение года публикации ’’ _ Format(MisDate, "yyyy") & " недопустимо") End Sub Наконец-то наш класс Book окончательно готов — его полный текст представлен в листинге 8.9. Однако для придания рассматриваемому примеру завершенности необходи- мо еще подготовить обычную процедуру, в которой будет продемонстрировано, как этот класс можно использовать на практике. Листинг 8.9. Полный текст класса Book Option Explicit ’ Описание класса Book, представляющего информацию о книге Const Omitted = "Отсутствует" Public Event YearMistake() ’(MisDate As Date) Dim bookTitle As String ’Переменная класса для свойства Title Dim bookAuthor As String ’Переменная класса для свойства Author Dim bookYear As Date ’Переменная класса для свойства PublishYear Dim bookPublisher As String ’Переменная класса для свойства Publisher Public Property Get Title() As String Title = bookTitle ’ Считывание текущего значения свойства End Property Public Property Let Title(NewTitle As String) bookTitle = NewTitle ’ Сохранение нового значения свойства End Property Public Property Get Author() As String Author = bookAuthor ’ Считывание текущего значения свойства End Property Public Property Let Author(NewAuthor As String) bookAuthor = NewAuthor ’ Сохранение нового значения свойства End Property Public Property Get PublishYear() As Date PublishYear = bookYear ’ Считывание текущего значения свойства End Property Public Property Let PublishYear(NewYear As Date) 150 Часть 2. Основы программирования на VBA
If Format(NewYear, "yyyy") <= Format(Date, "yyyy") Then bookYear = NewYear ' Сохранение нового значения свойства Else ' Генерация события извещения об ошибке RaiseEvent YearMistake(NewYear) End If End Property Public Property Get Publisher() As String Publisher = bookPublisher ' Считывание текущего значения свойства End Property Public Property Let Publisher(NewPublisher As String) bookPublisher = NewPublisher ' Сохранение нового значения свойства) End Property Public Sub Showinfo() 'Метод класса - вывод строки описания книги Dim strinfo As String strinfo = "Сведения о книге: " strinfo = strinfo & bookAuthor & ", strinfo = strinfo & bookTitle & "', " strinfo = strinfo & bookPublisher & ", " If bookYear > #12:00:00 AM# Then ' Свойство заполнено? strinfo = strinfo & Format(bookYear, "yyyy") Else ' Нет, выводится заменяющее значение strinfo = strinfo & Omitted End If MsgBox (strinfo) ' Вывод строки описания на экран End Sub Private Sub Class_Initialize() bookTitle = Omitted ' Инициализация свойства Title bookAuthor = Omitted ' Инициализация свойства Author bookYear = #12.\00:00 AM# ' Инициализация свойства PublishYear bookPublisher = Omitted ' Инициализация свойства Publisher End Sub Пример использования класса Создайте в текущем проекте новый программный модуль и присвойте ему имя Use- Book. Добавьте в этот модуль процедуру Testclass, с помощью которой проверим ра- боту только что созданного класса. Поскольку в этом модуле мы собираемся работать с классом Book, прежде всего нам потребуется создать экземпляр объекта этого класса. Для этого в операторе Dim объявим объектную переменную myBook с типом Book, а затем с помощью оператора Set присвоим ей значение в виде вновь созданного объекта данного класса (подробнее о создании объектов и работе с объектными переменными речь пойдет ниже, в этой же главе). Dim myBook AS Object Set myBook = New Book Глава 8. Объекты и коллекции 151
Как только объект myBook будет создан, откроется доступ к его свойствам и мето- дам, который осуществляется по тем же правилам, что и к любым другим объектам VBA (подробнее об этом ниже). Так, чтобы присвоить свойству Title этого объекта значение "Война и Мир", достаточно записать следующее. myBook.Title = "Война и Мир" Однако прежде чем присваивать свойствам вновь созданного объекта myBook класса Book некоторые конкретные значения, давайте проверим, как сработала подпрограмма об- работки события Initialize, которая должна была присвоить всем свойствам класса ис- ходные значения. Для этого поместим в текст модуля оператор MsgBox следующего вида. MsgBox (myBook.Author & myBook.Title _ & myBook.Publisher & myBook.PublishYear) Этот оператор должен вывести на экран окно сообщения с текущими значениями свойств объекта5. Выполним присвоение всем свойствам объекта некоторых значений и вновь воспользуемся приведенным выше оператором MsgBox для отображения текущих измененных значений свойств объекта. И наконец, остается последняя проверка — вы- звать метод класса Showinfo, чтобы убедиться в корректности его работы. Полный текст подпрограммы Testclass приведен в листинге 8.10, а результаты ее выполнения — на рис. 8.11 (композиция из последовательно отображаемых окон). Листинг 8.10. Подпрограмма TestClass, выполняющая проверку работы объекта класса Book Sub TestClass () ’ Определение переменной и создание нового объекта класса Book Dim myBook As Object Set myBook = New Book ’ Считывание и отображение значений свойств нового объекта MsgBox (myBook.Author & myBook.Title _ & myBook.Publisher & myBook.PublishYear) ’ Установка значений свойств объекта myBook.Author = "Л.H.Толстой" myBook.Title = "Война и Мир" myBook.Publisher = "М. из-во Эксмо" myBook.PublishYear = #3/1/2005# ’ Считывание и отображение значений свойств заполненного объекта MsgBox (myBook.Author & myBook.Title _ & myBook.Publisher & myBook.PublishYear) ’Проверка работы метода объекта myBook.Showinfo End Sub 5 Запись myBook. Author означает обращение к подпрограмме Get свойства Author для получения текущего значения этого свойства. Подробнее об этом в следующем разделе. 152 Часть 2. Основы программирования на VBA
Рис. 8.11. Результаты выполнения подпрограммы Testclass * После того как нужный класс создан и протестирован, его сразу же можно исполь- зовать в текущем проекте. Созданный класс может также неоднократно использоваться и в других проектах, однако для этого его нужно предварительно специальным образом подготовить — экспортировать. Для экспорта созданного в вашем проекте класса выпол- ните следующие действия. В окне Project щелкните мышью на имени нужного вам класса. Выберите команду меню File^ Export File и в раскрывшемся на экране диалоговом окне Export File укажите место сохранения экспортируемого файла. Убедитесь, что в списке Тип файла выбрано значение Class Files (*.cls), указывающее, что копируемый файл представляет собой файл исходного кода VBA. Обычно именно это значение выбирается в данном списке по умолчанию. Для завершения опера- ции экспорта файла щелкните на кнопке Сохранить. Глава 8. Объекты и коллекции 153
Теперь, чтобы использовать данный класс в другом проекте, его надо в этот проект импортировать. Для этого выполните следующие действия. Выберите в окне Project Explorer необходимый проект, т.е. тот проект, в котором требуется использовать данный класс, сделайте активным. Выберите команду меню File^ Import File. В раскрывшемся диалоговом окне Import File убедитесь, что в списке Тип файла выбрано значение Files of Type (*.frm, *.bas, *.cls), а затем укажите экспортированный файл с требуемым классом. Щелкните на кнопке Open. В результате требуемый класс будет доступен и в этом проекте. Следует заметить, что при изменении кода реализации класса в исходном проекте необ- ходимо будет повторно экспортировать его в файл, а затем импортировать измененный файл во все проекты, где этот класс используется. Иерархия объектов В объектной библиотеке VBA содержатся десятки различных классов системных объектов, находящихся на различных уровнях иерархии. С помощью иерархии устанав- ливается связь между классами и показываются пути доступа к каждому объекту. Так, на рис. 8.4 приведена часть объектной модели (иерархии) приложения Microsoft Excel, а на рис. 8.5 — приложения Microsoft Word. В языке VBA доступ к конкретному объекту можно получить без перемещения по ие- рархии объектов. Для обращения к нужному объекту достаточно использовать полную ссылку на объект, составленную из имен вложенных друг в друга объектов. Например, в Excel полная ссылка на рабочий лист Лист1 рабочей книги Архив будет иметь такой вид. Application .Workbooks (’’Архив”) .Worksheets (”Лист1”) Однако использовать полную ссылку на объект нет необходимости, если в данный момент вы работаете непосредственно с рабочей книгой Архив, т.е. именно этот объект является активным. В этом случае можно использовать сокращенное имя. Worksheets(”Лист1”) Возможность использования конкретных сокращенных имен зависит от прило- жения, в котором выполняется программа пользователя, и от состояния этого при- ложения. Так, при работе с приложением Word приведенное выше сокращенное имя Worksheets (”Лист1 ”) не будет иметь смысла, так как программа в данном случае на- ходится вне среды Excel, в которой только и могут существовать объекты этого класса. Однако следует заметить, что в приложениях Microsoft Office, включая и Word, имеются также классы объектов с одинаковыми именами. Создание и идентификация объектов Любой созданный в программе объект существует в оперативной памяти компьюте- ра. При работе с объектами нам не требуется оперировать действительными адресами памяти — работа с объектами проводится с использованием ссылок. Объектная ссылка представляет собой переменную, хранящую адрес, определяющий то место в памяти, где размещается объект, на который выполняется ссылка. Хотя на один и тот же объект мож- 154 Часть 2. Основы программирования на VBA
но создать несколько ссылок, следует помнить, что в памяти всегда будет присутствовать только одна копия (экземпляр) этого объекта, однако вполне могут существовать экзем- пляры других объектов этого же типа (класса). Прежде чем использовать ссылку на объект в программе, необходимо создать переменную, в которой эта ссылка будет храниться, за- тем создать экземпляр требуемого объекта, получить ссылку на него (адрес его размеще- ния в памяти) и присвоить ее как значение этой предварительно созданной переменной. Объектные переменные Объектные переменные объявляются точно так же, как и переменные любого типа. Мы уже знаем, что объявлять переменные нужно обязательно, при этом желательно указывать их тип данных. Поэтому переменная, которая будет содержать ссылку на некоторый объ- ект, должна быть объявлена с соответствующим типом. Объектную переменную можно объявить с помощью стандартного оператора Dim, используемого в языке VBA для объяв- ления переменных всех остальных типов. Напомним, что в этом операторе тип данных создаваемой переменной можно указывать или не указывать — в последнем случае для переменной будет принят тип Variant, общий тип данных языка VBA, который именно поэтому обычно и принимается по умолчанию. Dim 0бъект1 Dim 0бъект2 As Variant В обоих случаях объявленные переменные будут иметь тип Variant, и в них можно будет хранить как ссылки на объекты, так и любые другие данные, например строки или числа. Однако если переменная будет использоваться только для хранения ссылок на объ- екты, то объявлять ее следует с типом ОЬ j ect (см. листинг 8.10). Dim Объект As Object Переменную типа Object при, необходимости можно использовать для хранения ссы- лок на объекты любого типа (класса), однако ее нельзя будет использовать для хранения данных не объектных типов — таких как числа или строки. Переменную, которая должна хранить ссылку на объект, можно также объявить с ука- занием конкретного типа (класса) объекта, для которого предназначена создаваемая пере- менная. Следует заметить, что это очень удобно, так как VBA в этом случае не позволит поместить в такую переменную объекты других классов. Dim Документ As Word.Document Здесь создается переменная Документ, в которую можно будет помещать ссылки только на объекты указанного типа (Word. Document). Если переменной при объявлении сразу назначается определенный класс объектов (как тип ее данных), то такой метод объяв- ления объектной переменной называется ранним связыванием (early binding). Вот пример раннего связывания для среды Excel. Dim Приложение As Excel.Application Однако для того чтобы использовать механизм раннего связывания, проект должен со- держать ссылку на соответствующую библиотеку типов. Для этого выберите в редакторе VBA команду меню Tools^References (Сервис*=>Ссылки). Откроется диалоговое окно, показан- ное на рис. 8.12. Для создания ссылки нужно установить флажок напротив названия объект- ной библиотеки, а затем можно объявлять объектные переменные интересующего типа. Глава 8. Объекты и коллекции 155
References Project Available References: Я Visual Basic For Applications Й Microsoft Word 14.0 Object Library 5? OLE Automation < Normal____________________________ 3 □ IAS Helper COM Component 1.0 Type Library □ IAS RADIUS Protocol 1.0 Type Library О:-) VideoSoft VSFIexGnd 7.0 (Light) □ AcAuthEnbbeslTENU.tlb 1.0 Type Library □ AcCtrl Component ' \ AcDwgFilterlmp 1.0 Type Library □ AcHelp 1.0 Type Library □ AcInetEngme 16.0 Type Library I,AcObiClassImp L0 Type Library xj Priority Microsoft Office 14.0 Object Library Location: C: program Files ^Common Files’Microsoft Shared office 14Vnsc Language: Standard Puc. 8.12. Создание ссылок на объектные библиотеки в приложении Word 2010 Когда переменная объявляется с типом Object — общим объектным типом, что по- зволяет помещать в эту переменную ссылки на объекты любого типа (класса), используе- мый метод называется поздним связыванием (late binding). Dim Объект As Object Одним из преимуществ позднего связывания является возможность создания кода, определяющего наличие или отсутствие необходимой библиотеки типов на компьютере, а также создающего связи с разными версиями приложений в зависимости от принятых решений в процессе выполнения кода. Недостаток позднего связывания — недоступность библиотеки типов интересующего приложения в процессе написания кода. Таким образом, отсутствует справочная ин- формация о приложении, недоступны встроенные константы приложения, а ссылки на интересующее приложение не всегда действительны в процессе компиляции, так как их правильность нельзя проверить. Связи полностью проверяются только в процессе выпол- нения кода, а это требует определенных затрат времени, при этом на этапе проверки могут возникнуть ошибки, которые приведут к аварийному завершению работы приложения. Из двух типов объявления объектной переменной по возможности лучше использовать раннее связывание. Преимущества этого метода следующие. Уменьшается вероятность появления ошибок, так как VBA “не позволит” при- своить этой переменной данные неправильного типа. В свою очередь компилятор VBA, кроме проверки в операторах присвоения совпадения действительного класса объекта с объявленным, проверит также и остальную часть программного кода, что- бы получить гарантии использования в нем только методов и свойств, допустимых для объектов данного класса. Выполнение программы ускоряется, поскольку не требуется тратить время на про- верку совместимости методов и свойств объекта с теми методами и свойствами, которые вызываются в программе, — это все уже было выполнено компилятором. 156 Часть 2. Основы программирования на VBA
Программный код упрощается, что облегчает его чтение. Чтобы выяснить, для ка- кого класса предназначена та или иная переменная, достаточно просто взглянуть на строку с ее объявлением. Однако в некоторых случаях удобнее применять метод позднего связывания, позво- ляющий одну и ту же переменную использовать для хранения ссылок на объекты раз- личных классов. Предполагается, что эти объекты включают одинаковые по назначению методы и свойства, имеющие одни и те же имена, — именно эти методы и свойства будут использоваться в программе. Позднее связывание также применяется в тех случаях, когда необходимо обращаться к объектам из других приложений. После объявления объектной переменной, но перед ее использованием, необходимо поместить в нее ссылку на требуемый объект. Для этого используется ключевое слово Set, с которого должен начинаться соответствующий оператор присвоения. Set Объект! = Word.Document.List(1) Любой объект существует в памяти до тех пор, пока на него имеется хотя бы одна ссылка. Поэтому, если работа с объектом закончена и доступ к нему больше не требуется, желательно освободить данный объект от привязки к ссылающейся на него объектной переменной. Когда все ссылки будут ликвидированы, объект можно будет разрушить, что позволит освободить участок памяти, ранее занятый этим объектом. Для освобождения объектной переменной от хранящейся в ней ссылки используется оператор Set, в кото- ром этой переменной присваивается ключевое слово Nothing. Set Объект! = Nothing Nothing (Ничто) — это ключевое слово языка VBA, предназначенное специально для освобождения объектной переменной от хранящейся в ней ссылки. Создание новых объектов Если объект верхнего уровня, с которым вы собираетесь работать, еще не существует, его необходимо создать и в процессе создания получить на него ссылку. Для создания объекта в операторе Set необходимо указать ключевое слово New. Set Объект! = New Имя_класса Здесь Объект! — переменная, объявленная с типом, соответствующим создаваемому объекту, Имя_класса — имя класса создаваемого объекта. Подчеркнем, что ключевое слово New используется только при создании объектов верхнего уровня (как правило, это объекты класса Application). Дело в том, что их дочерние (согласно иерархии) объекты в программах на языке VBA просто не могут существовать, пока не будет создан соответствующий объект верхнего уровня. Поэтому дочерние объекты создаются позднее, когда уже создан объект верхнего уровня, и создаются они с помощью специальных мето- дов объекта Application, а не с помощью средств языка. КЗЯВ При создании нового экземпляра объекта верхнего уровня альтернативой использова- нию ключевого слова New является вызов функции CreateObject (). Данная функ- ция используется при создании объекта верхнего уровня из внешнего приложения. Она открывает указанное в качестве параметра приложение, которое и создает нужный объект. Возвращаемое функцией значение является ссылкой на объект, которая может быть присвоена объектной переменной в качестве значения. Глава 8. Объекты и коллекции 157
Получение ссылки на существующий объект Для работы с объектом верхнего уровня, который уже существует (поскольку соответ- ствующее приложение уже запущено), необходимо получить ссылку на этот объект. В этом случае следует использовать функцию Ge tOb j ect (). Однако после вызова функции Geto- b j ect () всегда нужно проверить, действительно ли требуемое приложение уже запущено. Если приложение не было запущено, следует создать его новый экземпляр, используя опера- тор Set с ключевым словом New или функцию CreateObj ect (). Например, пусть в прило- жении, работающем в среде Microsoft Excel, требуется получить ссылку на уже запущенный экземпляр приложения Microsoft Word или же создать новый экземпляр этого приложения. Тогда корректный код, реализующий эти действия, будет выглядеть следующим образом. Dim Пршюжение—Word As Word.Application On Error Resume Next ’Блокировка автоматической обработки ошибок Set Приложение-Word = GetObject(, "Word.Application") If Err = 429 Then ’Ошибка - Word не запущен Set Приложение-Word = New Word.Application End If Иногда использование функции GetObjectO может оказаться проблематичным. J V Например, если в системе запущено больше одного экземпляра требуемого приложе- ния, то нельзя проконтролировать или даже просто предсказать, ссылка на какой имен- но экземпляр объекта данного приложения будет возвращена функцией. Идентификация объекта для использования Для того чтобы сообщить VBA, с каким именно объектом вы собираетесь работать, необходимо использовать объектное выражение — любое выражение языка VBA, с помо- щью которого определяется конкретный объект. На основе объектного выражения VBA вычисляет значение, которое воспринимается как ссылка на требуемый объект. Объекты в среде VBA существуют в иерархии, при этом один объект служит контей- нером для других, подчиненных ему объектов. Поэтому для обращения к любому объ- екту необходимо указать его положение в иерархии объектов, используя точку в качестве разделителя последовательно указываемых имен его объектов-контейнеров. Любой под- чиненный объект можно идентифицировать с помощью соответствующего свойства его объекта-контейнера. Например, рассмотрим выражение, идентифицирующее конкрет- ный объект в документе приложения Microsoft Word. ThisDocument.Sections(3).Range Здесь ключевое слово ThisDocument используется для обозначения текущего объекта класса Document. В Word каждый объект класса Document имеет свойство Sections, представляющее собой ссылку на коллекцию Sections. Эта коллекция является объ- ектом, описывающим множество всех разделов данного документа, поэтому начальная часть выражения ThisDocument.Sections идентифицирует конкретную коллек- цию Sections, принадлежащую объекту ThisDocument. Идентифицировав объект коллекции Sections, можно выбрать в нем любой конкретный член этой коллекции. Например, запись Sections (3) является ссылкой на объект Section, представляющий третий раздел документа. Имя . Range идентифицирует свойство объекта Section, зна- чением которого является ссылка на объект класса Range. Таким образом, все выражение представляет собой ссылку на объект Range для третьего раздела текущего документа. 158 Часть 2. Основы программирования на VBA
Просто обратиться к объекту, т.е. получить на него ссылку, — это еще не означает вы- полнить над ним какие-либо действия. Для того чтобы сделать что-нибудь с интере- сующим вас объектом, необходимо прочитать или изменить значения свойств объекта либо вызвать его метод, в результате выполнения которого с объектом будут проведены какие-то действия. Работа с объектами в программе Напомним, что в программе на языке VBA для указания объекта, с которым следует работать, используется объектное выражение. В результате вычисления объектного вы- ражения будет получено значение, представляющее собой ссылку на требуемый объект. Иногда при написании программы может возникнуть такая ситуация, когда необхо- димо выяснить, ссылается ли данная объектная переменная на тот же объект, что и другая переменная или объектное выражение. В этом случае для проверки идентичности двух ссылок на объекты можно использовать оператор Is. Если ссылки идентичны, то зна- чением соответствующего выражения будет True, а если ссылки указывают на разные объекты — False. Dim Объект! As Object, 0бъект2 As Object If Объект! Is 0бъект2 Then ’Проверка идентичности объектов MsgBox ” Это одинаковые объекты." Else MsgBox " Это разные объекты." End If Оператор Is можно такж£ использовать при сравнении объектной переменной с объектным выражением. Однако всегда следует помнить, что оператор Is нельзя ис- пользовать для выяснения идентичности содержимого двух объектов. В программе на языке VBA для упрощения работы с объектами можно также исполь- зовать программные конструкции With...End With и For Each...Next, о которых под- робнее поговорим чуть ниже. Доступ к объектам в иерархии Каждое приложение Office имеет собственную (и весьма сложную) объектную модель. Любая из пользовательских программ на языке VBA обычно начинается с создания объек- тов верхнего уровня базового приложения, а доступ к объектам более низких уровней осуществляется получением ссылки на необходимый объект. Как правило, ссылка на ни- жестоящий в иерархии объект хранится в соответствующем свойстве объекта-контейнера. Поскольку важной частью иерархии объектов приложений являются объекты-коллекции, доступ к отдельным объектам часто требует доступа к той коллекции, к которой они при- надлежат. Обо всем этом мы уже говорили выше. Однако в языке VBA существуют и специальные типы имен, позволяющие упростить доступ к требуемым объектам. Так, специальные сокращенные имена реализуют ссылки на активную в данный момент часть приложения — ту, с которой программа работает в данный момент. Они имеют общую форму ActiveXXX. Например, это могут быть имена Active- Document (в Word), ActiveSheet (в Excel) и т.д. Но если принять во внимание, что в мо- мент обращения к активному документу приложение, с которым работает программа, может Глава 8. Объекты и коллекции 159
быть запущено в системе более чем в одном экземпляре, надежнее будет для обозначения требуемого объекта использовать иной тип ссылки — Thi sXXX. Так, для доступа к объекту типа Document можно использовать запись ThisDocument (в Word) или ThisWorkbook (в Excel). Эти ссылки всегда ссылаются на используемый в программе в данный момент до- кумент или рабочую книгу — независимо от того, активны они в настоящее время или нет. В некоторых VBA-приложениях (например, Excel или Word) реализован механизм, позволяющий в определенных ситуациях использовать сокращенные имена, которые сразу предоставляют доступ к требуемым объектам, без необходимости перемещения по иерархии объектов. Предположим, программа работает с рабочей книгой Отчет, xls, причем открыта (активна) только она и в ней содержится всего один рабочий лист Квартал. Тогда, учитывая все сказанное выше о доступе к объектам в иерархии, обра- титься к ней можно будет несколькими способами. Application.Workbooks("Отчет.xls").Worksheets("Квартал") ’Вариант 1 Workbooks(1).Worksheets("Квартал") ’Вариант 2 Workbooks(1).Worksheets(1) ’Вариант 3 Application.ActiveWorkbook.ActiveSheet ’Вариант 4 ActiveWorkbook.ActiveSheet 'Вариант 5 ActiveSheet ’Вариант 6 Работа с коллекциями Выше мы уже ознакомились с такими понятиями, как коллекции и контейнеры. Также было сказано, что для хранения объектов любых типов в любой комбинации предназначен родовой объект Collection, который можно использовать для управления множеством произвольных элементов. Сама по себе коллекция также является объектом с собственны- ми свойствами и методами. Например, каждая коллекция имеет свойство Count (Количе- ство), в котором сохраняется информация о количестве элементов в коллекции. Каждому элементу коллекции присваивается числовой индекс, ассоциированный со ссылкой на данный объект и изменяющийся в диапазоне от единицы до текущего значения свойства Count. В некоторых коллекциях каждый элемент также имеет уникальный ключ, пред- ставляющий собой строку, тем или иным образом идентифицирующую данный объект. В программе объекты-коллекции создаются точно так же, как и любые другие объекты, с использованием ключевого слова As для определения их типа. Например, для создания объекта типа Collection нужно вначале объявить имя переменной для этого объекта, после чего использовать оператор Set для создания этой переменной, не забывая при этом использовать ключевое слово New, чтобы создать новую коллекцию. Dim Коллекция! As Collection ’ Объявление объектной переменной Set Коллекция! = New Collection ’ Создание объекта-коллекции Кроме рассмотренного выше способа создания объекта типа Collection, можно ис- пользовать другой способ, при котором VBA создаст его автоматически при первом же использовании имени переменной в программном коде. Для этого в объявлении пере- менной следует поместить ключевое слово New. Dim Коллекция! As New Collection ’Объявление объектной переменной Коллекция!.Add Элемент! ’Этот оператор создает коллекцию ’и добавляет в нее элемент "Элемент!" 160 Часть 2. Основы программирования на VBA
Для получения доступа к отдельным элементам в коллекции можно использовать ме- тод Item этой коллекции. Синтаксис доступа к этому методу следующий. ИмяКоллекции.Item (index) Здесь index — числовой индекс элемента или его уникальный ключ. Следует заметить, что Item — это метод объекта Collection, вызываемый по умолчанию, а поэтому наше выражение можно записать и без указания метода Item. ИмяКоллекции(iпdex) Доступ к элементу коллекции можно также осуществить с помощью непосредственной ссылки, просто присвоив ее переменной. Например, для ссылки на рабочий лист с име- нем "Данные за квартал" в активной рабочей книге можно использовать следующий оператор. Dim Лист1 As Worksheet ’Объявление переменной Лист1 = Worksheets("Данные за квартал") Расширение коллекций Расширить коллекцию требуется в тех случаях, если, например, необходимо создать в Excel новую рабочую книгу либо добавить в уже имеющуюся новый рабочий лист или же создать новый документ в Word. В каждом случае потребуется добавить новый элемент в со- ответствующую коллекцию объектов, иначе говоря, расширить ее. При добавлении объекта в коллекцию сначала создается новый экземпляр объекта, а затем он добавляется в нее. В объектах типа Collection для добавления в коллекцию нового элемента преду- смотрен специальный метод Add, который может иметь один или несколько аргументов, предназначенных для задания требуемых начальных значений свойствам вновь добавляе- мых в коллекцию объектов. В общем случае метод Add имеет следующий синтаксис. Имя_коллекции.Add(Аргументы) Здесь аргументы метода содержат различные данные о добавляемом объекте (шаблон, тип и так далее), причем состав этих аргументов может меняться в зависимости от типа до- бавляемого объекта. Если метод Add вызывается без аргументов, то набор аргументов и их значения принимаются по умолчанию. Например, следующий оператор создает новый объект Document, который затем добавляется в коллекцию Documents, причем все свой- ства созданного объекта принимают значения, устанавливаемые по умолчанию. Documents.Add Метод Add всегда возвращает ссылку на вновь созданный объект, но это вовсе не означает, что вы обязаны с этой ссылкой что-либо делать. Если сохранить значение этой ссылки в какой-либо переменной, то в дальнейшем к объекту можно будет обращаться напрямую, хотя доступ к нему всегда будет возможен и через коллекцию. В случае ис- пользования записи по приведенному выше образцу, возвращаемая методом Add ссылка будет утеряна, и доступ к новому объекту будет возможен только через коллекцию. х-. Следует заметить, что для добавления в коллекцию сразу нескольких элементов мож- но воспользоваться циклом For...Next — подобно тому, как это делается при работе 11 с массивами. Глава 8. Объекты и коллекции 161
Для удаления существующего элемента из коллекции обычно используется метод Close. Синтаксис его вызова следующий. Ссылка_на_объект. Close (Аргументы) Здесь параметр Ссылка_на_объект представляет собой ссылку на удаляемый объ- ект коллекции, определяемый прямо или через коллекцию — это не имеет значения. Возможные аргументы этого метода обычно указывают на те действия, которые должны быть выполнены в связи с удалением этого объекта. вКМЦ На самом деле при указанном выше синтаксисе вызываемый метод Close принадле- жит не объекту коллекции, а самому удаляемому объекту. Однако некоторые коллекции ВИ также могут иметь метод Close, но при его вызове будут удалены все входящие в кол- лекцию объекты, а не какой-то один из них. Использование оператора With...End With Если в программе один и тот же объект используется в нескольких последовательно за- писанных операторах, то применение конструкции With...End With позволит ссылаться на свойства и методы данного объекта без указания полной объектной ссылки при каждом его упоминании. Чтобы сказанное выше было понятнее, рассмотрим пример, в котором устанавливаются значения трех различных свойств объекта Объект 1. Сначала запишем программный текст без использования конструкции With...End With. Проект1.Документ!.Объект!.Name = "Легенда" Проект!.Документ!.Объект!.Author = "Петров" Проект!.Документ!.Объект!.Туре = "Повесть" А теперь запишем этот же пример с использованием конструкции With.JSnd With. With Проект!.Документ!.Объект! .Name = "Легенда" .Author = "Петров" .Туре = "Повесть" End With При такой записи интерпретатор VBA знает, что имя, начинающееся с точки, является именем свойства или метода объекта, указанного в операторе With. Из приведенного при- мера наглядно видно, что вторая запись программного текста с использованием конструкции With...End With существенно упрощает код, делая его более читабельным и понятным. Конструкция With...End with особенно полезна, когда ссылки на объекты повторя- ются несколько раз в небольшом фрагменте кода. Кроме того, с использованием кон- струкции with...End With одновременно уменьшается и вероятность появления слу- чайных ошибок, поскольку программный текст становится намного проще. Использование конструкции For Each...Next В языке VBA конструкция For Each...Next предназначена для замены множества операторов, манипулирующих по отдельности всеми объектами некоторой коллекции. 162 Часть 2. Основы программирования на VBA
С помощью оператора For Each...Next можно последовательно получить доступ ко всем элементам указанной коллекции. Синтаксис этого оператора следующий. For Each элемент In группа ... (операторы) Next элемент Здесь элемент — это имя объектной переменной, используемой внутри цикла For Each... Next для получения ссылки на каждый объект обрабатываемой коллекции, а с помощью аргумента группа задается ссылка на ту коллекцию, которую необходимо обработать. Следует заметить, что в цикле For Each...Next выполняется последовательная обработка всех элементов указанной коллекции, и если некоторые действия требуется выполнить только по отношению к какому-то одному конкретному объекту (или нескольким) в кол- лекции, то для этой цели следует внутри конструкции For Each...Next поместить соот- ветствующий условный оператор If...Then. Dim 0бъект1 As Document For Each 0бъект1 In Documents If OObeKTl.Name = ’’Легенда" Then 0бъект1.Delete MsgBox ("Документ Легенда удален") End If Next 0бъект1 Здесь в конструкции For Each...Next условный оператор I f ...Then используется для на- хождения в коллекции Documents таких объектов класса Document, у которых свойство Name имеет значение "Легенда ’’. И только в том случае, если объект с указанным значе- нием свойства Name будет найден, выполняется оператор, удаляющий данный объект, о чем затем и выводится сообщение пользователю. Окно Object Browser Для нахождения и просмотра информации о классах, свойствах, методах, событиях и константах, содержащихся в библиотеках типов (т.е. классов объектов), используется инструмент Object Browser. Окно Object Browser уже было достаточно подробно описано в главе 2, в разделе “Окно проектов и обозреватель объектов”. Однако здесь хотелось бы добавить еще несколько слов о списке Members этого окна. В окне Object Browser, слева от имени каждого элемента в списке Members, отображаются особые значки, позволяю- щие легко различать принадлежность данного имени — методу или свойству (рис. 8.13). Значком с изображением руки, держащей карточку, обозначаются свойства объекта. Значком с изображением “летящего” зеленого прямоугольника обозначаются ме- тоды объекта. Значком с изображением голубого мячика над зеленым прямоугольником (на- пример, значок метода Item на рис 8.6) или с изображением руки с карточкой (например, значок свойства Count на рис 8.6) обозначается метод или свойство, являющиеся глобально доступными. Значком в виде серого прямоугольника со скругленными углами обозначаются константы. Плава 8. Объекты и коллекции 163
Рис. 8.13. Представление методов и свойств выбранного объекта в списке Members окна Object Browser Таким образом, с помощью окна Object Browser можно не только получить быстрый и удобный доступ к объектам, свойствам и методам, но и упростить процесс написания программ, которые с ними работают. Резюме В этой главе мы познакомились еще с одним важнейшим разделом языка VBA — объектами и средствами их реализации и обработки. То, что язык VBA является объектно-ориентированным, дает ему многие дополнительные преимущества. Посколь- ку объект представляет собой особую программную конструкцию, инкапсулирующую обрабатываемые данные вместе со средствами их обработки, это предполагает наличие специальных языковых механизмов, позволяющих получать к этим данным доступ из программы. Именно рассмотрению этих механизмов и посвящена большая часть данной главы, в которой были представлены методы и свойства объектов, описаны особенно- сти их организации, а также способы использования объектов-коллекций и объектов- контейнеров. В этой главе обсуждались такие теоретические понятия, как события, клас- сы и иерархия объектов, а также особенности их реализации в языке VBA. На примерах было показано, как описываются и вызываются свойства, методы и события классов, как можно получить доступ к требуемому объекту в иерархии, как объекты создаются и уничтожаются. Особое внимание было уделено работе с коллекциями как одному из важнейших типов объектов в VBA. В завершение было приведено полезное замечание о некоторых свойствах окна Object Browser в редакторе VBA. 164 Часть 2. Основы программирования на VBA
Тестовые задания Ниже приведено несколько тестовых заданий, предназначенных для закрепления из- ложенного в этой главе материала. В каждом задании вам предлагается вопрос и несколь- ко вариантов ответа на него, один (или несколько) из которых является правильным, а остальные — нет. Укажите правильный ответ. 1. Объект представляет собой: а) программную конструкцию, инкапсулирующую данные вместе со средствами их обработки; б) область памяти компьютера, в которой размещены данные и программы; в) шаблон, на основании которого создаются одинаковые элементы данных; г) специальную подпрограмму доступа к данным определенного типа. 2. Информация, характеризующая текущее состояние объекта, хранится в его: а) методах; б) событиях; в) свойствах; г) аргументах. 3. В объектных переменных языка VBA хранится: а) программный текст и данные объекта; б) адресная ссылка, указывающая на место размещения объекта в памяти компьютера; в) ссылка на описание объекта в программе; г) порядковый номер объекта в иерархии. 4. Коллекция представляет собой: а) массив из объектов, входящих в данную коллекцию; б) массив из ссылок на объекты, входящие в состав данной коллекции; в) область памяти компьютера, в которой размещены объекты, входящие в эту кол- лекцию; г) специализированный объект, позволяющий с помощью своих методов и свойств создавать наборы объектов определенного типа и получать к ним доступ. 5. Для упрощения записи процедур, выполняющих последовательную обработку всех объектов коллекции, VBA предлагает: а) конструкцию For Each...Do; б) конструкцию With...End With; в) конструкцию For Each...Next; г) конструкцию For All Item...Next. Глава 8. Объекты и коллекции 165

Часть Более сложные аспекты работы на VBA В этой части... > Глава 9. Встроенные функции VBA > Глава 10. Экранные формы и их элементы > Глава 11. Работа с файлами > Глава 12. Обработка ошибок и отладка программ

Глава 9 Встроенные функции VBA В этой главе... ♦ Математические функции ♦ Функции преобразования данных ♦ Функции проверки типов ♦ Функции даты и времени ♦ Строковые функции ♦ Финансовые и прочие функции ♦ Резюме Язык VBA, подобно другим развитым языкам программирования, содержит целый ар- сенал мощных встроенных средств, предназначенных для решения самых разнообразных задач, возникающих при создании проектов различного типа. В частности, в языке VBA имеется обширный набор встроенных функций, использование которых в значительной мере упрощает процесс программирования. Все эти функции можно разделить на такие основные категории, как математические функции, функции преобразования данных, функции проверки типов, функции даты и времени, функции обработки строковых данных, финансовые функции и пр. В этой главе мы подробно рассмотрим каждую из указанных выше категорий функций. Математические функции Для работы с числовыми значениями в языке VBA существует ряд математических функций, полезных при решении разнообразных вычислительных задач, как простых, так и достаточно сложных. Они могут использоваться не только при арифметических расче- тах, но и при вычислении разнообразных алгебраических и тригонометрических величин. Все математические функции, имеющиеся в языке VBA, приведены в табл. 9.1 Таблица 9.1. Встроенные математические функции языка VBA Функция Возвращаемое значение АЬз(число) Возвращает абсолютное значение величины число (модуль числа) At п( число) Возвращает арктангенс величины число (угол, измеряемый в радианах) Cos (число) Возвращает косинус величины число, понимаемой как угол, измеренный в радианах Ехр( число) Возвращает константу е в степени, равной заданному значению число (е приблизи- тельно равно 2,718282) Пх(число) Возвращает целую часть величины число. Для отрицательного числа функция Fix воз- вращает ближайшее отрицательное целое число, большее указанного либо равное ему
Окончание табл. 9.1 Функция Возвращаемое значение Int( число) Возвращает целую часть величины число. Для отрицательного числа функция Int воз- вращает ближайшее отрицательное целое число, меньшее указанного либо равное ему Ъод(число) Возвращает натуральный логарифм величины число, значение с плавающей точкой, двойной точности Rnd( число) Возвращает псевдослучайное числовое значение с плавающей точкой, одинарной точности. Параметр число (значение типа single) позволяет в определенной сте- пени управлять алгоритмом вычисления псевдослучайного числа Sgn( число) Возвращает знак величины число: 1 — положительная; 0 — равна нулю; -1 — от- рицательная 81п(число) Возвращает синус величины число, понимаемой как угол, измеренный в радианах Здг(число) Возвращает квадратный корень из величины число Tan (число) Возвращает тангенс величины число, понимаемой как угол, измеренный в радианах Если среди математических функций VBA нужная вам функция отсутствует, ее мож- но создать собственными силами, подготовив процедуру типа Function, которая будет решать нужную вам задачу, используя стандартные функции языка. После создания функ- ции сохраните ее в специальном модуле для дальнейшего использования. Функции преобразования данных Как вы помните, если при написании процедуры (процедуры-функции) не был указан конкретный тип данных, то VBA выполняет автоматическое преобразование данных од- них типов в другие. Кроме того, для явного преобразования данных одних типов в другие в языке VBA существует группа специальных функций. Преобразование строки в число и обратно осуществляется функциями Vai и Str соответственно. Функция Vai является единственной функцией VBA, принимающей в качестве аргумента только один тип данных. В то время как другие функции принимают тип данных Variant, функция Vai поддерживает только работу со строками. Это значит, что любое переданное в функцию Vai значение воспринимается как строка с текстовой записью числа, которое преобразуется в числовую величину. Синтаксис этой функции следующий. Vai(строка) Здесь строка — это исходное строковое выражение. Функция Vai читает строку, задан- ную аргументом строка, начиная с первого символа и до тех пор, пока не встретит сим- вол, недопустимый для представления чисел. Допустимыми символами считаются цифры от 0 до 9, знаки “+” или десятичная точка (а не запятая!), префикс, указывающий на восьмеричную (&0, где О — это латинская буква) или шестнадцатеричную (&Н, где н — это латинская буква1) систему счисления. Функция Vai игнорирует пробелы, символы табу- ляции и переходы на новую строку. Vai (’’25 113.2 14 АВС ”) 1 Для чисел, записанных в шестнадцатеричной системе счисления (т.е. с префиксом &Н), функ- ция VAL допускает наличие в строке-аргументе дополнительных шестнадцатеричных цифр (от 10 до 15) — А, В, С, D, Е и Е 170 Часть 3. Более сложные аспекты работы на VBA
В этом примере функция Vai возвращает число 25 113,214. Если VBA не может выпол- нить преобразование заданной строки в число, то функция Vai возвращает значение 0. Функция Str возвращает значение типа Variant (String) — строку с текстовым представлением исходного числа. Синтаксис этой функции следующий. Str(число) Здесь число — это произвольное числовое выражение. Для положительного числа резуль- тирующая строка начинается с пробела, а для отрицательного числа она будет начинаться со знака “минус”, без пробела. Функция Hex преобразует целые десятичные числа в строку символов, представляю- щую собой то же самое число, но в шестнадцатеричной системе счисления. Синтаксис ее следующий. Hex (число) Здесь число — произвольное числовое выражение, значение которого при необходимости предварительно округляется до ближайшего целого числа. Функция Oct преобразует целые десятичные числа в строку символов, представляющую собой то же самое число, но в восьмеричной системе счисления. Синтаксис ее следующий. Oct (число) Здесь число — произвольное числовое выражение, значение которого при необходимости предварительно округляется до ближайшего целого числа. Кроме этих часто используемых функций, в языке VBA имеется еще ряд функций, предназначенных для преобразования одного типа данных в другой (табл. 9.2). Таблица 9.2. Дополнительные функции преобразования данных Функция__________Возвращаемое значение_______________________________________ CBool(выражение) Числовое значение типа Boolean. Выражение — любая допустимая строка или числовое выражение. Возвращается значение False, если вычисленное значение выражения равно нулю, в противном случае возвращается True СЪуЬе(выражение) Числовое значение типа Byte (от 0 до 255). Выражение — любое допустимое числовое или строковое выражение, которое может быть преобразовано в число С си г (выражение) Числовое значение типа Currency. Выражение — любое допустимое числовое или строковое выражение, которое может быть преобразовано в число СЬаЬе(выражение) Значение типа Date. Диапазон представления даты от 1/1/100 до 12/31/9999 включительно С Dbl (выражение) Числовое значение типа Double. Выражение — любое допустимое числовое или строковое выражение, которое может быть преобразовано в число С i n t (выражение) Числовое значение типа Integer. Выражение — любое допустимое числовое или строковое выражение, которое может быть преобразовано в число СЪпд(выражение) Числовое значение типа Long. Выражение — любое допустимое числовое или строковое выражение, которое может быть преобразовано в число СЗпд(выражение) Числовое значение типа Single. Выражение — любое допустимое числовое или строковое выражение, которое может быть преобразовано в число С S t ^(выражение) Значение типа String. Выражение — любое допустимое числовое или стро- ковое выражение, которое может быть преобразовано в строку Cv аг (выражение) Значение типа Variant. Выражение — любое допустимое числовое или стро- ковое выражение, которое может быть преобразовано в строку Глава 9. Встроенные функции VBA 171
Форматирование данных Для форматирования данных в языке VBA предназначена функция Format, которая идентична функции Format как в Microsoft Excel, Microsoft Access, так и в других при- ложениях Microsoft Office. Функция Format форматирует данные любого встроенного типа по указанному образцу. При этом она конвертирует предложенное значение в новую строку, добавляя в нее символы, необходимые для представления данных в требуемом виде. Синтаксис функции Format следующий. Format (Выражение [, Формат [, ПервыйДеньНедели[, ПерваяНеделяГода]]]) Здесь указанные аргументы означают следующее. Выражение — любое допустимое выражение (обязательный аргумент). Формат — любое допустимое именованное или определенное пользователем вы- ражение формата (необязательный аргумент). ПервыйДеньНедели — константа, определяющая день недели, который считается первым (необязательный аргумент). ПерваяНеделяГода — константа, определяющая первую неделю года (необяза- тельный аргумент). Для данных различных типов в языке VBA имеются встроенные именованные форматы, которые указываются в качестве аргументов функции Format (табл. 9.3). Однако следует помнить, что имя любого используемого в качестве аргумента формата обязательно долж- но быть заключено в кавычки. Таблица 9.3. Именованные форматы для использования в функции Format Именованный формат Результат форматирования Пример (соответ- ствует установкам для языка Русский в панели управления) General Number Число без выделения разрядов тысяч 13050,2184 Currency Число с символом денежной единицы, с выделением разрядов тысяч и с двумя цифрами после десятичного разделителя 13 050,22р. Fixed Число без выделения разрядов тысяч и как минимум с одной цифрой перед десятичным разделителем и двумя — после него 12142,91 Standard Число с выделением разрядов тысяч и как минимум с одной цифрой перед десятичным разделителем и двумя — после него 12 142,91 Percent Число, умноженное на 100, с двумя цифрами после десятичного разделителя и знаком процента 35,25% Scientific Число в стандартном виде для научных расчетов 1,23Е+02 Yes/No Строка "Да" (Yes), если форматируемое число ненуле- вое, или строка "Нет" (No), если значение равно нулю Да True/False Строка "Истина" (True), если форматируемое число ненулевое, или строка "Ложь" (False), если значение равно нулю Истина 172 Часть 3. Более сложные аспекты работы на VBA
Окончание табл. 9.3 Именованный формат Результат форматирования Пример (соответ- ствует установкам для языка Русский в панели управления) On/Off Строка ”Вкл" (On), если форматируемое число ненуле- вое, или строка "Выкл” (Off), если значение равно нулю Вкл General Date Дата и время в формате, зависящем от установок на компьютере пользователя 25.09.03 15:52:43 Long Date Дата в формате, зависящем от установок на компьюте- ре пользователя для полного формата даты 25 Сентябрь 2003 г. Medium Date Дата в формате, зависящем от установок на компьюте- ре пользователя для среднего формата даты 25-Сен-ОЗ Short Date Дата в формате, зависящем от установок на компьюте- ре пользователя для короткого формата даты 25.09.03 Long Time Время (часы, минуты и секунды) в формате, завися- щем от установок на компьютере пользователя для полного формата времени 16:20:45 Medium Time Время (часы, минуты) в 12-часовом формате с метками до/после полудня в формате, зависящем от установок на компьютере пользователя 06:25 Short Time Время (часы, минуты) в 24-часовом формате, завися- щем от установок на компьютере пользователя 16:28 При использовании функции Format, кроме именованных форматов, приведенных в табл. 9.3, можно также указывать произвольные комбинации символов из особой группы, которые называют символами-заполнителями. С их помощью при необхо- димости можно создавать собственные пользовательские форматы для представления чисел, дат или времени. Общая идея состоит в том, что для получения требуемого образ- ца форматирования создается строка-шаблон, содержащая определенную комбинацию символов-заполнителей, которая затем используется функцией Format как инструк- ция по преобразованию исходных значений в строку. В табл. 9.4 приведены символы- заполнители, которые могут использоваться при создании шаблонов форматов для функции Format. В этой таблице для приведения примеров преобразования исполь- зуется числовое значение 2222,33, а настройки региональных стандартов приняты для русского языка. Таблица 9.4. Символы-заполнители, используемые при создании пользовательских форматов преобразования для функции Format Символ- Действие Пример заполнитель 0 Резервирует позицию цифрового разряда. Ото- Шаблон 00000.000 бражает цифру, если таковая находится в этой по- отображает 02222,330 зиции, в противном случае — 0 # Резервирует позицию цифрового разряда. Ото- Шаблон#####.### бражает цифру, если таковая находится в этой по- отображает 2222,33 зиции, в противном случае ничего не отображает Глава 9. Встроенные функции VBA 173
Окончание табл. 9.4 Символ- заполнитель Действие Пример . (точка) Резервирует позицию десятичного разделителя в строке из символов-заполнителей 0. Указание точки в строке формата определяет отображаемое количество разрядов слева и справа от десятичного разделителя Шаблон 0000.00 отображает 2222,33 % Резервирует процентное отображение числа и до- бавляет знак процента в позицию, указанную этим символом-заполнителем Шаблон ###0.00% отобража- ет число 0,222233 как 22,22% , (запятая) Разделитель тысяч, добавляет символ разделителя тысяч в указанные позиции в строках символов- заполнителей Шаблон #,###,### г###. 00 отображает 2 222,33 Е- е- Разделитель мантиссы и порядка в экспоненциаль- ном формате с указанием знака порядка только для отрицательных значений Шаблон #.#####Е-00 отобра- жает 2,22233Е03, а число 0,222233 отображает как 2,22233Е-01 Е+ е+ Разделитель мантиссы и порядка в экспоненци- альном формате с указанием знака порядка и для положительных, и для отрицательных значений Шаблон #. #####Е+00 отображает 2,22233Е+03 / Разделяет день, месяц и год в категории форматов Дата (Date) Шаблон mm/dd/yy отображает 25/09/03 m Определяет способ отображения месяца в датах Шаблон m отображает сентябрь как 9, mm — 09, mmm — сен (со- кращение названия месяца), mmmm — Сентябрь (полное на- звание месяца) d У Определяет способ отображения дня в датах Отображает день года как число от 1 до 366 Шаблон d отображает первое число месяца как 1, dd — 01, ddd — Пн (сокращение дня недели), dddd — Понедельник (полное название дня недели) 1уу q Определяет способ отображения года в датах Отображает квартал года как число от 1 до 4 Шаблон уу отображает 2003 год как 03, уууу — 2003 < Отделяет значения часов, минут и секунд в катего- рии форматов Время (Time) Отображает все символы в верхнем регистре Отображает все символы в нижнем регистре Шаблон hh: mm: s s отобража- ет 07:55:12 (число 2222,33 вос- принимается как количество секунд, прошедшее с полночи) $ Отображает знак доллара Шаблон $###,###. 00 отображает $2 222,33 Кроме функции Format, в языке VBA для работы с данными соответствующих ти- пов используются функции специального форматирования. Подобно функции Format, 174 Часть 3. Более сложные аспекты работы на VBA
каждая из этих функций возвращает строку с отформатированным представлением ис- ходного значения. Краткое описание этих функций приведено в табл. 9.5, а полный их синтаксис при необходимости можно найти в справочной системе VBA. Таблица 9.5. Функции специального форматирования Функция Назначение FormatNumber (Е [, N [, I [, U [, G]] ] ] ) Возвращает значение числа в виде отформатированной строки, где Е — единственный обязательный аргумент — представляет собой выражение, результат вычисления которого требуется форматиро- вать. При отсутствии необязательных аргументов функция форма- тирует число, исходя из установок, принятых по умолчанию, — т.е. заданных в поле Число на вкладке Региональные параметры окна Язык и региональные стандарты панели управления Windows. За- дание необязательных аргументов позволяет изменить параметры форматирования чисел, принятые по умолчанию. Здесь N — ко- личество отображаемых знаков после запятой; I — отображение незначащего нуля перед запятой для чисел меньше I; и — пред- ставление отрицательных чисел в скобках; G — отделение групп разрядов (пробелами) одной от другой Formatcurrency (E[,N[, I[,U[, G]] ] ] ) Возвращает значение числа, отформатированное как денежная ве- личина в соответствии с установками, принятыми по умолчанию, т.е. заданными в поле Сумма денег на вкладке Региональные параметры окна Язык и стандарты панели управления Windows. Эта функция работает аналогично функции FormatNumber и име- ет те же необязательные аргументы FormatDateTime(D[, N] ) Возвращает значение даты в виде форматированной строки. Здесь D — дата для форматирования, a N — числовое значение, опреде- ляющее требуемый формат. При опускании необязательного аргу- мента N результирующая строка форматируется в соответствии с системными установками для краткого формата даты и длинного формата времени, заданных в соответствующих полях на вкладке Региональные параметры окна Язык и стандарты панели управ- ления Windows FormatPersent (E [, N [, I [, U [, G] ] ] ] ) Возвращает значение числа, отформатированного как процентное отношение, т.е. исходное число умножается на 100 и к результату добавляется знак процента (%). Эта функция работает аналогич- но функции FormatNumber и имеет те же необязательные аргу- менты Функции проверки типов При работе с типом данных Variant для определения того, какой именно тип данных содержится в данный момент в конкретной переменной, можно использовать одну из не- скольких существующих в языке VBA функций проверки типов. Эти функции проверяют, является ли указанная переменная выражением заданного типа. Если переменная имеет соответствующий тип или содержит значение соответствующего типа, то любая из этих функций будет возвращать значение True, в противном случае — False. Перечень по- добных функций представлен в табл. 9.6. Глава 9. Встроенные функции VBA 175
Таблица 9.6. Функции проверки типов Функция Выполняемая проверка IsDate(переменная) IsNumeric(переменная) Проверяет, является ли значение указанной переменной датой Проверяет, является ли значение указанной переменной числовым значением IsObject(переменная) Проверяет, является ли значение указанной переменной объектом (объектной ссылкой) IsArray(переменная) IsNull(переменная) Проверяет, является ли значение указанной переменной массивом Проверяет, является ли значение указанной переменной пустым зна- чением (Null) IsEmpty(переменная) Проверяет, была ли указанная переменная типа Variant инициализи- рована (объявлена с помощью ключевого слова Dim) IsError(переменная) Проверяет, воспринимается ли значение указанной переменной или результат вычисления заданного выражения как ошибочное значение Функции даты и времени В языке VBA существует ряд функций, позволяющих определять текущую дату и вре- мя, выполнять различные вычисления со значениями даты и времени, а также извлекать из переменных со значениями даты/времени различные их компоненты: время, год или день недели. При задании аргументов в этих функциях следует помнить, что значения типа даты/времени заключаются между парой символов #, а строковые значения, опреде- ляющие интервал даты, — в кавычки. В табл. 9.7 приведены функции для работы с датами и временем. Полный синтаксис этих функций, включая перечень их необязательных аргу- ментов, которые здесь частично опущены, при необходимости можно найти в справочной системе VBA. Таблица 9.7. Функции обработки даты и времени Имя функции Возвращаемое значение Date Возвращает текущее значение системной даты с типом Variant (Date) Time Возвращает текущее значение системного времени с типом Variant(Date) Now Возвращает текущую системную дату и время с типом Variant(Date) DateAdd (интервал, Возвращает новое значение даты с типом Variant (Date), равное сумме число, дата) исходной даты и заданного числа указанных интервалов даты или времени. результат=дата+ (число* интервал) DateDiff(интервал. Возвращает значение с типом Variant (Long), представляющее собой дата1, дата2) количество временных интервалов заданного типа, прошедших между двумя указанными датами DatePart(интервал, Возвращает целое значение с типом Variant (Integer), представляю- дата) щее определяемую параметром интервал часть указанной даты (т.е. но- мер квартала, день недели и т.д.) DateSerial(год, Возвращает значение даты с типом Variant (Date), сформированное месяц, день) на основании значений аргументов год, месяц, день, которые должны иметь числовые значения из соответствующего диапазона (год: 100-9999; месяц: 1-12; день: 1-31) 176 Часть 3. Более сложные аспекты работы на VBA
Окончание табл. 9.7 Имя функции Возвращаемое значение DateValue Возвращает значение с типом даты, сформированное на основании значе- (строка_с_датой) ния аргумента, который должен представлять собой строковое значение или выражение, определяющее требуемую дату Day(дата) Возвращает целое значение с типом Variant (Integer), соответствую- щее дню месяца в заданной дате Month(дата) Возвращает целое значение с типом Variant (Integer), соответствую- щее месяцу (значение между 0 и 12 включительно) в указанной дате Year(дата) Возвращает целое значение с типом Variant (Integer), соответствую- щее году в указанной дате Hour(время) Возвращает целое значение с типом Variant (Integer), соответствую- щее количеству часов (значение между 0 и 23 включительно) в заданном значении времени Minute(время) Возвращает целое значение с типом Variant (Integer), соответствую- щее минутам (значение между 0 и 59 включительно) в заданном значении времени Second(время) Возвращает целое значение с типом Variant (Integer), соответствую- щее секундам (значение между 0 и 59 включительно) в заданном значении времени Timer Возвращает значение с типом Single, указывающее число секунд, про- шедших с момента начала (полночь) текущих суток TimeSerial(часы, Возвращает значение времени с типом Variant (Date), соответствую- минуты, секунды) щее значению времени, заданному числовыми аргументами часы, минуты, секунды TimeValue Возвращает значение с типом времени, сформированное на основании (строка_с_временем) значения аргумента, который должен представлять собой строковое зна- чение или выражение, определяющее требуемое время Weekday(дата) Возвращает целое значение с типом Variant (Integer), соответствую- щее дню недели в указанной дате Следует отметить, что, кроме перечисленных выше функций, в языке VBA существуют также специальные операторы работы с датами и временем, которые, в отличие от функ- ции, выполняют некоторые действия, не возвращая при этом результирующего значения. Оператор Date (дата) устанавливает системную дату в соответствии со значением аргумента дата. Оператор Time (время) устанавливает системное время в соответствии со значе- нием аргумента время. Сложение и вычитание значений датыи времени Поскольку операции сложения и вычитания значений даты и времени не подчиняются обычным правилам арифметики, в языке VBA для выполнения таких операций предна- значена специальная функция Date Add. С помощью этой функции можно прибавить к указанной дате любое значение, выраженное в годах, кварталах, месяцах и днях, или же суммировать интервалы времени, выраженные в часах, минутах, секундах. Функция Date Add имеет следующий синтаксис. Глава 9. Встроенные функции VBA 177
DateAdd (интервал, числог начальная_дата) Здесь аргумент интервал — это строковое выражение, определяющее тип временного интервала, добавляемого к исходной дате, поэтому его значение обязательно заключа- ется в кавычки. Значения, которые может принимать аргумент интервал, приведены в табл. 9.8. Аргумент число — это числовое выражение, задающее количество интервалов, которое нужно прибавить (для получения более поздних дат) к исходной дате или отнять (для получения более ранних дат) от нее. При необходимости вычитания интервалов в этом аргументе следует указывать отрицательное число. Аргумент началъная_дата — это та дата, к которой прибавляется или из которой вычитается указанный временной ин- тервал. Таблица 9.8. Значение аргумента интервал в функции DateAdd Значение аргумента Задаваемый интервал YYYY Год q m Квартал Месяц У d День года (эквивалентно значению d) День w День недели (эквивалентно значению d) ww h Неделя Час n Минута s Секунда Предположим, что требуется записать дату оплаты по квитанции предыдущим меся- цем. Тогда следует использовать такой оператор. Dim Dates As Date Dates = DateAdd("m", -1, Date) Функция DateAdd всегда возвращает корректное значение даты. Если добавить один месяц к дате 31 января, то функция DateAdd возвращает значение 28 февраля для не- И високосного года и 29 — для високосного. Для вычисления разности двух дат используется функция DateDif f, которая позво- ляет вычислить, сколько определенных интервалов времени (год, месяц,' неделя) прошло между двумя заданными датами или моментами времени. ТпдРазница = DateDiff ("m", #5/10/99#, #5/10/03#) После выполнения этого оператора переменная ТпдРазница будет содержать значе- ние, определяющее количество месяцев, прошедших между двумя указанными датами. В данном примере аргумент "т" сообщает функции DateDiff о том, что разность во времени нужно измерять в месяцах. Получение информации о дате и времени В языке VBA существует несколько функций, с помощью которых можно получить различную информацию о дате и времени — например, на какой день недели приходится 178 Часть 3. Более сложные аспекты работы на VBA
заданная дата. Самой гибкой из них является функция DatePart. Синтаксис этой функ- ции следующий. DatePart (интервал, дата, [первый_день_недели, первая_неделя_года] Здесь аргумент интервал — это строковое значение, определяющее интересующий ин- тервал. Этот параметр имеет такие же допустимые значения, как и параметр интервал в функции DateAdd. Аргумент дата — это то значение даты, для которой требуется полу- чить информацию. Необязательный аргумент первый_день_недели определяет, какой день следует считать первым днем недели, а аргумент первая_неделя_года — какую не- делю следует считать первой в году. В табл. 9.9 приведены допустимые значения аргумента первыи_день_недели, а допустимые значения для аргумента первая_неделя_года приведены в табл. 9.10. Таблица 9.9. Допустимые значения аргумента переый_день_недели Имя константы Числовое значение Описание vbUseSystem 0 Используются системные настройки vbSunday 1 Воскресенье (значение, принятое по умолчанию) vbMonday 2 Понедельник vbTuesday 3 Вторник vbWednesday 4 Среда vbThursday 5 Четверг vbFriday 6 Пятница vbSaturday 7 Суббота Таблица 9.10. Допустимые значения аргумента первая_неделя_аода Имя константы Числовое значение Описание vbUseSystem 0 Используются системные настройки vbFirstJani 1 Неделя, на которую попадает 1 января (значение, принятое по умолчанию) vbFirstFourDays 2 Первая неделя, на которую приходится, как мини- мум, четыре дня нового года vbFirstFullWeek 3 Первая полная неделя года Рассмотрим пример, в котором с помощью функции DatePart для указанной даты определяется значение интервала требуемого типа. ЫКвартал = DatePart("q", #20/09/2003#) В этом примере функция DatePart возвращает значение 3, так как 20 сентября при- ходится на третий квартал года. Следует также заметить, что смысл некоторых определи- телей интервалов для функции DatePart отличается от соответствующих определителей функции DateAdd, а именно: для "w" значение 1 возвращается для первого дня недели (по умолчанию — вос- кресенье) и 7 — для последнего дня недели (по умолчанию суббота); для " d" возвращается день месяца; для "у" — день года. Глава 9. Встроенные функции VBA 179
Строковые функции Строковые функции в языке VBA используются очень часто. Трудно представить себе программу, созданную в среде VBA, которая не была бы так или иначе связана с обработ- кой текста. Строковые данные очень важны и встречаются практически в каждом VBA- приложении, поэтому в языке VBA имеется довольно большая коллекция функций фор- матирования строк и извлечения из них тех частей, с которыми необходимо будет работать. В табл. 9.11 приведены функции обработки строковых выражений и их краткое описание. Таблица 9.11. Функции языка VBA для обработки строк Функция Возвращаемое значение Asс(строка) С h г(код_ символа) Возвращает числовой код первого символа в строке Возвращает символ, соответствующий числовому значению параметра код_символа InStr (строка!., строка2[, старт]) Возвращает позицию вхождения одной строки внутри другой. Строка 1 — исходная строка, в которой выполняется поиск. Строка2 — искомая строка. Поиск начинается в исходной строке с позиции старт (необязательный аргумент). Если этот аргумент опущен, то поиск на- чинается с первого символа исходной строки InStrRev(строка 1, строка2[, старт]) Возвращает позицию вхождения одной строки внутри другой. Строка 1 — исходная строка, в которой выполняется поиск. Строка2 — искомая строка. Поиск начинается с позиции старт (необязательный аргумент) и проводится в обратном направлении, от конца строки к ее началу. Если аргумент стартопущен, то поиск начинается с последне- го символа исходной строки InputBox(сообщение[, заголовок] [, ответ]) Возвращает строку, введенную пользователем с клавиатуры в поле ввода диалогового окна сообщения, выводимого при выполнении этой функции. Аргумент сообщение определяет текст сообщения в этом окне, аргумент заголовок — заголовок этого окна, а текст, указанный в аргументе ответ, помещается в поле ввода окна как исходное значе- ние по умолчанию Le ft(строка, длина) Возвращает подстроку, состоящую из заданного аргументом длина количества символов, начиная с первого символа исходной строки, определяемой аргументом строка Len(строка) LCase(строка) Возвращает число символов в строке Возвращает копию исходной строки, в которой все символы переведе- ны в символы нижнего регистра Ltrim(строка) Возвращает копию данной строки с удаленными символами пробелов, которые могли находиться в ее начале Mid(строка, старт, длина) Возвращает подстроку из заданного аргументом длина количества сим- волов (необязательный аргумент), скопированных из исходной строки строка, начиная с позиции, определяемой аргументом старт MsgBox(сообщение[, заголовок] ) Выводит окно с сообщением, определяемым строковым выражением в аргументе сообщение. Необязательный аргумент заголовок задает заголовок этого окна Right(строка, длина) Возвращает подстроку, состоящую из заданного аргументом длина количества символов, скопированную из исходной строки, задаваемой аргументом строка, начиная от ее конца 180 Часть 3. Более сложные аспекты работы на VBA
Окончание табл. 9.11 Функция Возвращаемое значение RTrim(строка) Возвращает копию исходной строки с удаленными символами пробе- лов, которые могли находиться в ее конце Space(число) Возвращает строку, состоящую из указанного аргументом число коли- чества пробелов StrComp{строка!, Возвращает результат сравнения двух строк, заданных аргументами строка2) строка! и строка2: 0, если строки равны; -1, если значение первой строки меньше значения второй; 1, если значение первой строки боль- ше значения второй StrConv{строка, Возвращает строку, полученную с помощью преобразования исходной метод_ перевода) строки в новую форму по методу, определяемому значением параметра метод_перевода String(число, символ) Возвращает строку, состоящую из заданного числа повторений одного и того же указанного символа Trim(строка) Возвращает копию данной строки с удаленными символами пробелов, которые могли быть в начале и в конце исходной строки UCase(строка) Возвращает копию исходной строки, в которой все исходные символы переведены в символы верхнего регистра Теперь остановимся на более подробном описании некоторых из приведенных выше строковых функций. Функция MsgBox Это одна из наиболее популярных функций языка VBA. Она очень часто используется при отладке процедур в редакторе VBA, поскольку, вставив оператор с этой функцией в любое место процедуры, можно приостановить вычисления и отобразить на экране в диалоговом окне любой интересующий вас промежуточный результат. Основное преиму- щество функции MsgBox в том, что она не только возвращает значения, но и выводит пользователю диалоговое окно с указанным сообщением и несколькими кнопками. Озна- комившись с сообщением, пользователь должен дать на него ответ, щелкнув на той или иной кнопке в окне. Ответ пользователя, определенный им с помощью щелчка на одной из кнопок в диалоговом окне сообщения, и является тем самым значением, которое воз- вращает функция MsgBox. Данная функция имеет пять аргументов, из которых только один обязателен. Синтаксис функции MsgBox следующий. MsgBox {сообщение [,кнопки] [, заголовок] [, файл_справки, раздел]) Здесь сообщение — обязательный аргумент, который может быть любым строковым вы- ражением, определяющим отображаемое в диалоговом окне сообщение для пользователя. Кнопки — необязательный аргумент, представляющий собой числовое выражение, за- дающее количество и тип отображаемых в диалоговом окне кнопок. Если этот аргумент опущен, то выводится только одна кнопка ОК. Допустимые значения для этого аргумента приведены в табл. 9.12. Необязательный аргумент заголовок содержит текст, который отображается в строке заголовка окна сообщений. Если этот аргумент опущен, то в заго- ловке будет выведено имя приложения. Необязательный аргумент файл_справки — это строковое выражение, определяющее имя справочного файла Windows. Необязательный Глава 9. Встроенные функции VBA 181
аргумент раздел — это числовое выражение, указывающее раздел в справочном файле. Если в список аргументов включен один из этих аргументов, то должен быть включен и второй. Таблица 9.12. Допустимые значения аргумента кнопки функции MsgBox Имя константы Числовое значение Описание vbOKOnly 0 Отображается только кнопка ОК vbOKCancel 1 Отображаются кнопки ОК и Отмена (OK, Cancel) vbAbortRetryIgnore 2 Отображаются кнопки Прервать, Повтор, Пропустить (Abort, Retry, Ignore) vbYesNoCancel 3 Отображаются кнопки Да, Нет, Отмена (Yes, No, Cancel) vbYesNo 4 Отображаются кнопки Да, Нет (Yes, No) vbRetryCancel 5 Отображаются кнопки Повтор, Отмена (Retry, Cancel) vbCritical 16 Отображается значок критического предупре- дительного сообщения (в виде белого крестика в красном кружке) vbQuestion 32 Отображается значок предупреждающего запро- са (в виде синего вопросительного знака в белом кружке) vbExclamation 48 Отображается значок предупреждающего сообще- ния (в виде черного вопросительного знака в жел- том треугольнике) vblnformation 64 Отображается значок информирующего сообще- ния (в виде синей буквы i в белом кружке) vbDefaultButtonl 0 Выбор по умолчанию первой кнопки vbDefaultButton2 256 Выбор по умолчанию второй кнопки vbDefaultButton3 512 Выбор по умолчанию третьей кнопки vbDefaultButton4 768 Выбор по умолчанию четвертой кнопки vbSystemModal 4096 Режим модальности: все программы приостанавли- ваются до тех пор, пока пользователь не ответит на сообщение Значения 1—5 параметра кнопки могут быть просуммированы со значениями 16—64 и256—4096. В этом случае первые значения определяют состав кнопок диалогового окна, вторые — вид отображаемого в окне значка, а третьи — выбор кнопки по умол- чанию. Например, если в качестве значения параметра указать выражение 3+64+512, то в диалоговом окне будут отображены кнопки Да, Нет, Отмена, значок информи- рующего сообщения и по умолчанию будет выбрана кнопка Отмена. Ниже приведен пример использования функцией MsgBox встроенной константы vbYesNoCancel (см. табл. 9.12). Как выглядит соответствующее окно сообщений, по- казано на рис. 9.1. Sub А() MsgBox ’’Нажмите нужную кнопку”, vbYesNoCancel, ’’Контрольный пример" End Sub 182 Часть 3. Более сложные аспекты работы на VBA
Рис. 9.1. Окно сообщения, отображаемое при выполнении функции MsgBox Чтобы закрыть выведенное функцией MsgBox диалоговое окно, пользователь должен щелкнуть на одной из его кнопок. По завершении выполнения функция MsgBox возвра- щает числовое значение целого типа, определяющее ту кнопку, на которой щелкнул поль- зователь. Однако возвращаемое значение можно сравнивать не только с конкретными чис- лами, но и с константами, предлагаемыми языком VBA, — они перечислены в табл. 9.13. Таблица 9.13. Константы для проверки возвращаемых значений функции MsgBox Константа Числовое значение Кнопка vbOK 1 OK vbCancel 2 Отмена (Cancel) vbAbort 3 Стоп (Abort) vbRetry 4 Повтор (Retry) vblgnore 5 Пропустить (Ignore) vbYes 6 Да (Yes) vbNo 7 Нет (No) Функция InputBox Функция InputBox, как и функция MsgBox, часто используется в программах для обмена данными с пользователем. Функция InputBox отображает диалоговое окно с текстовым полем ввода, куда пользователь может ввести запрашиваемую программой ин- формацию. Полный синтаксис этой функции и описание ее необязательных аргументов, которые здесь опущены, приведены в справочной системе VBA. Упрощенный вариант синтаксиса функции InputBox имеет следующий вид. InputBox(сообщение[, заголовок] [, Ответ] Здесь аргумент сообщение — это любое строковое выражение, результат вычисления ко- торого будет отображен в качестве сообщения в выводимом функцией диалоговом окне. Это единственный обязательный аргумент для функции InputBox. Аргумент (необяза- тельный) заголовок — это строка, которая будет выведена в качестве заголовка в отобра- жаемом функцией диалоговом окне. Аргумент (необязательный) Ответ — это строковое выражение, результат вычисления которого будет отображен как значение по умолчанию в поле ввода диалогового окна. Если этот аргумент опущен, то поле ввода будет пустым. Например, следующий оператор выводит диалоговое окно, в котором пользователю пред- лагается ввести фамилию нового сотрудника, причем в качестве значения, принятого по умолчанию, предлагается фамилия “Иванов”. strA = InputBox (’’Введите фамилию нового сотрудника’’, _ ’’Контрольный пример”, "Иванов") Плава 9. Встроенные функции VBA 183
При выполнении этого оператора на экране будет выведено диалоговое окно с соот- ветствующим сообщением и заголовком, а также полем ввода, в которое пользователю предлагается ввести требуемую информацию (рис. 9.2). Обратите внимание на то, что исходно в поле ввода отображается значение, принимаемое по умолчанию, — Иванов. Функция Input Box всегда возвращает значение, введенное пользователем, и для даль- нейшей обработки этой информации в программе следует присвоить возвращаемое функ- цией значение некоторой переменной. Рис. 9.2. Окно ввода, отображаемое на экране при использовании функции InputBox Функция StrConv С помощью функции StrConv над строковым значением можно выполнить множе- ство преобразований. Возвращаемое этой функцией значение — та же исходная строка, но преобразованная в новую форму в соответствии с указанным методом. Синтаксис функ- ции StrConv следующий. StrConv(строка, метод_перевода, LCID) Здесь аргумент строка задает исходную преобразуемую строку. Аргумент метод_ перевода определяет суть выполняемых преобразований и может принимать любое из значений, приведенных в табл. 9.14. LCID — необязательный аргумент, задающий иденти- фикатор региональных настроек, причем для него по умолчанию принимается значение LocalelD, т.е. тот системный идентификатор, который установлен в панели управления. Таблица 9.14. Допустимые значения аргумента метод_перевода функции StrConv Константа Числовое значение Преобразование vbUpperCase 1 Переводит строку в верхний регистр vbLowerCase 2 Переводит строку в нижний регистр vbProperCase 3 Переводит первые символы всех слов в верхний регистр, а остальные символы — в нижний vbWide 4 Переводит однобайтовые символы строки в двухбайтовые. Приме- ним только для кодировок восточных языков vbNarrow 8 Переводит двухбайтовые символы строки в однобайтовые. Приме- ним только для кодировок восточных языков vbKatakana 16 Преобразует символы Хирагана в символы Катакана. Только для японского языка vbHiragana 32 Преобразует символы Катакана в символы Хирагана. Только для японского языка vbUnicode 64 Переводит строку в кодировку Unicode vbFromUnicode 128 Переводит строку из кодировки Unicode в традиционную кодировку 184 Часть 3. Более сложные аспекты работы на VBA
Функция Chr В языке VBA функция Chr () используется, если необходимо включить в строку симво- лы, которые невозможно ввести с клавиатуры или которые уже используются в языке VBA для специальных целей (например, символ кавычек). Функция Chr () в качестве аргумента принимает числовой код требуемого символа и возвращает строку, содержащую единствен- ный символ, соответствующий этому коду. Синтаксис функции Chr () следующий. Chr(коД—Символа) Здесь аргумент код_символа — это числовое выражение, значение которого должно находиться в диапазоне от 0 до 255 (напомним, что каждый символ имеет свой уникаль- ный номер). Чтобы в списке кодов, которые распознает VBA, найти нужный код и со- ответствующий ему символ, нужно открыть справочную систему VBA и выбрать раздел Character sets (рис. 9.3). V Справка: Word - - х * * Д 4* А* * ? Character sets • р Поиск ’ Offline Developer Help Автономная работа Рис. 9.3. Список кодов символов (0—127) в справочной системе VBA С помощью функции Chr () можно поместить в строку, например, код символа воз- врата каретки (код этого символа 13), который генерируется компьютером всякий раз при нажатии на клавиатуре клавиши <Enter>. Если с помощью функции Chr () поместить в Глава 9. Встроенные функции VBA 185
текст код этого символа, он будет отмечать начало новой строки. Например, сообщение в диалоговом окне, выводимом с помощью оператора MsgBox, может быть отформатирова- но символами возврата каретки, задаваемыми с помощью функции Chr (). Ниже приве- ден соответствующий программный код, а результат его выполнения показан на рис. 9.4. MsgBox "Введите :" & Chr(13) & _ " Фамилию" & Chr(13) & _ " Имя" & Chr (13) & " Отчество" Рис. 9.4. Использование функции Chr () для форматирования сообщений Следует отметить, что язык VBA включает несколько предварительно определенных именованных констант для обозначения различных служебных символов (в частности, и для символа начала новой строки), что позволяет избежать необходимости использовать функцию Chr (). vbCh — символ возврата каретки (код символа 13). Константа vbCh эквивалентна выражению Chr (13) и означает требование начать новую строку при выводе по- следующего текста на экран. vbLf — символ смещения на одну строку вниз (код символа 10). Константа vbLf эквивалентна выражению Chr (10) и означает требование перехода к следующей строке при выводе последующего текста. vbChLf — символ возврата каретки/смещения на одну строку. Константа vbChLf эквивалентна выражению Chr (13) & Chr (10) и означает требование поместить последующий текст с начала следующей строки. vbTab — символ табуляции (код символа 9). Этот символ также вводится при на- жатии клавиши <ТаЬ> клавиатуры. Константа vbTab эквивалентна выражению Chr (9) и позволяет включить символы табуляции в текстовые строки для вырав- нивания данных по столбцам. Теперь предыдущий пример можно переписать с использованием соответствующих констант в следующем виде. MsgBox "Введите :" & vbCr & _ " Фамилию" & vbCr & _ " Имя" & vbCr & _ " Отчество" Следует отметить, что, кроме перечисленных выше функций, существуют также специальные операторы обработки строк, которые, в отличие от функции, выполняют 186 Часть 3. Более сложные аспекты работы на VBA
некоторые действия, не возвращая при этом результирующего значения. Эти операторы перечислены ниже. Оператор LSet отроковая_переменная = строка. С его помощью в указан- ную строковую переменную помещается значение строка начиная с самого левого байта переменной, при этом исходное значение переменной затирается. Например, если значение переменной Vari было "Вавилов", то после выполне- ния оператора Lset Vari = "Петровский" значением переменной Vari будет "Петрове". (Обратите внимание: длина значения не изменяется, лишние символы из строка просто отбрасываются, а недостающие заполняются пробелами.) Оператор Mid (с троков а я_ переменная, старт, длина) = строка. С его по- мощью в указанную строковую переменную помещается значение строка, начиная с позиции старт и в пределах количества символов, заданных аргументом длина. Так, если к переменной Vari с исходным значением "Вавилов " применить опера- тор Mid (Vari, 2, 3) = "Петровский", то в результате значение переменной Vari изменится на "ВПетлов". Оператор RSet строковая_переменная = строка. С его помощью в указанную строковую переменную помещается значение строка, выровненное так, чтобы его последний символ находился в самом правом байте переменной. Например, если значение переменной Vari было "Вавилов", то после выпол- нения оператора Rset Vari = "Петровский" значением переменной Vari будет ... снова "Петрове"! Но если исходным значением переменной Vari будет "Академик Вавилов", то результат будет " Петровский", т.е. слева будет добавлено шесть пробелов. Финансовые и прочие функции В языке VBA существует ряд функций, которые позволяют выполнять расчеты, ис- пользуемые при различных финансовых операциях. Например, эти функции можно при- менять для расчетов выплат по ссуде или возвращения инвестиций. Перечень финансовых функций представлен в табл. 9.15. Полный синтаксис этих функций и описание необяза- тельных аргументов, которые здесь опущены, приводится в справочной системе VBA. Таблица 9.15. Финансовые функции VBA Функция Возвращаемое значение DDB(стоимость, остаток, период) FV(ставка, кпер, пла та, сумма) Impt(ставка, период, кпер, сумма) IRR(значения()) Возвращает величину амортизации имущества за данный период, ис- пользуя метод двойного процента со снижающегося остатка Возвращает будущее значение вклада на основе периодических посто- янных платежей и постоянной процентной ставки Возвращает величину выплаты за указанный период на основе перио- дических постоянных платежей и постоянной процентной ставки Возвращает внутреннюю скорость оборота для ряда последовательных операций с наличными, представленными числовыми значениями MIRR(значения() , фин_ставка, реинвест ставка) Возвращает модифицированную внутреннюю скорость оборота средств для ряда последовательных периодических операций с наличными Глава 9. Встроенные функции VBA 187
Окончание табл. 9.15 Функция Возвращаемое значение Nper(ставка, пла теж, сумма) Возвращает общее количество периодов выплаты для данного вклада на основе периодических постоянных выплат и постоянной процентной ставки NPV(ставка, значения() ) Возвращает чистый текущий объем вклада, используя учетную ставку, а также объемы будущих платежей (отрицательные значения) и посту- плений (положительные значения) Pmt(ставка, кпер, сумма) PPmt () Возвращает величину выплаты по ссуде на основе постоянных выплат и постоянной процентной ставки Возвращает платежи по процентам за данный период на основе перио- дических постоянных выплат и постоянной процентной ставки PV (ставка, кпер, плата) Rate (кпер, плата, сумма) SLN(стоимость, остаток, период) SYD(стоимость, остаток, срок_ Возвращает текущий объем вклада на основе периодических постоян- ных платежей и постоянной процентной ставки Возвращает процентную ставку за один период при выплате ренты Возвращает величину непосредственной амортизации имущества за один период Возвращает годовую амортизацию имущества для указанного периода эксплуатации, период) Кроме перечисленных выше основных категорий функций, в языке VBA имеются так- же прочие типы функций, к которым, в частности, относятся функции выбора, дублирую- щие некоторые варианты записи операторов условного перехода. В табл. 9.16 приведены эти функции и дано их краткое описание. Таблица 9.16. Функции выбора Функция Возвращаемое значение Ilf (выражение, результатТгие, результатГа!зе) Возвращает значение результатТгие, если после вычисле- ния выражения, заданного аргументом выражение, получено значение True. В противном случае возвращается значение результатГа!зе Choose (индекс, вариант![, вариант2, [, варианты, ] ] ) Возвращает значение из списка аргументов вариант!, ]... вариант2, варианты, определяемое вычисленным значением аргумента индекс. Иначе говоря, если значение выражения индекс равно 1, возвращается первый элемент списка, если 2 — второй и т.д. Switch (выражение!, Функция последовательно вычисляет значения выражений, значение! [, выражение2, заданных аргументами выражение!—выражениемв списке ар- значение2]... [, выражением, гументов, и, как только будет получено первое значение True, значением, ] ] ) возвращает выражение, определяемое соответствующим аргу- ментом значение Рассмотрим еще некоторые функции, которые могут вам пригодиться при программи- ровании на языке VBA. Краткое их описание приведено в табл. 9.17. Следует напомнить, что при задании аргументов следует заключать в кавычки фактические значения таких параметров, как путь доступа к файлу. 188 Часть 3. Более сложные аспекты работы на VBA
Таблица 9.17. Различные полезные функции VBA Имя функции Возвращаемые значения DoEvents Позволяет операционной системе Windows обрабатывать другие события, пока ваша программа выполняется. В VBA эта функ- ция всегда возвращает 0, поэтому нет необходимости приписы- вать ее значение переменной — используйте ее как оператор Environ(строка/число) Возвращает содержимое переменной окружения, заданной либо строкой с ее именем, либо числом, определяющим ее позицию RGB(красный, зеленый, синий) Возвращает целое число, представляющее RGB-значение цвета, заданного числовыми значениями (0—255) яркости его компо- нентов красный, зеленый, синий (используйте это значение для установки цветовых свойств объектов) Rnd([число] ) Возвращает случайное значение; аргумент число является необязательным Shell(путь) Предпринимается попытка выполнить программу, файл кото- рой определяется значением аргумента путь. В случае успеха возвращается число, представляющее идентификатор програм- мы в среде Windows, в противном случае возвращает 0 GetAllSettings (имя_ приложения, раздел) Возвращает значение типа Variant, содержащее список всех установок для указанного раздела приложения в реестре Windows (в виде двухмерного массива) GetSetting (имя_приложения, Возвращает значение заданного параметра из указанного раз- раздел, параметр) Spc(число) дела приложения в реестре Windows Не возвращает никаких полезных значений и используется лишь для размещения указанного числа пробелов в потоке вы- вода оператора Print # или метода Debug. Print Tab(столбец) Не возвращает никаких полезных значений. Предназначена для смещения в указанный столбец потока вывода оператора Print # или метода Debug. Print Len (переменная) Возвращает количество байтов, необходимое для хранения по- мещенной в переменную информации TypeName (переменная) VarType (переменная) Возвращает строку, описывающую тип переменной Возвращает целое число, представляющее подчиненный тип переменной Следует отметить, что, кроме перечисленных выше функций, существуют также раз- личные операторы, которые, в отличие от функции, выполняют некоторые действия, не возвращая при этом результирующего значения. Описание этих операторов приведено в табл. 9.18. Таблица 9.18. Некоторые операторы VBA Операторы Выполняемые действия AppActivate название, ожидание Активизирует другое выполняемое приложение. Если необязательный аргумент ожидание имеет значение True, то VBA будет ждать, пока ваша программа не получит фокус ввода Веер Подает звуковой сигнал с помощью громкоговорителя ком- пьютера Глава 9. Встроенные функции VBA 189
Окончание табл. 9.18 Операторы Выполняемые действия Randomize DeleteSetting имя_приложения, раздел, параметр SendKeys строка, ожидание Инициализирует генератор случайных чисел Удаляет указанный аргументами элемент реестра Пересылает заданную аргументом строка последователь- ность символов в активное окно так, как будто эти символы были введены пользователем с клавиатуры. Если необя- зательный аргумент ожидание имеет значение True, то выполнение программы остановится, пока последователь- ность символов не будет обработана SaveSetting имя_приложения, раздел, параметр, значение Сохраняет заданное значение в элементе реестра, опреде- ляемом остальными аргументами Резюме В этой главе были представлены различные функции, встроенные в компилятор языка VBA. Богатейший спектр этих функций можно разбить на несколько категорий: матема- тические, преобразования данных, проверки типов, обработки даты и времени, обработки символьных строк, финансовые и пр. Использование этих функций связано с различными аспектами, которые подробно обсуждались в главе. Следует отметить, что без овладения всем спектром функций языка VBA создание собственных приложений в среде Microsoft Office будет малоэффективным. Тестовые задания Ниже приведено несколько тестовых заданий, предназначенных для закрепления из- ложенного в этой главе материала. В каждом задании вам предлагается вопрос и несколь- ко вариантов ответа на него, один (или несколько) из которых является правильным, а остальные — нет. Укажите правильный ответ. 1. Встроенные математические функции языка VBA позволяют выполнять следую- щие вычисления: а) вычислять значения тригонометрических функций; б) определять площади геометрических фигур; в) выполнять обработку матриц; г) генерировать случайные числа. 2. Преобразование строковых значений в число и обратно выполняется с помощью функций: a) Hex и Oct; б)CBoolи CByte; в) Vai и Str; r)CInt HCStr. 190 Часть 3. Более сложные аспекты работы на VBA
3. В шаблонах функции Format для представления цифровых разрядов чисел исполь- зуются следующие символы: а) А; 6)0; в) 9; г)п; Д) х; е)_; ж) #. 4. Для определения текущей даты можно воспользоваться следующей функцией VBA: a) Date; б) Time; в) Now; г) DateValue; Д) Day. 5. С помощью строковых функций языка VBA над строковыми значениями могут быть выполнены следующие действия: а) дублирование; б) выделение подстроки; г) перевод с одного языка на другой; д) поиск в строке заданной последовательности символов; е) проверка орфографии. Глава 9. Встроенные функции VBA 191
Глава 10 Экранные формы и их элементы В этой главе... ♦ Формы пользователя ♦ Элементы управления в формах ♦ Свойства элементов управления ♦ Общие методы и события элементов управления ♦ Создание процедур обработки событий ♦ Дополнительные элементы управления ♦ Проектирование и создание форм ♦ Пример создания формы ♦ Резюме Язык VBA позволяет вместо встроенных окон, принадлежащих Word, Excel и другим приложениям Windows, использовать экранные формы, созданные специально для кон- кретной программы. Эти формы в написанных вами программах могут представлять собой специальные диалоговые окна и поля, которые позволят решить практически любую по- ставленную перед вами задачу. Например, в языке VBA с помощью экранных форм можно создавать диалоговые окна для получения значений от пользователя или для вывода на экран данных, причем именно в таком виде, который требуется в данной программе. Это позволяет организовать программу так, чтобы обеспечить необходимую гибкость при вво- де и выводе данных, благодаря чему пользователь сможет работать с программой самым удобным для него образом. Формы пользователя Пользовательские диалоговые окна создаются в редакторе VBA как экранные формы, представляющие собой объекты класса UserForm. Такая экранная форма — форма поль- зователя — состоит из окна формы (это то самое окно, которое отображается на экране) и нескольких специфических элементов управления, размещенных в этом окне. Все фор- мы, как и любые элементы управления в форме, — это полноценные объекты VBA. Как уже говорилось, каждая форма пользователя представлена объектом класса UserForm, который описывает пустое диалоговое окно. Все объекты UserForm являются частью проекта и хранятся в коллекции UserForms. Каждый объект класса UserForm имеет
определенные свойства, методы и события, которые определены в этом классе объектов. Все элементы управления, размещенные в форме пользователя, представлены объектами в коллекции Controls. Каждый из элементов управления (точнее, представляющий его объект), так же как и сама форма пользователя, имеет свой набор событий. Следует отметить, что в редакторе VBA стандартные свойства объектов форм пользо- вателя и принадлежащих им элементов управления можно изменять непосредственно в специальных диалоговых окнах, без написания собственных подпрограмм. Однако, помимо свойств и процедур обработки стандартных событий, формы пользователя мо- гут содержать пользовательские процедуры и функции, а также специфические допол- нительные свойства, доступ к которым обеспечивается с помощью соответствующих пользовательских процедур. Для создания в проекте VBA новой формы пользователя необходимо активизировать этот проект в окне проектов и либо выбрать команду меню InsertsUserForm редакто- ра VBA, либо щелкнуть правой кнопкой мыши в окне проектов и выбрать команду InsertsUserForm в раскрывшемся контекстном меню. При этом новая форма (т.е. заготов- ка новой формы) появится в специально созданном для нее окне. Рядом с формой будет отображена панель элементов управления Toolbox — специальная панель инструментов, содержащая кнопки, с помощью которых соответствующие элементы управления мож- но разместить в создаваемой форме. Обратите внимание на сетку из точек, помещенную на поверхность отображаемой части окна формы. Эта сетка поможет вам выравнивать и контролировать размер элементов управления, помещаемых в форму. Сетка из точек отображается в форме только в режиме разработки. По умолчанию формам пользователя (т.е. соответствующим объектам) автоматически присваиваются имена UserForml, UserForm2 и т.д. При желании имя формы пользо- вателя можно изменить на более понятное, отражающее назначение формы. Для этого достаточно выбрать требуемую форму в окне проектов, а затем в окне свойств (окно Property) изменить значение ее свойства Name (Имя). Если окно свойств не отображено в окне редактора VBA, предварительно нажмите <F4> для вывода этого окна на экран, по- сле чего измените значение свойства Name формы. Общий вид окна формы пользователя (вместе с окном свойств) показан на рис. 10.1. Рассмотрим элементы формы пользователя, отображенные на рис. 10.1. Заполненное сеткой из точек диалоговое окно UserForml в центре окна Документ1 [UserForml (UserForm)] — это пустая форма пользователя; можно менять ее раз- меры и положение на экране, задавать цвет ее фона и размещать в ней элементы управления, предназначенные для выполнения тех или иных функций. Чтобы изменить размер формы, достаточно подвести курсор мыши к одному из белых маркеров (небольших прямоугольников) в центрах сторон или в углах формы и перетащить этот маркер до получения желаемого размера формы. Окно Toolbox (Панель элементов), расположенное справа от окна формы пользо- вателя, содержит единственную вкладку Controls (Элементы управления), где на- ходятся кнопки, представляющие все типы элементов управления, которые могут быть помещены в формы VBA. С помощью этих кнопок можно выбрать требуемый элемент управления и добавить его к форме. Следует отметить, что панель элемен- тов обычно появляется на экране в том случае, когда в окне проекта выбрана не- которая форма или один из ее элементов управления. Глава 10. Экранные формы и их элементы 193
Рис. 10.1. Пустая форма пользователя, готовая к редактированию После щелчка мышью на форме пользователя в окне свойств отображаются свой- ства формы как текущего выбранного объекта. Если выделить в форме один из ее элементов управления, то в окне Properties будут представлены свойства данного элемента управления. В окне свойств имеются две вкладки, на каждой из которых отображается один и тот же набор свойств: на вкладке Alphabetic (По алфавиту) эти свойства упорядочены по алфавиту, а на вкладке Categorized (По категориям) те же свойства сгруппированы по категориям. На каждой из этих вкладок слева указываются имена свойств, а справа от каждого имени — его текущее значение. При выборе некоторого свойства его значение автоматически отображается в поле, позволяющем это значение изменить, но только в пределах набора допустимых значений данного свойства. На панели инструментов окна Project слева находятся две кнопки View Code и View Object; Кнопка View Code позволяет отобразить для текущей формы окно программного кода, содержащее текст всех ее подпрограмм, т.е. методов и событий. Щелчок на кнопке View Object позволяет перейти в окно визуального представле- ния интерфейса формы. 194 Часть 3. Более сложные аспекты работы на VBA
Следует помнить, что перед созданием новой формы необходимо сделать активным именно тот проект (документ), в котором должна разместиться создаваемая форма. Ь Для этого сначала откройте документ проекта в VBA-приложении, а затем запустите редактор VBA. Если приложение позволяет открыть сразу несколько документов или если для работы с документом используется шаблон, то для выбора нужного проек- та дополнительно потребуется воспользоваться окном проекта (см. в главе 2 раздел “Окно проектов и обозреватель объектов”). Отображение экранной формы Отображение формы на экране в VBA выполняется в два этапа: загрузка формы в оперативную память компьютера; отображение загруженной формы на экране. Оба этапа можно выполнить с помощью одного оператора VBA, можно также выпол- нить каждый этап по отдельности, один за другим, используя при этом отдельные опера- торы для каждого этапа. Для отображения формы на экране используется метод Show (Показать) объекта UserForm (Экранная форма). Синтаксис вызова метода следующий. ИмяФормы. Show Здесь обозначение ИмяФормы представляет имя объекта требуемой формы, т.е. это может быть имя любого объекта класса UserForm в текущем проекте. Имя формы должно соот- ветствовать значению, которое отображается для данной формы в окне проектов. Ниже приведен пример процедуры (она должна находиться в обычном модуле VBA, а не в моду- ле экранной формы), которая отображает на экране форму Forml. Sub Вывод_формы() Forml.Show End Sub Метод Show добавляется к имени формы после точки-разделителя, так как является методом объекта класса UserForm. Метод Show сначала загружает данную форму, если она в данный момент еще не была загружена в память, а затем выводит ее на экран. Если форма была уже загружена, то метод Show просто выводит ее на экран. В любом случае метод Show выводит форму на экран, а затем передает ей управление. После вывода на экран форма остается видимой до тех пор, пока не будет закрыта. Следует отметить, что, в дополнение к методам, свойствам и событиям, в языке VBA имеются еще два оператора, очень полезные при работе с объектами форм. Это операторы Load (Загрузить) и Unload (Выгрузить). Синтаксис этих операторов следующий. Load ИмяФормы Unload ИмяФормы Оператор Load загружает в память форму, т.е. указанный объект класса UserForm, но не выводит ее на экран. После того как форма будет загружена, для работы с этим объектом UserForm можно использовать любую написанную на языке VBA программу. Оператор Unload выгружает (удаляет) форму, т.е. указанный объект класса UserForm, из памяти, после чего она становится уже недоступной для VBA-кода. Глава 10. Экранные формы и их элементы 195
Закрытие экранной формы Кроме рассмотренного выше оператора Unload, закрыть экранную форму можно так- же простым щелчком на стандартной кнопке Закрыть, расположенной в правом углу стро- ки заголовка формы. Однако часто для нормального завершения работы экранной формы потребуются некоторые дополнительные действия. Это может быть сохранение текущих значений полей формы в записи файла или копирование этих значений в глобальные переменные для последующего использования либо любые другие действия, необходимые для сохранения полученных результатов и нормального продолжения работы программы. В принципе, эти действия можно описать в подпрограммах обработки событий щелчка на командных кнопках ОК, Отменить и пр. Однако следует заметить, что щелчок на кнопке Закрыть не является событием самой экранной формы. Он обрабатывается на системном уровне и просто прерывает выполнение программного кода модуля экранной формы. При этом все операторы, которые необходимы для корректного закрытия формы и присут- ствуют в процедурах, связанных с событиями кнопок, не выполняются. Чтобы корректно закрыть экранную форму как по щелчку на этой кнопке, так и по щелчку на командных кнопках, следует все операторы, требуемые для корректного завершения работы формы, поместить в подпрограмму формы обработки данного системного события — она называ- ется UserForm_Terminate (Завершение экранной формы). Только в этом случае щелчок на кнопке Отмена и щелчок на кнопке Закрыть будут одинаково корректно выполнять закрытие формы. Чтобы поместить необходимый код в подпрограмму обработки некоторого события формы (например, UserForm Terminate), выполните двойной щелчок в любом свободном месте Окна формы — раскроется окно редактора кода с текстом программ- ного модуля формы. Выберите в левом списке (вверху) значение UserForm, а в пра- вом списке — название требуемой процедуры, и редактор вставит в модуль заготовку ее кода. Вам останется только заполнить эту заготовку нужными операторами, и всю работу по обработке соответствующего события формы можно считать выполненной. Незакрытая экранная форма будет оставаться на экране до тех пор, пока она не будет выгружена из памяти с помощью описанного выше оператора Unload либо не будет вы- полнен ее метод Hide (Скрыть) — этот метод объекта UserForm удаляет изображение экранной формы с экрана, но не выгружает ее из памяти компьютера. При этом для про- граммного кода VBA остаются доступными различные методы и свойства ее элементов управления. Чаще всего формы языка VBA являются модальными. Это означает, что нельзя выпол- нить какое-либо другое действие в приложении до тех пор, пока такая модальная форма (иначе их называют диалоговыми окнами) не будет закрыта или скрыта. Однако это правило вовсе не обязательно для всех форм. В действительности, будет форма модаль- ной или нет, определяется значением ее свойства ShowModal (подробности — в сле- дующем разделе). Если нужно скрыть экранную форму лишь на время выполнения какой-нибудь про- цедуры, следует поместить в начало этой процедуры оператор вызова метода Hide формы, за которым должен следовать оператор DoEvents. Например, в приведенной ниже про- цедуре некоторая экранная форма скрывается с экрана программы Excel после щелчка на содержащейся в ней командной кнопке CommandButtonl. Далее процедура записывает 196 Часть 3. Более сложные аспекты работы на VBA
в ячейки А1-А100 числа от 1 до 100 (цикл For-Next), а последний оператор этой про- цедуры выгружает данную экранную форму из памяти компьютера. Private Sub CommandButtonl_Click() Me.Hide DoEvents For r = 1 To 100 Cells(r, 1) = r Next r Unload Me End Sub После закрытия экранной формы ее элементы управления возвращаются в исходное со- стояние, т.е. все изменения, сделанные пользователем в диалоговом окне, которое было представлено данной экранной формой, становятся недоступными для процедур при- ложения. Для того чтобы эти изменения были сохранены и после закрытия экранной формы, следует еще до ее закрытия сохранить их как значения глобальных переменных. Некоторые свойства объекта UserForm У объекта UserForm есть большое количество принадлежащих ему свойств, кото- рые отображаются в окне свойств (Properties) при его выборе (т.е. выборе формы). Все эти свойства распределены в несколько групп, которые можно увидеть, перейдя в окне свойств на вкладку Categorized (По категориям). Так, группа свойств Appearance опре- деляет внешний вид формы — цвет ее фона (BackColor) и вид рамки (Borderstyle), текст в строке заголовка (Caption) и т.д. Вторая группа свойств, Behavior, отвечает за поведение формы — активна она или нет (Enabled), является модальной или обычной (ShowModal) и пр. Третья группа свойств, Font, включает единственное одноименное свойство, определяющее шрифт, который будет использоваться при выводе сообщений в данную форму. Группа Misc (Прочее) включает несколько свойств, которые нельзя от- нести к другим категориям. Это, в частности, вид указателя мыши в форме и имя файла справочной системы, связанного с этой формой. Группа свойств Position определяет ис- ходное положение и размеры формы на экране при ее отображении, а группа Scrolling (Прокрутка) — наличие и тип полос прокрутки в ее окне. Наконец, группа свойств Picture (Рисунок) определяет файл рисунка, который используется как фоновое изображение в окне формы, описывает расположение его файла и способ отображения фонового рисунка в окне формы. Некоторые наиболее важные свойства форм приведены в табл. 10.1. Таблица 10.1. Некоторые свойства объекта UserForm Свойство Назначение Caption Height MousePointer Name Содержит текст, отображаемый в строке заголовка формы Высота формы в пунктах (1 пункт = 1/72 дюйма) Определяет вид курсора мыши, когда он находится над формой Имя объекта данной формы — именно оно должно использоваться в про- грамме для ссылки на эту форму Picture Определяет файл рисунка, который используется как фоновое изображение в окне формы PictureAlignment Задает расположение фонового рисунка в окне формы Глава 10. Экранные формы и их элементы 197
Окончание табл. 10.1 Свойство Назначение PictureSizeMode Определяет, как должен изменяться размер рисунка при изменении размеров формы ShowModal Если значение этого свойства равно True (по умолчанию), то, прежде чем остальные части приложения смогут продолжить работу, данная форма обя- зательно должна быть закрыта. Если значение этого свойства равно False, то форма может отображаться на экране (будучи неактивной), когда пользо- ватель переходит в другую часть приложения SpecialEffeet Startupposition Задает вид формы пользователя Указывает, в каком месте экрана должна отображаться данная форма. Если выбирается значение 0 - Manual, то позиция формы определяется свой- ствами Left (Слева) и Тор (Сверху), задающими (в пунктах) расстояние между формой и соответствующим краем экрана Width Zoom Определяет ширину формы в пунктах Задает масштаб отображения содержимого формы пользователя, в процентах от нормального Если выбрать конкретное свойство в окне Properties, а затем нажать клавишу <F1 >, в окне справки редактора VBA будет отображена подробная информация об этом свойстве. Некоторые методы объекта UserForm Создав форму и ее элементы управления, вам, скорее всего, затем потребуется так или иначе манипулировать самим объектом формы. Это можно сделать с помощью стандарт- ных методов и рассмотренных выше свойств класса UserForm, а также с помощью его процедур обработки событий. В табл. 10.2 представлены чаще всего используемые методы объектов класса UserForm, которыми можно воспользоваться при создании форм поль- зователя. Таблица 10.2. Некоторые методы объекта UserForm Метод Выполняемые действия Сору Cut Hide Копирует выделенный в форме текст в буфер обмена Windows Вырезает выделенный в форме текст и помещает его в буфер обмена Windows Делает объект UserForm невидимым, не выгружая его при этом из памяти компьютера Paste PrintForm Вставляет содержимое буфера обмена Windows в форму Выводит изображение формы на принтер (используемый в Windows по умол- чанию) Repaint Show Перерисовывает изображение формы на экране Выводит форму на экран. Если данная форма еще не была загружена, то метод Show предварительно поместит ее в память компьютера, а затем выведет изо- бражение формы на экран 198 Часть 3. Более сложные аспекты работы на VBA
Элементы управления в формах Когда в окне редактора VBA какая-либо форма пользователя становится активной, на экран автоматически выводится окно Toolbox (Панель элементов). Это окно по умолча- нию содержит единственную вкладку Controls (Элементы управления), на которой на- ходится 15 кнопок1 (рис. 10.2), представляющих все типы элементов управления, которые могут быть помещены в форму при создании любых диалоговых окон, используемых в приложении. Дополнительно отображением панели элементов на экране можно управ- лять с помощью команды меню View^Toolbox. Если пиктограмма слева от этой команды отображается в рамке, панель элементов будет автоматически выводиться на экран при открытии любой формы. Если рамка вокруг пиктограммы отсутствует — панель элемен- тов на экран не выводится. При выборе команды состояние пиктограммы изменяется на обратное, а панель инструментов соответственно появляется или удаляется с экрана. Ко- манда меню View^Toolbox также продублирована кнопкой на панели инструментов Stan- dard. В табл. 10.3 последовательно перечислены все кнопки, присутствующие на панели элементов, и приведено краткое описание соответствующих элементов управления. Рис. 10.2. Панель элементов Таблица 10.3. Кнопки панели элементов Кнопка Элемент управления Назначение 2. Выбор объектов (Select Objects) Переключает форму в режим выбора элементов управ- ления, уже присутствующих в ней. Все остальные кнопки панели элементов переводят форму в режим вставки в нее нового элемента управления, кнопка которого выбрана в данный момент А Надпись (Label) Добавляет в форму надпись аЫ Поле (TextBox) Добавляет в форму поле ввода И Поле со списком (ComboBox) Добавляет в форму поле ввода с раскрывающимся списком ЕВ Список (ListBox) Добавляет в форму поле обычного списка Р Флажок (CheckBox) Добавляет в форму флажок опции Переключатель (OptionButton) Добавляет в форму отдельную кнопку переключателя 1 Для приложения Microsoft Excel в окне Toolbox имеется 16 кнопок. Глава 10. Экранные формы и их элементы 199
Окончание табл. 10.3 Кнопка Элемент упраеления Назначение Выключатель (ToggleButton) Добавляет в форму кнопку выключателя о Рамка (Frame) Добавляет в форму рамку (объект — контейнер для других объектов) -J Кнопка (CommandButton) Добавляет в форму командную кнопку -Li Набор вкладок (TabStrip) Добавляет в форму набор вкладок Li Набор страниц (MultiPage) Добавляет в форму многостраничный элемент (кон- тейнер для других объектов) ZJ Полоса прокрутки (ScrollBar) Добавляет в форму полосу прокрутки 11 Счетчик (SpinButton) Добавляет в форму поле счетчика Рисунок (Image) Добавляет в форму элемент управления, предназна- ченный для размещения изображения га RefEdit (Поле определения ссылки)2 Добавляет в форму поле ввода, предназначенное для упрощенного задания ссылок на ячейки и диапазоны Excel Добавление элементов управления Для добавления в форму элемента управления стандартного размера (принятого для этого элемента по умолчанию) необходимо выполнить следующие действия. 1. Активизируйте проект в окне проектов и либо выберите команду меню Inserts UserForm редактора VBA, либо щелкните правой кнопкой мыши в окне проектов и выберите команду Insert^UserForm в раскрывшемся контекстном меню. 2. Найдите кнопку требуемого элемента управления на панели элементов Toolbox и щелкните на ней левой кнопкой мыши. В результате указатель мыши при переме- щении его в поле формы примет вид перекрестья с дополнительным значком, ука- зывающим на тип выбранного элемента. Это свидетельствует о том, что форма была переведена в режим вставки в нее данного элемента управления (рис. 10.3, а). 3. Переместите перекрестье указателя мыши на то место в форме, где должен нахо- диться верхний левый угол вставляемого элемента управления, и щелкните левой кнопкой мыши. В результате выполнения указанных выше действий в форму в указанном месте будет добавлен соответствующий элемент управления. При этом новый элемент управления становится автоматически выбранным — вокруг него отображается рамка с точечным узором и белыми квадратиками, называемыми маркерами размеров этого элемента управ- ления (рис. 10.3, б). С помощью маркеров размеров любому элементу управления в форме можно придать требуемые размеры и форму. Для этого выполните следующие действия. 2 Это та самая шестнадцатая кнопка, которая присутствует только в Microsoft Excel. 200 Часть 3. Более сложные аспекты работы на VBA
a) Рис. 10.3. Добавление элемента управления Поле в форму: а — выбор места вставки; б — вставленный элемент управления автоматически выбирается 1. Поместите указатель мыши на маркер — боковой (для изменения размера в одном направлении) или угловой (для изменения размеров сразу по двум направлениям). При этом указатель мыши примет форму двунаправленной стрелки. 2. Нажмите левую кнопку мыши и перемещайте маркер до тех пор, пока элемент управления не достигнет требуемых размеров. Отпустите кнопку мыши. Аналогичным образом можно просто перемещать элемент управления в форме, не из- меняя его размеров. Отличие состоит лишь в том, что для этого указатель мыши помеща- ется не на маркер размера, а на саму рамку выделения. При перетаскивании курсора мыши за ним следует пунктирная рамка, отмечающая текущее положение объекта. Как только вы отпустите кнопку мыши, элемент управления займет свое новое место. В результате всех этих манипуляций любые требуемые элементы управления можно будет поместить в форму на отведенное им место, а затем придать им желаемые размеры. Как и другие программы для Windows, редактор VBA позволяет вырезать, копировать и вставлять элементы управления как по отдельности, так и группами. Отдельные элементы управления можно копировать, вырезать и вставлять в форму в любой последовательно- сти. При этом используются стандартные для среды Windows команды меню и комбина- ции клавиш. Кроме того, можно использовать кнопки Cut (Вырезать), Сору (Копировать) и Paste (Вставить) панели инструментов Standard редактора VBA. Один или несколько элементов управления можно удалить, не помещая их в буфер обмена, если выделить их, а затем нажать клавишу <Delete> или выбрать команду меню Edit"=>Delete. Для упроще- ния и автоматизации работы с отдельными элементами управления или их группами в редакторе VBA предназначены команды меню Format (подробнее в приложении Б), речь о которых пойдет чуть ниже. Выделение элементов управления После того как элементы управления были размещены в форме, их обычно требуется как-то изменить — поменять размер или уточнить положение, изменить значения свойств и т.д. Для работы с тем или иным элементом управления в форме его (или сразу несколько элементов, если требуется) необходимо сначала выделить. Для этого нужно выполнить следующие действия. Чтобы выделить один элемент управления, поместите на него указатель мыши и щелкните левой кнопкой. Глава 10. Экранные формы и их элементы 201
Чтобы выделить сразу несколько элементов управления, выделите первый эле- мент, а затем последовательно щелкайте мышью на других элементах управления, удерживая нажатой клавишу <Ctrl>. Другой вариант: щелкните мышью чуть левее и выше левого верхнего угла первого элемента и, удерживая кнопку мыши, пере- тащите отображаемую при этом пунктирную рамку так, чтобы она охватывала все требуемые элементы управления, после чего отпустите кнопку мыши. Еще один вариант: выберите один из требуемых элементов, нажмите <Shift> и выберите второй элемент, расположенный от него по диагонали условного прямоугольника, охватывающего все элементы, которые должны быть выделены. Как уже говорилось выше, выделенный элемент управления отмечается рамкой выде- ления и маркерами (маленькими квадратиками), которые появляются по углам и центрам сторон этого элемента. При выделении нескольких элементов управления с помощью клавиши <Ctrl> маркеры всех выделенных элементов будут черными, кроме последнего выделенного элемента, у которого маркеры будут белого цвета. При выделении несколь- ких элементов управления с помощью пунктирной рамки или клавиши <Shift> белые маркеры будут у элемента управления, выделенного первым. Чтобы отменить выделение одного элемента управления или группы элементов, щелкните на любом другом элементе управления. Чтобы выделить саму форму, щелк- ните в любом ее месте, где нет никаких элементов управления. При необходимости не- сколько элементов управления можно сгруппировать. Для этого выберите команду меню Format^Group (Формат^Группировать). Сгруппированные элементы управления ведут себя как один объект, когда вы их выбираете, перемещаете, копируете или редактируете, и остаются сгруппированными до тех пор, пока к выделенной группе не будет применена команда меню Format^Ungroup (ФорматаРазгруппировать), т.е. пока группа элементов не будет разгруппирована. Позиционирование и выравнивание элементов управления в форме Как уже говорилось выше, после помещения в форму элементов управления обычно требуется уточнить их размеры и расположение в форме, выровнять их между собой и от- носительно границ формы и т.д. Все эти операции можно выполнять вручную, по очереди выбирая каждый элемент управления и перемещая его в требуемое место формы. Однако этот путь слишком долог и к тому же недостаточно точен. Для автоматизации подобных работ ре- дактор VBA предоставляет различные инструменты, которые мы и рассмотрим в этом разделе. Использование сетки Для выравнивания и точной установки размеров помещаемых в форму элементов управления используется сетка из точек, образующих вертикальные и горизонтальные линии, отображаемые в поле формы. По умолчанию в редакторе VBA границы добавляе- мых элементов управления автоматически выравниваются по этой сетке. Это означает, что при вставке, перемещении или изменении размеров элемента управления его края не могут занимать произвольное положение между точками сетки, что значительно упрощает задачу выравнивания положения элементов управления в форме и уточнения их размеров. Если вас не устраивает размер ячеек сетки, принятый по умолчанию, его можно изменить или же вообще отключить отображение точек сетки, для чего необходимо выполнить сле- дующие действия. 202 Часть 3. Более сложные аспекты работы на VBA
1. Чтобы установить новые параметры сетки, прежде всего выберите команду меню Tools^Options. 2. В раскрывшемся диалоговом окне Options (Параметры) перейдите во вкладку General (Общие), где в группе Form Grid Settings находятся элементы управления, с помощью которых задаются параметры сетки (рис. 10.4). 3. Чтобы изменить шаг сетки (т.е. расстояние между ее точками) по горизонтали или вертикали, введите новые значения в поля Width (ширина) и Height (высота) со- ответственно. 4. Чтобы отключить отображение сетки в форме, сбросьте флажок опции Show Grid (Показывать сетку). 5. Чтобы включить (отключить) автоматическое выравнивание элементов управле- ния по линиям сетки, установите (сбросьте) флажок опции Align Controls to Grid (Выравнивать элементы управления по линиям сетки). Сбросив этот флажок, вы получите полную свободу в позиционировании и изменении размеров элементов управления. При этом сама сетка может по-прежнему оставаться видимой, даже когда функция автоматического выравнивания отключена. Edita | Editor Format General ! Docking | Form Grid Settings 17 Show Grid Grid Units: Points Width: [б Height; [б 7 Align Controls to Gr id (7 Show ToolTips 17 Collapse Proj. Hides Windows Edit and Continue Г" Notify Before State Loss Error Trapping <• Break on All Errors Г Break tn Class Module Break on Unhandted Errors Compile 17 Compile On Demand 17 Background Compile OK | Отмена , Справка Рис. 10.4. Вкладка General диалогового окна Options Применение команд меню Format Меню Format содержит команды, позволяющие автоматически устанавливать размеры и взаимное расположение элементов управления в форме, группировать и разгруппиро- вать их, а также управлять порядком расположения взаимно перекрывающихся элементов управления, т.е. указывать, какие из них находятся в этом случае сверху, а какие — снизу. Следует отметить, что некоторые команды меню Format предназначены для работы сразу с несколькими элементами управления или с группами элементов управления. Для таких команд форматирования один из выбранных элементов управления служит начальной точкой отсчета и называется доминирующим элементом управления — именно этот элемент управления выделяется на экране маркерами белого цвета. Все остальные элементы управ- ления имеют маркеры черного цвета. Глава 10. Экранные формы и их элементы 203
Для того чтобы выделить группу элементов управления, проще всего использовать Vzy рамку выделения или же последовательно щелкать на выделяемых элементах управ- ления при нажатой клавише <Shift> или <Ctrl>. Выделив группу элементов управле- ния, можно перемещать их, менять их размеры, вырезать или применять к ним иные команды форматирования как к единому целому, поскольку группировка позволяет применять эти команды сразу ко всем элементам группы одновременно. Выделение групп элементов управления особенно эффективно, когда требуется установить оди- наковые значения одноименным свойствам нескольких элементов управления. Для автоматического выравнивания элементов управления в форме относительно друг друга и границ формы предназначены специальные команды меню Format, которые позволяют изменять расстояние между выделенными элементами управления, — это ко- манды подменю Vertical Spacing (Расстояние по вертикали) и подменю Horizontal Spacing (Расстояние по горизонтали). Выделив несколько или все элементы управления в форме, можно применить к ним любую из команд этих подменю: Make Equal — сделать одинаковым; Increase — увеличить на один шаг сетки; Decrease — уменьшить на один шаг сетки; Remove — удалить пропуски, т.е. расположить элементы управления вплотную. Выделив один или несколько элементов управления, можно применить к ним и другие команды меню Format, которые позволяют работать как с отдельным элементом управ- ления, так и с их группой. Center in Form (Центрировать в форме). Эта команда позволяет центрировать объекты по вертикали или горизонтали. При выделении нескольких элементов управления команда Center in Form выставляет все элементы управления по сред- ней линии. Для того чтобы сцентрировать набор как одно целое, нужно сначала сгруппировать элементы управления. Arrange Buttons (Выстроить кнопки). Эта команда позволяет разместить одну или несколько выделенных кнопок у нижнего или у правого края формы. Команда Ar- range Buttons работает и тогда, когда выделенными оказываются не только кнопки. Однако перемещаются после выполнения этой команды только кнопки. Size to Fit (Задать размеры в соответствии с содержимым). Эта команда позволяет автоматически привести размер элемента управления в точное соответствие разме- ру содержащегося в нем текста. При использовании этой команды следует помнить, что она оказывает свое действие только относительно текущего содержания тек- стовых свойств объектов. Иначе говоря, она не присваивает свойствам AutoSize элементов управления значение True, а просто высчитывает требуемые размеры и помещает полученные значения в свойства высоты и ширины элементов управ- ления. Поэтому при изменении текста в элементе управления размеры последнего автоматически не изменяются, и для приведения его в соответствие новому тексту потребуется вновь воспользоваться этой командой. Size to Grid (Задать размеры по сетке). Эта команда используется для того, что- бы выставить все стороны элементов управления по ближайшим к ним линиям сетки. 204 Часть 3. Более сложные аспекты работы на VBA
В меню Format имеется также подменю Make Same Size (Сделать одного размера), ко- торое автоматически приводит все выделенные элементы управления к размерам домини- рующего элемента управления. При выборе этой команды VBA копирует размеры (высоту, ширину или оба значения — в зависимости от выбранной команды данного подменю) доминирующего элемента управления в соответствующие свойства остальных выделен- ных элементов управления. То же самое происходит и в случае выбора команд из подменю Align (Выровнять) — все выбранные элементы управления выравниваются определенным командой подменю способом относительно доминирующего элемента управления, ко- торый при этом остается на месте. Кстати, результат выполнения обсуждавшихся выше команд подменю Horizontal Spacing и Vertical Spacing Format тоже зависит от того, какой элемент управления будет доминирующим. Элементы управления в форме могут полностью или частично перекрываться, при этом верхний элемент всегда будет видимым, а расположенные под ним элементы иногда видимы, а иногда — нет, все зависит от уровня прозрачности, установленного для нахо- дящихся выше элементов управления. Для изменения порядка расположения перекры- вающихся объектов предназначены команды подменю Order, позволяющие переместить выделенный элемент управления вверх на один уровень (Bring Forward), вниз на один уровень (Send Backward), на самый верх (Bring to Front), на самый низ (Send to Back). В редакторе VBA нет команды, позволяющей равномерно распределить элементы управления в форме по горизонтали или вертикали. Однако приблизительно того же ~ эффекта можно достаточно просто достичь с помощью такой последовательности действий (все приведенные ниже команды находятся в меню Format). 1. С помощью мыши разместите элементы управления в форме примерно так, как это требуется. 2. Выделите эти элементы управления и выберите команду Align^Tops (Выровнять^ По верху) или любую другую команду выравнивания по горизонтали. 3. Оставив все элементы управления выделенными, выберите команду Horizontal Spacing^Make Equal (Расстояние по горизонтали1^ Сделать одинаковым). 4. Сгруппируйте выделенные элементы управления (т.е. выберите команду Group). 5. Выберите команду Center in Form1^Horizontally (Центрировать в форме^По гори- зонтали). В приведенной выше последовательности действий предполагалось равномерно рас- пределить элементы управления по горизонтали. Чтобы распределить их равномерно по вертикали, выберите в пп. 2,3 и 5 версии команд, соответствующие выравниванию по вертикали. Панель UserForm Выравнивание элементов управления можно также выполнять с помощью команд панели инструментов UserForm. Для отображения этой панели инструментов выберите команду меню View^> Tool bars^UserForm. Общий вид панели инструментов UserForm представлен на рис. 10.5. Рис. 10.5. Панель инструментов UserForm Глава 10. Экранные формы и их элементы 205
Кнопки панели инструментов UserForm соответствуют командам меню Format. Некоторые из этих кнопок комбинированные — справа от них видны небольшие направ- ленные вниз стрелки, раскрывающиеся в списки команд. Если щелкнуть на главной части такой кнопки, VBA выполнит ту команду, которая была выбрана в списке данной кнопки последней. Чтобы выбрать другую команду, нужно щелкнуть на маленькой стрелке справа и выбрать требуемую команду из раскрывшегося списка. При работе некоторые кнопки на панели инструментов UserForm оказываются вре- менно недоступными — в зависимости от того, сколько элементов управления (один или несколько) выделено в форме. Функции кнопок панели инструментов UserForm приве- дены в табл. 10.4. Таблица 10.4. Кнопки панели инструментов UserForm Кнопка Наименование Назначение Bring То Front (Поместить на передний план) Если элементы управления перекрываются, выделен- ный элемент помещается на передний план, над дру- гими элементами управления Send То Back (Поме- стить на задний план) Если элементы управления перекрываются, выделен- ный элемент помещается на задний план, за другими элементами управления Н Group (Сгруппировать) Объединяет несколько выделенных элементов управ- ления в один элемент Е1 Ungroup (Разгруппировать) Разделяет группу на отдельные элементы управления 1° * Align Lefts (Выровнять) Выравнивание элементов управления относительно друг друга или по сетке. Конкретный вариант выбира- ется из раскрывающегося списка Center Horizontally(no центру) Центрирование элементов управления: вертикальное или горизонтальное. Конкретный вариант выбирается из раскрывающегося списка Make Width Same Size (Выровнять размер) Приведение элементов управления к одинаковому раз- меру: по ширине, по высоте или и то, и другое вместе. Конкретный вариант выбирается из раскрывающегося списка 100% Zoom (Масштаб) Масштаб отображения формы (и всех ее элементов управления) Изменение свойств элементов управления Свойства элементов управления можно изменять как в процессе разработки экранной формы — вручную, внося изменения в окно свойств элемента управления, так и во время выполнения экранной формы, когда она уже выведена на экран для работы с пользова- телем, — программно. В последнем случае для изменения свойств элементов управления надо использовать соответствующие операторы VBA. В редакторе VBA окно Properties (Свойства) всегда содержит значения свойств вы- бранного объекта, независимо от того, выбран отдельный элемент управления в форме или сама экранная форма. На вкладках окна свойств названия свойств отображаются в левом столбце, а их текущие значения — в правом столбце. Для того чтобы изменить значение 206 Часть 3. Более сложные аспекты работы на VBA
конкретного свойства, щелкните на нем левой кнопкой мыши, после чего введите новое значение в правом столбце. Для некоторых свойств допустимые значения могут быть вы- браны из раскрывающихся списков или палитр. При обращении к другим свойствам на экран выводится диалоговое окно, в котором можно будет указать требуемое значение. В остальных случаях требуемое значение свойства можно будет ввести с клавиатуры. Если же выбрано несколько элементов управления, в окне Properties отображаются только свойства, общие для всех этих элементов управления. В этом случае при изменении свой- ства новое значение устанавливается для всех выделенных элементов управления. Если некоторый элемент управления выбран, то именно его свойства отображаются в окне свойств. Если не выбрано ни одного элемента управления, в окне свойств ото- бражаются свойства самой формы. Если в форме выбрано несколько элементов управ- ления, в окне свойств отображаются только свойства, общие для выбранных элемен- тов управления. Напомним также, что окно свойств имеет две вкладки — Alphabetic (По алфавиту), в которой свойства элемента упорядочены в алфавитном порядке, и Categorized (По категориям), в которой свойства сгруппированы по категориям. Обе вкладки содержат одни и те же свойства, только по-разному упорядоченные. Все сказанное выше относится только к изменению свойств элементов управления непосредственно в редакторе VBA, т.е. в процессе разработки экранной формы. Во время выполнения экранной формы, когда она выведена на экран для работы с пользователем, изменение свойств ее элементов управления также возможно и даже необходимо — имен- но в этом состоит ее реакция на действия пользователя. Однако в данном случае любые изменения свойств элементов управления могут осуществляться только программно, с по- мощью выполнения соответствующих операторов языка VBA. Эти операторы могут раз- мещаться как в обычных процедурах программы, так и в методах элементов управления, в том числе и того элемента, значение свойства которого изменяется данным оператором. В каждом случае размещение этих операторов зависит от особенностей проекта, в состав которого входит ваша программа. Свойства элементов управления Обращение к элементам управления происходит через их свойства и с помощью про- цедур обработки событий, написанных для того или иного отдельного элемента. Каждый элемент управления имеет свой набор свойств, которые определяют его вид и поведение. Ниже подробно описаны свойства каждого из типов элементов управления, перечислен- ных в табл. 10.3. Надпись Элемент управления Надпись (Label) представляет собой выделенную в форме пря- моугольную область, куда можно поместить некоторое текстовое сообщение или просто надпись, которые при необходимости могут отображаться поверх фонового рисунка (рис. 10.6). Текст в этом объекте не может изменяться пользователем. В надписях чаще все- го описывается назначение элементов управления или их групп, отображаются заголовки или выводится другая поясняющая информация. Текст, отображаемый объектом типа Надпись, вводится при создании формы в его свойство Caption в окне свойств (Proper- ties). Однако при необходимости текст в данном элементе управления можно изменять и Глава 10. Экранные формы и их элементы 207
динамически — при выполнении программы; для этого следует (программно) изменить значение его свойства с помощью того или иного метода. В табл. 10.5 представлены чаще всего используемые свойства элементов управления Надпись. Рис. 10.6. Элемент управления Надпись 9 При создании формы текст, который будет отображаться в элементе управления Надпись, можно ввести прямо в этом элементе управления. Для этого выделите его левой кнопкой мыши и нажмите клавиши <Shift+Enter> — в рамке выделения поя- вится текстовый курсор ввода. Введите требуемый текст. Для перехода на новую стро- ку еще раз нажмите <Shift+Enter>. Для перемещения по уже введенному тексту можно использовать клавиши управления курсором. Для завершения ввода выберите другой элемент управления. Таблица 10.5. Основные свойства элемента управления Надпись Свойства Описание AutoSize Задает режим определения размеров отображаемой области элемента управления. Значение True устанавливает режим автоматического вычисления размеров ото- бражаемой области исходя из размеров текста в свойстве Caption. Значение False устанавливает режим фиксированного размера отображаемой области, задаваемого значениями параметров Height (Высота) и width (Ширина) Caption Multiline Содержит текст, отображаемый в элементе управления Определяет допустимое количество строк. Значение True разрешает многострочный режим отображения текста в поле. Значение False допускает только однострочный режим Visible Определяет видимость элемента управления. Допустимые значения: True — элемент управления отображается на экране, False — элемент управления не отображается Wordwrap Определяет возможность переноса текста на следующую строку. Значение True раз- решает режим автоматического переноса на следующую строку при необходимости. Значение False запрещает сворачивание текста в несколько строк Поле ввода Элемент управления Поле (TextBox) предназначен для организации ввода текста, который затем будет использоваться в программе для тех или иных целей либо для вывода результатов выполненных в программе расчетов (рис. 10.7). Очень часто текст, введенный в элемент управления Поле, преобразуется затем в программе в числовые данные или в данные типа дата/время с использованием встроенных функций языка VBA. В табл. 10.6 представлены чаще всего используемые свойства элементов управления Поле. 208 Часть 3. Более сложные аспекты работы на VBA
Рис. 10.7. Элемент управления Поле Таблица 10.6. Основные свойства элемента управления Поле Свойства Описание AutoSize Задает режим определения размеров поля ввода элемента управления. Значение True устанавливает режим автоматического вычисления размеров поля ввода ис- ходя из размеров текста в свойстве Text. Значение False устанавливает режим фиксированного размера отображаемой области, задаваемого значениями пара- метров Height (Высота) и Width (Ширина) Enabled Определяет доступность (активность) данного элемента управления. Допустимые значения: True — элемент управления доступен пользователю (активен), False — элемент управления недоступен. В этом случае он все равно будет видимым, но закрашен серым цветом и недоступен пользователю MaxLength Задает максимально допустимое количество вводимых в поле символов. Если зна- чение равно 0, то ограничений нет Multiline Определяет допустимое количество строк в поле ввода. Значение True разреша- ет многострочный режим ввода текста в поле. Значение False допускает только однострочный режим PasswordChar Определяет символ, который будет отображаться в поле вместо введенных симво- лов при вводе пароля ScrollBars Определяет режим отображения в поле ввода полос прокрутки. Возможные зна- чения: 0 — fmScrollBarsNone (не выводить полос прокрутки); 1 — fmScroll- BarsHorizontal (выводить горизонтальную полосу прокрутки); 2 — fmScroll- BarsVertical (выводить вертикальную полосу прокрутки); 3 — fmScroll- BarsBoth (выводить горизонтальную и вертикальную полосы прокрутки) Text Содержит текст, введенный пользователем или отображаемый в данном элементе управления Value Visible Введенный в поле текст Определяет видимость элемента управления. Допустимые значения: True — эле- мент управления отображается на экране, False — не отображается Wordwrap Определяет возможность переноса текста на следующую строку. Значение True разрешает режим автоматического переноса на следующую строку при необходи- мости. Значение False запрещает сворачивание текста в несколько строк Поле со списком Элемент управления Поле со списком (ComboBox) используется для хранения списка значений, из которых в этом поле обычно отображается только один элемент, а все осталь- ные можно просмотреть, раскрыв список щелчком на кнопке раскрытия списка с изобра- жением треугольника (рис. 10.8). Элемент управления Поле со списком сочетает в себе Глава 10. Экранные формы и их элементы 209
функциональные возможности элементов управления Список и Поле. В данном элементе управления можно не только выбрать нужный элемент из списка уже имеющихся, но и до- бавить в список новое значение, воспользовавшись в этом элементе управления полем вво- да. Важнейшие свойства элемента управления Поле со списком представлены в табл. 10.7. Рис. 10.8. Элемент управления Поле со списком Таблица 10.7. Основные свойства элемента управления Поле со списком Свойства Описание ColumnCount ColumnHeads Определяет количество столбцов в списке Определяет режим вывода заголовков столбцов раскрывающегося списка: значение True — заголовки столбцов выводятся, False — заголовки не вы- водятся Columnwidths Controlsource DropButtonStyle Устанавливает ширину столбцов списка Задает ячейку, куда возвращается выбранный из списка элемент Определяет вид изображения на кнопке раскрытия списка: 0 — fmDropBut- tonStylePlain (кнопка без символов); 1 — fmDropButtonStyleArrowDis- plays (кнопка со стрелкой); 2 — fmDropButtonStyleEllipsis (кнопка с многоточием); 3 — fmDropButtonStyleReduce (кнопка с чертой) Enabled Определяет доступность (активность) данного элемента управления. Допусти- мые значения: True — элемент управления доступен пользователю (активен), False — элемент управления недоступен. В этом случае он все равно будет видимым, но закрашен серым цветом и недоступен пользователю ListRows ListStyle Определяет количество элементов в раскрывающемся списке Определяет способ выделения выбранного элемента в списке: значение 0 — fmListStylePlain (выбранный элемент из списка выделяется цветом) или 1 — fmListStyleOption (выбор элементов из списка осуществляется уста- новкой флажка перед элементом) MatchEntry Определяет режим поиска требуемого элемента в списке при наборе его имени на клавиатуре: 0 — fmMatchEntryFirstLetter (выводит нужный элемент из списка по набранной первой букве); 1 — fmMatchEntryComplete (вы- водит нужный элемент из списка по полному набранному имени); 2 — fm- MatchEntryNone (режим вывода нужного элемента из списка отключен) MatchFound Имеет значение True, если среди значений раскрывающегося списка есть элемент, совпадающий с вводимым в поле ввода, в противном случае — зна- чение False MatchRequired Определяет режим ввода новых значений. Если значение свойства — True, в поле ввода раскрывающегося списка нельзя ввести значения, отличные от имеющих- ся в списке; если значение — False, ввод новых элементов списка возможен 210 Часть 3. Более сложные аспекты работы на VBA
Окончание табл. 10.7 Свойства Описание RowSource Text Textcolumn Определяет диапазон, содержащий элементы списка Содержит значение выбранного в списке элемента Устанавливает столбец в списке, элемент которого возвращается свойством Text Toplndex Value Содержит элемент списка с наибольшим номером Введенное в текстовое поле списка значение Основное назначение данного элемента управления — не только предоставить поль- зователю возможность выбрать при работе с формой одно из заранее определенных значений, но и при необходимости самостоятельно ввести в поле новое значение, отсут- ствующее в списке. Например, если в форме присутствует элемент (скажем, изображе- ние), который можно рассматривать при разном увеличении, то при программировании формы можно поместить в нее элемент ComboBox с названием Масштаб и подготовить перечень стандартных значений масштаба: 50%, 75%, 100% 125% и т.д. Тогда при работе с формой пользователь может изменить масштаб элемента либо выбором в списке одного из предложенных стандартных значений, либо непосредственным вводом в поле желае- мого значения — например, 80%. Естественно, в модуле формы потребуется запрограм- мировать все манипуляции, связанные с обработкой установленного значения масштаба и собственно масштабирования элемента. Список Элемент управления Список (Li stBox) используется для хранения набора данных, из которого пользователь при выполнении программы сможет выбрать и затем использовать одно или больше значений (рис. 10.9). С помощью элемента управления Список нельзя ввести значение, которое не содержится в нем. В табл. 10.8 представлены чаще всего ис- пользуемые свойства этого элемента управления. Рис. 10.9. Элемент управления Список Таблица 10.8. Основные свойства элемента управления Список Свойства Описание ColumnCount Задает количество столбцов в списке ColumnHeads Определяет режим отображения заголовков столбцов раскрывающегося списка: значение True — заголовки выводятся, False — не выводятся Глава 10. Экранные формы и их элементы 211
Окончание табл. 10.8 Свойства Описание Columnwidths Controlsource Enabled Задает ширину столбцов списка Определяет ячейку, в которую помещается выбранный из списка элемент Определяет доступность (активность) данного элемента управления. Допусти- мые значения: True — элемент управления доступен пользователю (активен), False — элемент управления недоступен. В этом случае он все равно будет ви- димым, но закрашен серым цветом и недоступен пользователю List ListCount Listindex Содержит элемент списка, стоящий на пересечении строки и столбца Содержит количество элементов в списке Содержит номер текущего отображаемого элемента в списке (нумерация начи- нается с нуля) Liststyle Определяет способ выделения выбранного элемента списка: 0 — fmListStyle- Plain (выбранный элемент списка выделяется цветом); 1 — fmListStyleOption (выбор элементов в списке осуществляется установкой флажка перед элементом) MatchEntry Определяет режим вывода нужного элемента списка при наборе его имени на клавиатуре: 0 — fmMatchEntryFirstLetter (выводит нужный элемент из списка по набранной первой букве); 1 — fmMatchEntryComplete (выводит нужный элемент из списка по полному набранному имени); 2 — fmMatchEn- tryNone (режим вывода нужного элемента из списка отключен) MultiSelect Устанавливает способ выбора элементов в списке: 0 — fmMulti Select Single (выбор только одного элемента); 1 — fmMultiSelectMulti (выбор нескольких элементов либо щелчком, либо нажатием клавиши <Пробел>); 2 — fmMulti- SelectExtended (можно использовать клавишу < Shift > при выборе ряда по- следовательных элементов списка) RowSource Selected Определяет диапазон, содержащий элементы списка Если значение True, элемент списка выбран, в противном случае значение этого свойства False Text Textcolumn TopIndex Value Содержит значение выбранного элемента списка Определяет столбец в списке, элемент которого возвращается свойством Text Определяет элемент списка с наибольшим номером Выбранное в списке значение Основное назначение данного элемента управления — предоставить пользователю воз- можность выбрать при работе с формой одно из заранее заданных значений. Например, при заполнении формы, представляющей собой заявление на отпуск, можно поместить в эту форму список, содержащий название месяцев. Тогда при заполнении формы поль- зователь просто выберет желаемый месяц в списке — это упростит его работу, а также ис- ключит возможность появления грамматических ошибок и описок в названиях месяцев. Флажок, Переключатель и Выключатель Элементы управления Флажок (Checkbox), Переключатель (OptionButton) и Выключатель (ToggleButton) используются для предоставления пользователю воз- можности выбора из нескольких возможных вариантов. Элемент управления Флажок используется для включения или отключения некоторого режима (опции). Визуально он представляет собой маленький квадратик, в котором по- 212 Часть 3. Более сложные аспекты работы на VBA
является “галочка”, когда соответствующий режим включен (рис. 10.10). Поведение этого элемента управления це зависит от каких-либо других элементов, в том числе и флажков, даже если в форме их несколько. Обычно флажок предоставляет пользователю возмож- ность выбора из двух состояний: установленного (есть “галочка”) и сброшенного (нет “галочки”), но иногда может настраиваться и на выбор из трех вариантов. Этот режим кон- тролируется свойством TripleState, которое, может принимать два значения — False (выбор из двух вариантов True и False) и True (выбор из трех вариантов True, False и Null). В последнем случае к двум уже упоминавшимся состояниям добавляется третье, когда данный элемент управления будет иметь значение Nul 1 и визуально будет закрашен серым цветом. (М Флажки часто объединяются в группы, представляющие не зависящие друг от друга ва- рианты выбора. В каждой такой группе пользователь может установить столько флаж- ков, сколько ему будет нужно, — все, несколько или ни одного. Элемент управления Переключатель позволяет выбрать один из нескольких взаи- моисключающих вариантов. Переключатель — это группа небольших круглых кнопок, из которых во включенном состоянии может быть только одна (рис. 10.11). Все остальные принудительно остаются выключенными. При выборе пользователем другой кнопки пере- ключателя все остальные автоматически выключаются. Хотя в языке VBA каждая кнопка переключателя представляет собой отдельный объект, редактор автоматически организует совместную работу по указанному выше алгоритму всех кнопок-переключателей, при- сутствующих в форме. Если кнопки должны быть сгруппированы в несколько отдельных переключателей, то для этой цели должны использоваться контейнеры-рамки. Элемент управления Выключатель предоставляет те же самые функциональные воз- можности, что и флажок, но имеет иной визуальный облик — в виде кнопки, которая мо- жет быть во включенном (нажатом) или выключенном (отжатом) состоянии (рис. 10.12). Внешне он может выглядеть точно так же, как и командная кнопка, которая будет обсуж- даться ниже. Однако при щелчке мышью на выключателе он изменяет свое состояние и фиксируется в новом положении, тогда как командная кнопка активируется лишь на короткое время и тут же возвращается в исходное положение. Рис. 10.10. Элемент управле- ния Флажок Рис. 10.11. Группа из двух элементов управления Переключатель Рис. 10.12. Элемент управления Выключатель во включенном (ToggleButtonl) и выключе- нном (ToggleButton2) со- стоянии Все обсуждавшиеся в этом разделе элементы управления имеют несколько общих ча- сто используемых свойств, которые описаны в табл. 10.9. Глава 10. Экранные формы и их элементы 213
Таблица 10.9. Общие свойства элементов управления Флажок, Переключатель, Выключатель Свойство Описание Caption Enabled Надпись, отображаемая рядом с данным элементом управления Определяет активность элемента управления. Если значение равно True, данный элемент управления активен и пользователь может управлять его состоянием, если значение равно False, элемент неактивен и недоступен пользователю Value Если значение равно True, элемент управления установлен (включен), если значе- ние равно False, элемент управления сброшен (выключен). Если значение свойства TripleState равно True, возможно третье состояние — Null Visible Определяет видимость элемента управления в форме. Если значение равно True, данный элемент управления отображается; если значение равно False, элемент не отображается Рамка Элемент управления Рамка (Frame) применяется в том случае, если необходимо сгруппировать несколько элементов управления. Рамка — это очень важный элемент форм VBA, визуально представляющий собой простой прямоугольник с заголовком в верхней части, в котором обычно размещаются другие элементы управления (рис. 10.13). Рамки служат для выделения группы связанных элементов управления, а также позволяют разделить большие формы на несколько участков. Кроме того, рамки также используются как контейнеры для создания группы кнопок (переключателей), из которых пользователь должен выбирать только одну. Чтобы добавить новый элемент управления в рамку, необходимо щелкнуть на соот- ветствующем значке в панели инструментов, а затем перетащить его на то место в рамке, где он будет находиться. Можно также перетащить в рамку мышью любой из объектов, уже присутствующих в форме. После того как элементы управления будут размещены в рамке, границы рамки будут выделены в форме так, как будто данный элемент управления выбран (рис. 10.14). Удалить из рамки ненужный элемент управления можно, либо переместив его в другое место в форме (проделав те же манипуляции, что и при перемещении из формы), либо щелкнув на нем левой кнопкой мыши и нажав клавишу <Delete> (другой способ: выбрать команду Edit1^ Delete). Важнейшим свойством элемента управления Рамка является свойство Capture, со- держащее отображаемую в рамке надпись. Кнопка Визуально элемент управления Кнопка (CommandButton) представляет собой пря- моугольную кнопку, на которой находится поясняющий текст, например ОК, Отменить. Кнопка используется для инициирования пользователем некоторых действий — для этого ему достаточно щелкнуть на данной кнопке мышью (рис. 10.15). Действие может пред- ставлять собой запуск определенной программы, подтверждение конца ввода тех или иных данных, выбор конкретного варианта из нескольких предложенных способов про- должения работы и т.д. 214 Часть 3. Более сложные аспекты работы на VBA
Рис, 10,13, Элемент управле- ния Рамка Рис, 10,14, Размещение в рам- ке элементов управления Рис, 10,15, Элемент управле- ния Кнопка Сама по себе кнопка ничего не способна выполнять, пока ее требуемая реакция не бу- дет соответствующим образом описана в программе. Щелчок на кнопке вызывает в систе- ме событие, сведения о возникновении которого передаются данному объекту с помощью вызова его соответствующего метода. Однако, чтобы в результате программой были вы- полнены требуемые действия, необходимо описать их в программном коде метода — обра- ботчика события Click данного объекта. Этот программный код может включать любые допустимые операторы, манипулирующие свойствами данного объекта или любых других объектов в программе. В табл. 10.10 представлены чаще всего используемые в программах свойства объекта CommandButton, представляющего элемент управления Кнопка. Таблица 10.10. Основные свойства объекта CommandButton — элемента управления Кнопка Свойство Описание Accelerator Задает на клавиатуре клавишу, при нажатии которой одновременно с клавишей <Alt> инициируются те же действия, что и при щелчке на данной кнопке Cancel Значение True в этом свойстве определяет данную кнопку как выбираемую при отказе пользователя от выполненных им действий, т.е. связанные с этой кнопкой действия будут выполняться также при нажатии пользователем клавиши <Esc> Caption Default Содержит текст, отображаемый на элементе управления Значение True в этом свойстве определяет данную кнопку как выбираемую по умолчанию, т.е. связанные с этой кнопкой действия будут выполняться также при нажатии пользователем клавиши <Enter> Enabled Определяет доступность (активность) данного элемента управления. Допустимые значения: True — элемент управления доступен пользователю (активен) и щелчок на нем мышью будет обработан системой; False — элемент управления недоступен. В этом случае он все равно будет видим, но закрашен серым цветом и щелчок на нем будет проигнорирован Picture Определяет файл рисунка, который будет помещен на изображение кнопки вместо надписи Visible Определяет видимость элемента управления. Допустимые значения: True — эле- мент управления отображается на экране, False — элемент не отображается Набор страниц Элемент управления Набор страниц (MultiPage) позволяет организовать форму как многостраничное диалоговое окно, каждая из страниц которого представляется в форме отдельной страницей-вкладкой. При этом заголовки страниц будут присутствовать на Глава 10. Экранные формы и их элементы 215
корешках вкладок, отображаемых в главной форме. Для перехода со страницы на страни- цу достаточно щелкнуть левой кнопкой мыши на корешке вкладки с требуемой страницей (рис. 10.16). Рис, 10,16, Элемент управления Набор страниц Чтобы изменить количество вкладок элемента управления Набор страниц, выберите его в форме и щелкните правой кнопкой мыши на корешке требуемой вкладки. Раскроет- ся контекстное меню, содержащее четыре команды: New Page (Создать страницу), Delete Page (Удалить страницу), Rename (Переименовать) и Move (Переместить). При выборе команды New Page в элемент управления будет добавлена новая страница. Все остальные команды предназначены для выполнения соответствующих операций с той страницей, на корешке которой щелкнули. Следует также отметить, что объект MuitiPage — это контейнер, который содержит коллекцию Pages, представляющую собой набор объектов отдельных страниц, входящих в этот элемент управления. В табл. 10.11 представлены чаще всего используемые свойства элемента управления Набор страниц. Таблица 10.11. Основные свойства элемента управления Набор страниц Свойства_______Описание_______________________________________________________ MultiRow Если значение свойства равно True и все корешки страниц не помещаются в одну строку, они выводятся в несколько строк. Если значение равно False, то когда корешки страниц не помещаются в одну строку, для перехода к невидимым корешкам страниц выводятся специальные кнопки Selectedltem Свойство объектного типа; содержит ссылку на объект выбранной страницы Value Содержит номер активной страницы (нумерация страниц начинается с нуля) Набор вкладок Элемент управления Набор вкладок (Tabstrip) позволяет создать в диалоговом окне формы несколько вкладок. Следует отметить, что объект Tabstrip — это контейнер, ко- торый содержит в себе коллекцию, являющуюся набором объектов всех отдельных вкла- док, входящих в этот объект (рис. 10.17). Элемент управления Набор вкладок обладает теми же свойствами, что и элемент управления Набор страниц. Основное раз- личие между этими элементами управления состоит в том, что каждая страница в объекте MuitiPage имеет собственную отображаемую поверхность, независимую от остальных страниц этого объекта. Поэтому каждая страница может содержать собственный набор элементов управления и отображаемых в них данных. В объекте Tabstrip отображаемая на всех вкладках поверхность является общей и принадлежит непосредственно форме. Поэтому набор элементов управления на всех вкладках будет одинаков, однако отобра- 216 Часть 3. Более сложные аспекты работы на VBA
жаемые в них данные могут быть различными, так как с каждой вкладкой может быть связан собственный источник данных. Полоса прокрутки Элемент управления Полоса прокрутки (ScrollBar) отображается в форме в виде полоски с ползунком и двумя кнопками со стрелками, позволяя “прокручивать” отобра- жаемую часть содержимого связанного с ним объекта формы (рис. 10.18). Чтобы вывести на экран требуемый фрагмент содержимого, связанного с полосой прокрутки элемента управления, следует перетащить ползунок или последовательно щелкать на кнопках со стрелками, что позволит передвигаться в ту или иную сторону в пределах всего содер- жимого объекта. В табл. 10.12 представлены чаще всего используемые свойства элемента управления Полоса прокрутки. Рис, 10,17, Элемент управления Набор вкладок Рис, 10,18, Элемент управления Полоса прокрутки Таблица 10.12. Основные свойства элемента управления Полоса прокрутки Свойства Описание Enabled Определяет доступность (активность) данного элемента управления. Допустимые значения: True — элемент управления доступен пользователю (активен), False — элемент управления недоступен. В этом случае он все равно будет видим, но за- крашен серым цветом и недоступен пользователю Мах Максимальное значение для положения полосы прокрутки, только целые неот- рицательные числа Min Минимальное значение для положения полосы прокрутки, только целые неот- рицательные числа SmallChange Visible Шаг изменения значения при щелчке на одной из стрелок полосы прокрутки Определяет видимость элемента управления. Допустимые значения: True — элемент управления отображается на экране, False — элемент управления не отображается Счетчик Элемент управления Счетчик (SpinButton) отображается в форме в виде двух кнопок со стрелками (рис. 10.19). С помощью этих кнопок нельзя плавно “прокручивать” содер- жимое элемента управления, связанного с данным объектом, но они позволяют устано- вить требуемое значение, которое может изменяться в заданных границах с установлен- ным шагом. По остальным своим функциональным возможностям элемент управления Счетчик аналогичен элементу управления Полоса прокрутки и обладает таким же набором свойств. Глава 10. Экранные формы и их элементы 217
Рис. 10.19. Элемент управления Счетчик, помещенный в форме рядом с полем ввода Рисунок Элемент управления Рисунок (image) используется для размещения изображения в формах (рис. 10.20, а), а также на кнопках (рис. 10.20, б), флажках, переключателях и других элементах управления. Элемент управления Рисунок — это, по сути, просто над- пись без заголовка, поэтому для размещения изображений можно также воспользоваться элементом управления Надпись (Label). При размещении рисунка на элементе управ- ления (если текст на последнем не нужен) следует очистить значение свойства Caption этого элемента управления. В табл. 10.13 представлены часто используемые основные свойства элемента управления Рисунок. а) Рис. 10.20. Элемент управления Рисунок: а —в форме, б—на кнопке Таблица 10.13. Основные свойства элемента управления Рисунок Свойства Описание AutoSize Если значение свойства равно True, видимые размеры элемента управления автоматически устанавливаются в соответствии с размером выбранного изо- бражения Picture Значение свойства определяет графический файл, отображаемый в данном элементе управления PicturesizeMode Устанавливает способ отображения рисунка в границах, определяемых значе- ниями свойств Height (высота) и Width (ширина). Значение fmPicture- SizeModeClip указывает, что при необходимости рисунок следует обрезать по заданным размерам или же отобразить его целиком, оставив остальную часть поля незаполненной. Значение fmPictureSizeModeStretch указывает, что рисунок всегда занимает всю поверхность объекта, при не- обходимости со сжатием или растяжением без соблюдения его исходных пропорций. Значение fmPictureSizeModeZoom указывает, что рисунок 218 Часть 3. Более сложные аспекты работы на VBA
Окончание табл. 10.13 Свойства Описание пропорционально масштабируется так, чтобы он занимал максимально воз- можную часть поверхности объекта PictureAl ignment Устанавливает расположение рисунка в пределах поля объекта. Допустимые значения: PictureAlignmentTopLef t — в верхнем левом углу; Picture- Al ignmentTopRight — в верхнем правом углу; PictureAlignmentCen- ter — в центре; PictureAlignmentBottomLeft — в нижнем левом углу; PictureAlignmentBottomRight — в нижнем правом углу PictureTiling Если значение свойства равно True, поверхность объекта при необходимо- сти покрывается мозаикой из нескольких копий рисунка Для размещения рисунка на кнопке, флажке, переключателе или каком-либо другом элементе управления без использования дополнительного элемента управления Рисунок выполните следующие действия. 1. Щелкните в форме или на элементе управления в том месте, где требуется разме- стить рисунок. 2. В окне свойств выделенного объекта выберите строку свойства Picture. 3. Щелкните в поле значения свойства Picture на кнопке с многоточием, которая появилась в нем после выбора строки данного свойства. 4. В открывшемся диалоговом окне Load Picture (Загрузка рисунка) найдите файл с нужным изображением и щелкните на кнопке Открыть, чтобы добавить изображение в объект. При этом выбранный рисунок появится в элементе управления или форме (рис. 10.21). Теперь, используя свойства PictureAlignment, PictureSizeMo.de и PictureTiling (если они имеются у объекта, с которым вы в данный момент работаете), можно разместить рисунок так, чтобы он занял в объекте нужное место. Рис. 10.21. Помещение рисунка в элемент управления Форма Если необходимо удалить рисунок из элемента управления или формы, щелкните в V/ окне свойств на строке свойства Picture, выделите его, а затем нажмите клавишу <Delete> — это единственный способ, который позволяет удалить рисунок из элемен- та управления или формы. Глава 10. Экранные формы и их элементы 219
Элемент управления RefEdit В приложении Excel панель элементов в окне редактора VBA, кроме перечисленных выше кнопок, содержит элемент управления RefEdit (Поле определения ссылки), кото- рый используется для упрощенного ввода ссылок на ячейки или диапазоны ячеек Excel. Этот элемент управления отображается в форме как поле ввода с небольшой кнопкой справа (рис. 10.22). Хотя визуально он несколько отличается от кнопки сворачивания в стандартных диалоговых окнах Excel, тем не менее работает точно так же. Если щелкнуть на маленькой кнопке с правой стороны поля ввода, то диалоговое окно, в котором на- ходится данный элемент управления, свернется до заголовка окна и самого поля ввода. Это позволит выбрать требуемый диапазон ячеек на рабочем листе, просто выделив его с помощью мыши. Рис, 10,22, Элемент управления RefEdit Некоторые общие свойства элементов управления Кроме перечисленных выше специфических свойств отдельных элементов управле- ния, которые, как правило, характерны только для данного типа, существует достаточно много свойств, общих для всех или почти всех типов элементов управления. В этом под- разделе мы обсудим некоторые из них. Многие элементы управления имеют свойство, в котором хранятся его данные, — обычно это свойство Value. Тип сохраняемых в этом свойстве данных, безусловно, за- висит от типа элемента управления. В табл. 10.14 приведены сведения о типе данных и диапазоне допустимых значений, который имеет свойство Value у некоторых элементов управления. Таблица 10.14. Значение свойства Value различных элементов управления Элемент управления Допустимые значения____________________________ CheckBox Целое число. Допустимые значения: -1 (True), если флажок опции установлен; 0 (False), если флажок опции не установлен; Null, если значение не определено ComboBox Текущее выбранное в списке значение CommandButton Всегда имеет значение False ListBox Текущее выбранное в списке значение MultiPage Целое число, определяющее активную в данный момент страницу. Значе- ние 0 указывает на первую страницу, т.е. отсчет страниц ведется от нуля OptionButton Целое число. Допустимые значения: -1 (True), если данный элемент группы переключателей выбран; 0 (False), если элемент не выбран; Null, если значение не определено 220 Часть 3. Более сложные аспекты работы на VBA
Окончание табл. 10.14 Элемент управления Допустимые значения ScrollBar Целое число (Integer) в пределах, установленных значениями свойств Min и Мах. Определяет положение ползунка на полосе прокрутки SpinButton Целое число (Integer) в пределах, установленных значениями свойств Min и Мах. Определяет значение, отображаемое в поле ввода, которое связано с данным элементом управления TextBox Тип данных — String. Значение представляет собой введенный в поле текст ToggleButton Целое число. Допустимые значения: -1 (True), если выключатель вы- бран; 0 (False), если выключатель не установлен; Null, если значение не определено В табл. 10.15 перечислены еще не упоминавшиеся нами, но достаточно часто исполь- зуемые свойства, общие для большинства элементов управления, которые могут быть по- лезны при создании VBA-программ. Следует отметить, что многие элементы управления имеют еще немало других, реже используемых свойств, сведения о которых при необхо- димости можно найти в справочной системе редактора VBA. Таблица 10.15. Некоторые часто используемые свойства элементов управления Свойство Описание BackColor Определяет цвет фона в элементе управления Caption Содержит текст, который отображается в (или на) элементе управления ControlTipText Содержит текст, который отображается в виде всплывающей подсказки, когда курсор мыши задерживается над данным элементом управления Font Ссылка на объект Font, который управляет отображением текста в элементе управления ForeColor Определяет цвет изображения в элементе управления Locked Значение True указывает, что элемент управления заблокирован для редакти- рования или изменения Mouseicon Определяет пиктограмму указателя мыши, которая будет использоваться, если значение свойства MousePointer равно 99 (пользовательский тип) MousePointer Значение определяет вид указателя мыши, когда он находится над элементом управления, и выбирается из списка допустимых значений Tag Используется для хранения дополнительной информации о форме или элемен- те управления. Эта информаций не используется редактором VBA, она предна- значена для замечаний программистов С помощью свойства ForeColor задается цвет переднего плана, а свойство BackColor уТл определяет цвет фона для форм и элементов управления. Для элементов управления значение свойства ForeColor задает цвет текста, размещаемого на элементе управ- ления, — это свойство недоступно для тех элементов управления, на которых текст разместить нельзя. Во время работы с формами значение свойства ForeColor задает цвет, который будет использоваться по умолчанию для всех вновь размещаемых в фор- ме элементов управления, а также для сетки на форме (сетка видна только в режиме проектирования формы). Глава 10. Экранные формы и их элементы 221
Цвета, устанавливаемые свойствами ForeColor и BackColor, задаются шестнад- цатеричными числами. Если эти свойства установлены программно, а не с помощью окна Свойства (Properties), то удобно, вместо шестнадцатеричных чисел, использо- вать соответствующие им постоянные числовые значения (константы), приведенные в табл. 10.16. Таблица 10.16. Константы определения цвета Константа Значение Цвет vbBlack 0x0 Черный vbRed OxFF Красный vbGreen OxFFOO Зеленый vbYellow OxFFFF Желтый vbBlue OxFFOOOO Синий vbMagenta OxFFOOFF Розовый vbCyan OxFFFFOO Голубой vbWhite OxFFFFFF Белый Чтобы выбрать нужный цвет при создании формы, щелкните на кнопке со стрелкой в поле значения свойства ForeColor или BackColor. При этом появляется небольшое диалоговое окно с двумя вкладками. Щелчком на требуемом образце цвета на вкладке Palette (Палитра) можно выбрать цвет из предлагаемой палитры (рис. 10.23), при этом VBA автоматически назначит свойству числовое значение выбранного цвета. На вкладке System (Системные) можно выбрать требуемый цвет из палитры систем- ных цветов Windows (рис. 10.24), т.е. из набора цветов, заданных в панели управления Windows и используемых при отображении элементов интерфейса Windows. [UserForm 1 UserForm Alphabetic Categorized | Рис. 10.23. Вкладка Palette диалого- вого окна выбора цвета Рис. 10.24. Вкладка System диалого- вого окна выбора цвета 222 Часть 3. Более сложные аспекты работы на VBA
У большинства элементов управления, а также форм, с помощью свойства Font (Шрифт) можно выбрать для отображения текста любой шрифт, установленный в системе. Чтобы выбрать шрифт для элементов управления или формы в окне свойств (Properties), найдите свойство Font и щелкните на нем, а затем щелкните на появившейся в поле его значения кнопке с многоточием. На экран будет выведено стандартное диалоговое окно Шрифт (рис. 10.25), в котором можно будет установить необходимые значения. Рис. 10.25. Диалоговое окно для выбора шрифта, который будет использоваться по умолчанию | Свойство Font формы на самом деле ничего не меняет в самой форме, поскольку | шрифт, используемый для заголовка формы в ее строке заголовка, задается системными * установками в панели управления Windows. В действительности свойство Font формы задает шрифт, который будет использоваться по умолчанию для отображения текста тех элементов управления, которые будут добавляться в форму. Если необходимо исполь- зовать какой-то нестандартный шрифт для всех элементов управления в форме, то для того, чтобы не менять свойства Font для каждого из элементов управления по отдель- ности, следует в начале работы установить требуемое значение свойства Font для еще пустой формы. Элементы управления VBA обладают несколькими общими свойствами, с помощью которых можно управлять тем, что увидит пользователь при перемещении указателя мыши над ее элементами. При этом не потребуется программировать какие-либо события. Все, что нужно, — это просто изменить требуемым образом значения одного-двух свойств элементов формы. Для определения того, какой вид будет принимать указатель мыши при перемещении надданным элементом управления, выполните следующее. Выделите элемент управления (или форму), для которого требуется изменить стан- дартный вид указателя мыши. Выберите в окне свойств (Properties) свойство MousePointer и щелкните на кнопке со стрелкой, расположенной в его поле значения. Выберите в раскрывающемся списке этого поля требуемый пункт и щелкните на нем. Глава 10. Экранные формы и их элементы 223
Все значения в раскрывающемся списке свойства MousePointer (кроме последне- го) соответствуют различным типам формы указателя мыши, определенным в системе Windows и задаваемым с помощью ее панели управления. Поэтому при выборе любого из этих пунктов вид указателя мыши в процессе выполнения программы будет на самом деле зависеть от тех системных установок, которые были заданы именно на данном ком- пьютере. Последнее значение в списке указывает, что курсор должен принимать форму, определенную пользователем, — его конкретный вид указывается в свойстве Mouseicon и в данном случае уже не зависит от системных установок компьютера. Следует также отметить, что для отдельных элементов управления (но не для содержа- щей их формы) можно подготовить текст всплывающих подсказок, которые будут инфор- мировать пользователя о назначении данного элемента управления. Всплывающие под- сказки — это небольшие текстовые сообщения, которые появляются рядом с указателем мыши при задержке последнего на секунду на некотором элементе управления. Для того чтобы назначить элементу управления всплывающую подсказку, достаточно поместить соответствующий текст в его свойство ControlTipText (рис. 10.26). Рис. 10.26. Пример определения для элемента управления всплывающей подсказки и изменения вида курсора Управление порядком перехода В активном состоянии выведенная на экран форма будет вести себя так же, как и лю- бое диалоговое окно Windows. Для перемещения от одного элемента управления к другому можно воспользоваться клавишей <ТаЬ> или <Shift+Tab> (перемещение в обратном на- правлении). Перемещение с одного элемента управления на другой при нажатии клавиши <ТаЬ> в окне формы пользователя осуществляется слева направо и сверху вниз, при этом элемент управления, который после нажатия клавиши <ТаЬ> получает фокус ввода, ста- новится в форме выделенным. По умолчанию редактор VBA автоматически устанавливает последовательность пере- хода от одного элемента управления к другому в соответствии с тем порядком, в котором элементы управления были добавлены в форму. Как правило, после того как элементы управления помещаются в форму, их несколько раз приходится перемещать с места на место, чтобы придать форме более приемлемый вид. В результате нарушается принятая по умолчанию последовательность перехода от одного элемента управления к другому Для того чтобы изменить последовательность обхода элементов управления в форме, не- обходимо выполнить следующие действия. Выберите команду меню View^Tab Order (ВидФ Последовательность перехода). В раскрывшемся диалоговом окне (рис. 10.27) в списке Последовательность 224 Часть 3. Более сложные аспекты работы на VBA
перехода будут представлены все элементы управления формы, расположенные в установленной на данный момент последовательности их обхода. Щелкните в списке Tab Order (Последовательность перехода) на том элементе управления, положение которого в списке требуется изменить. Щелкните на кнопке Move Up (Вверх) для перемещения элемента управления вверх по списку или на кнопке Move Down (Вниз) — для перемещения его вниз. Щелкайте на кнопке Move Up или Move Down нужное количество раз — пока дан- ный элемент управления не достигнет предусмотренного для него места в списке. Для завершения операции щелкните на кнопке ОК. Рис. 10.27. Диалоговое окно Tab Order со списком элементов управления формы Порядок размещения элементов управления в списке Tab Order определяется значе- нием их свойства Tab Index. Для первого элемента управления значение свойства Tabi- ndex равно 0, для второго — 1 и т.д. При изменении значения этого свойства у одного элемента формы VBА соответствующим образом автоматически изменит свойства Tabi- ndex и других ее элементов. Для того чтобы удалить элемент управления из списка (т.е. вообще исключить его из списка обхода), установите значение его свойства Tabstop равным False. Это не из- менит расположение элемента управления. Если снова установить значение свойства Tabstop, равное True, элемент управления будет вновь включен в последовательность обхода элементов управления, причем там же, где и раньше. Общие методы и события элементов управления Наиболее важные методы (из числа общих для всех элементов управления) приведены в табл. 10.17. Напомним, что вызов метода некоторого объекта в общем случае имеет сле- дующий синтаксис: объект. метод (параметры). Таблица 10.17. Важнейшие общие методы элементов управления Метод______Описание___________________________________________________ Add Item Добавляет элемент в список данных, отображаемый в элементах управления List- Box или ComboBox Clear Удаляет все объекты из данного объекта или коллекции Глава 10. Экранные формы и их элементы 225
Окончание табл. 10.17 Метод Описание Move RemoveItem SetFocus Перемещает элемент управления в пределах формы Удаляет из списка элемент с указанным номером Перемещает фокус ввода на тот экземпляр элемента управления, которому принад- лежит этот метод (используется в программах обработки ошибок) ZOrder Помещает объект выше или ниже в “стопке” всех визуально перекрывающихся с ним объектов События форм и элементов управления Каждая создаваемая в VBA форма имеет свои собственные свойства и методы, но на- ряду с этим она также обладает элементами управления, а значит, и событиями, связан- ными с этими элементами управления. Каждый объект, каждый элемент управления в экранной форме пользователя, так же как и вся форма в целом, предназначены, прежде всего, для реагирования на определенные события, инициированные пользователем или программой, и поэтому имеют свой набор событий, которые можно зафиксировать у дан- ного объекта. Формы и различные элементы управления имеют одинаковые события, тем не менее набор событий каждого объекта индивидуален. После каждого нажатия клавиши кла- виатуры, перемещения мыши или щелчка на кнопке, в форме генерируется программное событие, которое передается на обработку соответствующему методу соответствующего объекта. Здесь мы рассмотрим чаще всего используемые события, краткое описание ко- торых приведено в табл. 10.18. С полным набором событий, описанных для элементов управления конкретного типа, при необходимости можно ознакомиться в справочной системе VBA. Таблица 10.18. Важнейшие общие события форм и элементов управления Событие________________При каких условиях генерируется Activate (Активизация) При активизации экранной формы (т.е. при передаче ей управле- ния) AddControl (Добавление При добавлении нового элемента управления в форму или объект элемента управления) классов Frame, Page или MuitiPage AfterUpdate После установки нового значения для данного элемента управления, (После изменения) перед передачей фокуса ввода от данного элемента управления к другому BeforeDragOver(Перед В процессе операции “перетащить и опустить”, когда указатель завершением перемещения) мыши находится над формой и кнопка мыши все еще нажата BeforeUpdate Перед тем как значение данного элемента управления будет изме- (Перед изменением) нено Change (Изменение) Перед изменением значения свойства Value (Значение) данного элемента управления Click (Щелчок) Щелчок левой кнопкой мыши, когда указатель мыши находится над экранной формой или над данным объектом DblClick Двойной щелчок левой кнопкой мыши, когда указатель мыши на- (Двойной щелчок) ходится над экранной формой или над данным объектом 226 Часть 3. Более сложные аспекты работы на VBA
Окончание табл. 10.18 Событие При каких условиях генерируется Deactivate (Деактивизация) Enter (Вхождение в управление) Error (Ошибка) При деактивизации экранной формы (т.е когда форма перестает быть активной, теряет фокус ввода) Непосредственно перед тем, как элемент управления получит фокус от другого элемента управления в той же форме При обнаружении ошибки, когда нельзя вернуть значение вызываю- щей программе Exit (Выход из управления) Сразу после передачи управления другому элементу этой же формы (т.е. при потере фокуса) Initialize (Инициализация) KeyDown (Нажатие клавиши) KeyPress (Нажатие ANSI-клавиши) Key Up (Отпускание клавиши) Layout (Макет) Перед отображением или загрузкой экранной формы При нажатии пользователем какой-либо клавиши на клавиатуре в тот момент, когда форма выполняется или имеет фокус ввода При нажатии пользователем клавиши на клавиатуре, генерирующей код ANSI, т.е. клавиши с печатаемым символом Когда пользователь отпустил ранее нажатую клавишу При изменении размера (или местоположения) экранной формы или данного элемента управления MouseDown (Нажата кнопка мыши) MouseMove (Перемещение мыши) При нажатии пользователем кнопки мыши, когда указатель мыши на- ходится над экранной формой или данным элементом управления При изменении пользователем местоположения указателя мыши, когда он находится над экранной формой или данным элементом управления MouseUp (Отпущена кнопка мыши) Когда пользователем отпущена ранее нажатая кнопка мыши, когда указатель мыши находится над экранной формой или данным эле- ментом управления QueryClose (Закрытие запроса) Removecontrol (Удаление элемента управления) Resize (Изменение размера) Scroll (Прокрутка) Перед выгрузкой экранной формы из памяти компьютера При удалении элемента управления во время выполнения экранной формы При изменении пользователем размера экранной формы При прокрутке пользователем содержимого элемента управления или экранной формы SpinDown (Щелчок на “уменьшающей” стрелке) SpinUp (Щелчок на “уве- личивающей” стрелке) Terminate (Завершение) Zoom (Масштаб) После щелчка, выполненного пользователем на левой (или нижней) стрелке счетчика После щелчка, выполненного пользователем на правой (или верхней) стрелке счетчика После выгрузки экранной формы из памяти компьютера Изменение масштаба отображения экранной формы Остановимся на некоторых из перечисленных в табл. 10.18 событий подробнее. Со- бытие Change происходит, когда изменяются текущие параметры объекта или значение свойства элемента управления (в частности, при изменении свойства Value). Причем не имеет значения, по какой причине произошло изменение его значения, — это событие Глава 10. Экранные формы и их элементы 227
происходит как при изменении свойства в результате действий пользователя, так и при изменении свойства в результате программных действий. Например, при щелчке на флаж- ке опции (Checkbox), редактировании текста в поле ввода (TextBox) или перемещении ползунка в полосе прокрутки (ScrollBar) для соответствующего объекта генерируется событие Change. Следует отметить, что событие Change является главным событием для элементов управления типа полос прокрутки, флажков опций, кнопок счетчиков, кнопок переключателей и выключателей. Как сама форма (когда она выполняет роль одной большой кнопки и щелчок в любом ее месте должен инициализировать выполнение какого-либо действия в программе), так и большинство элементов управления в языке VBA поддерживают это событие Click. Это событие происходит всякий раз, когда пользователь щелкает на объекте левой кнопкой мыши. Кроме того, событие Click иногда генерируется при изменении пользователем значения элемента управления с помощью клавиатуры. Примером второго варианта мо- жет быть изменение значения флажка опции (объект CheckBox) нажатием пробела, когда этот элемент управления имеет фокус ввода. Следует отметить, что при щелчке пользователем на объекте (перед генерированием интегрального события Click) сначала генерируются промежуточные события выпол- няемой пользователем операции — MouseDown и MouseUp. Событие DblClick генерируется только тогда, когда пользователь дважды щелкает мышью на данном объекте. Обработчику события DblClick дополнительно передается аргумент Cancel с типом MSForm. ReturnBoolean. Если значение аргумента Cancel устанавливается равным True, то элемент управления игнорирует второй щелчок мыши. Это полезно, например, для элементов управления типа Checkbox, когда первый щелчок изменяет его значение, а второй щелчок изменит его значение еще раз, возвращая элемент в первоначальное положение. Если аргумент Cancel имеет значение True, двойной щел- чок изменит значение элемента управления (потому что был зафиксирован только первый щелчок), а событие DblClick будет передано на обработку приложению (т.е. проигнори- ровано элементом управления). В этом случае перед событием DblClick обрабатываются также события MouseDown, MouseUp и Click. Событие Enter генерируется в тот момент, когда фокус в данной форме переходит с прежнего активного элемента управления на данный элемент управления. Событие Exit происходит, когда данный элемент управления теряет фокус и становится неактивным, при этом фокус переходит на другой элемент управления в той же форме. Эти события обычно происходят совместно непосредственно перед перемещением фокуса с одного элемента управления на другой. Поэтому событие Enter, например, можно использовать для отобра- жения информации об элементе, который становится активным, и других подготовительных действий, необходимых при получении им фокуса ввода, а событие Exit — для завершающих или восстановительных операций с элементом управления, который теряет фокус ввода. Событие Exit имеет аргумент с именем Cancel и типом MSForm. ReturnBoolean3. Если этот аргумент имеет значение False (принимается по умолчанию), то переход фокуса ввода от одного элемента управления к другому выполняется корректно. Если 3 Тип данных MSForm. ReturnBoolean (каки многие другие типы данных, используемые в классах, представляющих элементы форм) является типом, определенным пользователем. Его объявление содержится в библиотеке типов VBA, автоматически подключаемой к проекту, поэтому об объявле- нии этого и подобных ему типов данных беспокоиться нет необходимости. 228 Часть 3. Более сложные аспекты работы на VBA
аргумент Cancel имеет значение True, передача фокуса ввода на другой элемент управ- ления блокируется и фокус сохраняется у данного элемента управления. События KeyDown и KeyUp для соответствующего элемента управления генерируются в том случае, когда этот элемент управления является активным и пользователь нажи- мает (KeyDown) или отпускает (KeyUp) какую-нибудь клавишу на клавиатуре. События KeyDown и KeyUp распознают любую посылаемую им комбинацию клавиш. С этими со- бытиями работать труднее, чем с KeyPress, но они позволяют использовать в программе более широкий набор комбинаций клавиш. Например, можно создать процедуру обра- ботки события KeyDown, которая позволит с помощью комбинаций клавиш <Ctrl+<— > и <Ctrl+-»> соответственно уменьшать или увеличивать значение свойства Value объекта полосы прокрутки, скажем, на 10, тем самым выполняя прокрутку в пошаговом режиме. Событие KeyPress происходит, когда пользователь нажимает клавишу ANSI (клави- шу, представляющую печатный символ в кодировке ANSI). Событие KeyPress удобно использовать для распознавания клавиш с обычными “печатаемыми” символами (буквы, числа, знаки пунктуации), когда нужно обработать информацию, вводимую в текстовое поле или в поле со списком. С помощью этого события распознаются также многие из комбинаций клавиш типа <CtrH-oaeww/a>, а также клавиша <Backspace>. Событие KeyPress генерируется, если нажата одна из следующих клавиш: любой печатный символ клавиатуры; <Ctrl> в сочетании с символом стандартного алфавита; <Ctrl> в сочетании с любым специальным символом; <Backspace>; <Esc>. Событие KeyPress не генерируется для следующих клавиш: <ТаЬ>; <Enter>; клавиши управления курсором; любая клавиша, в результате нажатия которой фокус ввода переходит на другой элемент управления. События MouseDown и MouseUp генерируются для данного элемента управления, когда пользователь соответственно нажимает или отпускает какую-либо клавишу мыши и курсор находится надданным элементом управления. Событие MouseMove генерируется, когда кур- сор мыши перемещается над данным элементом управления. Если пользователь однократ- но или дважды щелкает мышью на объекте, события генерируются в следующем порядке: 1. MouseDown 2. MouseUp 3. Click 4. DblClick 5. MouseUp Если кнопка мыши была нажата, когда курсор находился над элементом управления, то объект захватывает события мыши. Это означает, что все последующие события, связанные с мышью, вплоть до наступления события MouseUp, обрабатываются этим Глава 10. Экранные формы и их элементы 229
объектом, даже если курсор “ушел” с объекта перед тем, как была отпущена кнопка мыши. Когда курсор мыши перемещается над объектом, событие MouseMove для него генерируется многократно. Создание процедур обработки событий Когда пользователь работает с диалоговым окном (выбирает элемент из списка, щел- кает на командной кнопке, устанавливает флажок опции и т.д.), любое его действие ини- циирует в системе одно или несколько событий. Мы уже ознакомились с таким понятием, как процедуры обработки событий (см. раздел “События и их обработка”, глава 8). Каждая такая процедура представляет собой подпрограмму, которая автоматически вызывается на выполнение всякий раз, когда в системе происходит связанное с ней событие, и которая определяет, что должен делать объект в ответ на это событие. Поэтому при наступлении соответствующего события объект автоматически предпринимает запрограммированные вами действия, при этом подготовленную процедуру обработки событий вызывать из про- граммы не требуется — ее вызов организует операционная система. Если же вы не хотите, чтобы объект реагировал на некоторые события, процедуры обработки таких событий создавать не следует. При работе с экранными формами процедуры обработки событий необходимо запи- сывать в модуль класса, который является частью класса UserForm4. Поэтому большая часть программы, которая записывается в модуль класса формы, будет связана именно с обработкой событий. По умолчанию процедуры обработки событий являются локаль- ными (Private), т.е. при создании процедуры редактор VBA автоматически добавляет в начало ее объявления ключевое слово Private. Private CommandButtonl_Click Процедура с типом Private может вызываться только из программного кода, свя- гА занного с данной формой. Однако если удалить ключевое слово Private и указать в вместо него Public, тогда можно будет вызвать соответствующую процедуру обра- ботки события и из любой другой части программы. Но прежде чем вызывать откры- тые (Public) процедуры формы, форму следует загрузить в память, причём вовсе не обязательно показывать ее при этом на экране. Процедуры обработки событий имеют имена, в которых название формы и элемента управления объединено с названием события с помощью символа подчеркивания. Такая схема построения имени позволяет VBA автоматически сопоставлять обнаруженное си- стемой событие с требуемой процедурой. Следовательно, при создании процедуры об- работки события Click для кнопки, которой по умолчанию было присвоено имя Сош- mandButtonl, имя данной процедуры будет CommandButtonl_Click. Процедуры обработки событий также могут вызываться из программного кода как обычные процедуры. Для того чтобы вызвать такую процедуру из программы, необходи- мо выделить ее имя в отдельный оператор, т.е. дать прямое указание выполнить данную процедуру. По сути, в этом случае мы заставляем VBA вести себя так, как будто соответ- ствующее событие действительно случилось. 4 Модуль класса UserForm автоматически создается редактором VBA при добавлении формы к проекту (InsertsUserForm). Чтобы открыть его в окне редактора кода, достаточно двойного щелчка мышью в любом свободном месте создаваемой формы. 230 Часть 3. Более сложные аспекты работы на VBA
CommandButton1_С1iск Написание процедуры обработки события ничем не отличается от создания любой другой процедуры в языке VBA. Программный код для процедуры обработки события по- мещается в редакторе VBA в окне программного кода соответствующей формы. Отсюда следует, что все процедуры обработки событий для всех элементов управления в форме, как и для самой формы, создаются непосредственно в окне программного кода формы. При этом не стоит беспокоиться об объявлении процедуры, так как VBA сделает это авто- матически, когда требуемое событие будет выбрано в окне программного кода. Поэтому перед тем как начать программировать процедуры обработки событий, необходимо вы- полнить следующие действия. 1. Откройте окно программного кода формы либо двойным щелчком на форме или на любом из ее элементов управления, либо выделив форму и выбрав команду View=>Code из контекстного меню формы (раскрываемого щелчком правой кноп- кой мыши), либо нажав клавишу <F7>, при условии что форма выделена в окне UserForm. 2. Выберите в левом списке окна программного кода формы тот объект, для которого будет создаваться процедура обработки события. Этот список содержит имена всех объектов, являющихся частью модуля: саму форму UserForm, все ее элементы управления и дополнительно категорию (General), которая относится к про- грамме уровня модуля, например объявлениям переменных, процедурам свойств и общим процедурам. 3. Выберите в правом списке окна программного кода формы событие, для которого нужно создать программный код. Этот список содержит имена всех процедур об- работки событий для объекта, выбранного в списке слева, причем процедуры со- бытий могут быть как пустые, так и уже заполненные. Если в левом списке выбрать категорию (General), то в правом списке будут представлены все существующие в модуле общие процедуры и процедуры свойств. После того как из раскрывающегося списка процедур будет выбрано требуемое со- бытие, VBA перейдет прямо к процедуре его обработки. Если для события еще не создан никакой программный код, VBA автоматически создаст заготовку требуемой процедуры, разместив курсор ввода в пустой строке между оператором объявления процедуры и завер- шающим ее оператором. Если процедура обработки события уже содержит программный код, VBA поместит курсор ввода в его первую строку. Одной из часто решаемых с помощью процедур обработки событий задач является за- дача проверки данных, введенных пользователем в элементы управления формы. Обычно программа предполагает ввод данных определенного типа. Однако пользователь может ввести любой текст в текстовое поле или поле со списком или же с помощью кнопок счет- чика выбрать недопустимое по тем или иным причинам число. Чтобы избежать таких “нештатных” ситуаций и тем самым повысить надежность работы создаваемой программы, в процедуру соответствующего элемента управления нужно добавить программный код, который будет выполнять проверку правильности введенных пользователем данных. Для этого программный код прежде всего должен получить введенные пользователем данные, а затем проверить их на соответствие за- данным критериям. Если условия выполняются, то программный код может сохранить введенные значения или передать их в другую часть программы, а затем продолжить Глава 10. Экранные формы и их элементы 231
корректную работу формы, подтвердив этим правомочность действий пользователя. В противном случае можно либо организовать вывод сообщения, в котором необходимо будет информировать пользователя о том, что возникла определенная ошибка, и ука- зать, как он должен на это реагировать, либо просто заблокировать дальнейшую работу формы, т.е. стереть введенные данные и организовать их повторный ввод. Можно также попробовать исправить сделанную пользователем ошибку — преобразовать введенные пользователем ошибочные данные в допустимый вид, например, отбросить избыточную часть слишком длинной строки или заменить недопустимо большое число максимально возможным. Для проверки текущих значений элементов управления можно использовать опера- торы If... Then и Select Case. Рассмотрим пример. Пусть в форме присутствует эле- мент управления Счетчик (SpinButtonl), связанный с текстовым полем (TextBoxl). Исходное значение счетчика, которое отображается в текстовом поле, равно 1. Щелчок на верхней кнопке счетчика увеличивает (а на нижней — уменьшает) значение в тексто- вом поле на единицу. Допустим, что это поле предназначено для ввода номера месяца года и, следовательно, может иметь значение от 1 до 12. В приведенной ниже процедуре обработки события Change счетчика, которое генерируется при щелчке на любой из его кнопок, проверяется на допустимость новое значение его свойства Value, которое VBA предварительно автоматически изменяет на единицу. Если новое значение выходит за пределы допустимого, то выполняется его замена на максимально (или минимально) возможное. Далее текущее значение счетчика присваивается свойству Value текстового поля. Private Sub SpinButtonl_Change() If SpinButtonl.Value = 13 Then SpinButtonl.Value = 12 ’Номер месяца не может превышать 12 End If If SpinButtonl.Value = 0 Then SpinButtonl.Value = 1 ’Номер месяца не может быть меньше 1 End If TextBoxl.Value = SpinButtonl.Value End Sub При запуске формы в текстовом поле отображается его исходное значение, которое за- тем может быть уменьшено или увеличено пользователем щелчками на кнопках счетчика. Однако если пользователь щелкнет на кнопке увеличения значения, когда в поле уже со- держится значение 12, новое значение счетчика 13 будет обнаружено программой и вновь заменено на 12. В результате, сколько бы пользователь ни щелкал на кнопке увеличения значения счетчика, значение в текстовом поле будет по-прежнему 12. Аналогичный эф- фект достигается и для нижней границы допустимого диапазона — достигнув 1, значение в текстовом поле перестанет уменьшаться. Проверка правильности вводимых пользователем данных может выполняться в любой момент взаимодействия пользователя с формой. В зависимости от выбранно- го момента, проверка осуществляется в различных процедурах обработки различных событий, относящихся к элементу управления или к форме в целом, как показано в табл. 10.19. В самом простом случае, когда нужно проверять вводимые данные при каждом из- менении значения элемента управления, используйте процедуру обработки события Change. 232 Часть 3. Более сложные аспекты работы на VBA
Таблица 10.19. Выбор процедуры для осуществления проверки вводимых пользователем данных Момент проверки данных Используемая процедура При нажатии любой клавиши Процедура обработки события KeyPress для элемента управления (позволяет получить информацию о нажатии отдельной клавиши или их комбинаций) При любом изменении значения эле- мента управления По окончании работы пользователя с элементом управления, непосред- ственно перед переходом к другому элементу При закрытии формы пользователем Процедура обработки события Change (для оценки нового значения) Процедура обработки события BeforeUpdate (позволяет отменить обновление данных и вернуть пользователя к те- кущему элементу управления) Процедура обработки события Click для кнопок ОК или Закрыть в форме Во время работы с текстовыми полями и полем со списком пользователь при вводе символов может ввести и такие, которые будут недопустимы для используемого типа данных. В этом случае необходимо воспользоваться процедурой обработки события Key- Press, в которой можно будет запрограммировать выявление и удаление с экрана недо- пустимых символов, случайно (или преднамеренно) введенных пользователем. В приве- денной ниже процедуре пользователю разрешается вводить в поле ввода TextBoxl только буквы и цифры. Private Sub TextBoxl_KeyPress(ByVai KeyAscii _ As MSForms.Returninteger) ’ весь следующий блок является условием: If Chr(KeyAscii) < "0” Or _ (Chr(KeyAscii) > "9" And Chr(KeyAscii) < "A") Or _ (Chr(KeyAscii) > ”Z" And Chr(KeyAscii) < "a") Or _ Chr(KeyAscii) > "z" Then Beep ’Подача звукового сигнала KeyAscii = 0 ’ отбрасывание символа End If End Sub Как только оператор If. . . Then обнаружит недопустимый символ, будет подан зву- ковой сигнал, предупреждающий пользователя о том, что введен недопустимый символ. Далее выполняется оператор KeyAscii = 0. Здесь KeyAscii — аргумент процедуры обработки события KeyPress, поэтому он используется в данной процедуре как локаль- ная переменная. Изменение его значения меняет код символа, передаваемого в текстовое поле. А поскольку текстовое поле не воспринимает символ, имеющий код 0, введенный пользователем недопустимый символ исчезнет без следа. Изменение значения аргумента KeyAscii позволяет изменять неверно введенные данные на правильные. Следует отметить, что не всегда удобно (или достаточно) перепроверять вводимое значение элемента управления при каждом вводе символа. Иногда гораздо удобнее от- ложить проверку данных до того момента, когда пользователь завершит ввод полностью; это позволит выловить такие ошибки, которые невозможно обнаружить при анализе символов по отдельности. Чтобы проверить значение элемента управления после того, как пользователь полностью закончит ввод, нужно создать процедуру обработки события Глава 10. Экранные формы и их элементы 233
BeforeUpdate. Это событие генерируется, когда пользователь щелкает на другом эле- менте управления, нажимает клавишу <ТаЬ> или комбинацию клавиш, назначенную другому элементу управления. VBA генерирует событие BeforeUpdate непосредственно перед тем, как данный элемент управления потеряет фокус ввода, что позволяет при не- обходимости отменить обновление данных и сохранить фокус ввода на прежнем месте, при этом пользователю предлагается исправить ошибку. В приведенном ниже примере показано, как использовать свойство Cancel процедуры обработки данного события. Private Sub TextBoxl_BeforeUpdate(ByVai Cancel _ As MSForms.ReturnBoolean) If Len(TextBoxl.Value) > 5 Then MsgBox ’’Слишком много символов. Повторите ввод.” Cancel = True End If End Sub В данном случае ошибка фиксируется, когда количество символов, введенных пользо- вателем в поле TextBoxl, окажется больше пяти. Для ее исправления пользователю выда- ется соответствующее сообщение и свойству Cancel процедуры присваивается значение True, после чего фокус ввода сохраняется на данном поле. Иногда имеет смысл отложить проверку данных элемента управления до щелчка, вы- полненного пользователем на кнопке ОК, закрывающей форму. Это делается в том случае, когда критерии проверки корректности данных используют значения сразу нескольких элементов управления в форме. Если выбран такой тип проверки, поместите соответ- ствующий программный код в процедуру обработки события Click кнопки ОК. Предположим, вы разрабатываете форму, предназначенную для ввода даты будущих важных событий. В форме имеется список, с помощью которого пользователь может ука- зать, за какое время до наступления события нужно напомнить о нем. Если пользователь запланирует некоторую встречу7 на завтра, но попросит напомнить о ней за два дня до этого события, вы можете сообщить о запрете ввода таких данных уже после того, как пользова- тель щелкнет на кнопке ОК. Поместив соответствующий код проверки с использованием нескольких введенных пользователем значений в процедуру обработки события Click кнопки ОК, не придется требовать от пользователя ввода данных в элементы управления в определенном жестком порядке, при котором ошибки подобного типа можно было бы обнаружить при вводе отдельных данных. Помимо проверки вводимых данных, в процедурах обработки событий можно выпол- нять разнообразные действия по управлению состоянием данного и любых других элемен- тов управления формы — изменять их цвет, видимость и расположение на экране, управлять порядком обхода элементов, автоматически подставлять предполагаемые значения в те эле- менты управления, которые пользователь будет заполнять следующими, и многое другое. Например, приведенные ниже подпрограммы обработки событий Enter (получение фокуса ввода) и Exit (потеря фокуса ввода) для поля ввода TextBoxl позволяют вы- делить его светло-зеленым цветом, пока данное поле обладает фокусом ввода и, следо- вательно, ему адресуются данные, вводимые пользователем с клавиатуры. Этот метод особенно удобен, когда в форме присутствует несколько полей ввода — активное поле в форме будет сразу заметно, а при выходе из него его цвет вновь станет белым. Private Sub TextBoxl_Enter() TextBoxl.BackColor = RGB(230, 256, 230) 234 Часть 3. Более сложные аспекты работы на VBA
End Sub Private Sub TextBoxl_Exit(ByVai Cancel As MSForms.ReturnBoolean) TextBoxl.BackColor = RGB(256, 256, 256) End Sub Для сокрктия/отображения элементов управления в форме можно использовать их свойство Visible, позволяющее “убирать” из формы те элементы управления, которые не требуются при выбранном пользователем режиме работы. Свойство Enabled позво- ляет сделать элемент управления неактивным — он будет по-прежнему виден в форме, но выделен серым цветом и недоступен пользователю. Другие свойства элементов управ- ления задают их размеры, положение в форме, цвет, используемый шрифт и т.д. Степень детализации поведения формы и ее элементов ограничивается лишь вашей фантазией и поставленными задачами, что позволяет превратить разрабатываемое приложение в действительно удобный и привлекательный инструмент, с которым пользователь сможет эффективно и охотно работать. Дополнительные элементы управления В языке VBA, кроме перечисленных стандартных элементов управления, имеется еще ряд дополнительных элементов управления. Дополнительные элементы управления — это само- стоятельные объекты, обладающие свойствами и методами. Эти свойства и методы могут быть как общими для всех стандартных элементов управления, так и их собственными (т.е. присущими только дополнительным элементам управления). Добавить дополнительный эле- мент управления на панель элементов управления можно, выполнив следующие действия. 1. Выберите команду меню Tools«=>Additional Controls (Сервис*^Дополнительные эле- менты) либо щелкните правой кнопкой мыши в панели элементов управления и выберите команду Additional Controls. 2. В раскрывшемся диалоговом окне Additional Controls (Дополнительные элемен- ты) в списке Available Controls (Доступные элементы) перечислены все элементы управления, которые инсталлированы в вашей системе. Установите флажок опции напротив добавляемого элемента (рис. 10.28), после чего щелкните на кнопке ОК. Рис. 10.28. Диалоговое окно Additional Controls Глава 10. Экранные формы и их элементы 235
ЯКЯЦ Для удаления ненужного элемента управления из панели элементов управления от- кройте диалоговое окно Additional Controls (Дополнительные элементы управления) и сбросьте флажок опции напротив удаляемого элемента управления. Для завершения операции щелкните на кнопке ОК. Один из очень полезных дополнительных элементов управления, присутствующих в списке диалогового окна Additional Controls, — это элемент управления Microsoft Office Outlook Date Control (см. рис. 10.28). Выбрав данный элемент и поместив его пиктограм- му на панель инструментов (рис. 11.29), вы получите в свое распоряжение эффективный инструмент создания в форме удобного интерфейса для ввода дат (рис. 11.30). Основные свойства элемента управления OlkDateControl приведены в табл. 11.20. Рис. 11.29. Кнопка элемента управле- ния для представления и ввода даты (OlkDateControl) на панели элемен- тов управления Toolbox Рис. 11.30. Элемент OlkDateControl в фор- ме (страница календаря открывается щелч- ком на кнопке рядом с текстовым полем) Таблица 11.20. Основные свойства элемента управления OlkDateControl Свойства Описание Date (Дата) Свойство (тип Date), предназначенное для считывания или установки текущего значения элемента управления программным путем ForeColor Text Value Определяет цвет шрифта для отображаемой даты Содержит текстовое значение, отображаемое в элементе управления Содержит дату, установленную на данный момент в календаре пользователем (или программно) Единственный метод элемента управления OlkDateControl приведен в табл. 11.21. Таблица 11.21. Метод элемента управления OlkDateControl Методы Описание DropDown Раскрывает страничку календаря, позволяющую выбрать требуемый день, месяц и год 236 Часть 3. Более сложные аспекты работы на VBA
Проектирование и создание форм Вы уже могли убедиться на собственном опыте, что создавать формы в редакторе VBA очень просто. Однако при разработке реальных программ совершенно необходим этап их предварительного проектирования. Не забывайте, что формы в этом случае являются частью создаваемой программы, которая имеет вполне определенное практическое назна- чение. Поэтому каждая форма нуждается в тщательной проработке и продумывании как ее интерфейса в целом, так и функциональности ее отдельных элементов. Следовательно, прежде чем вызывать редактор форм и приступать к манипулированию элементами управ- ления, уделите хотя бы минимум времени выполнению перечисленных ниже действий. 1. Определите цель создания своей программы. 2. Этот этап необходим, даже если в создаваемой программе вообще нет форм, одна- ко если формы потребуются, то при их проектировании всегда следует помнить о главной цели всей программы. 3. Для каждой формы в программе определите ту конкретную задачу, которая должна решаться с ее помощью в русле основной задачи всей программы. 4. Какая информация должна отображаться в форме, какую информацию должен ввести пользователь и какие дополнительные данные потребуются пользователю для того, чтобы решить, в каком направлении выполнение программы будет про- должено? Ответы на эти вопросы преобразуйте в конкретный набор элементов управления в создаваемой форме. 5. Для каждой специально решаемой задачи или функции формы подберите тот эле- мент управления, который лучше всего подходит для этих целей. 6. Например, если необходимо предоставить пользователю возможность выбрать одну из нескольких взаимоисключающих возможностей, то лучше всего поместить в форму переключатель с набором соответствующих кнопок. Однако если поль- зователь должен выбрать один или несколько режимов функционирования, неза- висимых друг от друга, то лучше всего для этой цели использовать флажки. И так далее. 7. Решите, где лучше всего разместить каждый из элементов управления в форме. 8. Критериями принятия решения должны быть важность выполняемой элементом управления задачи, вероятная частота использования, связь с другими решаемыми в форме задачами (чтобы определить, с какими другими элементами управления будет целесообразно сгруппировать данный элемент) и др. 9. Получив ответы на все эти частные вопросы, подготовьте (хотя бы мысленный) набросок общего вида создаваемой формы. 10. Не размещайте в формах слишком много элементов управления. Возможно, более рациональным решением будет использование формы с несколькими страница- ми — это уменьшает общее Число форм создаваемого приложения. Тем не менее, минимизация количества форм не является главной задачей проектирования. Воз- можно, более оптимальным окажется вариант, в котором проект будет содержать несколько дополнительных форм, если это поможет избежать перегруженности и упростит использование основных форм. Глава 10. Экранные формы и их элементы 237
11. После того как вы учтете и реализуете все описанные выше практические рекомен- дации, полезно будет подумать и об эстетическом оформлении проекта. 12. Особый шрифт на кнопках или специальные стрелки-изображения на кнопках прокрутки — помогут ли они пользователю работать с формой? Какое цветовое решение повысит эффективность восприятия самой важной информации в фор- ме? Стоит потратить время на поиски ответов на эти и подобные им вопросы. В разумных пределах правильно подобранные цвета, шрифты и изображения, не- сомненно, привлекают интерес и внимание пользователя, но неумеренность здесь вызовет только его раздражение. Общее представление о том, что нужно получить в конечном результате, поможет в разработке пробной версии каждой формы проекта и тестировании ее прототипа, что- бы выяснить, что в конце концов будет работать, а что — нет. Следует еще раз обратить внимание читателя на то, что при полном игнорировании этапа планирования задачи, в целом, и ее форм, в частности, впоследствии наверняка потребуется немало усилий для многократной переделки созданных форм, пока достигнутые результаты можно будет считать удовлетворительными. Дополнительно следует отметить, что при разработке VBA-проекта часто бывает по- лезно распечатать предварительные варианты его форм, которые затем можно предъявить будущим пользователям проекта для обсуждения и критического редактирования раз- личных возможных вариантов. Чтобы распечатать форму в редакторе VBA, выполните следующие действия. 1. Выделите форму в окне проектов (если нужно распечатать только одну форму в проекте). Если же необходимо распечатать все формы некоторого проекта, выде- лите формы, модуль или любой другой компонент этого проекта. 2. Выберите команду File^Print или нажмите комбинацию клавиш <Ctrl+P>. 3. В раскрывшемся диалоговом окне Print — Имя проекта (рис. 10.31) установите флажок опции Form Image (Изображение формы). 4. Сбросьте флажок опции Code (Программный код), если не требуется распечаты- вать вместе с изображением формы и ее программный код. 5. Установите переключатель Range в положение Current Module (Данный модуль), если нужно распечатать только одну форму, или же в положение Current Project (Данный проект), если нужно напечатать все формы проекта. 6. Щелкните на кнопке ОК. Рис. 10.31. Диалоговое окно Print... 238 Часть 3. Более сложные аспекты работы на VBA
Пример создания формы Чтобы закончить эту главу, рассмотрим конкретный пример создания формы. Это достаточно простая форма, но в ней используются почти все важные приемы, которые требуются для реализации основных функциональных возможностей типичных форм. Пусть наша форма будет предназначена для ввода текста объявлений, которые затем будут напечатаны в некотором рекламном листке или газете. При этом предусматривается ввод пользователем следующих данных: фамилия и контактный телефон заказчика; текст и категория (куплю, продам и пр.) объявления; сведения о количестве номеров рекламного листка, в которых оно должно быть напечатано, — будем полагать, что листок выходит по понедельникам, средам и пятницам и одно объявление может печататься на протяжении от одной до пяти недель. Для ввода фамилии, контактного телефона и текста объявления воспользуемся эле- ментами управления типа Поле. Категория объявления будет задаваться с помощью переключателя с тремя кнопками, а выбор дней недели — с помощью флажков опций. Количество недель, на протяжении которых будет печататься объявление, удобнее всего будет вводить с помощью поля счетчика, значения которого ограничены цифрами 1-5. Наконец, для фиксации или отмены выполненной работы нам понадобятся две команд- ные кнопки, Готово и Сброс, которые также следует поместить в форму. Кроме того, для завершения работы формы потребуется еще одна командная кнопка Выход. Создавать форму будем в приложении Word, поэтому начнем с того, что запу- стим эту программу MS Office и откроем в ней окно редактора VBA (<Alt+Fl 1 >). Как нам уже известно, для того чтобы создать новую форму, необходимо выбрать команду Insert^UserForm. При этом редактор создаст пустую форму с именем UserForml и ото- бразит панель инструментов ToolBox. Однако прежде чем выполнять эти действия, подумаем, а куда будет добавлена новая форма и, следовательно, где она будет сохранена? По умолчанию при открытии окна ре- дактора VBA в Word автоматически выбирается текущий документ и именно в него будет вставлен модуль с новой формой. В результате доступ к создаваемой форме можно будет получить только в том случае, если этот документ будет предварительно открыт в Word, что очень неудобно. Для того чтобы форма была доступна из нескольких документов, ее следует сохранить в шаблоне, использованном при их создании. Если необходимо, чтобы форму можно было открыть из любого документа Word, ее нужно сохранить в шаблоне Normal. Именно так мы и поступим в нашем примере. Прежде чем создать новую форму, выделите в окне проектов шаблон Normal, а затем выберите команду Insert^UserForm. В этом случае новая форма будет помещена в общий шаблон и, следовательно, станет доступной из любых приложений (рис. 10.32). Начнем создавать форму с изменения ее имени — для этого выберите в окне Proper- ties свойство Name формы и поместите в него значение Форма 1. Далее изменим название формы в ее строке заголовка — для этого измените значение ее свойства Caption на Ввод объявления. Чтобы форма выглядела эффектнее, выберите для ее свойства Special- Effect значение 1 - fmSpecialEf fectsRaised. При этом заготовка формы примет вид, показанный на рис. 10.33. Глава 10. Экранные формы и их элементы 239
Рис. 10.32. Новая форма добавлена в шаблон Normal Рис. 10.33. Пустая форма в исходном состоянии Теперь следует задать форме необходимые размеры — установите значение ее свойства Width (Ширина) равным 500, а свойства Height (Высота) равным 250 пикселей. Теперь можно начать заполнять форму требуемыми элементами управления. 1. Поместите в форму элемент управления Надпись, разместив его слева вверху, и присвойте его свойству Caption значение Заказчик, свойству Width — значе- ние 200, а свойству Height — значение 12. Имя этого элемента будет Labell. 2. Правее поместите еще одну надпись, для которой свойству Caption присвойте значение Телефон, свойству Width — значение 100, а свойству Height — значе- ние 12. Имя этого элемента управления будет Labe 12. 3. Выберите оба элемента управления и выровняйте их по верхнему краю (команда Format^Align^Top) и по высоте (команда Formats Make Same Size^Height). 4. Не сбрасывая выполненного на предыдущем этапе выделения, измените значение свойства Font, установив для надписей шрифт Arial размером 10 пунктов, полу- жирный, а также свойства TextAlign, выбрав для него значение 2-fmTextAl- ingCenter. 5. Поместите в форму два элемента управления Поле, расположив их под элементами управления Labell и Label2. Измените их свойства Name на Заказчик и Телефон соответственно. Выберите оба поля и установите для них высоту поля 17 пунктов и шрифт Times New Roman размером 10 пунктов, обычный. Чтобы увидеть, как будет выглядеть помещаемый в поля ввода текст, присвойте их свойствам Value значение Проба текста. В результате форма примет вид, показанный на рис. 10.34. Действуя аналогичным образом, поместите в форму под полем Заказчик еще одну надпись, Label3, которая будет содержать текст Текст объявления. Все остальные ее параметры установите такими же, как и для надписи Labell. Под этой надписью поместите третье поле ввода с именем Текст, с такими же параметрами, как и у поля Заказчик. Измените лишь значение свойства Heght, установив его равным 12 0, а также выберите для свойства Multiline значение True, что позволит вводить в данное поле 240 Часть 3. Более сложные аспекты работы на VBA
несколько строк текста. Таким образом, при вводе текст будет автоматически переходить на новую строку по достижении границы поля, а принудительно начать новый абзац мож- но будет с помощью комбинации клавиш <Shift+Enter>. Рис. 10.34. Форма после вставки первых двух надписей и полей Теперь поместите в форму элемент управления Рамка, расположив его под полем Телефон — это будет элемент управления Frame 1. Значение его свойства Caption должно быть Категория, а параметры шрифта такие же, как у надписей в форме. Раз- меры рамки подберите такими, чтобы по высоте она равнялась высоте поля Текст, а по ширине — полю Телефон. Поместите в рамку три кнопки переключателя, присвоив им имена Кат1, Кат2 и КатЗ. Свойства Caption этих элементов управления должны иметь значения Куплю, Продам и Прочее соответственно. Выделите все три кнопки и присвойте им одинаковую высоту и ширину, например, 17 и 70 пунктов соответственно, а затем выровняйте их в рамке так, как показано на рис. 10.35. Шрифт для кнопок установите Arial, 10 пунктов, обычный. Затем поместите в рамку еще по одному элементу Надпись и Поле. Имя элемента надписи оставьте без изменения — Label4, а полю присвойте имя Заголовок. Далее в надпись поместите текст Заголовок, отцентрируйте его и установите для этого элемента шрифт Arial, 9 пунктов, полужирный. Для поля ввода установите ширину 17 пунктов, а все осталь- ные параметры установите такие же, как и для поля Заказчик или Телефон. В результате форма будет выглядеть так, как показано на рис. 10.35. Теперь добавим в форму еще одну рамку, с заголовком Печатать в номере. Имя этого элемента управления оставьте Frame2, а параметры шрифта сделайте такими же, как у первой рамки. Разместите рамку на одном уровне с полями Заказчик и Телефон, а размеры ее установите так, чтобы она занимала оставшуюся часть формы справа. Поме- стите в эту рамку три элемента управления Флажок и присвойте им имена День 1, День2 и День3. Свойствам Caption этих элементов присвойте значения Понедельник, Среда и Пятница соответственно, а затем выровняйте их и установите параметры шрифта такие же, как и для переключателя в первой рамке. Наконец, поместите под флажками еще два элемента управления — Поле (с именем Недели) и Счетчик (с именем SpinBtl), рас- положите их рядом таким образом, чтобы они образовали единую группу, а затем справа добавьте Надпись (с именем Label5), содержащую текст Недели. Установите параметры Глава 10. Экранные формы и их элементы 241
шрифта этих элементов такими же, как у флажков. В результате форма должна приобрести примерно такой вид, как показано на рис. 10.36. Рис. 10.35. В форму добавлена рамка с кнопками переключателя Рис. 10.36. Добавление в форму второй рамки с флажками опций и счетчиком Последнее, что нам остается сделать, — это поместить в форму три элемента управ- ления Кнопка, разместив их в нижней части формы. Свойства Name и Caption каждой кнопки должны совпадать и иметь значения Сброс, Готово и Выход соответственно. Параметры шрифта для кнопок установите такие же, как и для надписей в форме, а затем выровняйте их. Окончательный вид формы показан на рис. 10.37. На этом построение формы можно считать оконченным, и все, что осталось сделать, — это оживить ее, заставив элементы управления в ней действовать необходимым нам об- разом. Эта цель достигается подготовкой подпрограмм обработки событий для формы в целом и ее отдельных элементов. Однако сначала необходимо выяснить, как именно должны реагировать элементы управления на действия пользователя, и лишь после этого можно будет перейти непосредственно к программированию. 242 Часть 3. Более сложные аспекты работы на VBA
Рис. 10.37. Окончательный вид формы Ввод объявления в окйе редактора VBA Во-первых, необходимо решить, как будет выглядеть форма в исходном состоянии, т.е. сразу после отображения на экране или после щелчка на кнопке Сброс. Логично предположить, что в этом случае все поля ввода должны быть пустыми, переключатель должен быть установлен в верхнее положение (Куплю), все флажки опций должны быть сброшены, а в счетчик должно быть помещено значение 1. Кроме того, поскольку поле ввода Заголовок необходимо только при установке переключателя в положение Прочее, целесообразно сделать его и надпись Labe 14 невидимыми. Из командных кнопок актив- ными (т.е. доступными пользователю) должны быть только кнопки Сброс и Выход, по- скольку случайный щелчок на кнопке Готово в тот момент, когда данные в форму еще не введены или введены не полностью, вызовет запись данных, непригодных к дальнейшей обработке. Во-вторых, выберем порядок обхода элементов управления формы. Разумнее всего начинать заполнение формы с фамилии и телефона заказчика, которые должны быть введены в форму обязательно. Затем пользователь должен выбрать категорию объявления (если это Прочее, то дополнительно потребуется ввести его заголовок) и набрать текст объявления. Завершается работа установкой флажков требуемых номеров и заданием количества недель, которое данное объявление должно печататься в рекламном листке. Только после этого должна стать активной кнопка Готово, щелчок на которой позволит записать введенную информацию на диск. Не откладывая дела в долгий ящик, выделите в окне редактора VBA только что созданную форму и выберите команду View=>Tab Order. В открывшемся диалоговом окне Tab Order (Последовательность перехода) переставьте элементы в списке так, чтобы они располагались в оговоренной выше последовательности (рис. 10.38). Для этого выделите в этом диалоговом окне нужный элемент и щелчками на кнопке Move Up (Вверх) или на кнопке Move Down (Вниз) переместите выбранный элемент в требуемое место списка. Затем выделите в форме рамку Frame 1 и повторите эту же операцию для помещенных в нее элементов управления — порядок должен быть такой: Кат1, Кат2, КатЗ, Заголовок, Label4. Наконец, выделите рамку Frame2 и установите для содержащихся в ней элементов следующий порядок обхода: День1, День2, ДеньЗ, SpinBtl,Недели, Label5. Глава 10. Экранные формы и их элементы 243
Рис. 10.38. Установка порядка обхода элементов управления формы Теперь можно приступать непосредственно к программированию методов и событий формы. Начнем с приведения формы в исходное состояние. Дважды щелкните в любом свободном месте формы, и на экране раскроется окно кода. Выберите в левом списке элемент Форма 1, а в правом — событие Activate. Поместите в заготовку процедуры сле- дующий программный текст. Private Sub OopMal_Activate() ’Приведение формы в исходное состояние Заказчик.Value = ” ’Очистка текстовых полей Телефон.Value = ”” Текст.Value = ”” Заголовок.Value = ”” Кат1.Value = True ’Уст-ка переключателя в исходное положение Кат2.Value = False КатЗ.Value = False Заголовок.Visible = False ’Сокрытие поля заголовка Label4.Visible = False День1.Value = False ’Сброс флажков опций День2.Value = False ДеньЗ.Value = False Недели.Value = 1 ’Исходное количество недель SpinBtl.Value = 1 ’Исходное значение счетчика Готово.Enabled = False ’Блокировка кнопки Готово Заказчик.SetFocus 'Установка фокуса ввода на это поле End Sub Как было решено ранее, исходный вид форма должна также принимать и после щелч- ка на кнопке Сброс. Поэтому выделите все операторы в теле только что созданной про- цедуры и скопируйте их в буфер обмена. Теперь выберите в окне кода процедуру Click для элемента управления Сброс и вставьте в ее заготовку скопированный текст. Для проверки работы этой подпрограммы просто нажмите клавишу <F5>, и на экране раскроется окно нашей формы, которое должно выглядеть так, как это показано на рис. 10.39. Введите в поля произвольный текст, установите переключатель в другое положение, выберите один или несколько флажков опций и щелкните на кнопке Сброс. Форма должна вновь вер- нуться в исходное состояние. Для закрытия формы и возврата в редактор VBA щелкните на ее системной кнопке закрытия (X) в строке заголовка — кнопка Выход еще не работает, поскольку для нее пока не написано никаких процедур обработки событий. 244 Часть 3. Более сложные аспекты работы на VBA
Рис. 10.39. Исходное состояние формы при ее выполнении Теперь можно продолжить программирование поведения формы и ее элементов. В со- ответствии с нашим планом, поле Заказчик обязательно должно быть заполнено, поэтому мы должны обеспечить наличие в нем каких-либо данных, прежде чем курсор можно бу- дет переместить в какое-либо иное поле формы. Воспользуемся для этой цели событием BeforeUpdate. Выберите это событие в окне кода для элемента управления Заказчик и поместите в него следующий код: Private Sub Заказчик_Ве£oreUpdate(ByVai Cancel _ As MSForms.ReturnBoolean) If Len(Заказчик.Value) = 0 Then MsgBox ’’Поле ’Заказчик’ должно быть заполнено обязательно.’’ Cancel = True End If End Sub Теперь, если запустить форму и попытаться что-либо в ней изменить, оставив поле Заказчик незаполненным, будет выведено предупреждающее сообщение (рис. 10.40) и курсор ввода останется на прежнем месте. i ii Поле 'Заказчик' должно быть заполнено обязательно. I ок I Рис. 10.40. Окно с предупреждением о необходимости заполнить поле Однако если корректно ввести данные в это и любые другие поля, а затем щел- кнуть на кнопке Сброс, появится такое же сообщение! Но это нам совсем не нужно, поэтому данную ситуацию необходимо исправить. Сначала надо выяснить причину происходящего — по всей видимости, она связана с действиями, которые выполняются в процедуре Click кнопки Сброс. Можно предположить, что при выполнении оператора Заказчик. Value = " " также генерируется событие BeforeUpdate, и, поскольку в поле Глава 10. Экранные формы и их элементы 245
записывается пустое значение, только что написанная процедура честно предупреждает нас, что этого делать нельзя. Как же выйти из подобной ситуации? Ответ прост — надо “научить” процедуру отличать одну ситуацию (очистка формы) от другой (отказ пользо- вателя от ввода обязательного значения). Для этого выберите в левом списке окна кода значение (General) и поместите в верхнюю строку оператор Dim Очистка As Boolean. Иначе говоря, в общей секции формы мы определяем логическую переменную Очистка. Будем считать, что ее значение всегда равно False, за исключением случая, когда вы- полняется очистка формы. Это позволит подпрограмме анализировать ситуацию, просто проверив текущее значение данной переменной. Реализовать этот механизм несложно — достаточно добавить в процедуру Click кнопки Сброс оператор Очистка = True, по- местив его в самом конце процедуры. Теперь реализуем проверку ситуации в процедуре BeforeUpdate поля Заказчик. Private Sub ЗаказчиК—BeforeUpdate(ByVai Cancel _ As MSForms.ReturnBoolean) If Очистка = True Then ’Это сброс формы Очистка = False Exit Sub End If If Len(Заказчик.Value) = 0 Then MsgBox ’’Поле ’Заказчик’ должно быть заполнено обязательно.” Cancel = True End If End Sub Если теперь вновь запустить форму на выполнение, можно убедиться, что нежелатель- ный побочный эффект устранен. Поскольку поля Телефон и Текст также должны быть обязательно заполнены пользователем, скопируем текст только что созданной процедуры Заказчик_ВеforeUpdate и поместим его в заготовки процедур обработки событий Exit этих элементов управления. Событие Exit выбрано вместо события BeforeUpdate потому, что при выходе из этих элементов управления без попытки поместить в них что- либо событие BeforeUpdate для них не генерируется и проверка не выполняется, тогда как событие Exit генерируется всегда, когда фокус ввода покидает элемент управления. Не забудьте изменить имя элемента управления в операторах I f и MsgBox. И вновь мы сталкиваемся с нежелательным побочным эффектом — на этот раз со- общение о недопустимости наших действий появляется при попытке щелкнуть на кнопке Сброс, когда курсор находится в любом из полей ввода (кроме поля Заказчик), которое еще не заполнено. И это правильно с точки зрения программы — чтобы выполнить щелчок на кнопке, она должна получить фокус ввода, но прежде его нужно снять с текстового поля, которое пусто, — а этого наша подпрограмма делать не разрешает. Но с точки зрения пользователя это неправильно — он имеет полное право в любой момент отказаться от уже выполненных им действий и начать все сначала. И вновь, чтобы исправить положение, надо “научить” подпрограммы Exit полей ввода отличать щелчок на кнопке Сброс от любых других действий пользователя, вызывающих передачу фокуса ввода. Это совсем несложно — в подпрограммах у нас уже реализована проверка состояния переменной Очистка, осталось лишь присвоить ей значение True в требуемый момент. Как же узнать, что пользователь намерен щелкнуть на кнопке Сброс? Вспомним, что для этого он должен, как минимум, поместить на нее указатель мыши! Вот и решение проблемы — выберем для кнопки Сброс событие Mo us eMove и поместим 246 Часть 3. Более сложные аспекты работы на VBA
в его процедуру единственный оператор: Очистка = True. Но это только половина решения — ведь если пользователь просто проведет указателем мыши над кнопкой Сброс, не щелкая на ней, переменной уже будет присвоено значение True и логика работы про- граммы будет нарушена. Проверьте это и убедитесь, что теперь достаточно провести кур- сор над кнопкой, и блокировка выхода из пустого поля не срабатывает. Окончательно решить проблему можно, если сбросить переменную Очистка, как только курсор покинет пространство над кнопкой. Как же это сделать? Подумайте, где курсор оказывается, когда покидает кнопку, — конечно же, над формой. Поместим оператор Очистка = False в процедуру события MouseMove формы, и проблема будет полностью решена. Теперь форма ведет себя так, как нам требуется, вы можете убедиться в этом на практике. МЯЦ Столь большое внимание исправлению относительно мелких “недоработок” здесь уде- лено т0г0, что^ы показать читателю, как можно устранить разные проблемы и не- И желательные побочные эффекты, которые сплошь и рядом возникают при разработке форм. Не отчаивайтесь — прежде всего постарайтесь выявить причину происходящего, а затем подберите наиболее простой и удобный способ ее устранения. Теперь обратимся к переключателю Категория. Три его кнопки находятся в одной рам- ке (Frame 1), и это автоматически обеспечивает необходимую функциональность — в лю- бом случае включена может быть только одна из трех кнопок, а две остальные всегда будут сброшены. Это нас вполне устраивает, и заботиться тут больше не о чем. Однако, как было решено на этапе проектирования, в исходном состоянии формы поле Заголовок скрыто, и нам следует позаботиться о том, чтобы оно отображалось в форме при установке пере- ключателя в положение Прочее. Для этого достаточно присвоить значение True свойству Visible поля Заголовоки надписи Label4 втот момент, когда значение свойства Value кнопки КатЗ становится равным True. И наоборот, свойствам Visible поля и надписи следует присвоить значение False, когда свойству Value кнопки присваивается значе- ние False. Эти действия удобнее всего выполнять в процедуре события Change кнопки КатЗ. Откройте в окне кода данную процедуру и поместите в нее следующий текст. Private Sub КатЗ_СИапде() If КатЗ.Value = True Then Заголовок.Visible = True ’Поле становится видимым Label4.Visible = True Else Заголовок.Visible = False ’Поле становится невидимым Label4.Visible = False Заголовок.Value = ”” End If End Sub Обратите внимание на последнюю команду в операторе I f — с ее помощью при со- крытии поля Заголовок автоматически стирается его значение. Можно с уверенностью предположить, что если само поле в форме нам больше не требуется, то не потребуется и то значение, которое в него, возможно, было введено. Проверьте работу формы и убеди- тесь, что все происходит именно так, как было задумано. Однако опытный программист сразу заметит, что предложенное решение нельзя назвать оптимальным. Действительно, свойствам поля и надписи присваивается значение True, когда свойство Value кнопки КатЗ получает это же значение, и наоборот. Но тогда зачем же проверять, какое имен- но значение имеет данное свойство этой кнопки, — можно просто воспользоваться его Глава 10. Экранные формы и их элементы 247
текущим значением! Замените текст приведенной выше процедуры новым, как показано ниже, и убедитесь, что все прекрасно работает. Private Sub КатЗ-Change() Заголовок.Visible = КатЗ.Value Label4.Visible = КатЗ.Value Заголовок.Value = ’’’’ End Sub Правда, теперь содержимое поля Заголовок стирается дважды — как при его отобра- жении на экране, так и при сокрытии, но это совсем небольшая плата за столь простое и элегантное решение поставленной задачи. Флажки опций не потребуют от нас никаких дополнительных усилий — их работа нас вполне устраивает. А вот поле Недели и счетчик нуждаются в дополнительной функцио- нальности. Мы должны не только обеспечить изменение значения поля при щелчках на кнопках счетчика, но и реализовать ограничение, согласно которому значение в поле Недели может изменяться только от 1 до 5. Установка исходных значений в этих элемен- тах управления уже реализована нами выше, в процедуре сброса формы. Осталось позабо- титься о корректном изменении их значений. Поместите в процедуру обработки события Change счетчика SpinBtl следующий код (принцип его работы обсуждался выше). Private Sub SpinBtl_Change() If SpinBtl.Value = 6 Then SpinBtl.Value = 5 ’Число недель не может превышать 5 End If If SpinBtl.Value = 0 Then SpinBtl.Value = 1 ’Число недель не может быть меньше 1 End If Недели.Value = SpinBtl.Value End Sub Теперь осталось лишь реализовать функции командных кнопок Готово и Выход, после чего форма будет окончательно готова. Начнем с кнопки Выход. Пользователь должен щелкнуть на ней, чтобы завершить работу с формой. Предполагается, что он может сде- лать это в любой момент, независимо от текущего состояния остальных элементов управ- ления, причем никакого сохранения или иной обработки введенных в форму данных не предусматривается — они просто отбрасываются. В этом смысле поведение кнопки Выход должно повторять поведение кнопки Сброс. Иначе говоря, в процедуру МоиseMove кноп- ки Выход также следует поместить единственный оператор Очистка = True. Однако процедура Click этой кнопки должна обеспечивать совсем иную функциональность — работа формы завершается и она должна быть удалена с экрана. Этого можно достичь, если обратиться к методу Hide формы. Private Sub Выход_СИск () Форма!.Hide End Sub Кнопка Готово предназначена для фиксации введенной пользователем информа- ции. Однако в исходном состоянии формы она неактивна и, следовательно, недоступна пользователю. Когда же мы должны сделать ее активной? Тогда, когда вся необходимая информация уже будет введена пользователем в форму. О том, чтобы обязательные тек- стовые поля были заполнены, мы уже позаботились. Переключатель нас не интересует, 248 Часть 3. Более сложные аспекты работы на VBA
поскольку он всегда находится в одном из допустимых состояний. Это же можно сказать и о счетчике — он всегда содержит корректное значение, поэтому мы не станем дополни- тельно анализировать значение поля Недели. А вот состояние флажков нельзя оставлять без дополнительного контроля — если ни один из флажков не выбран, то объявление не попадет ни в один из номеров рекламного листка. Отсюда и ответ на интересующий нас вопрос: кнопка Готово должна активизироваться только после того, как будет установлен хотя бы один из флажков опций. Решение оказалось совсем простым — поместим опера- тор Готово. Enabled = True в процедуру обработки события Change каждого из трех флажков опций. Однако здесь есть подводный камень — если после установки одного из флажков пользователь случайно сбросит его и не заметит этого, то данные в форме окажут- ся в некорректном состоянии и либо кнопка вновь должна стать неактивной, либо щелчок на ней вместо фиксации данных должен вызывать появление предупреждающего сообще- ния. Поместим соответствующий код проверки в процедуру Click кнопки Готово. Private Sub Готово_СИск () If (День1.Value Or День2.Value Or ДеньЗ.Value) = False Then MsgBox "Укажите номера, в которых следует печатать объявление" День!.SetFocus Готово.Enabled = False Exit Sub End If 'Обработка введенных в форму данных । End Sub Как видите, если ни один из флажков не установлен, выводится предупреждающее сообщение, после чего фокус ввода перемещается на первый флажок, а кнопка Готово вновь становится неактивной. Если же хотя бы один флажок установлен, выполняются требуемые действия по обработке введенных в форму данных, например они записыва- ются в файл (подробнее об этом будет сказано в следующей главе). В любом случае обработка данных должна завершаться приведением формы в исходное со- стояние, т.е. выполнением тех же действий, которые осуществляются после щелчка на кнопке Сброс. Получается, что одни и те же действия должны выполняться в трех разных процеду- рах — это слишком расточительно. Поступим иначе. Выделите все операторы в процедуре Activate формы и скопируйте их в буфер обмена. Теперь выберите в левом списке окна кода значение (General) и введите под объявлением переменной Очистка оператор Private Sub Сброс_формы, а затем вставьте под ним текст из буфера. Редактор автоматически до- бавит оператор End Sub, и мы получим собственную процедуру, осуществляющую сброс формы. Наконец, замените все операторы в процедуре Activate формы одним оператором. Private Sub UserForm_Activate() Сброс_формы End Sub В процедуре Click кнопки Сброс замените все операторы, кроме последнего, опера- тором СбрОС—форМЫ. Private Sub C6poc_Click() Сброс_формы Очистка = True 'Отметка ситуации очистки формы End Sub Глава 10. Экранные формы и их элементы 249
Теперь осталось лишь поместить оператор Сброс_формы последним в процедуру Click кнопки Готово. Согласитесь, такой вариант предпочтительнее троекратного ду- блирования одного и того же кода. И наконец, чтобы придать нашей форме некоторую эстетичность, сделаем так, чтобы при помещении фокуса ввода в текстовое поле последнее меняло цвет фона с белого на светло- зеленый, а при потере фокуса белый фон восстанавливался. Для этого добавим в процеду- ру Enter каждого поля следующий код (не забывайте менять имя элемента управления!). Private Sub ЗаказчиК-Enter() Заказчик.BackColor = RGB(230, 256, 230) End Sub Чтобы белый цвет фона восстанавливался при переходе фокуса ввода к другому эле- менту управления, добавьте в процедуры Exit текстовых полей оператор (с соответствую- щим именем) Заказчик.BackColor = RGB(256, 256, 256) На этом создание формы можно считать завершенным. Окончательный вид формы с заполненными полями показан на рис. 10.41. Конечно, можно продолжить совершен- ствование ее внешнего вида, изменив стандартную цветовую гамму, подобрав рисунок для заполнения фона формы в целом или отдельных элементов управления, поместив пикто- граммы на кнопки и т.д. Однако того, что было сказано выше, вполне достаточно, чтобы читатель смог справиться с этой задачей самостоятельно. Рис. 10.41. Готовая форма с введенными данными Созданная нами форма имеет еще один побочный эффект. Он проявляется, если по- I | еле заполнения поля Заказчик нарушить предусмотренную последовательность обхо- ш/w да полея — например, щелкнуть мышью на одном из флажков опций. Кнопка Готово станет активной, хотя поля Телефон и Текст остались пустыми, а при щелчке на этой кнопке будет предпринята попытка обработать неполные данные. Выйти из этой ситуа- ции можно различными путями — например, добавить еще одну проверку в процедуру Click кнопки Готово с выводом сообщения и отказом от сохранения или же проверять состояние полей в процедуре Enter флажков опций и переключателей, принудитель- 250 Часть 3. Более сложные аспекты работы на VBA
но помещая фокус ввода в пустое поле. Решение этой проблемы мы оставим читателю в качестве самостоятельного упражнения — приведенных выше примеров достаточно, чтобы найти способ ее устранения. Запуск формы на выполнение Следующий шаг — написать программу, которая будет вызывать данную форму. Эту программу можно поместить в отдельном программном модуле, добавленном в шаблон Normal. Текст ее представлен ниже. Единственный оператор в этой процедуре представ- ляет собой вызов метода Show нашей формы. Public Sub Вывод_Формы1() Форма1.Show End Sub В начале главы говорилось, что для загрузки форм в память предназначен специаль- гТд ный оператор Load. Иначе говоря, правильнее было бы сначала поместить в проце- дуру оператор Load Форма 1 и только потом вызывать метод Show уже загруженной формы. Однако это необязательно — при обращении к методу Show некоторой формы VBA всегда предварительно проверяет, была ли она уже загружена в память, и если нет, то автоматически загружает ее. Этой возможностью мы и воспользовались при написании процедуры. Теперь можно закрыть редактор VBA — для работы с формой он нам больше не по- надобится. В окне Word выберите на ленте вкладку Вид и в группе Макросы выберите команду Макросы. На экране раскроется диалоговое окно Макросы (рис. 10.42). Вы- берите в списке доступных макросов значение Вывод_формы1 и щелкните на кнопке Выполнить — на экране раскроется созданная нами форма. Для ускорения запуска можно назначить макросу Вывод_формы1 комбинацию быстрых клавиш или создать для него кнопку на панели быстрого доступа. Эти операции должны быть знакомы пользователям Word, и здесь мы на них останавливаться не будем. Рис. 10.42. Запуск формы в MS Word из окна Макросы Глава 10. Экранные формы и их элементы 251
Резюме В этой весьма обширной главе мы познакомились с формами языка VBA. После обще- го ознакомления с этим понятием обсуждались элементы управления, которые можно по- местить в форму, чтобы придать ей необходимую функциональность. Набор стандартных элементов управления VBA достаточно велик, чтобы можно было реализовать практически любые требования к функциональным возможностям и оформлению форм. Обширный перечень свойств, методов и событий этих элементов управления позволяет организовать их взаимодействие именно таким образом, как это требуется для решения поставленной задачи, обеспечивая при этом необходимую эстетичность внешнего оформления формы. Тем не менее, доступный в VBA перечень элементов управления вовсе не ограничивается их стандартным набором — пользователь может подключить дополнительные библиоте- ки, содержащие множество полезных и удобных компонентов. Большое внимание было уделено практическим вопросам проектирования и создания форм в редакторе VBA, включая развернутый пример реализации формы — от постановки задачи и до проверки ее функционирования в приложении Word. Тестовые задания Ниже приведено несколько тестовых заданий, предназначенных для закрепления из- ложенного в этой главе материала. В каждом задании вам предлагается вопрос и несколь- ко вариантов ответа на него, один (или несколько) из которых является правильным, а остальные — нет. Укажите правильный ответ. 1. В языке VBA форма пользователя представляет собой: а) специализированную графическую подпрограмму; б) объект класса UserForm, отображающий на экране диалоговое окно формы; в) программный модуль, содержащий набор элементов управления; г) документ базового приложения MS Office. 2. Для добавления элемента управления в форму следует: а) указать требуемый элемент управления в процедуре обработки события Activate формы; б) щелкнуть на кнопке требуемого элемента на панели элементов и указать курсо- ром его расположение и размеры в форме; в) щелкнуть на кнопке требуемого элемента на панели элементов и перетащить его в форму мышью; г) выбрать команду Inserts Class module; д) щелкнуть на кнопке требуемого элемента на панели элементов, а затем щелкнуть в форме. 3. К общим свойствам большинства элементов управления можно отнести следующие: a) Enabled; б)SpicialEffeet; в) Left; г) Cancel; 252 Часть 3. Более сложные аспекты работы на VBA
д)Orientation; е) Visible; ж)Height. 4. Различные методы элементов управления позволяют программно выполнять над ними следующие операции: а) делать элемент управления невидимым; б) помещать на элемент управления фокус ввода; в) имитировать щелчок мышью на элементе управления; г) перемещать элемент управления в форме; д) изменять визуальные размеры элемента управления. 5. При перемещении курсора мыши над элементом управления для последнего гене- рируются следующие события: a) MouseDown; б) MouseUp; в) MouseMove; г) Click; д) DblClick. Глава 10. Экранные формы и их элементы 253
Глава 11 Работа с файлами В этой главе... ♦ Типы файлов ♦ Открытие и закрытие файлов ♦ Ввод и вывод данных в файлы последовательного доступа ♦ Работа с файлами произвольного доступа ♦ Бинарные файлы ♦ Операторы и функции управления файлами ♦ Работа с файлами как с объектами ♦ Резюме Работа с файлами и управление ими — это одна из интереснейших задач, с которыми встречается программист, в какой бы системе программирования он ни работал. В языке УВАдля этой цели используется мощный набор инструментов, включающий различные операторы, функции и методы для выполнения общих задач управления файлами. Что же такое файл? Файл — это реально существующая область данных на диске, в которой хранится та или иная информация. Если в программе при работе с данными возникает необходимость сохранить их надолго, то для этого существует всего лишь один доступный способ — сохранить данные в файле на диске. Затем, для того чтобы исполь- зовать эти данные повторно при дальнейшей работе, их нужно будет просто считать из созданного ранее файла. Отсюда следует, что работа с файлами характеризуется двумя аспектами — доступ к файлам и управление ими. Под доступом к файлам понимает- ся набор методов, используемых для чтения данных из файлов или записи их в файлы. Управление файлами включает такие действия, как копирование файлов, удаление неис- пользованных файлов для освобождения дисковой памяти, перемещение файлов с одного диска на другой и создание-удаление папок. Кроме того, управление файлами включает такие виды обработки, как организация просмотра списка файлов, сохраняемых в папке, с предоставлением сведений о размере файла, дате и времени его последней модифика- ции, а также обращения к нему. При программировании на языке VBA можно применить два подхода к получению доступа и управлению файлами. При первом подходе обработка файлов в VBA осущест- вляется по встроенной схеме, в рамках которой файлы не рассматривают как объекты. В этом случае для выполнения файловых операций используются обычные операторы и функции, а не свойства и методы. Второй подход — объектно-ориентированный; здесь файловая система рассматривается как объект верхнего уровня, с помощью которого манипулируют файловыми объектами более низких уровней, обращаясь к их свойствам и методам, предназначенным для обработки файлов. Выбор того или иного подхода к об-
работке файлов никоим образом не влияет на конечный результат, но определяет способ написания программ. Следует отметить, что для большинства задач, решаемых средствами VBA, предпочтительнее иметь дело с файловыми объектами, о чем будет сказано ниже. Типы файлов Работа с файлом в программе на языке VBA предусматривает выполнение следующих действий: открытие файла; чтение из файла или запись в файл; закрытие файла. Дополнительно следует отметить, что VBA допускает работу с тремя разными типами файлов, каждый из которых предназначен для обработки определенного типа данных, — это файл последовательного доступа, файл произвольного доступа и бинарный файл. Файл последовательного доступа представляет собой текстовый файл, состоящий из строк переменной длины, разделенных специальными символами. Эти строки принято назы- вать записями. Записи имеют переменную длину — иначе говоря, длина каждой записи не фиксирована, а определяется ее содержимым. Разделителем между последовательными записями (который определяет конец одной записи и начало другой) является символ возврата каретки/перевода строки (carriage retum/line feed — CRLF). Наличие в строке единственного символа CRLF обозначает пустую запись. В файле с последовательным доступом записи всегда читаются или записываются последовательно — одна задругой (от начала файла) в порядке их физического расположения. Числа в файлах с последователь- ным доступом представлены символьными величинами и хранятся как текст, т.е. значение 77,7 будет храниться в файле не в двоичном представлении, а как символьная величина "77.7". Текст в таком файле также сохраняется в виде последовательности символов. Файлы с произвольным доступом состоят из записей фиксированной длины. Размер записи в каждом файле указывается при его открытии, что позволяет определить рас- положение любой записи в файле непосредственно по ее номеру. Нумерация записей в файле с произвольным доступом всегда начинается с 1, что позволяет организовать не- посредственный доступ к каждой записи по ее номеру без предварительного считывания всех предыдущих записей. Например, в файле, состоящем из 50 записей, можно получить доступ к записи с номером 35 без предварительного чтения записей от 1-й до 35-й. В фай- лах с произвольным доступом могут сохраняться как текстовые данные, представленные в символьном формате, так и числовые данные, сохраняемые в двоичном формате. В файле с произвольным доступом каждая запись содержит фиксированное количе- ство байтов (или символов) и включает одно или несколько полей, каждое из которых также имеет фиксированную длину. Таким образом, размер записи равен сумме длин входящих в нее полей. В файлах с произвольным доступом не используются разделители, отмечающие конец одного поля и начало другого. Так как отдельные поля и сами записи имеют фиксированную длину, совсем не сложно вычислить, где начинается требуемое поле или очередная запись. Например, если размер записи составляет 24 байта, то 30-я запись в файле начинается с байта с номером 24*(30 - 1) + 1 = 697. Записи в режиме про- извольного доступа могут содержать поля с любым типом данных VBA фиксированной длины или типом данных, определенным пользователем и содержащим исключительно данные типов, имеющих фиксированную длину. Глава 11. Работа с файлами 255
В бинарных файлах данные хранятся как сплошной поток байтов. В файлах этого типа обрабатываются отдельные байты файла, в них нет записей или полей, нет символов- разделителей. Бинарный доступ можно использовать для чтения и изменения любых типов файлов на диске, а также для хранения данных программ. В связи с отсутствием в бинарном файле записей или какой-либо другой структуры, вся ответственность за контроль над данными и их хранением полностью ложится на программы, которые их обрабатывают. Открытие и закрытие файлов Прежде чем приступать к работе с файлом, а именно: считывать из него или записы- вать в него информацию, файл необходимо открыть. Для этого в языке VBA существует оператор Open (Открыть), который открывает файл для ввода-вывода информации. Син- таксис этого оператора следующий. Open Путь For Режим [Access Доступ] [Блокировка]_ As [#]Номер—Файла [LEN=Длина] Здесь Путь (Pathname) — обязательный аргумент, определяющий полный путь (с указани- ем диска и каталога) и название файла, который необходимо открыть. Полный путь дол- жен быть указан как строчное выражение. При записи оператора эту строку необходимо заключать в кавычки. Если в аргументе Путь не указана информация о диске и пути, файл открывается в текущей папке. Режим (Mode) — это обязательный аргумент, задающий режим доступа к файлу. До- пустимые значения для этого аргумента кратко представлены в табл. 11.1. Доступ (Access) — это необязательный аргумент. Его значением является ключевое слово, определяющее тип операций, которые будут выполняться над файлом. Допустимые значения для аргумента Доступ представлены в табл. 11.2. Блокировка (Lock) — это необязательный аргумент, определяющий возможности доступа к данному файлу для других процессов. Допустимые значения этого аргумента кратко описываются в табл. 11.3. Номер-Файла (Filenum) — это обязательный аргумент, он может принимать любое целое значение в диапазоне от 1 до 511, которое еще не было присвоено другому файлу. Обычно (но не обязательно) в операторе открытия перед номером файла ставят знак #. Длина (Reclen) — необязательный аргумент, задаваемый как целое значение, опреде- ляющее для файла длину его записи в байтах. Максимальное значение этого аргумента равно 327 67. Для файлов с произвольным доступом это значение равно длине записи, а с последовательным доступом — размеру буфера. Следует отметить, что этот аргумент нельзя применять к бинарным файлам. Таблица 11.1. Допустимые значения аргумента Режим в операторе Open Значение Режим доступа к файлу е операторе Open Выполняемые действия APPEND Последовательный доступ к файлу. Если файл, местоположение и имя которого определяются значением аргумента pathname, уже существует, то новые данные добавляются в его конец. Если такого файла нет, он создается заново Данные сохраняются в виде серии символов. Применяется для тек- стовых файлов, а также для файлов баз данных в кодировке ASCII при использовании в качестве раздели- телей запятых 256 Часть 3. Более сложные аспекты работы на VBA
Окончание табл. 11.1 Значение Режим доступа к файлу е операторе Open Выполняемые действия INPUT Последовательный доступ. Только для чтения данных из файла. Если файла, местоположение и OUTPUT имя которого определяются значением аргумента pathname, не существует, при выполнении опе- ратора фиксируется ошибка Последовательный доступ. Только для записи данных в файл. Если файл, местоположение и имя которого определяются значением аргумента pathname, уже существует, то этот файл удаля- ется и создается новый файл. Если такого файла нет, он создается в указанном месте RANDOM Произвольный доступ. Для чтения и записи дан- Данные сохраняются в виде записей ных в файл. Если файла, местоположение и имя фиксированной длины, при этом которого определяются значением аргумента чтение и запись могут выполняться pathname, не существует, он создается заново, до тех пор, пока известно текущее Данный режим доступа используется по умолча- положение в файле нию, если аргумент mode не задан BINARY Бинарный доступ. Для чтения и записи данных в Данные сохраняются в виде потока файл. Если файла, местоположение и имя которо- байтов го определяются значением аргумента pathname, не существует, то файл создается заново Таблица 11.2. Допустимые значения аргумента Доступ в операторе Open Значение Описание READ WRITE READ WRITE Файл открывается только для чтения Файл открывается только для записи Файл открывается для чтения и записи. Этот режим распространяется только на файлы с произвольным доступом, бинарные файлы и последовательные файлы, открытые в режиме append Таблица 11.3. Допустимые значения аргумента Блокировка в операторе Open Значение Описание SHARED Данный файл может считываться и записываться любым процессом LOCK READ Данный файл не может считываться никаким другим процессом. Программа откроет файл в режиме LOCK read только в том случае, если к этому моменту доступ на его чтение еще не получил никакой другой процесс LOCK write Никакой другой процесс не может записывать данные в этот файл. Програм- ма откроет файл в режиме LOCK write только в том случае, если к этому моменту доступ на его запись еще не получил никакой другой процесс LOCK read write Никакой другой процесс не может читать или записывать данные в файл. Программа откроет файл в режиме LOCK read write только в том случае, если к этому моменту доступ на его чтение или запись еще не получил ника- кой другой процесс и для него не установлен режим блокировки на чтение или запись Глава 11. Работа с файлами 257
Ниже приведен пример стандартной процедуры открытия файла. Здесь для получе- ния текущего значения свободного номера файла в программе используется стандартная функция FreeFile (). Если ее аргумент равен 0, возвращается наименьшее свободное значение в диапазоне от 1 до 2 5 5, если аргумент равен 1 — в диапазоне 256-511. Dim Номер_файла As Integer Номер_файла = FreeFile(0) ’Текущий свободный номер файла OPEN "с:\Мои документы\Объявления. txt’’ For APPEND As #Номер_файла После того как работа с файлом завершена, его следует закрыть. При закрытии фай- ла все его измененные данные, временно сохраняемые в файловом буфере (область для временного хранения данных), записываются на диск, а соответствующий файлу номер и другие занимаемые им ресурсы освобождаются и становятся доступными для других приложений. В языке VBA для закрытия файла, открытого с помощью оператора Open, используется оператор Close. Чтобы закрыть конкретный файл, необходимо выполнить оператор Close #Filenum, где аргумент #Filenum определяет его файловый номер. Можно закрыть сразу несколько файлов, указав их номера в качестве аргументов, отде- ляемых запятыми: Close # 1, #2. Для закрытия всех открытых в программе файлов ис- пользуется оператор Close без аргументов. Если закрываются файлы, открытые в режиме записи output или append, то содержимое их буферов вывода переписывается в буфер операционной системы, после чего все буферное пространство, связанное в программе с этими файлами, удаляется и связь файлов с их файловыми номерами прекращается. При выходе из VBA-программы все открытые в ней файлы автоматически закрываются. В качестве примера ниже приведен текст процедуры, в которой три файла открывают- ся для записи. Путь содержит только имя файла, поэтому они будут созданы в каталоге, который является текущим для того приложения, где открыт редактор VBA. В каждый файл записывается текстовая строка, после чего файлы закрываются. Sub OpenProbaO Dim N, FileFl For N = 1 To 3 FileFl = ’’PROBA” & N ’ создать имя файла Open FileFl For Output As #N ’ открыть файл Print #N, "Запись в файл ’’ & FileFl ’ запись строки в файл Next N Close ’ закрытие всех файлов End Sub Ввод и вывод данных в файлы последовательного доступа Для записи данных в файл последовательного доступа используется оператор Write #. Синтаксис этого оператора следующий. Write #Номер—Файла, [Список_Вывода] Здесь Номер_Файла — это обязательный аргумент, указывающий номер файла, который использовался при открытии данного файла в операторе Open. Файл следует открыть в 258 Часть 3. Более сложные аспекты работы на VBA
режиме APPEND или OUTPUT. СписоК—Вывода — это необязательный аргумент, представ- ляющий собой одно или несколько числовых или строковых выражений, записываемых в файл. Если аргумент Список_Вывода не задан, то в файл записывается пустая запись, т.е. пустая строка. При записи информации в файл оператор Write # автоматически вставляет запятые между выводимыми элементами списка и заключает строковые данные в кавычки. Следует также отметить, что при написании программного кода с использованием оператора Write # необходимо (во избежание проблем) учитывать некоторые особен- ности этого оператора. Все числовые данные записываются в файл с десятичным разделителем в виде точки. Все булевы значения записываются как #TRUE# или # FALSE#. Все даты записываются с помощью универсального формата дат. Если аргумент Список_Вывода равен значению Null, в файл выводится #Null#. Значение ошибок записывается в виде #Еггог код_ошибки. Поскольку символ двойных кавычек используется при выполнении оператора Write yl # как разделитель поля, его нельзя включать в данные, сохраняемые с помощью этого ' оператора. Для считывания данных из файла последовательного доступа используется оператор Input #. Этот оператор считывает данные и присваивает их указанным переменным. Синтаксис этого оператора следующий. Input #Номер_Файла, Список_Переменных Здесь Номер_Файла — это обязательный аргумент, указывающий номер файла, кото- рый использовался при открытии данного файла в операторе Open. Аргумент Список_ Переменных — обязательный, представляет собой список из одной или нескольких пере- менных, которым в качестве значений присваиваются данные, прочитанные из файла. Если такой список содержит несколько имен переменных, они должны отделяться за- пятыми. Данные, считываемые оператором Input #, — это обычно те данные, которые были записаны в этот файл оператором Write #. Оператор I при t # считывает из файла столько полей очередной строки, сколько переменных указано в его списке переменных. Например, приведенный ниже оператор считывает первые три поля из очередной строки файла, открытого с номером 1, и присваивает их в качестве значений переменным Wl, W2 и W3 соответственно. Input #1, Wl, W2, W3 Следует отметить, что если оператор Input # читает данные в переменную строкового типа, то конец поля определяется одним из следующих способов: двойными кавычками, если поле начинается с двойных кавычек; запятой, если поле не начинается с двойных кавычек; символом возврата каретки CR/LF. Если оператор I приt # читает данные в числовую переменную, то конец поля опреде- ляется запятой, одним или несколькими пробелами или символом CR/LF. Глава 11. Работа с файлами 259
Пример записи данных в файл и считывания этих данных из файла с последующим выводом их на экран приведен в листинге 11.1. Вывод данных осуществляется с помощью метода Debug. Print, отображающего содержимое указанной при его вызове перемен- ной в окне Immediate (команда View^lmmediate Window). Результат выполнения подпро- граммы Test приведен на рис. 11.1. Листинг 11.1. Запись данных в последовательный файл и считывание их из этого файла Sub Test() ’ Запись данных в последовательный файл с именем File Dim StrSl Open ’’File” For Output As #2 Write #2, "Придя на работу," Write #2, "не забудьте поздороваться с сотрудниками," Write #2, "а уходя, не забудьте попрощаться с ними." Close #2 ’ Считывание данных и вывод их на экран Open "File" For Input As #2 Do While Not EOF(2) Input #2, StrSl Debug.Print StrSl Loop Close #2 End Sub Puc. 11.1. Окно Immediate с результатами выполнения подпрограммы Test Для записи текста в файл последовательного доступа также может использоваться оператор Print #. В отличие от оператора Write #, этот оператор не разграничивает поля запятыми и не заключает строки в двойные кавычки, а просто записывает в файл указанный текст без каких-либо изменений или добавлений. Синтаксис этого оператора следующий. Print #Номер_Файла, [Список_Вывода] Здесь #Номер_ Файла — это обязательный аргумент, указывающий номер файла, который был присвоен ему при открытии (в режиме OUTPUT или APPEND). Список_Вывода — это необязательный аргумент, представляющий собой список из одного или нескольких выражений-строк, записываемых в файл. Если список содержит несколько выражений, то они должны отделяться либо запятой (при этом данные следующего выражения выво- дятся в ту же строку, но в следующей зоне печати — по принципу табуляции), либо точкой с запятой (при этом данные следующего выражения выводятся в ту же строку непосред- 260 Часть 3. Более сложные аспекты работы на VBA
ственно после предыдущих). При отсутствии в списке вывода разделителей в виде запя- той или точки с запятой (используется разделитель “пробел”) вывод данных очередного выражения осуществляется в новую строку. Кроме того, в аргументе Список_Вывода допускается использование функции Sps (п), предназначенной для вставки п пробелов в строку, или функции Tab (п), позволяющей переместить курсор в столбец с номером п. Если аргумент Список_Вывода в операторе Print # не задан, в файл записывается пустая строка. Оператор Line Input # предназначен для чтения из последовательного файла по одной строке текста. Этот оператор всегда читает из файла целую строку текста и помеща- ет полученные данные в указанную переменную. Оператор имеет следующий синтаксис. Line Input #Номер_Файла, Переменная Здесь Номер_Файла — обязательный аргумент, указывающий номер, соответствующий данному файлу при его открытии в режиме INPUT. Обязательный аргумент Переменная определяет имя переменной типа String, в которую записывается считанная строка текста. При многократном выполнении оператор Line Input # последовательно читает строки из указанного файла, одну за другой. Поэтому считывание всего файла в построч- ном режиме организуется с помощью открытия файла и выполнения для него оператора Line I nput # до тех пор, пока не будет достигнут конец этого файла. Пример подобной процедуры приведен в листинге 11.2, а результат ее выполнения — на рис. 11.2. Листинг 11.2. Запись данных в последовательный файл и построчное их считывание Sub Testl() ’ Запись данных в последовательный файл File Dim StrSl Open ’’File” For Output As #3 Print #3, "Приходя на работу, ’’; Print #3, "не забудьте поздороваться с сотрудниками," Print #3, "а уходя, не забудьте попрощаться с ними." Close #3 ’ Считывание данных и вывод Open "File" For Input As Do While Not EOF(3) Line Input #3, StrSl Debug.Print StrSl Loop Close #3 End Sub их на экран #3 ’ открытие файла ' цикл чтения до конца файла ’ считать строку данных ’ вывод на экран ’ закрытие файла Рис. 11.2. Окно Immediate с результатами выполнения подпрограммы Testl Глава 11. Работа с файлами 261
Обратите внимание на то, что в этом случае данные выведены в окне Immediate в две строки, хотя они записывались с помощью трех операторов Print #. В чем же причина? Да в том, что в первом операторе Print # список выводимых переменных заканчивается точкой с запятой, а это указывает на то, что следующие выводимые в файл данные долж- ны быть помещены в ту же строку. Работа с файлами произвольного доступа Поскольку файл с произвольным доступом состоит из записей фиксированной длины, программа, зная эту длину, может извлекать ту или иную запись непосредственно по ее номеру. Именно поэтому для разграничения записей в файле с произвольным доступом не требуется каких-либо специальных символов. Записи в таком файле всегда последова- тельно пронумерованы, с первой до последней записи. Так, если каждая запись в файле имеет длину 10 байт, то байты данных в файле от 1 до 10 содержат первую запись (позиции байтов в файле всегда начинаются с 1), а запись с номером 5 занимает байты файла от 41 по 50. Поскольку в файле произвольного доступа записи всегда упорядочены по номеру записи, можно быстро перемещаться по файлу для выбора требуемой записи, при этом предыдущие записи пропускаются. Максимальное количество записей, которое может быть сохранено в файле с произ- вольным доступом, составляет 2 147 483 647. Предполагается, что в файле с произвольным доступом каждая входящая в него запись состоит из одного или нескольких полей. Структура полей в записях фиксирована — во всех записях файла поля расположены в одной и той же последовательности и соответ- ствующие поля имеют одну и ту же длину. Структура файла с произвольным доступом определяется при создании файла. Обычно это делается с помощью ссылки на определен- ный пользователем тип (user-defined type), который подробно рассматривался в главе 4. При создании файла произвольного доступа следует указать длину (параметр Len) каж- дой помещаемой в него записи. Это же значение длины записи впоследствии должно ука- зываться при каждом открытии уже созданного файла. Необходимо помнить и внимательно следить за тем, чтобы выводимые в файл записи данных не превышали установленную дли- ну, поскольку лишняя информация в конце записи будет просто отрезана, без каких-либо дополнительных предупреждений. Однако это не распространяется на операцию считы- вания данных из файла. Если считывать запись в переменную большей, чем требуется, длины, помещенные в нее данные просто будут занимать не все отведенное для них место. 9 При работе над проектом удобно создать отдельный файл, в котором хранится инфор- мация о структурах всех используемых в нем файлов произвольного доступа: длины записей, структуры и заголовки их полей. Следует отметить, что, в отличие от файла последовательного доступа, при открытии файла произвольного доступа указывать специально, открывается он для ввода или выво- да информации, не требуется. После открытия файла с произвольным доступом он всегда становится доступным как для чтения, так и для записи. Запись данных в файл с произ- вольным доступом осуществляется с помощью оператора Put. Синтаксис этого оператора следующий. Put #Номер_Файла, [Номер_3аписи] , Имя_Переменной 262 Часть 3. Более сложные аспекты работы на VBA
Здесь Номер_Файла — это обязательный аргумент, задающий тот номер, который был присвоен файлу с произвольным доступом при его открытии. Номер_3аписи — это необязательный аргумент, определяющий номер записи в файле, в которой должны быть сохранены данные. Если этот аргумент опущен, то данные автоматически помещаются в следующую запись файла, при этом номер текущей записи определяется последним вы- полненным оператором Get или Put либо задается как результат выполнения функции Seek. Если файл был только что открыт, данные записываются в его первую запись. Если значение аргумента Номер_3аписи указывает на запись, которая уже существует в файле, то прежние данные в записи заменяются новыми. Аргумент Имя_Переменной определяет имя переменной, содержащей те данные, которые необходимо записать в файл. Следует помнить, что в случае отсутствия второго аргумента вместо него нужно ставить запятую. Put #1,,Строка_отчета Если необходимо добавить одну или несколько записей в уже существующий файл, то все новые записи должны быть помещены в конец файла. Для определения количества за- писей в файле используется функция Lof (), возвращающая значение типа Long, равное общей длине в байтах указанного файла, который должен быть предварительно открыт с помощью оператора Open. Для определения размера закрытого файла следует использо- вать функцию FileLen (), которая выполняет те же функции, что и Lof (), но для закры- того в данный момент файла. Зная длину каждой записи файла, количество записей в нем легко вычислить с помощью операции деления. Например, пусть Номер_Файла — это номер уже открытого файла с произвольным доступом, тогда количество записей в нем вычисляется так: NumRecords = Lof(Номер_Файла) \ Len(item) Здесь i tem — это тип данных, определенный пользователем и соответствующий структуре записи файла. Далее, для добавления новой записи в конец файла, необходимо выполнить следующий оператор. Put #Номер_Файлаf NumRecords + 1, item Для чтения данных из открытого файла с произвольным доступом используется опе- ратор Get. Этот оператор считывает данные и помещает их в указанную переменную. Синтаксис этого оператора следующий. Get #Номер—Файла, [ Номер_3аписи] , Имя_Переменной Здесь Номер_Файла — это обязательный аргумент, задающий тот номер, который был присвоен файлу с произвольным доступом при его открытии. Номер_3аписи — необя- зательный аргумент, определяющий номер записи в файле, которая должна быть счита- на. Если этот аргумент опущен, считывается следующая запись файла, при этом номер текущей записи определяется последним выполненным оператором Get или Put либо задается как результат выполнения функции Seek. Если файл только что был открыт, считывается первая запись. Аргумент Имя_Переменной определяет имя той переменной, в которую считываются данные из файла. При отсутствии второго аргумента вместо него нужно ставить запятую. Get #1,,Строка_отчета Любые данные, которые можно считать оператором Get, должны быть предварительно записаны в файл с помощью оператора Put. Глава 11. Работа с файлами 263
Следует отметить, что для каждого открытого файла с произвольным доступом язык VBA поддерживает файловый указатель, контролирующий текущую позицию в файле. Иначе говоря, он определяет номер следующей записи файла, которая будет считана или записана. В процессе чтения и записи данных файловый указатель изменяется следую- щим образом: увеличивается на 1 при каждом вызове оператора Get или Put без аргумента Номер_ За писи', принимает значение Номер_3аписи + 1, если оператор Get или Put вызывается с указанием аргумента Номер_3аписи. В табл. 11.4 приведены некоторые примеры работы с файловыми указателями файлов произвольного доступа в программах на языке VBA. Таблица 11.4. Работа с файловыми указателями Оператор или функция Описание Seek(Номер_Файла) Возвращает текущую позицию файлового указателя для файла с номе- (функция) ром Номер_Файла Seek Номер_Файла, Устанавливает файловый указатель файла с номером Номер_ Файла на Номер_записи (оператор) значение Номер_записи. Если указанное значение аргумента Номер_ записи превышает размеры файла, файл соответствующим образом увеличивается в размерах. Если значение аргумента Номер_записи равняется 0 или отрицательное, оператор выдает ошибку Loe (Номер_Файла) Возвращает позицию последней прочитанной или записанной записи. Если файл был только что открыт, оператор возвращает значение 0 Бинарные файлы В бинарных файлах данные хранятся как сплошной поток байтов. В таком файле нет записей и полей. В принципе, бинарный файл можно понимать как частный случай фай- ла произвольного доступа, когда размер его записи принимается равным одному байту. Следует заметить, что при работе с бинарным файлом программист вынужден постоянно контролировать, что и где сохраняется в этом файле. Все бинарные файлы, как и файлы произвольного доступа, имеют соответствующий файловый указатель. Однако, в отличие от файла произвольного доступа, где файло- вый указатель оперирует записями, указатель в бинарном файле отмечает ту байтовую позицию в файле, начиная с которой будет выполняться чтение или запись. При этом любой бинарный файл рассматривается как содержащий п байт с номерами позиций от 1 до п. Работа с файловыми указателями в бинарных файлах во многом напоминает приме- нение файлов с произвольным доступом. При первом открытии файла указатель уста- навливается на позицию 1. После выполнения очередной операции (чтения или записи) указатель устанавливается на байт, расположенный непосредственно следующим за по- следним прочитанным или записанным байтом данных. Изменить значение файлового указателя или определить его значение можно с помощью того же оператора Seek или функций Seek и Loe, которые применяются и для файлов с последовательным доступом. VBA знает режим доступа, с которым был открыт данный файл, и правильно интерпрети- рует используемые варианты функций Seek и Loe, организуя работу с байтами для бинар- 264 Часть 3. Более сложные аспекты работы на VBA
ных файлов или с записями для файлов с произвольным доступом. Для бинарного файла можно также использовать функцию Eof, чтобы определить, был ли достигнут конец файла. Для записи данных в бинарный файл используется оператор Put. Для чтения данных из бинарного файла используется оператор Get. Это те же самые операторы, которые используются при работе с файлами произвольного доступа. Они по-разному интерпре- тируются, в зависимости от того режима, в котором был открыт файл. Синтаксис этих операторов при работе с бинарными файлами следующий. Get #Номер_Файла, Номер_Позиции, Переменная Put #Номер_Файла, Номер_Позиции, Переменная Здесь Номер_Файла — обязательный аргумент, определяющий номер файла, открытого в бинарном режиме. Аргумент Номер_Позиции — необязательный; задает номер байта (т.е. то место в файле, с которого считываются или записываются данные). Если этот ар- гумент не указан, то используется текущее значение файлового указателя данного файла. Аргумент Переменная — обязательный, это любая переменная VBA, в которую помеща- ются считанные данные или значение которой помещается в файл. Операторы Get и Put автоматически считывают из файла или записывают в файл количество байтов, содержа- щихся в указанной переменной. Put #1, 1200z StrVol ' записывает переменную StrVol в ’ двоичный файл начиная с позиции 1200 Get #1, 1200, StrVol ' читает в переменную StrVol строку ' данных из двоичного файла с позиции 1200 Если аргумент Переменная определяет строку переменной длины, то количество пере- данных байтов равно количеству символов, содержащихся в этой переменной. /"Л Следует отметить, что в бинарных файлах можно хранить данные любого типа. Контроль за их реальной структурой и расположением в файле в этом случае полно- стью возлагается на программу. При работе с бинарными файлами необходимо учитывать еще несколько важных моментов. Если в конец существующего бинарного файла нужно добавить новые данные, для перемещения указателя на конец файла следует выполнить оператор Seek #Номер_Файла, Lof (Номер_Файла) + 1. Если новые данные записываются в уже существующий бинарный файл начиная с некоторой позиции и до текущего конца файла, то они будут записаны поверх существующих данных. Если новые данные записываются с позиции указателя, находящегося за пределами нынешнего конца файла, файл будет расширен до новой длины. Однако та часть файла, которая находится между предыдущим концом файла и началом вновь за- писанных данных, будет содержать неопределенные значения. При попытке чтения данных с позиции указателя, выходящей за границы файла, сообщение об ошибке не выдается, но полученные в результате данные будут бес- смысленными. Глава 11. Работа с файлами 265
Операторы и функции управления файлами В языке VBA управление файлами и доступ к их данным могут выполняться с помо- щью операторов и функций. Список соответствующих операторов и функций приведен в табл. 11.5, некоторые из них мы рассмотрим подробнее. При записи аргументов функций не забывайте заключать символьные значения таких аргументов, как путь, в кавычки. Таблица 11.5. Операторы и функции, предназначенные для управления файлами и доступа к ним Функция или оператор Тип Выполняемые действия (для операторов) и возвра- щаемые значения (для функций) RmDir (путь) Оператор Удаляет заданную папку MkDir (путь) Оператор Создает заданную папку ChDir(путь) Оператор Делает указанный путь активным ChDrive(имя_ диска) Оператор Делает указанный диск активным CurDir Функция Возвращает текущий путь (диск и имя каталога) в виде строки Dir (путь) Функция Возвращает имя первого файла или каталога, соответствую- щего аргументу путь. Последний может содержать символы групповой подстановки ? и * FileAttr(номер_ файла) Функция Возвращает информацию об открытом файле номер_файла, а именно значение, указывающее на его режим: 1 — INPUT, 2 - OUTPUT, 4 - RANDOM, 8 - APPEND, 32 - BINARY FileCopy (источник, цель) Оператор Копирует дисковый файл, определяемый аргументом источник, в файл, определяемый аргументом цель. По- следний может задавать путь, имя файла или и то и другое одновременно FileDateTime(путь) Функция Возвращает значение типа Date с датой и временем создания или последнего изменения файла, определяемого аргумен- том путь FileLen(путь) Функция Возвращает длину (в байтах) файла, заданного аргументом путь GetAttr(путь) Функция Возвращает целое значение, определяющее статус атрибутов файла или папки, заданных аргументом путь Kill (путь) Оператор Удаляет с диска один или несколько указанных файлов (аргумент путь может содержать символы групповой под- становки ? и *) MkDir путь Оператор Создает новый каталог, определяемый аргументом путь Name старый_путь As новый_путь Оператор Переименовывает дисковый файл или папку, заданную аргу- ментом старый_путь, в аргумент новый_путь RmDir путь Оператор Удаляет каталог, определяемый аргументом путь SetAttr путь, а трибуты Оператор Устанавливает заданные атрибуты дискового файла, указан- ного аргументом путь. Аргумент а трибуты задает числовое значение, являющееся суммой устанавливаемых атрибутов. VBA предоставляет стандартные именованные константы для каждого из атрибутов 266 Часть 3. Более сложные аспекты работы на VBA
Поиск файлов и управление их атрибутами Каждый файл, который сохраняется на любом из дисков Windows, имеет свои атри- буты. Атрибуты файла в среде Windows и DOS указывают, какие действия по управлению файлами допускаются для конкретного файла. При создании пользователем или програм- мой нового файла операционная система Windows записывает в каталог информацию об атрибутах этого файла, которые являются частью информации файла. Атрибуты файла, подобно свойствам объекта, описывают определенные характеристики файла, которыми он обладает. Обычно пользователю нет необходимости заботиться о значениях атрибутов файлов, так как система Windows автоматически обновляет и сохраняет в оглавлении дис- ка информацию об атрибутах файла вместе с информацией о его имени, размере, дате и времени создания. Для определения различных характеристик файла в Windows используется семь атрибутов. Archive — этот атрибут указывает, вносились ли в данный файл изменения со вре- мени его последнего архивирования той или иной программой резервного копиро- вания. Наличие этого атрибута указывает на необходимость повторного создания резервной копии для этого файла. Отсутствие атрибута Archive означает, что он не изменялся со времени его последнего резервного копирования. Directory — этот атрибут означает, что данный файл является каталогом или подкаталогом. Атрибут Directory указывает Windows о наличии в данном фай- ле управляющей информации о других файлах и одновременно запрещает его переименовывать, копировать или удалять, пока из него не будут удалены все со- храняемые в нем файлы. Hidden — этот атрибут означает, что данный файл должен быть скрыт и Windows не следует показывать сведения о нем при отображении данных о содержимом того каталога, в котором он располагается. Normal — этот атрибут означает отсутствие у файла каких-либо специальных атрибутов. В этом случае дополнительно допускается только наличие атрибута Archive, указывающего на необходимость повторного резервного копирования данного файла. Read Only — наличие этого атрибута означает, что данный файл доступен толь- ко для чтения. При наличии у файла атрибута Read Only операционная система Windows не позволит переименовывать, копировать или удалять этот файл. System — этот атрибут означает, что данный файл является частью установленной на компьютере операционной системы Windows. При наличии у файла этого атри- бута операционная система Windows не позволит переименовывать, копировать или удалять этот файл. Volume Label — этот атрибут указывает, что данный файл является меткой тома диска, т.е. он содержит имя, присвоенное разделу жесткого диска (или дискете) при его форматировании. Каждый отдельный атрибут файла Windows представляется уникальным числом, кото- рое сохраняется вместе с информацией об имени и размере файла. При наличии у файла нескольких атрибутов операционная система Windows просто складывает эти кодовые числа и сохраняет их сумму. В табл. 11.6 представлены коды отдельных атрибутов файлов и внутренние константы языка VBA для этих кодов. Глава 11. Работа с файлами 267
Таблица 11.6. Константы атрибутов файла VBA Константа Значение Атрибут vbNormal 0 Normal vbReadOnly 1 Read Only vbHidden 2 Hidden vbSystem 4 System vbVolume 8 Volume Label vbDirectory 16 Directory vbArchive 32 Archive Для определения атрибутов некоторого файла в языке VBA используется функция GetAttr (), которая имеет следующий синтаксис. GetAttr (путь) Здесь путь — это обязательный аргумент, определяющий путь (это может быть имя файла, каталог или полный путь с буквой диска) и представленный любым строковым выраже- нием языка VBA. Возвращаемое функцией GetAttr значение представляет собой сумму соответствующих числовых кодов имеющихся у файла атрибутов (см. табл. 11.6). При ис- пользовании этой функции надо помнить, что значение, которое определяет состояние атрибутов файла и которое VBA сохраняет в каталоге, является суммой всех кодовых чисел каждого из атрибутов данного файла. Что же касается переменных, которые используются для сохранения кодов атрибутов, то их следует объявлять как переменные типа Integer, так как кодовое число атрибута файла всегда находится в диапазоне допустимых значений для типа Integer. Для изменения атрибутов файла используется оператор SetAttr, который имеет сле- дующий синтаксис. SetAttr путь, атрибуты Здесь путь — это обязательный аргумент, определяющий путь (это может быть имя фай- ла, каталог или полный путь с буквой диска) и представленный любым строковым выра- жением языка VBA. Обязательный аргумент а трибуты — это числовое выражение (число между 1 и 2 55), заданное как отдельное кодовое число требуемого атрибута файла или как сумма кодовых чисел атрибутов, если у данного файла их несколько. SetAttr ”D:\Начисление зарплаты\Выплаты.xls”, vbHidden SetAttr "D:\Начисление зарплаты\Выдано\Вьшлаты.xls”, _ vbHidden + vbReadOnly В аргументе атрибуты можно использовать любые из именованных констант, при- веденных в табл. 11.6, кроме vbVolume и vbDirectory. Для добавления нового атрибута файла к уже имеющемуся набору его атрибутов це- LJ лесообразно использовать логический оператор Or. Применение оператора Or для Ь объединения атрибутов файла в единое числовое значение с помощью побитовой опе- рации исключает любые проблемы, связанные с использованием арифметического сложенйя числовых констант для объединения новых атрибутов с уже имеющимися. В частности, значение 1 будет результатом вычисления выражения 0 Or 1, а также вы- ражения 1 Or 1. Поэтому с помощью оператора Or очень просто и совершенно безо- пасно объединять новый атрибут файла с уже имеющимся у него набором атрибутов — достаточно воспользоваться выражением типа OldAtt г Or vbArchive. 268 Часть 3. Более сложные аспекты работы на VBA
Работа с файлами как с объектами Выше мы уже говорили о том, что VBA позволяет работать с файлами как с объектами и манипулировать файловыми объектами с помощью их свойств и методов. Эта возмож- ность обеспечивается соответствующей внешней объектной библиотекой — Microsoft Scripting Runtime, — которая содержит основные средства, необходимые для работы с файлами как с объектами. Доступ к файлам Если в программе предполагается работать с файлами как с объектами, то, прежде чем создавать соответствующий программный код, в VBA-проект нужно добавить ссылку на библиотеку Microsoft Scripting Runtime — при условии, что указанная библиотека установ- лена на компьютере. Библиотека Microsoft Scripting Runtime представляет собой файл с именем SCRRUN. DLL и после установки находится в папке Windows\System. Эта библиотека устанавливается автоматически при установке Windows 98 или Windows ХР с дополнением Option Pack. Убедившись, что в вашей системе библиотека Microsoft Scripting Runtime установлена, добавьте ссылку на нее в каждый проект, в котором предполагается ее использовать. Для этого необходимо выполнить следующие действия. 1. В окне проводника проектов выберите проект. 2. Выберите команду меню Tools'^References, откроется диалоговое окно References (Ссылки). 3. В списке Available References этого диалогового окна найдите значение Mi- crosoft Scripting Runtime и установите флажок, соответствующий этому пункту (рис. 11.3). 4. Закройте диалоговое окно References, щелкнув на кнопке ОК. References VBAProject Available References: □ Microsoft Outlook 14.0 Object Library □ Microsoft PowerPoint 14.0 Object Library □ Microsoft Remote Data Object 2.0 □ Microsoft Remote Data Services 2.7 Library О Microsoft Remote Data Services Server 2.7 Library □ Microsoft Rendezvous control 1.0 Type Library □ Microsoft Script Control 1.0 3] Priority □ Microsoft Scnptiet Library □ Mrcrosoft Sdpblb 1.0 Type Library □ Microsoft Shell Controls And Automation □ Microsoft Smart Tags 2.0 Type Library □ Microsoft Soap Type Library П Microsoft Soeech Obiect Library Microsoft Scripting Runtime Location: C:\WWOWStoystem32teCTrun.dH Language: Standard Puc. 11.3. Добавление в проект ссылки на библиотеку Microsoft Scripting Runtime Глава 11. Работа с файлами 269
Указанные действия должны быть выполнены для каждого проекта, использующего библиотеку Microsoft Scripting Runtime. Помните, что только после выбора этой библио- теки типов в диалоговом окне References в проекте будет возможен доступ к ее классам, методам и свойствам через окно Object Browser — как показано на рис. 11.4. (Напомним, что работа в окне Object Browser обсуждалась в главе 8.) Рис. 11.4. Выбор компонентов библиотеки Microsoft Scripting Runtime в окне Object Browser После того как библиотека Microsoft Scripting Runtime установлена в системе и соот- ветствующая ссылка добавлена в VBA-проект, можно приступать непосредственно к соз- данию объектно-ориентированного программного кода, предназначенного для доступа к любым файлам на диске и манипуляции ими. Прежде всего в программе необходимо создать экземпляр класса FileSystemObject (ниже для ссылок на него мы будем ис- пользовать аббревиатуру FSO) — этот класс находится на вершине иерархии объектов, используемых для доступа и работы с файлами. Поэтому любая программа, в которой предусматривается использовать подобные объекты, должна начинать работу с файлами с создания экземпляра объекта класса FileSystemObject — объекта высшего уровня, обеспечивающего доступ к любым файлам на дисках. Dim FSO As FileSystemObject ’Определение переменной Set FSO = New FileSystemObject ’Создание экземпляра объекта После того как экземпляр класса Fi leSys temOb j ect (в нашем примере это FSO) соз- дан, необходимо создать объект класса Textstream. Этот объект можно рассматривать как представитель стандартного текстового файла в составе класса FileSystemOb j ect. Именно с помощью методов и свойств объекта класса Textstream организуется доступ к файлу в одном из трех режимов: чтение данных из файла, запись данных в файл или чтение и запись данных в файл. 270 Часть 3. Более сложные аспекты работы на VBA
В VBA при объектно-ориентированной работе с файлами любые файлы на диске об- рабатываются как текстовые потоки, поэтому иерархия классов в библиотеке Microsoft Scripting Runtime включает единственный класс непосредственной обработки файла — класс Textstream. Прежде чем прочитать данные из файла или записать их в файл, необходимо сначала открыть файл как текстовый поток. В программном коде работа с текстовым потоком означает работу с объектом класса Textstream. Начать работу с файлом можно тремя способами: 1) открыв существующий объект File в режиме текстового потока; 2) создав новый файл и одновременно открыв его как текстовый поток; 3) открыв существующий на диске файл как текстовый поток. В приведенном ниже листинге 11.3 показана реали- зация всех трех вариантов. Листинг 11.3. Различные способы открытия файла как объекта Sub Textstream() Dim FSO As FileSystemObject Dim Файл1 As File Dim ТПоток1 As Textstream Dim ТПоток2 As Textstream Dim ТПотокЗ As Textstream 'Создание объекта файловой системы Set FSO = CreateObject("Scripting.FileSystemObject") 'Вариант 1. Создание объекта класса File и использование 'его для открытия существующего файла как текстового потока Set Файл1 = FSO.GetFile("С:\Существующий_Файл.txt") Set ТПоток! = Файл1.OpenAsTextStream(ForReading) 'Вариант 2. Создание нового файла с открытием его как 'текстового потока Set ТПоток2 = FSO.CreateTextFile("С:\Новый_Файл.txt") 'Вариант 3. Открытие уже существующего файла как 'текстового потока Set ТПотокЗ = FSO.OpenTextFile("С:\Старый_Файл.txt") End Sub Доступ к файлу с помощью объекта класса Textstream может быть организован в одном (или нескольких) из следующих режимов ввода-вывода: в режиме только для чтения; в режиме для записи — запись символов предполагается с начала текстового потока; в режиме для записи в конец текстового потока — добавление данных в конец файла. Для каждого конкретного объекта класса Textstream режимы доступа определяются в зависимости от того, каким методом объекта класса FileSystemObject был создан данный текстовый поток, а в случае использования для открытия этого потока метода OpenAsTextStream объекта File — от указанного для него в качестве аргумента режи- ма. Сведения о доступных в каждом случае методах приведены в табл. 11.7. Глава 11. Работа с файлами 271
Таблица 11.7. Режимы доступа к файлу, предоставляемые при различных способах создания объекта класса Textstream Метод___________________Доступные режимы ввода-вывода________________________ CreateTextFile Чтение и запись (создает новый текстовый файл, перезаписывая (объект FileSystemOb j ect) одноименный файл, если он существует) OpenTextFi 1е Чтение и добавление данных (открывает текстовый файл для чтения и/ (объект Fi leSystemOb j ect) или записи, причем новые данные добавляются к уже существующим) OpenAsTextStream Чтение, запись или добавление (только один из режимов) (объект File) Следует отметить, что при создании объекта Textstream с помощью объекта File требуемый режим ввода-вывода задается как аргумент вызываемого метода OpenAsText- Stream. Указанный аргумент может принимать только одно из трех допустимых значений, задаваемых с помощью специальных поименованных констант: ForReading (для чте- ния), ForWriting (для записи) и ForAppending (для добавления). Пример использова- ния константы ForReading приведен выше, в листинге 11.3. Если необходимо добавить данные в конец уже существующего файла, то для его открытия можно воспользоваться следующим оператором. Set Тпоток1 = Файл1.OpenAsTextStream(ForAppending) После того как объект класса Textstream открыт с необходимым режимом доступа, можно начинать работу с содержимым данного файла. Как и любые другие, объекты клас- са TextSt ream также обладают собственными свойствами и методами, которые в данном случае предназначены непосредственно для работы с файлом. Свойства этих объектов описаны в табл. 11.8, а методы — в табл. 11.9. Следует отметить, что все свойства объекта Textstream доступны только для чтения. Таблица 11.8. Свойства объектов класса Textstream Свойство Описание AtEndOfLine Имеет значение True, если указатель находится в конце строки; в противном случае имеет значение False. Свойство AtEndOfLine доступно только для файлов, открытых для чтения, иначе фиксируется ошибка AtEndOfStream Имеет значение True, если указатель находится в конце файла; в противном случае имеет значение False. Свойство AtEndOf Stream доступно только для файлов, открытых для чтения, иначе фиксируется ошибка Column Возвращает текущий номер колонки в файловом указателе. Первый символ в строке находится в колонке 1 Line Возвращает текущий номер строки в файловом указателе Таблица 11.9. Методы объектов класса Textstream Метод Описание Close Закрывает файл, соответствующий данному объекту Textstream. По окончании работы с файлом его необходимо всегда закрывать, что по- зволит освободить занимаемые им системные ресурсы и память Read (число_символов) Читает заданное количество символов начиная с текущей позиции в файле и возвращает полученную строку 272 Часть 3. Более сложные аспекты работы на VBA
Окончание табл. 11.9 Метод Описание ReadAll Читает весь файл и возвращает полученные данные в виде одной строки ReadLine Читает очередную строку начиная с текущей позиции в файле и воз- вращает полученную строку S k i р (число_ симв слов) Пропускает заданное количество символов при чтении файла. Сле- дующая операция чтения будет начата с первого символа, который расположен за пропущенными SkipLine Пропуск следующей строки в файле. Следующая операция чтения бу- дет начата с первого символа, который находится за пропущенными Write(строка) Записывает строку в файл, не добавляя в нее дополнительных симво- лов или символов новой строки WriteBlankLines (число_ строк) Записывает в файл указанное аргументом количество пустых строк WriteLine(строка) Записывает строку в файл, добавляя в ее конец символ начала новой строки В процессе работы с объектом Textstream нужно всегда помнить, что при исполь- зовании метода, не соответствующего режиму открытия файла, возникает ошибка. Не- которые из перечисленных в табл. 11.9 методов можно применять только для файлов, от- крытых для чтения или записи. При этом используемые методы чтения начинают чтение данных с самого начала файла и читают его до конца. С помощью методов SkipHSki- pLine можно организовать перемещение в файле на заданное количество символов, но это касается только перемещения вперед. Попытка перемещения в обратном направлении вызовет ошибку. Кроме того, если требуется записать данные в файл, а затем прочитать их (или наоборот), то после первой операции необходимо закрыть этот файл, а потом снова открыть его. Затем, используя метод Skip, следует пропустить на одну позицию меньше, чем номер той позиции в файле, с которой требуется начать чтение, и только после этого обратиться к методу чтения. Например, если необходимо прочитать 100 символов начи- ная с 15-го символа в файле, то в программу следует поместить следующие операторы. ТПоток1.Close Set TIIotokI = Файл1. OpenAsTextStream (ForReading) ТПоток1.Skip(14) TIIotokI . Read (100) Управление файлами Управление файлами включает в себя такие действия, как копирование файлов, удаление неиспользованных файлов для освобождения дисковой памяти, перемещение файлов с одного диска на другой и создание папок. В предыдущих разделах были рас- смотрены операторы и функции, с помощью которых можно управлять файлами (или папками), встроенными средствами языка VBA. Здесь мы остановимся на объектно- ориентированных приемах управления файлами. Прежде чем в программе приступить к выполнению любой из задач управления фай- лами, необходимо создать экземпляр объекта класса FileSystemObject (FSO) — также как и при объектно-ориентированном доступе к файлам. Глава 11. Работа с файлами 273
Dim FSO As FileSystemObject Set FSO = New FileSystemObject Объект класса FileSystemOb j ect — это самый верхний объект в иерархии объектно- ориентированного представления файловой системы компьютера, который обеспечива- ет доступ как к локальным, так и к сетевым дискам, папкам и файлам системы. Другие объекты этой иерархии в совокупности отражают способ организации файловой системы. Давайте вспомним принципы организации файловой системы компьютера и поставим в соответствие ее отдельным элементам объекты, образующие иерархию, возглавляемую объектом класса FileSystemObject. Объект Drive соответствует отдельному дисковому устройству в компьютерной файловой системе. Поэтому в иерархии объектов файловой системы каждый диск представлен собственным объектом класса Drive. Свойства объекта класса Drive предоставляют информацию о данном дисковом устройстве. Все объекты класса Drive системы содержатся в коллекции Drives объекта FileSystemObject. У каждого объекта класса Drive есть объектное свойство RootFolder, которое возвращает ссылку на объект Folder. Объект Folder соответствует отдельной папке (или каталогу) на некотором дис- ке. У каждого объекта класса Folder есть коллекция Folders, которая содержит объекты класса Folder, представляющие подкаталоги в данном каталоге. У каждого объекта класса Folder есть также коллекция Files, в которой содер- жатся объекты класса File, представляющие отдельные файлы в данной папке. У объекта верхнего уровня FileSystemObject также имеются собственные методы, предназначенные для выполнения некоторых операций управления файлами; они кратко описаны в табл. 11.10. Таблица 11.10. Некоторые методы объекта класса FileSystemObject Метод Описание BuildPath(путь, имя) Возвращает строку описания пути доступа к файлу, построенную из значения аргумента путь, к которому присоединяется значе- ние аргумента имя СгeateFolder(имя_папки) Создает новую папку, имя которой задано аргументом имя_папки. Если такая папка уже существует, метод выдает ошибку DriveExists(имя_диска) Возвращает True, если указанный диск существует. Аргумент имя_диска — это буква дисковода или имя сетевого диска GetAbsolutePathName (путь) Возвращает полную и точную спецификацию пути, соответствую- GetDrive(путь) щую заданному значению аргумента путь Возвращает объект Drive, представляющий диск в описании пути, заданном значением аргумента путь GetFileName(путь) Возвращает имя файла в пути, заданном значением аргумента GetFolder(путь) путь, или пустую строку, если это значение не содержит имени файла Возвращает объект Folder, соответствующий конечной папке в описании пути, заданном значением аргумента путь GetTempName Возвращает строку, содержащую путь к текущей рабочей папке с именем временного рабочего файла, которое гарантированно не используется в данный момент 274 Часть 3. Более сложные аспекты работы на VBA
Объект Drive Единственным свойством объекта FileSystemOb j ect является свойство Drives — ссылка на коллекцию Drives, которая содержит объекты Drive, представляющие все дисковые устройства, доступные в системе. Здесь имеются в виду все локальные диски компьютера (включая флоппи-дисководы, подключенные флеш-карты, CD, DVD), а так- же сетевые диски и папки, представленные в системе как логические дисковые устройства. Таким образом, свойства объектов класса Drive предоставляют информацию о физиче- ских дисках системы — это количество свободного места на диске (AvailableSpace), тип диска (DriveType), готовность диска (IsReady), путь к дисководу (Path), ссылка на объект корневой папки диска (RootFolder) и т.д. Все эти свойства доступны только для чтения и подробно описаны в справочной системе редактора VBA. В листинге 11.4 показано, как можно получить информацию сразу обо всех системных дисках: выяснить назначенную букву, определить свободное место на диске и присвоенное ему имя тома. Листинг 11.4. Получение информации о дисках в системе Public Sub GetDriveO ’Определение объектных переменных Dim FSO As FileSystemObject Dim D As Drive Set FSO = New FileSystemObject ’Вывод сведений о дисках в окно редактора VBA Immediate Debug. Print ’’Диск”, "Свободное место", "Имя" For Each D In FSO.Drives If D.IsReady Then ’Диск готов, вывод сведений Debug.Print D.Path, D.AvailableSpace, D.VolumeName Else ’Диск не готов Debug. Print d.Path & ’’ is not ready." End If Next D End Sub Объект Folder Объект Folder соответствует отдельной папке или подкаталогу на диске. При работе в среде VBA с объектом класса Folder программисту доступно следующее: методы объекта, предназначенные для копирования, перемещения или удаления данной папки; свойства объекта, содержащие информацию о данной папке; коллекция Files, содержащая объект File для каждого файла в данной папке; коллекция SubFolders, содержащая объект Folder для каждой подпапки в дан- ной папке. Свойства объекта Folder предоставляют информацию о соответствующей папке — это дата и время создания папки (DateCreated), дата и время последнего доступа к папке (DateLastAccessed), дата и время последнего изменения папки (DateLastModified), имя папки (Name), ссылка на объект Folder, представляющий родительскую папку дан- Глава 11. Работа с файлами 275
ной папки (ParentFolder), путь к данной папке, включая букву дисковода (Path). Все эти (и другие) свойства объекта Folder подробно описаны в справочной системе VBA. Кроме рассмотренных выше свойств, объект Folder обладает следующими методами. Метод Сору копирует данную папку и ее содержимое в новое место. Сору путь_назначения, перезапись Здесь параметр путь_назна чения — это строка, определяющая полный путь к пап- ке, в которую должна быть скопирована данная папка. Параметр перезапись — это необязательный параметр, который может принимать следующие значения: True — данные записываются поверх существующих файлов или папок, False — перезапись запрещается. По умолчанию используется значение True. Метод Move перемещает папку и ее содержимое из одного места в другое. Move путь_назначения Здесь путь_назначения — это строка, определяющая полный путь к папке, в ко- торую должна быть перемещена данная папка. Метод Delete удаляет папку и ее содержимое. Delete принудительно Здесь принудительно — это необязательный параметр, принимающий следующие значения: True — если нужно удалять файлы или папки с атрибутом “только для чте- ния”, False — если этого не требуется. По умолчанию принимается значение False. Для папок определенного диска точкой входа в его файловую структуру является свойство RootFolder соответствующего объекта Drive. Оно содержит ссылку на корневую папку диска, т.е. на папку Самого верхнего уровня его файловой структуры. “Углубляясь” от этой точки, можно войти в любой подкаталог на диске. Кроме того, начав с любого подкаталога диска, можно также “подняться” по его иерархии папок. Объект File Этот объект представляет отдельный файл на диске. Свойства и методы объекта File по- зволяют выполнять различные манипуляции данным файлом. Перед тем как начать работу с файлом (подразумеваются такие действия, как перемещение и копирование файла), нужно получить ссылку на соответствующий объект File одним из двух возможных способов. Первый способ заключается в использовании метода GetFile объекта класса FileSys- temObject, возвращающего ссылку на объект File, соответствующий тому файлу, имя и путь которого указаны в качестве параметров вызова метода. Синтаксис метода GetFile следую- щий (предполагается, что FSO — это объект класса FileSys temOb j ect). Dim Файл1 As File Set Файл1 = FSO.GetFile(Имя_Файла) Здесь Имя_ Файла — это полное имя файла, включающее его путь. Если указанное имя не найдено на диске, метод выдаст ошибку. Этот способ получения ссылки прост, но он требует знания имени файла и его полного пути. Второй способ получения ссылки на объект File — поиск необходимого объекта в коллекции Files объекта папки Folder. В этом случае следует просмотреть состав дан- ной коллекции и выбрать ссылки на один или больше интересующих файлов. 276 Часть 3. Более сложные аспекты работы на VBA
Получив ссылку на объект File, соответствующий требуемому файлу, можно использовать свойства этого объекта для получения информации о файле или же его методы, предназначен- ные для манипуляции файлом. Свойства объекта File кратко описаны в табл. 11.11. Таблица 11.11. Свойства объекта File Свойство Описание Attributes DateCreated DateLastAccessed DateLastModified Name Возвращает значение, определяющее состояние атрибутов файла Возвращает дату и время создания файла Возвращает дату и время последнего доступа к файлу Возвращает дату и время последнего изменения файла Содержит имя файла, это свойство можно считать или изменить непосред- ственно из программы ParentFolder Возвращает ссылку на объект Folder, представляющий родительскую папку файла Path Size Возвращает полный путь файла, включая букву диска Возвращает размер файла в байтах Рассмотрим несколько примеров, полагая, что используемый объект класса File име- ет имя Файл1. Так, с помощью свойства Size можно выяснить размер файла. Dim Размер_Файла As Long Размер_файла = Файл1.31ге С помощью свойства DateLastModified можно узнать, когда файл изменялся по- следний раз. Dim Дата_изменения As Date Дата_изменения = Файл1. DateLastModified Свойство Attributes содержит информацию об атрибутах файла (например, файл си- стемный или он доступен только для чтения). При необходимости некоторые атрибуты файла можно менять и непосредственно из программы. Свойство Attributes возвращает един- ственное числовое значение — сумму числовых значений всех установленных атрибутов файла. Числовые значения для отдельных атрибутов файла представлены в табл. 11.12. Таблица 11.12. Числовые значения, назначенные атрибутам файлов Атрибут Значение Описание Normal 0 Файл без каких-либо установленных атрибутов Readonly i Файл доступен только для чтения Hidden 2 Файл скрытый. Доступен для чтения/записи System 4 Файл системный. Доступен для чтения/записи Volume 8 Файл является меткой тома дисковода. Доступен только для чтения Directory 16 Файл является папкой. Доступен только для чтения Archive 32 Файл был изменен с момента создания последней резервной копии. До- ступен для чтения/записи Alias 64 Файл является ссылкой или сокращенным путем доступа. Доступен только для чтения Compressed 128 Файл сжат. Доступен только для чтения Глава 11. Работа с файлами 277
Чтобы выделить значения отдельных атрибутов из совокупного значения свойства At- tributes, можно воспользоваться логическими операторами VBA. Так, чтобы выяснить, установлен ли для данного файла некоторый конкретный атрибут, используется оператор And. В приведенном ниже примере определяется, установлен ли атрибут Hidden для фай- ла, представленного объектом класса File с именем Файл1. If Файл1.Attributes And 2 Then ’Задан атрибут Hidden Else ’Не задан атрибут Hidden End If У объектов класса File, кроме метода OpenAsTextStream, который уже был описан выше в этом разделе, есть еще три метода, представленные в табл. 11.13. Таблица 11.13. Прочие методы объекта File Метод Описание Сору путь_назначения, перезапись Move путь_назначения Delete принудительно Копирует файл в местоположение, определяемое аргументом путь_ назна чения. Аргумент перезапись определяет действия в том случае, если файл с данным именем уже существует в указанной папке. Если он имеет значение True (принимается по умолчанию), существующий файл перезаписывается, в противном случае операция отменяется Перемещает файл в местоположение, определяемое аргументом путь_ назначения Удаляет файл. Если необязательный аргумент принудительно имеет значение True, то файл удаляется даже в том случае, если он доступен только для чтения. По умолчанию для этого аргумента принимается значение False С помощью методов объекта класса File файл данных можно скопировать, переме- стить или удалить. Файл1.Сору ”с:\игры\” ’Копирование файла Файл1.Move ”с:\мои игры\" ’Перемещение файла Файл1.Delete ’Удаление файла Следует заметить, что если имя файла изменять не требуется, то при вызове методов Сору и Move указывать имя файла нет необходимости, достаточно указать только путь назначения. Однако при этом не забывайте в конце пути добавить обратную косую черту, отделяющую имя файла. Резюме В этой главе обсуждались методы работы с файлами, существующие в языке VBA. Были рассмотрены два основных подхода к организации доступа к файлам и манипулиро- вания ими — с помощью встроенных функций языка VBA и отражения файловой струк- туры компьютера в иерархию объектов VBA. В начале главы речь шла об использовании встроенных функций. Были описаны три типа файлов, а также было показано, как файлы каждого типа могут открываться и обрабатываться. Затем подробно обсуждались функции 278 Часть 3. Более сложные аспекты работы на VBA
управления файлами, позволяющие выполнять их копирование, пересылку, удаление и пр. В конце главы детально обсуждались методы работы с файлами как с объектами. В этом случае в программе создается иерархия объектов, отражающая строение файловой системы компьютера. В основе этой иерархии находится объект класса FileSystem- Object, а последующие ее уровни представлены объектами классов Drive, Folder и File. Для доступа к информации в отдельном файле используются объекты классов Fi- leTextStream. Методы и свойства объектов всех этих классов позволяют эффективно работать с файлами и папками в VBA-программах. Тестовые задания Ниже приведено несколько тестовых заданий, предназначенных для закрепления из- ложенного в этой главе материала. В каждом задании вам предлагается вопрос и несколь- ко вариантов ответа на него, один (или несколько) из которых является правильным, а остальные — нет. Укажите правильный ответ. 1. Функции языка VBA позволяют работать с файлами следующих типов: а) бинарными; б) текстовыми; в) последовательного доступа; г) индексно-последовательного доступа; д) произвольного доступа. 2. Записи фиксированной длины используются в файлах следующих типов: а) текстовых; б) с последовательным доступом; в) с произвольным доступом; г) бинарных. 3. Для записи данных в файлы последовательного доступа используется функция: a) Put (); б) Get (); в) Read (); г) Write (); Д)Append(); е) Output (). 4. Для записи данных в файлы произвольного доступа используется функция: a) Put (); б) Get (); в) Read (); г) Write (); д) Append (); е) Output (). Глава 11. Работа с файлами 279
5. В иерархию объектов, представляющих файловую систему компьютера, входят объекты следующих классов: a) Textstream; б)FileSystemObject; в) Record; г) File; д) Folder; е) Directory; ж) Drive; з) Disk. 280 Часть 3. Более сложные аспекты работы на VBA
Глава 12 Обработка ошибок и отладка программ В этой главе... ♦ Перехват и обработка ошибок ♦ Тестирование программы обработки ошибок ♦ Отладка приложений ♦ Специализированные окна отладчика ♦ Резюме Составить программный код без ошибок очень непросто, на каком из языков про- граммирования вы ни писали бы программы. Для этого нужен навык и большая практика, и все равно вы никогда не будете застрахованы от разного рода ошибок и оплошностей (вспомните пример приложения из главы 10 — сколько разного рода неожиданностей воз- никало в процессе его написания). Конечно, каждый программист стремится написать хорошую и надежную программу, которую легко понять и в которой ошибки были бы сведены к минимуму, но сделать это нелегко. Поэтому в этой главе мы будем обсуждать приемы и средства отладки, которые в случае возникновения ошибок во время выполне- ния программного кода помогут вам выйти из трудных ситуаций. Перехват и обработка ошибок В программе, написанной на языке VBA, все ошибки, которые могут возникнуть при написании и эксплуатации программы, можно (как уже говорилось в разделе “Обработка ошибок” в главе 3) отнести к трем категориям. Ошибки компиляции. Это синтаксические ошибки, к которым в первую очередь относятся орфографические ошибки, возникающие при неправильном вводе программного кода. Они обнаруживаются редактором VBA непосредственно при редактировании программы. Это может быть, например, некорректно введенное число скобок или неправильно указанный аргумент для встроенной функции. Кро- ме того, к этой категории относятся ошибки компиляции, возникшие уже после начала выполнения программы, — например, неправильно введенное имя в опера- торе GoTo, из-за чего переход выполняется на несуществующую метку, или вызов несуществующей процедуры. Если эти ошибки редактор VBA не заметит до начала выполнения программы, работа программы будет некорректной.
Логические ошибки. Это ошибки, допущенные при проектировании программы, в результате которых программа делает или вовсе не то, что хочет от нее разработ- чик, или ведет себя не совсем так, как это ожидалось. Такие ошибки труднее всего обнаружить, а еще сложнее установить причину их возникновения. Логические ошибки далеко не всегда очевидны при выполнении программы и редко приводят к прерыванию программного кода, но при работе такой программы вы совершенно неожиданно можете получить неправильный результат. Исправление таких ошибок весьма трудоемко и требует тщательного анализа алгоритма программы с парал- лельным использованием средств отладки для проверки возможных версий. Ошибки выполнения. Это такие ошибки, которые проявляются исключительно в про- цессе выполнения программного кода. Они приводят к останову выполнения про- граммы, если VBA в процессе ее выполнения встречает выражение или оператор, который нельзя выполнить или вычислить. Причины таких ошибок весьма разноо- бразны: это может быть некорректная информация, появившаяся из-за сбоя при считывании файла с диска, неправильные данные, введенные неопытным пользова- телем, и, как следствие, некорректность вычислений (скажем, деление на нуль). С самых первых шагов создания приложения следует помнить о необходимости об- работки потенциальных ошибок. Поэтому при разработке программы настоятельно рекомендуется вставлять в нее специальные фрагменты, предназначенные для обнаруже- ния ошибок и их обработки. По сути, обработка потенциальных ошибок связана с двумя аспектами, которые имеют равное значение. Первый аспект — это стремиться избегать логических ошибок, т.е. по мере возможности писать надежные программы, второй — предвидеть те ошибки выполнения, избежать появления которых нельзя, и принимать профилактические меры по их выявлению или предотвращению. Конечно, желательно при создании программы сочетать оба подхода, применяя для каждой возможной ошибки тот, который в данном случае будет наиболее эффективным. Здесь будут полезны следующие рекомендации, о которых желательно помнить и которых следует придерживаться при написании программ. Для предотвращения случайных ошибок обязательно объявляйте все используемые переменные. Для этого включайте в начало каждого модуля оператор Option Ex- plicit, который сообщает редактору VBA о том, что все переменные в программе должны быть объявлены явно. Это предотвращает трудно отслеживаемые ошибки, которые могут возникнуть из-за неправильно указанных в операторах имен пере- менных. Это требование можно даже установить как автоматически поддерживае- мый режим: выберите команду Tools^Options и в раскрывшемся диалоговом окне Options установите на вкладке Editor флажок опции Require Variable Declaration. Избегайте типа данных Variant. Несмотря на то что в общем смысле тип данных Variant является весьма гибким и очень полезным типом данных, его использова- ние может оказаться причиной появления в программе некоторых трудноуловимых ошибок. Поэтому старайтесь использовать этот тип данных не для собственного удобства, а только тогда, когда это действительно необходимо. В любой программе при работе с данными выполняйте хотя бы их минимальную предварительную проверку, т.е. проверяйте любые данные на допустимость, пре- жде чем подвергнуть их дальнейшей обработке. Совершенно необходимо проверять корректность данных, введенных пользователями, а также корректность значений, полученных различными процедурами в качестве аргументов. Для этого в VBA есть 282 Часть 3. Более сложные аспекты работы на VBA
много инструментов, которые можно использовать для предотвращения некор- ректного ввода данных или недопустимых данных в различных выражениях. Такой подход поможет заранее избавиться от множества разнообразных потенциальных ошибок и служит первым признаком профессионального уровня программиста. Старайтесь придерживаться следующих общих правил объявления переменных: начинайте процедуру с явного объявления всех переменных и располагайте каждую объявленную переменную в отдельной строке. Несмотря на то что тип Variant в языке VBA является типом данных, принимаемым по умолчанию, — переменные этого типа также должны быть объявлены в программе явно. Dim A As Variant Dim В As Integer Dim C As Double He следует писать несколько операторов в одной строке. Это ухудшает читабель- ность программы и увеличивает время поиска ошибок. Приняв во внимание все перечисленные выше рекомендации, можно избежать по- явления лишь некоторых, но далеко не всех ошибок. Но все оставшиеся неизбежные ошибки необходимо обязательно перехватывать и обрабатывать. Перехват ошибок Хорошо написанная программа никогда не должна аварийно прерываться. Для этого в каждую программу следует включать средства перехвата любой возможной ошибки. Каждая обнаруженная ошибка должна быть обработана, т.е. для пользователя на экран должно быть выдано сообщение о характере возникшей ошибки, а программа, если только это возможно, должна избегать аварийного завершения и продолжать свою работу. Всю обработку ошибок в программе следует выполнять на процедурном уровне, т.е. в каждой процедуре, в которой потребуется обеспечить перехват и обработку ошибок, должна присутствовать собственная программа обработки ошибок — обработчик ошибок. Так принято называть блок программ- ного кода, выполняемый только тогда, когда обнаруживается ошибка. Если во время вы- полнения процедуры что-то пойдет не так, VBA вызовет обработчик ошибок, чтобы с его помощью выяснить, какого именно типа произошла ошибка, и, в зависимости от сложив- шейся ситуации, предпримет те или иные предусмотренные вами в программе действия. Для того чтобы добавить в процедуру программный код обработчика ошибок, необхо- димо выполнить следующее: в начало процедуры добавить оператор On Error, назначение которого состоит в перехвате ошибки и сообщении VBA о том, где найти программный код обработ- чика ошибок; в конец процедуры поместить оператор Exit Sub (или Exit Function), за кото- рым будет следовать программный код обработчика ошибок; создать программный код самого обработчика ошибок, начало которого должно быть отмечено некоторой меткой. Следует отметить, что выполнение всех этих действий является строго обязательным. Так, например, при отсутствии оператора On Error VBA вообще не узнает, что в про- цедуре имеется обработчик ошибок. Синтаксис этого оператора следующий. On Error Goto метка Глава 12. Обработка ошибок и отладка программ 283
Здесь метка — это метка, которая идентифицирует в процедуре начало программного кода обработчика ошибок и является первым оператором в его процедуре. Напомним, что обычно программный код обработки ошибок помещается после основной процедуры и, следовательно, не может получить управление при ее нормальной работе. В общем слу- чае структура процедуры с обработкой ошибок выглядит следующим образом. Public SubError() ' Здесь должно быть объявление данных. On Error Goto Обработка_ошибки ' Здесь должно быть тело процедуры. Exit Sub ' Здесь завершается выполнение процедуры, когда ошибок нет Обработка_ошибки: ' Здесь должны быть операторы обработчика ошибок. End Sub Однако для оператора On Error существуют еще две возможные формы записи. 1. On Error GoTo 0; Этот оператор отменяет программную обработку ошибок в процедуре, начиная с данного места, и выполняет очистку объекта Err (подроб- ности — ниже). Его используют в том случае, если по каким-либо причинам необ- ходимо временно отказаться от услуг имеющегося обработчика ошибок. Оператор On Error GoTo 0 отменяет действие ранее выполненного оператора On Error GoTo метка. 2. On Error Resume Next. Этот оператор дает указание VBA игнорировать строку программного кода, ставшую причиной ошибки, и продолжить выполнение проце- дуры со следующей за ней строки. Игнорирование ошибки, конечно, не устраняет ее, но таким способом обработку этой ошибки можно просто отложить. Оператор On Error Resume Next будет полезен при работе с объектами из содержаще- го программу приложения или других программных компонентов, которые были созданы не вами. Поэтому при работе в программе с внешними объектами с по- мощью оператора On Error Resume Next полезно указать то место, где может произойти ошибка, связанная с этими объектами, — например, при создании их экземпляров. Затем после оператора, который может вызвать внешнюю ошибку, необходимо проверить объект Err, чтобы узнать, произошла ли потенциальная ошибка, и если это так, то обработать ее появление. Следует обратить особое внимание на обязательное наличие в процедуре оператора Exit Sub, он требуется для того, чтобы обработчик ошибок выполнялся только тогда, когда в программе возникает ошибка, а не при каждом выполнении процедуры. Если это будет процедура типа Sub, то используйте оператор Exit Sub, а для процедуры типа Function используйте Exit Function. Любой обработчик ошибок всегда должен решать три главные задачи — выяснить тип возникшей ошибки, выполнить те или иные действия по ее исправлению и указать место, с которого будет продолжено выполнение основной процедуры. По своей сути эти три задачи различны, но на практике они выполняются практиче- ски одновременно. Для получения информации об имевшей место ошибке используется объект Err языка VBA. Это внутренний объект VBA, и поэтому его можно использовать 284 Часть 3. Более сложные аспекты работы на VBA
сразу, без предварительного создания экземпляра этого объекта. Кроме того, объект Err всегда доступен в любой VBA-программе. При обнаружении ошибок VBA вначале авто- матически очищает объект Err, а затем сохраняет информацию о последней из случив- шихся в программе ошибок и помещает ее в свойства объекта Err. Обработчик ошибок для определения типа возникшей ошибки может анализировать эти свойства, перечень которых представлен в табл. 12.1. Таблица 12.1. Свойства объекта Err Свойство Описание Description HelpContext Строковое выражение, содержащее текст сообщения об ошибке Контекстный идентификатор файла справки VBA, соответствующий ошибке с кодом, указанным в свойстве Number HelpFile Полный путь к файлу справки, содержащему информацию, связанную с данной ошибкой LastDLLError Если ошибка была вызвана обращением к динамически подсоединяемой библио- теке (DLL), то это свойство содержит соответствующий системный код ошибки Number Числовой код ошибки. Может как считываться, так и устанавливаться из при- кладной программы Source Содержит имя объекта, вызвавшего ошибку Свойство Number хранит системный номер (код) ошибки, определяющий ее тип. Каж- дый обработчик ошибок находится в процедуре, а процедуры предназначены для решения отдельных конкретных задач, поэтому диапазон возможных ошибок при их выполнении будет так или иначе ограничен. Подробный список кодов ошибок VBA можно найти в справочной системе VBA в разделе Trappable Errors (распознаваемые ошибки). Доступ к этому разделу можно получить, поместив значение trappable errors в поле аргумен- та поиска в окне справки (рис. 12.1). В табл. 12.2 приведены коды часто встречающихся ошибок. Таблица 12.2. Коды часто встречающихся ошибок Код Описание ошибки 5 6 7 9 11 13 18 52 53 54 55 56 61 68 Приложение не запущено Переполнение Не хватает памяти Индекс элементов массива или коллекции выходит за пределы допустимого Деление на нуль Несоответствие типа Произошло прерывание, вызванное пользователем Для файла указано неправильное имя или несуществующий идентификатор Файл не найден Неверный режим работы с файлом Файл уже открыт Ошибка ввода-вывода Переполнение диска Устройство недоступно Глава 12. Обработка ошибок и отладка программ 285
Окончание табл. 12.2 Код Описание ошибки______________________________________________________________ 71 Диск не готов 72 Повреждена поверхность диска 335 Невозможен доступ к системным ресурсам 368 Истек срок действия указанного файла с элементом ActiveX. Программе требуется файл более новой версии 482 Ошибка принтера Рис, 12,1, Начальная страница раздела описания значения кодов ошибок VBA Например, в процедуре, считывающей данные из дискового файла, необходимо сле- дить за ошибками, связанными с файловыми операциями, а не с делением на нуль или выходом индекса массива за существующие пределы. Ниже приведен пример обработки кодов ошибок, в котором наглядно видно, что указывать свойство Number нет необходи- мости, так как это свойство для объекта Err принято как элемент, к которому обращаются по умолчанию. Обработка_ошибки: If Err = 52 Then MsgBox("Неверное имя файла.") 286 Часть 3. Более сложные аспекты работы на VBA
Elself Err = 54 Then MsgBox("Неверный режим работы с файлом.") End If Свойство Description содержит краткое текстовое сообщение об ошибке. Это свой- ство можно использовать в том случае, если программный код обработки ошибок не об- рабатывает какой-то тип ошибок, но вывод текстового сообщения о случившемся может быть полезен пользователю. Например, данная подпрограмма обработки ошибок просто отображает на экране сообщения с информацией о любой возникшей в программе ошибке. Обработка_ошибки: MsgBox("Произошла " & Err & " ошибка: " & _ Err.Description) Чтобы предоставить пользователю возможность просмотреть справочную информа- цию о какой-либо ошибке из справочной системы редактора VBA, используются свойства HelpFile и HelpContext. По моему личному убеждению, делать этого не следует, так как информация в справочной системе VBA обычно предназначена для разработчика, а не для пользователя. В любом случае, чтобы все же предоставить подобную информацию об ошибке пользователю, необходимо сначала сделать справочную информацию VBA до- ступной в используемом приложении, а затем передать значения свойств HelpContext и HelpFile объекта Err в функцию MsgBox, чтобы соответствующие страницы справки отображалась по умолчанию, если пользователь нажмет <F1> при появлении на экране сообщения об ошибке. ErrorHandler: temp = "Произошла ошибка. Номер: " & Err temp = temp & " , Описание: " & Err.Description _ & vbCrLf temp = temp & _ "Нажмите Fl для получения справки." a = MsgBox(temp, , "Ошибка", Err.HelpFile, _ Err.HelpContext) т'-'У Свойство Source объекта Err указывает на компонент проекта, который генериро- вал ошибку. Значение этого свойства полезно проверять, чтобы убедиться, что ошибка вызвана объектом, принадлежащим вашей программе. Например, если проект VBA предназначен для автоматизации работы в Excel и ошибка возникает именно в Excel, то свойство Err. Number будет содержать код ошибки Excel, а свойство Err. Source — значение Excel .Application. Если же ошибка происходит в стандартном модуле проекта, свойство Source будет содержать название данного проекта. Если ошибка происходит в модуле класса проекта, то свойство Source будет содержать название проекта и (через точку) имя класса. Кроме перечисленных выше свойств, объект Err обладает также некоторыми методами. Метод Clear очищает значения всех свойств объекта Err. Он используется для очист- ки значений свойств объекта Err от информации об ошибке, после завершения обработ- ки этой ошибки. Следует отметить, что метод Clear неявно вызывается системой всякий раз при выполнении оператора Resume любого типа, при выполнении операторов Exit Sub, Exit Function или Exit Property, а также при выполнении любого оператора On Error. Глава 12. Обработка ошибок и отладка программ 287
Метод Raise генерирует ошибку выполнения и используется для моделирования си- туаций появления ошибки, т.е. для имитации возникновения ошибки VBA, при этом но- мер ошибки и другая необходимая информация предоставляются вами при вызове этого метода. Синтаксис метода Raise следующий. Raise number, [source,] [description,] [helpfile, helpcontext] Здесь number — это обязательный аргумент, определяющий номер генерируемой ошибки, он задается целым числом и может принимать значения от 0 до 65535. Необязательный аргумент Source — это строковое значение, определяющее имя объекта или приложения, в котором якобы возникла данная ошибка. Необязательный аргумент Descripti on пред- ставляет собой строковое выражение, которое содержит описание ошибки. Необязатель- ный аргумент НеIpfile задает полное имя файла справки Microsoft Windows, содержащей описание данной ошибки. Необязательный аргумент Helpcontext задает контекстный идентификатор, определяющий соответствующий обрабатываемой ошибке раздел в том файле справки, который указан в аргументе helpfile. Обратите внимание на то, что набор аргументов метода Raise в точности совпада- Ly ет с набором основных свойств объекта Err. И это не удивительно — именно в эти е свойства и записываются значения аргументов, заданные при вызове метода Raise. Однако если один или несколько аргументов при вызове Raise будут опущены, то в соответствующих свойствах объекта Err сохранятся значения, оставшиеся от преды- дущих ошибок. Поэтому перед вызовом метода Er г. Raise целесообразно вызывать метод Err. Clear. Продолжение выполнения программы Итак, подпрограмма-обработчик ошибок завершила свою работу. Теперь необходимо решить, что же делать дальше — вернуться в ту процедуру, в которой произошла ошибка, и продолжить ее выполнение или передать управление той процедуре, из которой про- цедура с ошибкой была вызвана. Если имеет смысл продолжить выполнение текущей процедуры, несмотря на возник- шую в ней ошибку, поместите в обработчик ошибок оператор Resume. С помощью этого оператора можно контролировать, с какого именно места будет продолжено выполнение программы. Оператор Resume имеет несколько вариантов написания. Resume — при этом варианте записи оператор Resume возвращает управление в процедуре тому же самому оператору, который вызвал ошибку. Данный вариант целесообразно использовать в том случае, если желательно повторить операцию, вызвавшую ошибку. Resume Next — при этом варианте записи оператор, ставший причиной появле- ния ошибки, пропускается и выполнение программы возобновляется с оператора, непосредственно следующего за ним. Resume метка — в этом случае выполнение программы возобновляется начиная с оператора, определяемого параметром метка. Здесь метка представляет собой ссылку на метку, размещенную где-то в той же процедуре, что и оператор Resume метка. Используя этот оператор, можно продолжить выполнение программы с оператора, который находится как после, так и до оператора, вызвавшего ошибку. 288 Часть 3. Более сложные аспекты работы на VBA
Ошибки модулей класса При выполнении программы модули класса, так же как и стандартные модули, не защищены от ошибок, но обрабатываются эти ошибки несколько иначе. Кроме того, работая с модулем класса, можно определить специальные ошибки, представляющие не- которые объектные ситуации, на которые должно реагировать приложение. В общем случае класс не должен непосредственно обрабатывать собственные ошибки. Будет корректнее, если класс лишь предоставляет отчет использующей его программе для обработки сложившейся ситуации. По такому принципу должны обрабатываться все стандартные ошибки языка VBA, а также ошибки, специфические именно для данных классов, — например, обнаружение некорректного значения, переданного в метод класса в качестве аргумента. При определении специальных ошибок каждой такой ошибке необходимо поставить в соответствие некоторый номер. Разумеется, нельзя использовать номера, которые вы- делены для обозначения встроенных ошибок языка VBA. Поэтому в модулях классов при определении специальных ошибок можно использовать любой номер начиная с vbOb- j ectError + 512 и до vbObj ectError + 65 536. Константа vbObj ectError всегда доступна в среде VBA, а номера ошибок в указанном диапазоне не используются для обо- значения встроенных ошибок языка, поэтому они свободны и их можно использовать без ограничений. Для номеров ошибок и их описаний, а также для имен файлов справки и контекстов, если они используются, в классе лучше определить константы. Чтобы определить ис- точник ошибки и стандартное базовое значение для номеров ошибок на уровне модуля, соответствующие константы можно объявить, например, следующим образом. Private Const КЛАСС_ИСТОЧНИК_ОШИБКИ As String = "Класс Имя_класса" Private Const БАЗОВЫЙ_НОМЕР_ОШИБКИ_КЛАССА As Long = vbObjectError + 512 В .этом случае константу для конкретной специальной ошибки, которая может воз- никнуть в классе, можно определить следующим образом. Private Const НОМЕР_ОШИБКИ_КЛАССА_НЕВЕРНЫЙ_АРГУМЕНТ As Long = БАЗОВЫЙ_НОМЕР_ОШИБКИ_КЛАССА + 1 Private Const ОПИСАНИЕ_ОШИБКИ_КЛАССА_НЕВЕРНЫЙ_АРГУМЕНТ As String = КЛАСС_ИСТОЧНИК_ОШИБКИ + " Некорректный аргумент — значение не может быть нулевым." Если ошибка возникает в процедуре, в которой организован перехват ошибок, то она | будет обработана собственной прбграммой обработки ошибок этой процедуры, и све- s дения о ней не будут переданы в программу, использующую объект. Чтобы передать ошибку из процедуры модуля класса, имеющей собственную программу обработки ошибок, в использующую этот класс программу, повторно вызовите метод Raise в программе обработки ошибок. Тестирование программы обработки ошибок Подпрограмму обработки ошибок, как и любую другую программу, нужно тщательно протестировать, прежде чем приложение будет передано в эксплуатацию. Тестирова- ние таких подпрограмм заключается в том, что соответствующие ошибки искусственно Глава 12. Обработка ошибок и отладка программ 289
создаются, после чего проверяется, как на них реагирует программа. Некоторые из оши- бок можно вызвать простейшими манипуляциями, например просто не вставить дискету в дисковод, когда программа обращается к нему. Другие ошибки нужно имитировать с по- мощью метода Raise. Тестирование подпрограмм ошибок — нелегкая, но очень важная часть процесса разработки. В среде разработки VBA поддерживается несколько различных способов реакции си- стемы на возникновение ошибок в VBA-программах. Для того чтобы выбрать один из до- ступных способов обработки ошибок, выберите команду меню Tools^Options и перейдите в раскрывшемся диалоговом окне Options на вкладку General. В группе Error Trapping установите переключатель в положение, определяющее требуемый способ прерывания работы программы (рис. 12.2). Break on All Errors (Прерывание при всех ошибках). Любая ошибка прерывает вы- полнение программы проекта независимо от того, имеется ли в данный момент ак- тивная подпрограмма обработки ошибок, а также находится ли вызвавший ошибку код в модуле класса. Break in Class Module (Прерывание в модуле класса). Выполнение проекта пре- рывается только на ошибках, которые возникли в коде модуля класса и не были перехвачены. Break on Unhandled Errors (Прерывание на необрабатываемых ошибках). Выпол- нение проекта прерывается на любой необрабатываемой ошибке, независимо от типа модуля, в котором она происходит. Рис. 12.2. Выбор способа обработки ошибок в среде разработки VBA Ошибки, которые возникают при выполнении программы, можно регистрировать, т.е. организовать запись сведений обо всех происходящих в программе ошибках в журнале ошибок, который представляет собой файл на диске. В этом случае всякий раз при воз- никновении ошибки информация о ней записывается в файл журнала, включая дату и время возникновения ошибки, а также другую полезную информацию. Журнал ошибок проще всего реализовать как класс, внедрив затем этот класс в проект как глобальный 290 Часть 3. Более сложные аспекты работы на VBA
объект. Для сохранения текущих свойств объекта Err в файле можно использовать метод Write. Новые записи при этом добавляются в конец файла, теперь журнал ошибок будет представлять собой регистрацию исторической последовательности возникающих при выполнении проекта ошибок. Работа с непредвиденными ошибками Далеко не всегда можно предвидеть все возможные и невозможные ошибки, которые могут возникнуть в той или иной процедуре, поэтому лучше включить во все создаваемые процедуры общую подпрограмму обработки ошибок — в дополнение к подпрограмме, об- рабатывающей конкретные учтенные ошибки. В этом случае возникшая непредвиденная ошибка не будет обработана специальным образом, но можно будет хотя бы предоставить пользователю какую-то стандартную информацию об ошибке (и записать ее в журнал ошибок, если он используется). При работе с непредвиденными ошибками полезно было бы знать, где именно произо- шла ошибка, т.е. в какой процедуре проекта она имела место. VBA не предоставляет такую информацию автоматически, но это можно достаточно просто организовать вручную. В каждой процедуре объявите константу, в которой хранится название процедуры, как показано ниже. Public Sub НекотораЯ—Процедура() Const ИМЯ_ПРОЦЕДУРЫ As String = ”Некоторая_Процедура” Dim msg As String End Sub Тогда общая программа обработки ошибок будет выглядеть так. ErrorHandler: ’ В начале находится код обработки конкретных учтенных ошибок. ’ Выполнение доходит до данного этапа только в том случае, ’ если возникла непредвиденная ошибка. msg = ’’Произошла непредвиденная ошибка. Пожалуйста, запишите ” msg = msg & ’’следующую информацию: ” & vbCrLf msg = msg & ’’Номер ошибки: ” & Err & vbCrLf msg = msg & ’’Описание: ” & Err. Description & vbCrLf msg = msg & ’’Источник: ” & Err. Source & vbCrLf msg = msg & ’’Место ошибки: ” & ИМЯ_ПРОЦЕДУРЫ MsgBox(msg) Отладка приложений При работе с программой, как мы уже выяснили, могут возникать ошибки синтакси- ческие (легко вылавливаемые и устраняемые), логические (препятствующие правильной работе программы), а также ошибки выполнения (как правило, останавливающие рабо- ту программы). Возникновение при работе программы тех или иных ошибок потребует их исправления, прежде чем дальнейшее использование программы будет возможно. Для исправления ошибки прежде всего необходимо отыскать ее в программе. Процесс Глава 12. Обработка ошибок и отладка программ 291
отыскания ошибок в программе называется отладкой. Хорошо, когда ошибки сами за- являют о себе, — это будут легкие ошибки, которые нельзя не заметить. Однако в про- грамме могут присутствовать и другие ошибки, которые будет очень непросто выявить. Например, в отличие от синтаксических ошибок, которые вылавливаются редактором VBA, логические ошибки можно обнаружить только создателями или пользователями программы. Поэтому настоятельно рекомендуется только что написанную программу обязательно протестировать, причем как можно более тщательно. При тестировании внимательно наблюдайте за ходом выполнения программы при каждом ее запуске, стараясь не пропустить малейших признаков ошибок или любых от- клонений в поведении программы. Обязательно обращайте внимание на точность и пра- вильный формат каждого из полученных результатов, выводимых программой на экран или помещаемых ею в документ. Старайтесь проследить за значениями всех переменных в ходе выполнения программы, чтобы иметь уверенность, что с этой стороны тоже не возникнет каких-либо неожиданностей. Вот несколько дополнительных советов по те- стированию программ. При работе с разными типами документов обязательно опробуйте работу програм- мы со всеми их допустимыми типами. Попытайтесь работать с программой, когда в VBA-приложении не открыт ни один документ или когда открыто сразу несколько документов. Проверьте, как выполняется программа, когда окно документа развернуто, сверну- то или восстановлено. Попробуйте выполнить программу, когда в окне документа выделены различные элементы или группы элементов. При вводе информации пользователем через окно ввода или специальную форму (если этого требует программа) обязательно опробуйте все возможные варианты ввода и проанализируйте получаемый результат. Например, если вводимое значе- ние предполагается числовым, попробуйте ввести строку символов, дату и т.д. При работе программы со значениями дат и времени попробуйте задать ей разные даты (в том числе, например, 29 февраля) и разное время суток (в том числе и пол- ночь). Опробуйте не только ввод разных значений даты и времени, но и проверьте работу самой программы при обработке разных дат и разных значений времени, установив для этого на своем компьютере подходящие показания системного вре- мени и даты. Если после успешно проведенного тестирования при запуске программы все же воз- никнет прерывание (т.е. появится сообщение об ошибке выполнения), необходимо будет обратиться к отладке программы с помощью встроенных средств отладки редактора VBA. Редактор VBA, как и все современные системы программирования, предоставляет в распоряжение программиста различные инструменты интерактивной отладки программ- ного кода. К средствам отладки в первую очередь относится панель инструментов Debug, показанная на рис. 12.3. ► и j 1 з .3 Д £ Рис. 12.3. Панель инструментов Debug 292 Часть 3. Более сложные аспекты работы на VBA
ЛЛ Панель инструментов Debug не выводится на экран по умолчанию. Для того чтобы отобразить эту панель, необходимо выбрать команду меню View^Toolbars^Debug. Панель инструментов Debug настраивается и перемещается по экрану точно так же, как и все другие панели инструментов Windows-приложений. Наименование, описа- ние всех кнопок панели инструментов Debug и комбинации клавши, которыми мож- но воспользоваться при отладке программного кода, перечислены в приложении Б. При отладке программы часто возникает необходимость проследить за тем, как вы- полняются отдельные операторы в отлаживаемой программе или же какие значения принимают те или иные переменные на различных этапах выполнения программы. Для достижения этих целей в редакторе VBA реализован режим прерывания. Останов выполнения программы Останов выполнения программы или перевод ее в режим прерывания (break) — это вре- менная остановка выполнения программы на некотором операторе в программном коде. В режиме прерывания программа не выполняется, но при этом занимает определенный уча- сток памяти. В этом режиме можно просматривать и изменять значения переменных и вы- ражений, а также перемещаться по программному коду, выполняя при этом один или группу операторов. Для перевода программы в режим прерывания существует ряд способов. Назначение точки останова требуемой строке программного кода. Когда при вы- полнении программа дойдет до оператора, с которым связана точка останова, ее выполнение прервется и программа перейдет в режим прерывания. Использование в программном коде оператора Stop. В результате выполнения этого оператора программа переходит в режим прерывания, причем продолжение ее ра- боты начнется с выполнения оператора, следующего заданным оператором Stop. Запуск программы непосредственно в режиме прерывания. В этом случае программа запускается на выполнение с помощью команды Debugs Step Into или нажатия клавиши <F8> (подробнее об этом мы будем говорить чуть ниже). Ручной останов работы программы. Выполняется с помощью щелчка на кнопке Break (Пауза), выбора команды меню Run^Break или нажатия клавиш <Ctrl+Break> во время выполнения программы. Эта возможность полезна для восстановления кон- троля над программой, которая по каким-то причинам не желает останавливаться сама. В этом случае после ручной остановки программы у вас появится возмож- ность установить, где именно произошло ее зацикливание. Создание контролируемых выражений. Этот инструмент позволяет включить в состав программы контрольные точки, в которых анализируется результат вычисления выражения или значение указанной переменной. В этом случае программа будет остановлена, когда контролируемое выражение либо получит значение True, либо просто изменит свое значение. Выполняемая программа также переходит в режим прерывания, когда в ней возникает ошибка выполнения. В этом случае VBA выводит диалоговое окно с описанием возник- шей ошибки и следующими кнопками (рис. 12.4). Continue (Продолжить). Щелчок на данной кнопке позволяет продолжить выпол- нение программы. Чаще всего при возникновении ошибки выполнения эта кнопка будет неактивна. Глава 12. Обработка ошибок и отладка программ 293
End (Закончить). Щелчок на этой кнопке прекращает выполнение программы. Debug (Отладка). Щелчок на данной кнопке переводит выполнение программы в режим прерывания. При этом редактор VBA откроет окно программного кода, в котором желтым цветом будет выделен тот оператор, при выполнении которого возникла данная ошибка. Help (Справка). При щелчке на этой кнопке будет выведено диалоговое окно со справочной информацией, описывающей возникшую ошибку. Рис, 12.4, Окно сообщения об ошибке выполнения Чтобы совсем прекратить выполнение программы, выберите команду меню Run«=£ Reset. Для этой же цели можно воспользоваться кнопкой Reset панели инструментов Debug. В среде Windows нажатие комбинации клавиш <Alt+F4> останавливает выполне- ние вообще любой программы, в том числе и VBA-программ. Однако прежде чем нажать клавиши <Alt+F4>, убедитесь, что активной является именно ваша VBA-программа — в противном случае закроется либо редактор Visual Basic, либо базовое VBA-приложение, либо какая-то другая программа Windows. Иначе говоря, нажатие <Alt+F4> вызывает не- медленное прекращение работы программы, активной в данный момент. Точки останова Перевести программу в режим прерывания в некоторый, заранее известный момент ее выполнения можно с помощью установки точки останова, которая указывает, что при достижении данного оператора программа должна перейти в режим прерывания, т.е. приостановить работу. Такую точку можно поместить в любой строке программного кода. Однако чаще всего точку останова помещают в строке программного кода непосредствен- но перед оператором, который, по вашему предположению, является причиной возник- новения ошибки. В этом случае при останове программы в ее тексте выделяется тот самый “подозрительный” оператор, который будет выполнен сразу же после выхода программы из режима прерывания. Это позволяет выполнить любые проверки и необходимые под- готовительные действия, выявляющие причины возникновения ошибки. Для размещения точки останова в программном коде (рис. 12.5) выполните одно из следующих действий. 1. Щелкните на серой полоске, расположенной в левой части окна редактирования кода, напротив требуемой строки программного кода. 2. Поместите курсор в нужную строку кода и нажмите <F9>. Количество размещаемых точек останова неограниченно, поэтому в разных строках программы можно разместить столько точек останова, сколько сочтете необходимым. 294 Часть 3. Более сложные аспекты работы на VBA
Единственное условие — нельзя размещать точки останова в строках комментариев и строках с операторами, которые VBA на самом деле не выполняет, например в строках с объявлениями переменных. Рис, 12,5, Назначение точки останова в редакторе VBA После помещения в программу точки останова она будет выполняться обычным об- разом вплоть до оператора, указанного этой точкой. Это позволяет при отладке пропу- стить ту часть программного кода, которая (по вашему мнению) не содержит ошибок. Как только по ходу выполнения программы достигается оператор, которому назначена точка останова, работа программы приостановится. Теперь можно будет проверить (и при необходимости изменить) текущие значения любых переменных, а с помощью команд по- шагового выполнения (Step Into и пр.) проследить за тем, как эти значения меняются при последовательном выполнении каждого из операторов в блоке, связанном с устраняемой ошибкой. После того как ошибки в программном коде будут исправлены, можно удалить ненуж- ные точки останова, и тогда при всех последующих запусках программа будет выполняться уже без каких-либо задержек. Удалить установленную ранее точку останова можно по- вторным щелчком на ней в окне редактирования кода или нажатием клавиши <F9>. Для того чтобы удалить сразу все назначенные в программе точки останова, выберите команду меню Debugs Clear All Breakpoints или нажмите комбинацию клавиш <Ctrl+Shift+F9>. Из сказанного выше следует, что точки останова использовать очень просто, но они имеют один недостаток: они временны, т.е. действительны только в данном сеансе работы с редактором VBA. Точки останова не сохраняются в программном коде и при закрытии окна документа основного VBА-приложения сведения о них теряются. Когда программа достаточно сложная, едва ли вам удастся проверить и отладить ее полностью с первого же раза. Скорее всего, тестирование и отладка такой программы потребуют нескольких дней работы. Однако открыв проект в редакторе VBA в следующий раз, установленных прежде точек останова вы уже не увидите. Глава 12. Обработка ошибок и отладка программ 295
Избежать подобных неприятных ситуаций можно размещением в коде постоянных точек прерывания, создаваемых с помощью оператора Stop. Чтобы установить постоян- ную точку прерывания, просто поместите оператор Stop в требуемое место программного кода. Теперь, как только этот оператор встретится при выполнении программы, послед- няя будет приостановлена и перейдет в режим прерывания. Поскольку оператор Stop сохраняется в коде вместе с другими операторами программы, с его помощью создается постоянная точка останова, которую можно будет удалить, только удалив сам оператор Stop из программного кода. После того как причина появления ошибки установлена (или станет ясно, что вы ище- те не там, где надо), выполнение программы можно продолжить. Для этого используются те же самые команды, что и для первоначального запуска программы на выполнение. В режиме прерывания команда Run Sub/Useform меню Run, которой запускается вы- полнение программного кода, а также кнопка Run панели инструментов Debug изменя- ют свои названия на Continue (Продолжить). Это же замечание относится и к клавише <F5> — ее функциональность меняется аналогичным образом. Продолжающая свое вы- полнение программа может вновь перейти в режим прерывания, если будет обнаружена очередная точка останова или возникнут иные условия, при которых активизируется ре- жим прерывания. Отладка кода в пошаговом режиме Теперь, когда вы уже знаете, как перейти в режим останова и как из него выйти, можно приступить к рассмотрению таких команд меню Debug, как Step Into, Step Over и Step Out, позволяющих выбрать тот или иной вариант дальнейших действий, выполняемых в пошаговом режиме. Очевидно, что такая возможность будет чрезвычайно полезной при отладке программы. Пошаговое выполнение операторов в процессе отладки позволяет проследить за тем, что действительно происходит при выполнении отдельных процедур, функций или программы в целом. Доступ к командам группы Step возможен через меню Debug, с помощью соответствующих кнопок панели инструментов Debug, а также с по- мощью комбинаций клавиш, приведенных ниже в соответствующих подразделах. Команда Step Into Команда Step Into (Войти в процедуру) вызывается нажатием клавиши <F8>. При вводе этой команды выполняется очередной оператор программного кода, а затем работа программы вновь приостанавливается в режиме прерывания. Эта команда будет полезна при необходимости выполнять процедуру по шагам, в порядке естественного выполнения операторов. Каждый раз при вводе этой команды VBA выполняет следующий оператор программы, и программа вновь переходит в режим прерывания, что позволяет увидеть происшедшие при этом изменения. Если очередной оператор является вызовом проце- дуры типа Sub или Function, то применение команды Step Into приведет к открытию текста вызываемой процедуры в окне редактирования кода и позволит пройти эту про- цедуру по шагам, увидев результаты всех выполняемых в ней действий. МНВ Команда Step Into также позволяет начать выполнение любой программы или процеду- ры сразу же в пошаговом режиме. Для этого достаточно в окне редактирования кода по- местить курсор в любое место интересующей вас процедуры и ввести команду Step Into (например, нажать <F8>). В результате будет выполнен первый оператор процедуры, а затем она будет переведена в режим прерывания. Понятно, что последующие нажатия клавиши <F8> приведут к пошаговому выполнению данной процедуры. 296 Часть 3. Более сложные аспекты работы на VBA
Команда Step Over Команда Step Over (Обойти процедуру) вызывается нажатием комбинации клавиш <Shift+F8>. При вводе этой команды выполняется следующий оператор, а затем работа программы вновь приостанавливается в режиме прерывания. Однако если следующий оператор является вызовом некоторой процедуры, то последняя выполняется полностью и работа программы останавливается уже после выхода из этой процедуры. Из сказанного следует, что команда Step Over работает подобно команде Step Into, но если очередным оператором является вызов процедуры или функции, команда Step Over не приводит к пошаговому выполнению вызываемой процедуры и останов программы происходит только после завершения ее выполнения. Иначе говоря, если оператор, кото- рый должен выполняться следующим, вызывает некоторую процедуру, то при вводе ко- манды Step Over она будет выполнена целиком, без предоставления возможности увидеть промежуточные результаты ее работы. Подобный обход процедур при отладке позволяет экономить очень много времени (конечно, при условии, что вызываемые процедуры ра- ботают так, как нужно). С помощью команды Step Over нельзя начать выполнение программы в пошаговом режиме. Команды Step Out и Run То Cursor Команда Step Out (Выйти из процедуры) вызывается нажатием комбинации клавиш <Ctrl+Shift+F8>. При вводе этой команды программа выполняется до конца текущей процедуры, а затем останавливается в режиме прерывания на операторе, следующем в вы- зывающей процедуре непосредственно за оператором вызова данной процедуры. Кроме перечисленных выше трех команд группы Step, в меню Debug имеется также команда Run То Cursor (Выполнить до курсора), которая вводится нажатием комбинации клавиш <Ctrl+F8>. В этом случае программа выполняется до той строки кода, в которой в данный момент находится курсор, после чего останавливается в режиме прерывания. Обратите внимание на то, что команды Step Into и Run То Cursor в меню Debug до- ступны, даже если программа не находится в режиме прерывания. Начиная выполне- ние программного кода с одной из этих команд, а не с обычной команды Run Sub/User Form (клавиша <F5>), можно не только запустить проект, но и выполнять его либо по- строчно, либо до точки текущего положения курсора. Выполнение пошаговой отладки Пошаговое выполнение программы позволяет при переходе ее в режим прерывания не только выяснять текущие значения переменных, но и редактировать программный код или же изменять порядок, в котором должны выполняться операторы. Другими словами, в режиме прерывания вам предоставляется возможность добавлять новые операторы, кото- рые затем станут частью выполняемой программы, а также редактировать или удалять уже имеющиеся. Можно также объявлять новые переменные, чтобы сразу же использовать их в вычислениях в комбинации с уже существующими переменными программы. Кроме того, можно перемещаться в программном коде как вперед, так и назад, пропускать не- верные фрагменты программного кода или повторять выполнение некоторого фрагмента программного кода до тех пор, пока не удастся понять, как же он в действительности ра- ботает и в чем заключается причина возникновения ошибки. Глава 12. Обработка ошибок и отладка программ 297
Для изменения порядка выполнения операторов программы в режиме прерывания сна- чала поместите указатель мыши на стрелку, указывающую на оператор, при выполнении которого произошел останов (при этом указатель мыши сам примет вид аналогичной стрел- ки — как показано на рис. 12.6, а), после чего перетащите эту стрелку к требуемому опера- тору (рис. 12.6, 6). После отпускания кнопки мыши выделенным станет выбранный вами оператор, и выполнение программы будет продолжено с указанного места (рис. 12.6, в). а) б) е) Рис. 12.6. Изменение порядка выполнения операторов в программе 298 Часть 3. Более сложные аспекты работы на VBA
Следует также отметить, что в редакторе VBA реализован механизм автоматической подсказки, которая позволяет увидеть текущее значение любой переменной в программе. Для этого, когда программа находится в режиме прерывания, задержите на секунду ука- затель мыши на имени интересующей вас переменной, и на экране появится окно под- сказки — небольшой прямоугольник с именем и текущим значением переменной в нем (рис. 12.7). Рис. 12.7. Автоматическая подсказка значения переменной Возраст Обычно режим подсказки значений данных по умолчанию включен, но если прямоу- гольники с подсказками значений на экране не появляются, необходимо самостоятельно установить флажок опции Auto Data Tips (Автоматическая подсказка значений). Для этого выберите команду меню Tools^Options и установите этот флажок на вкладке Editor раскрывшегося диалогового окна Options. Редактор Visual Basic позволяет также увидеть тип и область видимости переменной. Для этого поместите текстовый курсор на имя переменной и нажмите <Ctrl+I >. На экране появится окно подсказки Quick Info (Краткая справка) с соответствующей информацией, как показано на рис. 12.8. При этом вовсе не обязательно, чтобы программа находилась в режиме прерывания, что особенно удобно при работе с большими программами, когда объявления переменных находятся где-то в самом начале кода. Рис. 12.8. Отображение подсказки Quick Info для переменной Глава 12. Обработка ошибок и отладка программ 299
Если поместить текстовый курсор на имя подпрограммы или встроенной функции, то уТД при нажатии <Ctrl+1> будет отображено окно Quick Info со сведениями об ее аргумен- тах. Для закрытия окна Quick Info достаточно щелкнуть мышью в любом месте окна программного кода или нажать клавишу <Esc>. Специализированные окна отладчика Помимо средств прерывания и пошагового выполнения, отладчик редактора VBA предоставляет в распоряжение программиста несколько специализированных диалого- вых окон, призванных дополнительно упростить процесс отладки программ и предоста- вить программисту дополнительные инструменты поиска ошибок. Доступ к этим окнам осуществляется с помощью команд меню View, а также соответствующих кнопок панели инструментов Debug. Окно Immediate В режиме прерывания окно Immediate (Окно немедленного выполнения команд) имеет сферу действия, совпадающую с областью видимости текущей процедуры. Ис- пользование этого окна упрощает поиск ошибок в программе. Чтобы открыть окно Im- mediate (рис. 12.9), выполните одно из следующих действий: выберите команду меню View=>Immediate Window, щелкните на кнопке Immediate Window панели инструментов Debug или просто нажмите <Ctrl+G>. Рис. 12.9. Окно Immediate, отображающее текущее значе- ние переменной IntBoapacT Окно Immediate редактора VBA позволяет контролировать значения переменных и вы- ражений, проводить вычисления, изменять значения переменных и проверять результаты выполнения функций. Кроме того, в окне Immediate можно выполнять отдельные опера- торы сами по себе, без помещения их в текст какой-либо процедуры. Для отображения в окне Immediate интересующей информации используется оператор Print. Введите этот оператор в окне Immediate и в качестве аргументов перечислите интересующие вас пере- менные и выражения, а затем нажмите клавишу <Enter> (см. рис. 12.9). 300 Часть 3. Более сложные аспекты работы на VBA
л Л Если в операторе Print необходимо указать несколько аргументов, они должны от- делиться запятыми. Предоставляемые редактором VBA средства отладки собраны в объекте Debug. Объект VBA Debug имеет только один метод — Print. При необходимости можно направить в окно Immediate вывод промежуточных значений переменных и выражений непо- средственно при выполнении программы. Для этого разместите в подходящих строках программы операторы, вызывающие метод Debug.Print (рис. 12.10). По завершении выполнения программы можно будет просмотреть сразу все выведенные значения. Таким образом, можно быстро выяснить, все ли интересующие вас значения оказались верны, при этом рассматривать их по отдельности в разные моменты времени при пошаговом выполнении программы нет необходимости. I (General) |lestListlnfMrt Sub TestPrint() ’ запись данных в последовательный файл File Dim TextLine Open "File" For Output As #2 Print Print Print Close End Sub #2 #2 #2 #2 "Приходя на работу "не забудь поздороваться с сотрудниками. "Уходя, не забудь сказать им до свидания ' считывание данных и вывод их на экран Sub TestListInput() Dim StrSl Open "File" For Input As #2 Do ¥hile Not EOF(2) Line Input #2, StrSl Debug.Print StrSl Loop Close #2 End Sub ' открыть файл 1 цикл чтения до ко 1 считать данн 1 вывод на экран ’ закрытие файла Приходя на работу не забудь поздороваться с сотрудниками. Уходя, не забудь сказать им до свидания. zi I Puc. 12.10. Окно Immediate с результатами выполнения опера- тора, вызывающего метод Debug. Print Из окна Immediate можно также обратиться к справочной системе VBA для получения информации по некоторому ключевому слову. Для этого следует нажать клавишу <F1>, которая здесь работает точно так же, как и в окне редактирования программного кода. В окно Immediate можно перетащить текст, выделенный в окне редактирования про- граммного кода, — при этом отпадает необходимость вручную набирать длинные выра- жения или имена переменных снова. Однако помните, что если при перетаскивании не удерживать нажатой клавишу <Ctrl>, выделенный фрагмент программного кода будет не скопирован в окно Immediate, а перемещен туда из окна редактирования. Глава 12. Обработка ошибок и отладка программ 301
Окно Locals Окно Locals (Окно локальных переменных) практически всегда должно присутство- вать на экране, когда отладка программы выполняется в режиме прерывания. Чтобы от- крыть окно Locals, щелкните на кнопке Locals Window панели инструментов Debug или выберите команду меню View^Locals Window. В окне Locals, показанном на рис. 12.11, автоматически отображаются имена, значе- ния и типы данных всех переменных, доступных в выполняемой в данный момент проце- дуре. Эта информация обновляется редактором Visual Basic после выполнения любого из операторов, поэтому в окне Locals всегда представлены текущие значения переменных. Рис. 12.11. Окно Locals с текущими значениями переменных выполняемой процедуры Окно Locals содержит три столбца: Expression — имя переменной или объекта; Value — текущее значение переменной или свойства объекта; Туре — тип данных или объекта. Если нужная вам информация не помещается в столбце, то ширину столбцов в окне Locals можно изменить. Для этого поместите указатель мыши на разделитель между заго- ловками столбцов и, после того как он примет вид двунаправленной стрелки, перетащите этот разделитель влево или вправо, чтобы установить требуемую ширину столбца. При необходимости можно предварительно увеличить размеры самого окна Locals. Отображаемые в окне Locals строки могут содержать информацию как об обычных переменных, так и о массивах, переменных пользовательских типов и объектах. Такие элементы не имеют собственных значений, а содержат другие переменные или элементы иных типов. Изначально после запуска процедуры в окне Locals они будут представлены в виде свернутых разделов, поэтому содержащихся в них подчиненных элементов видно не будет. Для того чтобы развернуть любой из свернутых разделов, щелкните на прямоуголь- 302 Часть 3. Более сложные аспекты работы на VBA
нике с плюсом слева от имени раздела. Теперь в развернутом разделе появится список всех элементов со значениями, которые каждый из них имеет в настоящий момент. Развернутыми уже на самом верхнем уровне иерархии окна Locals будут показаны только те переменные, которые явно или неявно объявлены в выполняемой в данный мо- мент процедуре. Чтобы увидеть переменные уровня модуля, доступные всем процедурам данного модуля, разверните первый раздел в окне Locals. Этот раздел всегда принадлежит модулю, содержащему выполняемую процедуру. В окне Locals не отображаются открытые переменные или переменные из других проектов. Следует отметить, что при необходимости значения переменных можно менять непо- средственно в окне Locals. Для этого требуется выполнить следующие действия. 1. Выполните двойной щелчок на текущем значении переменной так, чтобы ока- залось подсвеченным только это значение (после щелчка в любом другом месте строки выделенной окажется вся строка). 2. Введите новое значение. Если значение должно быть строковым, заключите его в кавычки, а если это значение даты, поместите его между парой символов #. 3. Если вы передумали менять значение переменной, нажмите <Esc>, а чтобы зафик- сировать внесенные изменения — <Enter>. При этом, если введенное значение редактор VBA сочтет недопустимым, будет выдано сообщение об ошибке с некото- рыми объяснениями по поводу того, что именно оказалось неправильным. Помимо этого, можно менять значения элементов массивов и элементов переменных пользовательских типов. Однако для получения доступа к этим элементам не забудьте раз- вернуть раздел, соответствующий нужному массиву или переменной пользовательского типа. При работе с объектной переменной можно менять свойства соответствующего объ- екта (за исключением тех, которые предназначены только для чтения), но нельзя изменить ссылку на объект. Кроме того, не забывайте, что увидеть подлежащие редактированию свой- ства объекта можно, только развернув раздел, соответствующий объектной переменной. Окно Watches При отладке редактор VBA предоставляет программисту возможность использовать определенные выражения для контроля за данными, с которыми в этот момент работает отлаживаемая программа. Этим контрольным выражением может быть переменная, свой- ство, функция и т.д. Для этой цели в редакторе VBA используется окно Watches (Окно контролируемых выражений), в котором можно просматривать значения выражений по ходу пошагового выполнения программного кода. Общий вид этого окна показан на рис. 12.12. Чтобы открыть окно Watches, щелкните на соответствующей кнопке панели инструментов Debug или выберите команду меню View^Watch Window. Рис. 12.12. Окно Watches в режиме пошагового выполнения программного кода Глава 12. Обработка ошибок и отладка программ 303
Окно Watches делает, по сути, то же самое, что и окно Locals, но с одним очевид- ным отличием — те выражения, значения которых будут показаны в этом окне, долж- ны задаваться непосредственно вами. Причем каждая, из строк окна Watches позволяет контролировать значение любого допустимого в VBA выражения, а не только отдельной переменной. Поскольку в окне Watches можно контролировать переменные из любого модуля или процедуры проекта, в этом окне добавлен еще один столбец Context (Кон- текст — наименование процедуры и модуля, где находится выражение). В этом столбце указывается область действия, в рамках которой отображается значение данной перемен- ной или выражения. Если выполняемая процедура находится вне заданного контекста, можно будет увидеть только пометку Out Of Context (Вне контекста). Если необходимо контролировать значение некоторого выражения или отдельной переменной программного кода, требуется добавить это выражение (переменную) в окно Add Watch. Для этого достаточно в окне программного кода выделить требуемое выра- жение (или поместить текстовый курсор на имя переменной), щелкнуть на выделенном тексте правой кнопкой мыши и выбрать в раскрывшемся контекстном меню команду Add Watch. На экране раскроется диалоговое окно Add Watch, показанное на рис. 12.13. Другой вариант — выделив требуемое выражение, выбрать команду меню Debug^Add Watch. Рис. 12.13. Диалоговое окно Add Watch В диалоговом окне Add Watch в поле Expression (Выражение) указывается то выраже- ние, значение которого необходимо контролировать. Если перед открытием окна в тексте программы желаемое выражение было выделено именно в том виде, который требуется, то менять в поле Expression ничего не придется. Однако при необходимости выражение в этом поле всегда можно откорректировать и даже просто ввести заново. В группе Context выбираются процедура и модуль, в котором редактор VBA будет вычислять и отображать значение заданного выражения. Обычно в полях Procedure (Процедура) и Module (Мо- дуль) указываются те процедура и модуль, из которых контролируемое выражение было выбрано. Однако если необходимо видеть значение данного выражения при выполнении другой процедуры, выберите ее имя в соответствующем списке. Если это процедура из другого модуля, то сначала выберите нужный модуль, а затем процедуру. Кроме того, если вас интересует именно значение контролируемого выражения, переключатель Watch Туре (Тип контроля) оставьте установленным в положение Watch Expression (Контролируемое выражение). Завершив настройку, щелкните на кнопке ОК. В окне Watches появится новая строка (если это окно еще не было открыто, оно откроется автоматически), содержимое ко- торой будет соответствовать значениям, введенным в поля диалогового окна Add Watch. 304 Часть 3. Более сложные аспекты работы на VBA
Следует отметить, что если задано одно или несколько контролируемых выражений, то информация в окне Watches будет обновляться при каждом входе программы в режим прерывания. В этом случае можно проанализировать значения некоторых выражений и сделать заключение, дают ли они какую-либо полезную информацию о причинах воз- никновения ошибки. Кроме этого стандартного режима, можно также связать контролируемые выраже- ния с автоматическим переводом программы в режим прерывания. В частности, мож- но потребовать, чтобы программа переводилась в режим прерывания всякий раз, когда контролируемое выражение дает при вычислении значение True или же когда значение контролируемого выражения просто изменяется. Данный тип контроля выбирается в диа- логовом окне Add Watch установкой переключателя Watch Туре в положение Break When Value is True (прерывание, когда контрольное выражение имеет значение True) или Break When Value Changes (прерывание, когда значение контрольного выражения изменяется). В окне Watches для каждого из трех возможных типов контроля за значением выражения в крайнем слева столбце отображаются разные символы. Когда выполнение программы прерывается за счет проверки значения контролируемого выражения, соответствующая строка в окне Watches выделяется (но чтобы увидеть это выделение, следует из окна про- граммного кода перейти в окно Watches!). В окне Watches, так же как и в окне Locals, можно менять значение выражения прямо во время выполнения программы. Однако установки в столбце Context для контролируе- мого выражения в окне Watches менять нельзя. Если это все же необходимо выполнить, то откройте диалоговое окно Edit Watch (Редактирование контролируемого выражения), показанное на рис. 12.14. Для этого нажмите комбинацию клавиш <Ctrl+W> или выбери- те команду меню Debugs Edit Watch. Рис. 12.14. Диалоговое окно Edit Watch В диалоговом окне Edit Watch можно изменить контекст контролируемого выражения, его тип и даже само выражение точно так же, как в окне Add Watch при первоначальном добавлении выражения к списку контролируемых. Кроме того, можно удалить некоторое контролируемое выражение, если его значение больше не требуется контролировать. Для этого либо в окне Watches выделите строку с выражением, которое требуется удалить, и нажмите клавишу <Delete>, либо выберите команду меню Debug^Edit Watch и щел- кните на кнопке Delete в раскрывшемся диалоговом окне. Глава 12. Обработка ошибок и отладка программ 305
При отладке программ в редакторе VBA существует также возможность быстрого контроля за данными. Для этого в редакторе VBA используется окно Quick Watch (Окно быстрого контроля), показанное на рис. 12.15. Чтобы открыть окно Quick Watch в режиме прерывания, выделите в тексте программы необходимое выражение и нажмите <Shift+F9> или же выберите команду меню Debug^Quick Watch. В раскрывшемся диалоговом окне Watch Quick будет отображено текущее значение выражения, его тип данных и контекст. Рис. 12.15. Отображение информации о значении выражения в окне Quick Watch Окно Call Stack Часто при отладке программы возникает необходимость уточнить то место программ- ного кода, в котором выполняемая программа находилась в момент перехода в режим прерывания, или же установить последовательность вызовов процедур, выполненных до оператора, породившего ошибку. Предположим, что при выполнении программы в определенной процедуре возникает ошибка, вызванная тем, что из вызывающей про- цедуры ей передается некорректный аргумент. В тех случаях, когда процедура в программе вызывается из нескольких других процедур, удобнее всего воспользоваться диалоговым окном Call Stack (Стек вызовов), с помощью которого можно проследить за реальной последовательностью вызова процедур при выполнении программы, что позволит опреде- лить, из-за какой именно вызывающей процедуры происходит эта ошибка. В стеке вы- зовов отображаются все активные на данный момент процедуры, т.е. процедуры, которые еще не закончили свою работу. Чтобы открыть диалоговое окно Call Stack (рис. 12.16), выберите команду меню View^Call Stack или нажмите комбинацию клавиш <Ctrl+L> (предварительно необхо- димо тем или иным образом перевести программу в режим прерывания). Рис. 12.16. Диалоговое окно Call Stack со списком активных процедур Диалоговое окно Call Stack содержит две кнопки — Show и Close. Кнопка Close пред- назначена для закрытия диалогового окна Call Stack, а с помощью кнопки Show можно найти в программном коде оператор, вызвавший выполняемую в данный момент подпро- 306 Часть 3. Более сложные аспекты работы на VBA
грамму. Этой кнопкой можно также воспользоваться для проверки значений аргументов, переданных выполняемой процедуре. Сделать это очень просто: выберите в списке ак- тивных процедур имя той процедуры, которая вызвала текущую процедуру, и щелкните на кнопке Show. VBA закроет диалоговое окно Call Stack и отметит в окне программного кода оператор, содержащий вызов текущей процедуры. Резюме В этой главе подробно обсуждался один из важнейших аспектов работы программи- ста — тестирование и отладка программ. Понятно, что никто не застрахован от ошибок, возникающих по самым разным причинам. Понятно и то, что программа с ошибками не может считаться законченной и ее нельзя будет использовать для решения практических задач. Отсюда становится очевидным, что написать программу — это только полдела. Не менее важно убедиться в том, что она работает именно так, как ожидалось, корректно выполняя все предусмотренные функции. При обнаружении каких-либо отклонений не- обходимо установить их причину, а затем и устранить ее. Для этого редактор VBA предоставляет программисту богатый набор инструментов, позволяющих эффективно контролировать и вносить требуемые коррективы в работу программ. Спектр этих инструментов очень широк — от пошагового режима выполнения программ до специализированных окон, позволяющих собирать любую интересующую вас информацию о программе и обрабатываемых данных. Эффективное овладение всем этим инструментарием просто необходимо каждому, кто хочет научиться успешно писать программы на VBA. Еще один важный аспект работы программиста, речь о котором шла в этой главе, — это создание надежных программ, которые будут устойчиво работать с реальными данными, часто неполными или содержащими различного рода ошибки. В текст программы дол- жен быть включен специальный код, позволяющий перехватывать системные сообщения о возникновении ошибок и корректно их обрабатывать. Главная цель в этом случае — со- хранить работоспособность программы в критических ситуациях, а также защитить об- рабатываемые данные от разрушения или искажения. Тестовые задания Ниже приведено несколько тестовых заданий, предназначенных для закрепления из- ложенного в этой главе материала. В каждом задании вам предлагается вопрос й несколь- ко вариантов ответа на него, один (или несколько) из которых является правильным, а остальные — нет. Укажите правильный ответ. 1. Ошибки, возникающие при написании и эксплуатации программ, написанных на языке VBA, могут относиться к следующим категориям: а) ошибки пользователя; б) ошибки выполнения; в) ошибки оборудования; г) логические ошибки; д) ошибки компиляции; е) ошибки в данных. Глава 12. Обработка ошибок и отладка программ 307
2. Для организации перехвата ошибок в процедуру необходимо поместить следующие операторы: a) On Error, Sub Error, текст обработчика; б) On Error, Exit Sub, текст обработчика; в) On Error, текст обработчика; г) Sub Error, текст обработчика. 3. Системный номер (код) ошибки определяет: а) ее тип; б) порядковый номер возникновения; в) место появления ошибки; г) степень опасности ошибки. 4. Отладкой принято называть: а) проверку функционирования программы в различных режимах; б) организацию в программе перехвата возникающих ошибок; в) процесс отыскания в программе причин возникновения ошибок; г) процедуру пошагового выполнения программ; д) устранение причин найденных в программе ошибок. 5. Диалоговое окно Call Stack позволяет: а) останавливать выполнение программы в заданной точке; б) просматривать значения переменных и выражений; в) переводить программу в режим прерывания и изменять последовательность вы- полнения операторов; г) следить за последовательностью вызова процедур и значениями передаваемых им параметров; д) проверять результаты выполнения процедур и функций. 308 Часть 3. Более сложные аспекты работы на VBA
Часть Создание приложений в MS Office В этой части... > Глава 13. Программирование на VBA в Excel > Глава 14. Программирование на VBA в Word > Глава 15. Программирование на VBA в Outlook > Глава 16. Общие аспекты программирования на VBA в приложениях Microsoft Office

Глава 13 Программирование на VBA в Excel В этой главе... ♦ Объектная структура Excel ♦ Объект Workbook ♦ Объект Worksheet ♦ Объект Range ♦ Использование диалоговых окон Excel ♦ Программирование пользовательских функций ♦ Использование встроенных функций Excel ♦ Программирование событий Excel ♦ Работа с диаграммами ♦ Резюме Язык VBA служит мощным инструментом для создания настраиваемых приложений, базирующихся на электронных таблицах и способных выполнять вычисления и форма- тирование результатов расчетов. При программировании на VBA в Excel следует знать, что Excel — это программа для работы с электронной таблицей, предназначенной для анализа и отображения данных. В Excel можно хранить числовые и текстовые данные, проводить вычисления с данными и создавать диаграммы, основанные на данных. В Excel реализовано большое количество специализированных функций для часто используемых вычислений, включая финансовые, статистические и научные. В первом приближении файл Excel можно представить себе как бухгалтерскую книгу, содержащую множество страниц, каждая из которых разграфлена на столбцы и строки. Эта книга невероятно велика — на каждом листе содержится 1 048 576 строк и 16 384 столбца. Столбцы идентифицируются буквами: первые 26 — от А до Z, следующие 26 — от АА до AZ и так до XFD. Строки идентифицируются числами, начиная с единицы. Количество рабочих листов в книге ограничивается только доступной памятью. На пересечении строк и столбцов находятся ячейки. Каждая ячейка может содержать число, текст или формулу. Именно возможность размещать в ячейках листа не только дан- ные, но и формулы, составляет основу чрезвычайной эффективности приложения Excel. Формулы позволяют выполнять практически любые типы вычислений на основе данных, содержащихся в других ячейках того же рабочего листа или других рабочих листов той же или другой рабочей книги.
Приложение Excel также предоставляет пользователю эффективные средства построе- ния диаграмм для графического представления данных, которое выполняется множеством разнообразных способов. Когда данные на рабочем листе изменяются, результаты вы- числения всех формул автоматически пересчитываются и изменяется вид уже созданных диаграмм. Встроенные функции Excel можно использовать как непосредственно в этом приложении, так и вызывать из среды других программ Microsoft Office или иных при- ложений, поддерживающих язык VBA, применяя эти формулы как инструмент для чис- ленного анализа данных или построения диаграмм. Объектная структура Excel В VBA для каждого приложения Office 2010 определено множество объектов, органи- зованных в иерархию, называемую объектной моделью приложения. Поэтому, работая с языком VBA в среде Excel, для достижения успеха необходимо хорошо понимать, что такое объект, и четко представлять себе объектную модель этого приложения. Итак, объекты в Excel, как и в других приложениях MS Office 2010, образуют единую иерархию объектов, начальный фрагмент которой показан на рис. 13.1. Как видите, на вершине этой иерархии находится объект Application (Приложение), который со- держит все остальные объекты и отвечает за функционирование всей программы Excel в целом. Объект Application выступает хранилищем для свойств и методов, которые не подходят для включения в любой другой объект, но необходимы для программного управ- ления Excel. Например, существуют свойства объекта Application, предназначенные для управления обновлением экрана и включения предупреждений. Существует метод объекта Application, пересчитывающий формулы в открытых книгах. | Application | ^Workbooks (Workbook) | ►>- -[Worksheets (Worksheet) | -jcharts (Chart) | -| Documentproperties (Documentproperty) | ~~[ vBProject I Puc. 13.1. Начальный фрагмент объектной модели при- ложения Microsoft Excel 2010. Темным выделены только объекты, а светлым — объекты и коллекции. Стрелки указывают на существование подчиненной подсхемы Когда программа на языке VBA запущена в среде Excel, объект Application это- го приложения автоматически становится доступным ей посредством ключевого слова Application. Более того, объект Application принимается в любой VBA-программе в качестве неявной ссылки, используемой в любых объектных выражениях по умолча- нию. Например, при записи Workbooks .Add предполагается вызов метода Add объекта Excel.Application.Workbooks. Если доступ к приложению Excel осуществляется из среды другого приложения пакета Office, то следует явным образом создать экземпляр приложения Excel и получить ссылку на него для доступа к объекту Excel. Application. Например, чтобы запустить скрытую 312 Часть 4. Создание приложений в MS Office
копию Excel, создать новую рабочую книгу и поместить значение 10 в ячейку А1 рабочего листа List 1 из программы, функционирующей в среде любого другого приложения пакета Office, нужно использовать следующий фрагмент кода. Dim PrExcel As Excel.Application Set PrExcel = New Excel.Application ’Открытие скрытой копии Excel PrExcel.Workbooks.Add ’Создание новой рабочей книги PrExcel.Worksheets("Listl”).Cells(1,1)>Value=10 Следует отметить, что если приложение Excel запущено программно, в нем по умол- чанию новая рабочая книга не открывается — ее нужно создавать явным образом, если она требуется (как в приведенном выше фрагменте). Количество листов в новой рабочей книге определяется значением свойства Application. SheetsInNewWorkbook и по умолчанию равно 3. Объект Application предоставляет множество ссылок, которые можно применять для обращения к активным объектам без указания явного имени. Это позволяет исполь- зовать в VBA-программе непосредственно те объекты, которые будут активны в момент выполнения ее процедур. Иначе говоря, эти свойства дают возможность создавать уни- версальный код, который будет работать с объектами одного и того же типа, даже имею- щими разные имена. Следующие свойства объекта Application являются глобальны- ми и позволяют ссылаться на активные объекты, которые могут оказаться полезными программисту: ActiveCell (Активная ячейка) — это свойство содержит ссылку на ячейку актив- ного листа, в которой расположен курсор; ActiveChart (Активная диаграмма) — это свойство содержит ссылку на выделен- ную диаграмму из активной книги; ActivePrinter (Активный принтер) — это свойство содержит ссылку на актив- ный принтер; ActiveSheet (Активный рабочий лист) — это свойство содержит ссылку на ак- тивный лист активной книги; Activewindow (Активное окно) — это свойство содержит ссылку на активное окно Excel; Activeworkbook (Активная рабочая книга) — это свойство содержит ссылку на активную рабочую книгу. Помимо того, что объект Application имеет множество свойств и методов, предна- значенных для установки общих параметров приложения Excel, он также имеет специ- альные методы, реализующие полезные встроенные функции рабочего листа, — напри- мер, вычисление числа л: Application. Pi (). Следует отметить, что по умолчанию Excel отображает на экране компьютера каждое изменение в рабочей книге, сделанное по ходу выполнения VBA-программы. Однако можно отключить подобное непрерывное обновление экрана, что приведет к увеличению скорости работы многих VBA-приложений. Данным режимом управляет свойство Scree- nUpdating объекта Application. Для отключения обновления экрана этому свойству следует присвоить значение False. Application.Screenupdating = False Глава 13. Программирование на VBA в Excel 313
В этом случае изображение в окне приложения будет “заморожено” до установки свойства ScreenUpdating в значение True или до завершения работы процедуры и возврата управления пользовательскому интерфейсу Excel. Необходимо подчеркнуть, что в конце работы VBA-процедуры в свойство ScreenUpdating обязательно следует вновь поместить значение True, т.е. восстановить отображение изменений на экране, иначе пользователь просто не сможет увидеть полученный результат. Хотя при обращении к свойству ScreenUpdating требуется явно указывать имя объекта Application, тем не менее в большинстве случаев к свойствам объекта Application можно обращаться напрямую. Например, свойство ActiveSheet объекта Application содержит ссылку на рабочий лист, активный в данный мо- мент. Для обращения в программе к активному листу вместо записи Application. ActiveSheet можно использовать упрощенный вариант ActiveSheet. Важнейший элемент объектной модели приложения Excel — объект Worksheet, пред- ставляющий один рабочий лист в файле. Каждый объект Worksheet является частью кол- лекции Worksheets, которая принадлежит объекту Workbook, представляющему файл рабочей книги Excel (см. рис. 13.1). Поскольку в приложении Excel одновременно можно открыть несколько рабочих книг, существует также и коллекция Workbooks, содержащая по одному объекту Workbooк на каждый открытый файл. Эта коллекция принадлежит объекту Application. Большая часть действий, которые пользователь (или программа) выполняет в Excel, связана с объектом Range, представляющим выделенный диапазон ячеек (рис. 13.2). ► ► Рис. 13.2. Фрагмент структурной схемы объекта Range приложения Excel Хотя имя класса Range в объектной модели Excel соответствует имени одного из классов и в приложении Word и общий смысл их достаточно схож — обрамление части документа, ' с которым проводится работа, все же имеются и заметные отличия. Так, в Excel Диа- пазоном может выступать не только отдельная ячейка, но и двухмерный блок ячеек на рабочем листе или трехмерный блок ячеек, охватывающий несколько рабочих листов. 314 Часть 4. Создание приложений в MS Office
Еще одной важной составной частью объектной модели Excel является объект Chart. Этот объект создается для каждой диаграммы в рабочей книге, и все они помещаются в коллекцию Charts. Каждому объекту Chart подчинено множество объектов, представ- ляющих составные части диаграммы (рис. 13.3). Рис. 13.3. Фрагмент структурной схемы объекта Chart приложения Excel ► Объезды Chart представляют собственно диаграммы, обычно расположенные на отдельных рабочих листах. Если диаграмма внедрена на рабочий лист с данными, то представляющий ее объект Chart дополнительно помещается в объект Char tOb j ect, представляющий собой специальный контейнер. Сделать активной ту или иную рабочую книгу в окне приложения Excel можно с помо- щью объектов Window. Объекты Window являются членами коллекции Windows объекта Application. Ссылка на требуемое окно осуществляется указанием при обращении к коллекции Windows в качестве индекса имени файла, содержащего требуемую рабочую книгу, например Windows ("Квартальный отчет.xls"). Если для одной рабочей книги открыто несколько окон, необходимо после имени рабочей книги через двоеточие указать номер окна. Windows("Квартальный отчет.xls:2") Объект Workbook В иерархии Excel сразу после объекта Application следует объект Workbook — ра- бочая книга (см. рис. 13.1). Каждый объект Workbook в приложении представляет один файл с расширением . XLSX (стандартная рабочая книга) или . XLSM (стандартная рабочая книга с макросами). Когда Excel открывается не из VBA-программы, а как самостоятель- ное приложение, в нем по умолчанию создается новая рабочая книга. При запуске Excel из среды VBA задача создания новых рабочих книг возлагается на программу. Глава 13. Программирование на VBA в Excel 315
Открытие и создание рабочих книг Поскольку объекты рабочих книг Workbook входят в коллекцию Workbooks, для соз- дания новой рабочей книги следует использовать метод Add коллекции Workbooks. Workbooks.Add(шаблон) Здесь аргумент шаблон представляет собой либо имя файла, который будет использован в качестве шаблона при создании новой рабочей книги, либо одну из предопределенных кон- стант xlWBATemplate. (Полный перечень этих констант можно увидеть в Object Browser, поместив имя xlWBATemplate в поле поиска и щелкнув на кнопке Найти.) Когда в каче- стве аргумента задается константа, в новой рабочей книге будет содержаться только один рабочий лист заданного типа. Если аргумент Template опущен, создается новая рабочая книга, содержащая то количество рабочих листов, которое указано в свойстве Sheets In- NewWorkbook объекта Application (по умолчанию — 3). Метод Add возвращает ссылку на новую рабочую книгу, которую можно сохранить в переменной соответствующего типа. Dim Новая_книга As Excel.Workbook Set Новая_книга = Workbooks.Add(шаблон) Открыть рабочую книгу на диске можно с помощью метода Open коллекции Work- books. Синтаксис вызова этого метода следующий. Workbooks.Open(Имя_файла) Здесь обязательный аргумент Имя_файла задает путь и имя открываемого файла. Запись этого метода в программном коде может выглядеть следующим образом. Set Workbookl = Workbooks.Open (FileName:="C:\Data\SalesDatal.xls") Следует также отметить, что возвращаемое значение метода Open можно непосредствен- но применить для создания объектной переменной с целью обращения к открытой книге в дальнейшем. Метод Open также имеет несколько дополнительных аргументов, сведения о которых при необходимости можно найти в справочной системе приложения Excel. Сохранение и закрытие рабочих книг Для сохранения рабочей книги, которой уже было присвоено имя, используется метод Save объекта Workbook. Этот метод не имеет аргументов. Для первого сохранения новой рабочей книги с присвоением ей имени или для сохранения уже именованной книги под другим именем используется метод SaveAs. Синтаксис его следующий. Новая_книга.SaveAs(Имя_файла) Здесь аргумент Имя_файла определяет новое имя файла, включая его путь. Метод SaveAs также имеет несколько необязательных дополнительных аргументов, которые подробно описаны в справочной системе. Чтобы сохранить копию рабочей книги под другим именем, не изменяя при этом имени текущей книги, нужно использовать метод SaveCopyAs. Новая_книга..SaveCopyAs (Имя_файла) Перед тем как рабочая книга будет сохранена и ей будет присвоено имя, в свойстве Name объекта Workbook будет содержаться имя, присвоенное ей по умолчанию прило- жением Excel (Bookl, Book2 и т.п.). После того как рабочей книге будет назначено новое имя, оно также будет помещено в свойство Name. Рассмотрим пример добавления книги и сохранения активной книги в рабочем файле. 316 Часть 4. Создание приложений в MS Office
Application.Workbooks.Add Call Application.ActiveWorkbook.SaveAs("temp.xls") В результате работы этого кода создается новый объект Workbook. Ссылка на создан- ный объект не сохраняется. Вместо этого для взаимодействия с объектом используется свойство Application. ActiveWorkbook. Однако существуют и другие способы обра- щения к коллекции для получения конкретного экземпляра класса Workbook или сохра- нения ссылки на созданный объект. Ниже приведены примеры реализации этих способов (любая из этих ссылок может использоваться при вызове метода SaveAs). ’ Сохранение копии, полученной по номеру из коллекции Workbooks Application.Workbooks.Add Call Application.ActiveWorkbook.SaveAs("tempi.xls") Application.Workbooks("tempi.xls)".SaveAs("copy of tempi.xls") ’ Использование сохраненной ссылки на добавленный объект Dim As Workbook Set W = Workbooks.Add Call W.SaveAs("tempi.xls)" В первом примере показано, как создавать новую книгу и сохранять ее, получая ссылку через свойство ActiveWorkbook. После этого ссылка на книгу извлекается из коллекции по имени книги, и с помощью полученной ссылки создается резервная копия. Во втором примере показано, как сохранять ссылку на созданный экземпляр класса Workbook в объектной переменной и вызывать метод SaveAs этого экземпляра. Обе операции приводят к одному и тому же результату. Важно обратить внимание на то, что существует различие между операциями над объектом коллекции Workbooks и отдельным объектом Workbook. Можно заметить, что в приведенных выше примерах (как в первом, так и во втором) используется метод Add коллекции Workbooks и метод SaveAs отдельного объекта Workbook. Следовательно, можно сказать, что коллекция поддерживает метод Add и обращение к элементам коллекции, а объект Workbook под- держивает метод SaveAs. Значение свойства Name объекта Workbook нельзя изменить напрямую — это можно сделать только с помощью метода SaveAs. Объект Workbook содержит еще два свой- ства, которые также связаны с его именем. Как только рабочая книга будет сохране- на, свойство FullName будет содержать полное имя файла (вместе с путем), а свойство Path — только путь. Для закрытия рабочей книги используется метод Close объекта Workbook. Новая_книга.Close{SaveChanges, Filename, RouteWorkbook) Здесь все три аргумента необязательны. Аргумент Sa veChanges задает вариант действий для случая, когда рабочая книга содержит несохраненные изменения. Возможные значения: True (для сохранения изменений) и False (для игнорирования изменений). Если этот аргумент опущен, пользователю будет предложено сохранить изменения. Аргумент Fi 1 eName — это имя файла, в котором сохраняется рабочая книга. Если этот аргумент опущен, используется текущее имя. Если такового не существует, пользователю будет предложено его ввести. Глава 13. Программирование на VBA в Excel 317
Аргумент Routeworkbook относится только к тем рабочим книгам, которые име- ют список распространения (routing slip) и еще не были распространены. Устанав- ливается значение True, если требуется отправить рабочую книгу следующему по- лучателю, в противном случае устанавливается False. Если этот аргумент опущен, пользователю выводится соответствующий запрос. Рассмотрим пример использования метода Close объекта Workbook. Sub Closeworkbook() Dim Workbookl As Workbook Set Workbookl = Workbooks.Open(FileName: ThisWorkbook Path &"\Temp.xls") Range(Al).Value = Format(Date, "ddd mmm dd, yyyy") Range(Al).Entirecolumn.AutoFit Workbookl.Close SaveChanges:=True End Sub Иногда возникает необходимость оставить измененную книгу открытой для просмо- тра, не сохранять внесенные изменения и не получать запросов на сохранение при за- крытии книги. Для этого нужно установить свойство Saved объекта книги в значение True. Excel посчитает, что книга не содержит изменений, которые необходимо сохра- нять. Однако перед использованием следующей строки в своей программе еще раз все взвесьте и удостоверьтесь, что это действительно то, что нужно. ActiveWorkbook.Saved = True Вывод на печать содержимого рабочей книги Большинство рабочих листов, создаваемых в Excel, сразу же проектируется для по- следующей печати в виде отчета. Выводить документы Excel на печать очень просто, по- скольку приложение осуществляет полное управление печатью рабочих книг. С помощью метода Printout, предназначенного для вывода рабочей книги на печать, доступны следующие объекты и коллекции: Chart (диаграмма); Charts (коллекция диаграмм); Range (диапазон); Sheets (коллекция таблиц); Window (окно); Workbook (рабочая книга); Worksheet (рабочий лист); Worksheets (коллекция рабочих листов). Синтаксис метода Printout следующий. Object.Printout(From, То, Copies, Preview, _ ActivePrinter, PrintToFile, Collate, PrToFileName) Здесь все аргументы необязательны. Если метод Printout вызывается без аргументов, он печатает одну копию всего содержимого заданного объекта на принтере, который ис- пользуется по умолчанию. Необязательные аргументы имеют следующие значения. 318 Часть 4. Создание приложений в MS Office
Аргументы From и То задают первую и последнюю страницы для печати. Значени- ем по умолчанию являются первая и последняя страницы объекта. Аргумент Copi es задает количество печатаемых копий. По умолчанию печатается одна копия. Аргумент Preview может принимать значения True или False, в зависимости от того, требуется ли при печати открывать окно предварительного просмотра. Значе- ние по умолчанию — False. Аргумент Acti vePr inter задает имя используемого принтера. Если этот аргумент опущен, выбирается тот принтер, который задан в Windows для использования по умолчанию. Аргумент PrintToFi 1е принимает значения True или False, в зависимости от того, следует ли вместо устройства печати перенаправить вывод в файл. Значение по умолчанию — False. Аргумент Collate принимает значения True или False, в зависимости от того, следует ли разложить страницы по копиям при печати. Значение, принятое по умолчанию, — True. Аргумент PrToFileName задает имя файла, в который будет направлен вывод, если аргумент PrintToFi 1е имеет значение True. Если этот параметр опущен, у пользователя запрашивается имя файла. Объект Worksheet Большая часть работы, которая выполняется программами в среде Excel, обычно связана непосредственно с рабочими листами, представленными объектами Worksheet в коллекции Worksheets. Как уже упоминалось выше, в иерархии объектов Excel класс объектов Worksheet следует непосредственно после объекта Workbook, который явля- ется родительским для коллекции Worksheets (см. рис. 13.1). Для доступа к объектам Worksheet коллекции Worksheets можно воспользоваться свойством Item. В качестве параметра свойства Item используется имя листа или номер, описывающий положение листа в коллекции (нумерация выполняется слева направо). Объект Worksheet предоставляет доступ ко всем атрибутам листа в Excel. Это касает- ся как форматирования листа, так и других его свойств. Кроме того, объект Worksheet предоставляет события, которые могут обрабатываться программно. Для добавления нового рабочего листа в коллекцию Worksheets используется ее метод Add. Dim Новый_лист As Excel.Worksheet Set Новый_лист = Worksheets.Add(Before, After, Count) Здесь все аргументы являются необязательными, и если они опущены, то сразу после ак- тивного создается один рабочий лист. Аргументы Before и After используются для ука- зания уже существующего рабочего листа, до (или после) которого следует вставить новый рабочий лист. Для того чтобы добавить еще несколько рабочих листов, необходимое их количество задается в аргументе Count. Если этот аргумент больше единицы, метод Add возвращает ссылку на последний из добавленных рабочих листов. Полезно сразу же после создания назначить новым рабочим листам имена, чтобы впоследствии по этим именам можно было обращаться к листам в программе. Глава 13. Программирование на VBA в Excel 319
Новыи_лист.Ыате="Объемы_продаж" К листу можно обращаться как по имени, так и по порядковому номеру в коллекции Worksheets. Если известно имя листа, то его можно использовать для выбора листа из коллекции Worksheets. Если необходимо отобразить все элементы коллекции Work- sheets, например, в цикле For...Next, на каждый лист можно ссылаться по порядково- му номеру. В приДелах книги на лист Sheet 1 можно ссылаться с помощью следующих конструкций. ActiveWorkbook.Worksheets("Sheet1") ActiveWorkbook.Worksheets(1) Для удаления рабочего листа используется метод Delete объекта Worksheet. ActiveWorkbook.Worksheets(Имя_листа).Delete Здесь аргумент Имя_листа — это имя удаляемого рабочего листа. Обычно, когда поль- зователь делает попытку удалить рабочий лист в окне программы, Excel автоматически выводит окно запроса для подтверждения операции удаления. Для того чтобы при удале- нии листа из программы этот запрос не выводился, необходимо присвоить свойству Dis- playAlerts объекта Application значение False. Однако, после того как ненужный или временно используемый в программе рабочий лист будет удален, обязательно вновь поместите в это свойство значение True. Application.DisplayAlerts = False ActiveWorkbook.Worksheets("Объемы_продаж ").Delete Application.DisplayAlerts = True Копирование и перемещение рабочих листов Методы Сору и Move объекта Worksheet позволяют копировать и перемещать один или несколько листов в результате выполнения одной операции. Копировать и переме- щать рабочие листы можно как в пределах одной рабочей книги, так и между несколькими книгами. Чтобы копировать рабочий лист в пределах одной рабочей книги или в другую книгу, используется следующий синтаксис. Лист.Copy(Before, After) Здесь параметр Лист задает ссылку на копируемый рабочий лист. Если нужно скопиро- вать рабочий лист в ту же рабочую книгу, используются аргументы Before или After для указания того уже существующего рабочего листа, до (или после) которого требуется поместить копию данного. Если эти аргументы опущены, рабочие листы копируются в новую книгу. Например, рабочий лист Объемы_продаж копируется в последнюю пози- цию текущей рабочей книги. Worksheet("Объемы_продаж ").Сору _ After:=Worksheets(Worksheets.Count) Для перемещения рабочего листа нужно использовать метод Move. Его синтаксис та- кой же, как и метода Сору. Например, для перемещения рабочего листа Объемы_продаж в позицию непосредственно перед рабочим листом с именем Проекты нужно выполнить следующее. Worksheet("Объемы_продаж ").Move Before:="Проекты" 320 Часть 4. Создание приложений в MS Office
Следует отметить, что оба метода не возвращают значение или ссылку, поэтому для соз- дания объектной переменной, которая ссылается на перемещенный или скопированный лист, придется воспользоваться другими методами. Обычно это не проблема, так как первый лист, полученный в результате работы метода Сору, или первый лист, полученный в резуль- тате перемещения группы листов, становится активным сразу после завершения операции. Объект Range Объект Range является одним из ключевых объектов VBA и в иерархии Excel следует сразу после объекта Worksheet. В Excel объект Range (см. рис. 13.2) может представлять одну ячейку, целую строку или столбец рабочего листа и даже произвольный двух- или трехмерный блок ячеек рабочей книги. VBA-программа может ссылаться на любое не- обходимое ей количество объектов Range, и доступные для программы элементы рабочей книги не ограничиваются выделением, выполненным пользователем в данный момент. Иначе говоря, для воздействия программы на какую-либо область рабочей книги ее не требуется вручную выделять на экране. Объект Range является свойством объекта Worksheet и представляет собой средство обращения к некоторому диапазону ячеек. Диапазон определяется указанием адресов первой и последней входящих в него ячеек. Использование объекта Range позволяет создавать более эффективный код за счет упрощенного способа обращения к требуемым элементам рабочих листов Excel. Определение объекта Range В Excel доступно несколько способов идентификации диапазона (из одной или не- скольких ячеек), на который должен воздействовать программный код. 1. Стандартная ссылка на ячейку. Так называемый А1-стиль ссылки на ячейку явля- ется, пожалуй, самым простым способом работы с объектами Range. Для опреде- ления диапазона необходимо заключить ссылку в кавычки и указать ее в скобках непосредственно после ключевого слова Range, как показано ниже. ActiveSheet.Range("ВЗ") Worksheets("Лист2").Range("М5:S2 0") 2. Именованные диапазоны. Если рабочий лист содержит именованные диапазоны, для обращения к подобным объектам Range их имена могут использоваться вместо указания конкретных ссылок. Для присвоения диапазону имени соответствующее значение должно быть помещено в свойство Name объекта Range. Worksheets("Финансовый отчет").Range("АЗ:В4").Name = "Выплата_процентов" Range("Выплата__процентов").Cells.Interior.ColorIndex = 8 3. Сокращенная запись. Поскольку объекты Range используются в программном коде очень часто, Excel позволяет опускать ключевое слово Range при указании диа- пазона в А1-стиле или при обращении к нему по имени. В этом случае ссылка на ячейки или имя диапазона заключается в квадратные скобки, как показано в при- веденном ниже примере. ActiveSheet[Al:Z26] 'Обращение к явно заданному диапазону ячеек [Квартальныи_отчет] 'Обращение к поименованному объекту Range Глава 13. Программирование на VBA в Excel 321
4. Свойство Cells объекта Worksheets. Этот способ особенно удобен при написании сложных VBA-программ, так как позволяет определять диапазон не путем явно- го указания фиксированных адресов ячеек, а посредством использования для его задания содержимого переменных. Основная идея состоит в подготовке числовых значений координат строк и столбцов требуемого диапазона, сохраняемых в пере- менных, имена которых и указываются при обращении к данному свойству. Под- робнее об этом речь пойдет ниже, в разделе “Использование свойства Cells для определения диапазона” данной главы. 5. Свойство Selection. Когда программа должна работать с диапазоном, который в дан- ный момент выделен пользователем в окне приложения, используется свойство Selection объектов Application или Window. Подробнее об этом речь пойдет ниже, в разделе “Работа с выделением” данной главы. 6. Свойство ActiveCell. Свойство ActiveCell (Активная ячейка) используется для доступа к диапазону, представляющему активную ячейку указанного окна. При опускании спецификатора объекта окна (что означает обращение к объекту Application) свойство ActiveCell ссылается на текущее активное окно. Значение_ячейки = ActiveCell.Value ’Чтение значения ячейки 7. Свойства Rows или Columns объекта Worksheet. Доступ к диапазону, включающему всю строку или весь столбец, осуществляется с помощью свойств Rows и Columns объекта рабочего листа соответственно. В операторе указывается номер требуемого столбца или строки — нельзя адресовать столбец, указав его буквенное обозначе- ние, отображаемое на экране в заголовке этого столбца. Так, в следующем примере определяется диапазон, включающий столбец G, т.е. седьмой столбец. Workbooks("Отчет.xls").Worksheets("Сводная ведомость").Columns(7) 8. Именованные ссылки на объекты. Поскольку диапазон является объектом, в про- грамме можно создать именованную объектную ссылку на него, после чего доступ к данному диапазону будет выполняться с помощью указания имени ссылки. Та- кой подход проще и надежнее, чем многократное указание требуемого диапазо- на. Ниже, после помещения ссылки на обрабатываемый диапазон в объектную переменную Диапазон!, ее значение используется для доступа к свойствам этого диапазона. Dim Диапазон! As Range Set Диапазон! = Worksheets("Лист!").Range("В12:В12") KI = Диапазон!.Value ’Выборка значения коэффициента Поскольку непосредственно проверить работу приведенных выше фрагментов кода затруднительно, в листинге 13.1 приведен развернутый пример, в котором используются все приведенные выше (за исключением пп. 4-5, о которых речь пойдет ниже) варианты задания диапазона обрабатываемых ячеек. Для наглядности ячейкам в задаваемых диа- пазонах присваивается определенный цвет фона (свойство Cells. Interior. Colorin- dex — подробнее см. в главе 8), а значение активной ячейки выводится в окне сообщений (рис. 13.4). 322 Часть 4. Создание приложений в MS Office
Рис. 13.4. Результат работы примера из листинга 13.1 Листинг 13.1. Пример использования различных способов задания диапазона обрабатываемых ячеек Public Sub Proba() ’ Изменение цвета фона указанной ячейки Dim n As Integer ’ Целое число Dim a As Range ’ Объектная переменная класса Range ’Стандартная ссылка на ячейку - цвет желтый Worksheets(”Лист1”).Range("А2:В5").Cells.Interior.Colorindex = 6 ’ Именованные диапазоны - цвет голубой Worksheets("Лист1").Range("В4:D9”).Name = ”Выплата_процентов" Range("Выплата_процентов").Cells.Interior.Colorindex = 8 ’ Сокращенная запись - цвет бежевый и синий ActiveSheet.[С6:Е8].Cells.Interior.Colorindex = 12 Worksheets("Лист1").Range("С9:Е12").Name = "Проценты" [Проценты].Cells.Interior.Colorindex = 25 Глава 13. Программирование на VBA в Excel 323
’ Свойства Rows или Columns объекта Worksheet - цвет бирюзовый ActiveSheet.Columns(7).Cells.Interior.Colorindex = 14 ’ Именованные ссылки на объекты - цвет фиолетовый Set а = Worksheets("Лист1").Range("DIO:Н16") а.Cells.Interior.Colorindex = 21 ’ Свойство ActiveCell - отображение значения в активной ячейке Е2 n = ActiveCell.Value ’Чтение значения активной ячейки MsgBox (п) End Sub Использование свойства Cells для определения диапазона При использовании в выражении без указания координат свойство Cells объекта Worksheets определяет диапазон, включающий все ячейки данного рабочего листа. Аналогично свойство Cells объекта Application содержит ссылку на все ячейки ли- ста, активного в данный момент. (В этом случае свойство Cells может использоваться само по себе, без указания в явном виде объекта Application, т.е. Application .Cells эквивалентно Cells.) Если обрабатывается диапазон, включающий лишь часть ячеек рабочего листа, при обращении к свойству Cells потребуется указать числовые координаты строк и столбцов (буквенное указание столбцов не допускается). В следующем примере определяется диа- пазон, включающий только ячейку ЕЗ. Worksheets("Предыдущий отчет") .Cells (3,5) Обратите внимание на то, что в данном случае сначала указывается координата строки (3), а затем столбца (5) — прямо противоположно записи в А1-стиле. В приведенном выше примере второе значение в ссылке на ячейку равно 5, т.е. указывает на пятый столбец — Е. Следует отметить, что такая система записи довольно трудна для понимания и главное ее преимущество состоит в том, что обе координаты являются числами, а значит, их можно указывать как значения переменных. Использование переменных для хранения координат позволяет динамически, непосредственно при выполнении программы, определять, где находится требуемый диапазон, — на основе введенных пользователем данных, исходя из результатов вычислений и т.д. В приведенном ниже примере строка таблицы выбирается в зависимости от текущего месяца года. Месяц = Month(Now ()) Показатель = Worksheets("Годовой отчет").Cells(Месяц, 8) Для определения диапазона на неактивном листе необходимо совместно использовать свойства Range и Cells этого листа. Следующее выражение определяет диапазон E3:F4 на рабочем листе с именем Лист2. Worksheets("Лист2").Range(Worksheets("Лист2").Cells(3,5), _ Worksheets("Лист2").Cells(4,6)) Приведенный выше пример выглядит весьма громоздко, однако его можно упростить за счет использования оператора With, позволяющего избежать повторных ссылок на рабочий лист. В следующем примере к содержимому того же диапазона применяется по- лужирное форматирование. 324 Часть 4. Создание приложений в MS Office
With Worksheets ("Лист‘2") .Range(.Cells (3,5), .Cells(4,6)).Font.Bold = True End With Обратите внимание: в данном случае наличие точки перед каждым обращением к свой- ству Cells является обязательным. Именно точка указывает на принадлежность свойства Cells тому рабочему листу, который выше в коде был задан оператором With. При от- сутствии точки свойство Cells будет воспринято как принадлежащее активному листу, что приведет к возникновению конфликта при определении ссылки для свойства Range. Для получения ссылки на конкретную ячейку в пределах текущего значения диапазо- на, заданного в объекте Range, можно воспользоваться свойством Item объекта Range и в качестве параметров передать относительные координаты строки и столбца. Параметр строки всегда является числовым. Параметр столбца может быть числовым или строко- вым (содержать букву столбца). Следующие строки кода возвращают ссылку на одну и ту же ячейку, расположенную на пересечении второй строки и второго столбца в пределах диапазона, определенного в данный момент в объекте Range на активном листе. Cells.Item(2, 2) Cells.Item(2, "В") Свойство I tern является принятым по умолчанию свойством объекта Range, поэтому обращение к свойству можно опустить. Cells(2, 2) Cells (2, "В") Учтите, что в данном случае столбцы (и их буквы) отсчитываются от столбца начала диа- / у пазона, а не от начала рабочего листа. Чтобы это уточнение было понятнее, в листин- ге 13.2 показан пример подобного обращения к ячейкам, а на рис. 13.5 — вид рабочего листа после выполнения этого примера. Листинг 13.2. Обращение к ячейкам в пределах Диапазона, заданного объектом Range Public Sub ProbalO ’ Изменение цвета заданной ячейки Dim a As Range ’ Объектная переменная класса Range ’Определение именованного диапазона Worksheets("Лист1”).Range("В2:Е14”).Name = ’’Выплата_процентов” ’Ображение к ячейкам в пределах диапазона [Выплата_процентов].Cells.Item(4, 4).Interior.Colorindex = 6 ’ Цвет желтый Set а = [Выплата_процентов].Cells.Item(2, 2) ’ Использование переменной а.Interior.Colorindex = 4 ’ Цвет зеленый [Выплата_процентов].Cells.Item(3, "В").Interior.Colorindex = 25 ' Цвет синий End Sub Обычно числовые параметры полезны при циклическом переборе последовательно- сти строк или столбцов с использованием счетчика. В следующем примере в пределах диапазона B3:G14 на активном листе выполняется перебор строк с 1 до 10 и столбцов с 1 по 5 и в каждую ячейку заносится соответствующее значение, представляющее собой произведение номера строки на номер столбца (листинг 13.3). Глава 13. Программирование на VBA в Excel 325
Выплата_процентов ▼ . Рис. 13.5. Вид диапазона, заданного объектом Range (для на- глядности выделен), после выполнения примера из листинга 13.2 Листинг 13.3. Циклический перебор строк и столбцов в пределах диапазона с использованием объекта Range Public Sub FillCells() Dim i As Integer Dim j As Integer ’Определение именованного диапазона Worksheets("Лист1").Range("B3:G14").Name = "Диапазон" For i = 1 To 10 For j = 1 To 5 [Диапазон].Cells(i, j).Value = i ★ j Next j Next i End Sub Результат выполнения этого кода показан на рис. 13.6. Рис. 13.6. Циклический перебор строк и столбцов в пределах диа- пазона, заданного объектом Range (для наглядности выделен) 326 Часть 4. Создание приложений в MS Office
Выполнение операций над диапазоном ячеек С помощью свойств диапазона можно одним действием изменять характеристики всех ячеек, входящих в данный диапазон. Например, следующий оператор изменяет размер шрифта для всех ячеек указанного диапазона. Worksheets("Лист1").Range("В12:Н13").Font.Size = 14 В подобных случаях полезно использовать конструкцию With (особенно если не- обходимо обратиться к нескольким свойствам или методам диапазона), как показано в листинге 13.4. Результат выполнения этого кода показан на рис. 13.7. Листинг 13.4. Циклический перебор строк и столбцов в пределах диапазона с использованием объекта Range Public Sub Formatcells() Dim Диапазон! As Range Dim пшДиапазон! As String Set Диапазон! = Worksheets("Лист1").Range("B3:C11") With Диапазон! 'Определенная ранее объектная ссылка .Value =20 'Значение всех ячеек устанавливается равным 20 .Font.Name = "Arial Cyr" .Font.Italic = True .Name = "Базовая_таблица" пшДиапазон! = .Name End With MsgBox (пшДиапазон!) End Sub 'Используемый шрифт 'Начертание курсивное 'Присвоение имени диапазону 'Сохранение имени в переменной 'Отображение значения переменной Рис. 13.7. Форматирование ячеек с помощью объекта Range Работа с отдельными ячейками диапазона Как было показано в предыдущем примере, с помощью одного оператора можно поместить одно и то же значение во все ячейки диапазона. Однако в Excel нет метода, позволяющего с помощью единственного оператора изменять текущие значения ячеек диапазона. Оператор, подобный приведенному ниже, в Excel является недопустимым. Диапазон.Value = Диапазон.Value + 10 Глава 13. Программирование на VBA в Excel 327
Вместо этого потребуется выполнить циклический перебор всех ячеек диапазона — например, с помощью цикла For Each. . .Next. Этот цикл удобен тем, что при его использовании не требуется знание общего количества ячеек, входящих в диапазон. Вот правильный способ реализации требуемого действия. For Each aCell In Диапазон aCell.Value = aCell.Value + 10 Next Здесь переменная aCell должна быть объявлена с типом Range, а в качестве параметра Диапазон можно указать системный объект Selection (текущие выделенные ячейки на рабочем листе; подробнее ниже) либо желаемый диапазон ячеек, заданный с помощью объекта Range. Часто перед тем, как принять решение о необходимости выполнения того или иного действия над отдельной ячейкой, требуется проверить ее содержимое. Например, в зави- симости от текущего значения ячейки программа может принять решение отформатиро- вать, изменить или же использовать ее значение для выполнения некоторых вычислений. В подобных случаях также используется цикл For Each. . . Next (листинг 13.5). Листинг 13.5. Форматирование ячеек диапазона в зависимости от их текущего значения Public Sub AnalisCells () Dim i As Integer Dim j As Integer Dim aCell As Range ’Определение именованного диапазона Worksheets("Лист1").Range("ВЗ:G14").Name = "Диапазон" ’Заполнение ячеек произведением номера столбца и номера строки For i = 1 То 10 For j = 1 То 5 [Диапазон] .Cells (i, j).Value = i * j Next j Next i ’Определение значения в ячейке и форматирование чисел For Each aCell In Worksheets("Лист1").Range("A5:D14") If IsNumeric(aCell) Then ’в ячейке числовое значение Select Case aCell Case 5 To 10 ’Подчеркнуть значение aCell.Font.Underline = xlUnderlineStyleSingle Case 10 To 20 ’Выделить значение курсивом aCell.Font.Italic = True Case Is > 20 ’Выделить значение полужирным aCell.Font.Bold = True End Select End If Next End Sub 328 Часть 4. Создание приложений в MS Office
В этом примере сначала используется цикл для занесения в ячейки диапазона B3:G14 числовых значений, равных произведению их номера строки на номер столбца (как в листин- ге 13.3), а затем значение в каждой ячейке диапазона A5:D14 форматируется в зависимости от того, в какой числовой диапазон оно попадает, — подчеркивается, выделяется курсивом или полужирным начертанием. Результат выполнения этого примера показан на рис. 13.8. текущих значений в пределах диапазона, заданного объек- том Range (для наглядности выделен) Работа с текущим выделением При работе с приложением Excel пользователь должен предварительно выделить тре- буемые ячейки, прежде чем он сможет изменить их значение или формат. Однако в среде VBA предварительное выделение ячеек в окне приложения не требуется, так как Для иден- тификации ячеек, над которыми должны выполняться определенные действия, можно использовать объекты Range. Тем не менее в среде VBA есть инструменты, позволяющие работать и с текущим выделением, выполненным пользователем в окне приложения. Чаще всего они используются для достижения двух целей — когда программе необходимо выяснить, какие ячейки были выделены пользователем, и когда программе требуется ука- зать пользователю то место на рабочем листе, где происходит что-то важное для него. Очень часто программа должна выполнять некоторые действия в отношении выбран- ных пользователем ячеек — как это делают встроенные команды Excel. Для доступа из программы к выделенному пользователем диапазону используется объектное свойство Selection (Выделение) объекта Application или Window. Свойство Selection объекта Application возвращает диапазон, выделенный в данный момент на активном рабочем листе. Следующие два оператора идентичны. Application.Selection.Value = 20 Selection.Value = 20 Если требуется гарантировать, что ссылка относится к определенному окну приложе- ния независимо оттого, какое окно активно в текущий момент, необходимо использовать свойство Selection объекта этого окна. Сохранив полученную объектную ссылку на Глава 13. Программирование на VBA в Excel 329
диапазон, представляющий текущее выделение на требуемом листе, в дальнейшем можно будет повторно обращаться к этому же диапазону. Dim Диапазон! As Range Set Диапазон! = Windows("Список товаров.xlsx").Selection With Диапазон! ’Обработка ячеек выделенного диапазона .Checkspelling ’ Проверка правописания .Сору ’ Копирование в буфер End With Если VBA-программа вносит некоторые изменения в рабочий лист и необходимо, чтобы пользователь их заметил, следует использовать метод Select (Выделить). Этот метод имеется у всех объектов, представляющих различные элементы интерфейса, ко- торые можно выделить в окне приложения, — диапазон, диаграмму или что-либо другое. Поэтому метод Select можно применять фактически к любому существующему в Excel объекту, имеющему визуальное представление в окне приложения, — в том числе к объ- ектам Chart и всем их компонентам (каждая часть диаграммы представлена отдельным VBA-объектом), к объектам Shape (Форма) и, конечно же, к объектам Range. Для выделения диапазона из программы необходимо сначала активизировать тот ра- бочий лист, на котором этот диапазон находится, а затем использовать метод Select для соответствующего объекта Range. With Worksheets("Статотчет") .Activate ’Активизация рабочего листа .Range("Рабочие часы").Select ’Выделение именованного диапазона End With Следует отметить, что метод Select в применении к объектам Worksheet не выпол- няет ничего, кроме активизации указанного рабочего листа без изменения уже суще- ствующего в нем выделения. Другими словами, он полностью эквивалентен методу Activate объекта Worksheet. Аналогичным образом методы Activate и Select можно использовать для активизации листа диаграммы, но ни один из методов не вы- деляет самой диаграммы. Для того чтобы выделить компонент диаграммы или внедрен- ную диаграмму, нужно использовать метод Select для требуемого объекта. Чтобы сделать некоторую ячейку активной для ввода, вызывается метод Activate (Активизировать) объекта Range с указанием данной ячейки. Если активизированная ячейка находится в пределах текущего выделения, весь диапазон остается выделенным. Если же активизированная ячейка находится за пределами выделения, оно автоматически перемещается на активизированную ячейку. В следующем примере на активном рабочем листе последовательно выделяется диа- пазон ВЗ:Е10, а затем в его пределах задается активная ячейка (на пересечении третьей строки и второго столбца), в которую будут вставляться вводимые пользователем данные (результат выполнения этого примера представлен на рис. 13.9). Public Sub SelectAndActivate() Range("ВЗ:Е10").Select Range("B3:E10").Cells.Item(3, 2).Activate End Sub 330 Часть 4. Создание приложений в MS Office
Рис. 13.9. Выделение диапазона ячеек и указание в нем активной ячейки При необходимости можно использовать и прямое указание адреса активизируемой ячейки — например, тот же результат даст замена третьей строки предыдущего примера на: Range("С4").Activate Прежде чем выполнять какие-либо операции с выделением, обычно следует убедить- ся, что текущее выделение содержит именно тот тип объектов, который предполагается обрабатывать в программе. Если программа предпримет попытку работать с выделением как с ячейками, когда в действительности выделенной является диаграмма, это приве- дет к возникновению ошибки. Для предотвращения подобных ситуаций в VBA имеется функция TypeName, которая возвращает строку, определяющую тип объекта выделения. На основании полученного от нее значения с помощью структур If...Then или Case- Select можно выяснить, какие из действий допускается применять к выделенному в дан- ный момент объекту. В приведенном ниже примере выражение TypeName (Selection) в операторе Select (вторая строка кода) возвращает строку, содержащую тип объекта текущего выделения. Данная строка затем проверяется серией операторов Case, чтобы установить, является ли текущее выделение диапазоном (в этом случае в его ячейки помещается значение 2010) или областью диаграммы (в этом случае для выделения устанавливается красный цвет). Если же выделение в текущий момент вовсе отсутствует, пользователю выводится сообще- ние об отсутствии выделения. Также предусмотрен вывод соответствующего сообщения для случая, когда выделение не принадлежит ни одному из перечисленных выше типов. With Selection Select Case TypeName(Selection) Case "Range" .Value = 2010 'Это диапазон ячеек Case "ChartArea" .Interior.Colorindex = 3 'Это диаграмма Case "Nothing" MsgBox "Ничего на выделено" Case Else MsgBox "Выделен недопустимый объект!" End Select End With Глава 13. Программирование на VBA в Excel 331
Использование диалоговых окон Excel Приложение Excel предлагает программисту на языке VBA те же самые возможности работы с его диалоговыми окнами и их элементами, что и любое другое приложение па- кета Office 2010. Безусловно, отображение окон не потребуется, если обращение к Excel из VBA-программы осуществляется как к скрытому приложению. Вполне возможны си- туации, когда работа с приложением Excel должна быть явной, чтобы пользователь мог получить доступ к диалоговым окнам и различным имеющимся в них инструментам. В VBA-программах можно использовать для своих целей множество диалоговых окон, имеющихся в приложении Excel. Доступ к этим окнам осуществляется через коллекцию Dialogs, которая является свойством объекта Application. Для использования неко- торого диалогового окна прежде всего нужно создать ссылку на это диалоговое окно. Dim Диалог As Dialog Set Диалог = Dialogs(Тип_окна) Здесь аргумент Тип_окна определяет конкретное диалоговое окно, доступ к которому требуется получить. В библиотеке типов Excel содержится список предопределенных констант в форме xlDialogXXXX, где хххх определяет конкретное диалоговое окно. В большинстве случаев (но не во всех) имя хххх связано с именем соответствующего диа- логового окна в английской версии приложения. Например, константа xlDialogOpen определяет диалоговое окно открытия файла. Когда диалоговое окно имеет вкладки, константа приобретает вид xlDialogXXXXyyyy, где хххх определяет диалоговое окно, а уууу — его отдельную вкладку. Так, константа xlDialogFormatNumber определяет вклад- ку Число диалогового окна Формат ячеек. После того как ссылка на требуемое диалоговое окно получена, для его отображения можно использовать метод Show этого объекта. Синтаксис его следующий. Окно.Show(Аргументы) Здесь набор параметров Аргументы определяется типом открываемого окна. Иногда никаких аргументов не требуется, а в других случаях передаваемые открываемому окну аргументы обязательны и определяют исходное состояние открываемого диалогового окна. Набор и краткое описание аргументов метода Show диалоговых окон можно найти на странице справочной системы редактора VBA в Excel, если в ее строку поиска ввести значение Built-In Dialog Box Argument Lists. Следует отметить, что изменения и любые действия, выполненные пользователем в открытом диалоговом окне, вступают в силу автоматически, обычным способом. Ваша программа сама должна получить информацию о внесенных пользователем изменениях, а затем поступить с ними требуемым образом. Метод Show возвращает значение типа Boolean, определяющее, какая кнопка ис- пользована для закрытия окна: True, если пользователь щелкнул на кнопке ОК, и False, если щелчок был сделан на кнопке Отмена (Cancel). Следующий пример показывает, как открыть из программного кода диалоговое окно Open, а затем проверить, открыл ли пользователь какой-либо файл. Dim Диалог As Dialog Dim Кнопка As Boolean Set Диалог = Application.Dialogs.(xlDialogOpen) 332 Часть 4. Создание приложений в MS Office
Кнопка = Диалог.Show If Кнопка Then MsgBox ("Файл открыт") Else MsgBox ("Файл не открыт") End If В этом случае, если в раскрывшемся диалоговом окне пользователь выберет некоторый файл и щелкнет на кнопке Open, указанный файл будет открыт и метод Show возвратит значение True. В противном случае для закрытия диалогового окна пользователь вынуж- ден будет щелкнуть на кнопке Отмена, и метод возвратит значение False. В приложении Excel имеется 1101 (!) встроенное диалоговое окно. Информацию о них можно получить с помощью справочной системы редактора VBA, выполнив поиск фразы Built-in Dialog Boxes. Результаты поиска по этой фразе включают множество ссылок на описание доступных в Excel диалоговых окон, а полный перечень всех окон с указанием аргументов их вызова можно увидеть, если перейти по первой ссылке — Built-In Dialog Box Argument Lists. Программирование пользовательских функций Использование языка VBA в среде Excel позволяет создавать пользовательские функции, существенно превосходящие по своим возможностям встроенные формулы, которые могут записываться непосредственно в ячейке. Пользовательские функции позволяют проводить как вычисления, так и другие операции, выполнение которых с помощью формул, основанных на использовании встроенных функций Excel, просто невозможно. Даже когда формула, записанная стандартными средствами, дает такой же результат, как и пользовательская функция, последняя все же имеет для пользователя существенные преимущества — например, простота ввода, проверка результатов, пони- мание принципов работы и т.д. Так, вместо стандартной строки формул, в распоряжение программиста предоставляется целое окно редактирования кода, где можно разбить сложную логическую конструкцию на отдельные элементы, организовать ее поэтапное построение и проверку. Еще одно важное преимущество (которое следует максимально использовать!) состоит в возможности вставки комментариев рядом с тем кодом, к кото- рому они относятся. Написание пользовательских функций рабочего листа Пользовательские функции Excel — это в сущности обычные VBA-функции. Текст функции начинается с декларации ее имени и заканчивается оператором End Function. Внутри может присутствовать оператор, присваивающий значение переменной с именем функции, — данное значение как раз и будет возвращать функция при выполнении. Function SeparatorAvailable() SeparatorAvailable = Application.Decimalseparator End Function Данная функция просто возвращает символ, который в настоящее время принят в ка- честве десятичного разделителя в приложении Excel. Поскольку функция получает эту информацию из системы, она не имеет аргументов. Глава 13. Программирование на VBA в Excel 333
Выполнить функцию в программе — значит использовать стандартную процедуру об- ращения к функции в языке VBA, те. вызвать ее внутри процедуры Sub. Подробно об этом речь шла в главе 7. Для того чтобы вставить в рабочий лист значение, возвращаемое созданной вами функцией, следует использовать тот же механизм, который применяется для встроенных функций Excel, — внести имя функции в ячейку после знака равенства. Вслед за именем функции следуют круглые скобки, в которые заключаются требуемые значения аргумен- тов. Скобки необходимы даже в том случае, когда аргументы отсутствуют. Например: =SeparatorAvailable(). Так же как и встроенные, пользовательские функции могут быть частью более сложной формулы ячейки. Например: -'Используется десятичный разделитель & Separator- Available() & Результат помещения этой формулы в ячейку рабочего листа показан на рис. 13.10. (Напомним, что приведенное выше определение функции SeparatorAvail- able () должно присутствовать в одном из программных модулей, доступных приложению в данный момент.) Рис. 13.10. Использование пользовательской функции в формуле ячейки Если вы не помните, какие аргументы требуются для функции и принимает ли функция W вообще какие-либо аргументы, не стоит беспокоиться, панель формул Excel распозна- * ет пользовательские функции и показывает все, что необходимо для каждой из них. Можно добавить к функции описание, которое будет появляться в диалоговом окне мастера вставки функций Excel при выборе функции. Чтобы создать описание, на вкладке Вид ленты приложения в группе Макросы раскройте меню кнопки Макросы и выберите команду Макросы, а затем в раскрывшемся диалоговом окне Макрос в поле Имя макроса введите имя функции (по умолчанию функции не отображаются в списке макросов это- го окна). Теперь щелкните на кнопке Параметры и введите описание функции в поле Описание раскрывшегося диалогового окна Параметры макроса (рис. 13.11). По завер- шении щелкните на кнопке ОК и закройте окно Макрос. Если нужная функция хранится в текущей книге, достаточно просто написать ее имя в ячейке формулы. Для того чтобы использовать функцию, хранящуюся в другой открытой книге, имени функции должно предшествовать имя рабочей книги и восклицательный знак, например =Лимные_функции.х18т!8ерага1огА7аПаЬ1е(). Для доступа к функциям, хранящимся в книгах, не открытых в текущий момент, необходимо создать на них ссылку. Для этого в окне редактора VBA выберите команду Tools'^References. Если нужная рабочая книга — точнее, имя требуемого VBA-проекта, сохраняемого в этой книге, — не представлена в списке раскрывшегося диалогового окна References, щелкните на кнопке Browse для ее локализации и добавления в список. Если в раскрывшемся диалоговом окне Add References флажок рядом с требуемым проектом не установлен, обязательно установите его для активизации ссылки. Теперь любую из со- держащихся в данном проекте функций можно использовать, просто указав ее имя, не указывая при этом имени книги. 334 Часть 4. Создание приложений в MS Office
EJ Выполнить t pilCeiis Formatcells Имя макроса: | Separator AvailaWe() | Параметры... | Рис. 13.11. Ввод описания пользовательской функции Войти Изменить j Удалить Отмена j Если при выполнении пользовательской функции, помещенной в формулу рабочего листа, происходит ошибка, обычное сообщение об ошибке в VBA-функции не выводится. Все, что можно будет увидеть в этом случае, — лишь малопонятное сообщение об ошибке вроде #ЗНАЧ! в ячейке, содержащей формулу. Поэтому прежде чем использовать функ- цию в своих рабочих листах, обязательно протестируйте ее работу, организовав ее вызов в редакторе VBA через процедуру Sub. В этом случае будут выводиться обычные сообще- ния об ошибках VBA, с предоставлением доступа к инструментам отладки. Если функция требует передачи ей ссылки на ячейки, при ее вызове для проверки функционирования необходимо использовать объект Range. Sub Тест() Результат = Функция!(Range("В8:В13"), Range("С8")) MsgBox Результат End Sub Кроме того, для отладки можно в код функции, указанной в формуле на рабочем листе, поместить в редакторе VBA точку прерывания. Функция будет запускаться при каждом пересчете Excel рабочего листа, и как только при ее выполнении будет достигнута строка, содержащая точку прерывания, автоматически откроется окно редактора VBA с текстом функции, подготовленным к проведению отладки. Функции, определенные пользователем, должны храниться в стандартных программ- ных модулях. Модули рабочих листов и модуль Эта книга (ThisWorkbook), также пред- ставленные в окне проектов, являются специальными модулями и для этой цели не подходят. Поэтому функция, размещенная в одном из таких модулей, не будет воспри- нята Excel как функция, определенная пользователем. Использование встроенных функций Excel Приложение Excel имеет массу встроенных функций, которые выполняют разноо- бразные вычисления с данными рабочего листа. Из VBA-программ эти функции можно Глава 13. Программирование на VBA в Excel 335
вставлять в ячейки рабочей таблицы, а затем получать результат их выполнения. Предпо- ложим, что ячейки А1:А10 содержат числа, среди которых необходимо найти наиболь- шее. Функция МАХ (МАКС) возвращает наибольшее значение в диапазоне, поэтому для решения поставленной задачи можно поместить ее в некоторую ячейку и использовать возвращаемый ею результат. Worksheets ("Лист1") .Range ("All") .Value="=max (Al :А10) ’’ Максимум = Worksheets("Лист1").Range("All").Value Однако если на самом рабочем листе это вычисленное значение показывать не нужно, а требуется оно только VBA-программе, то для получения результата применения любой функции Excel к диапазону рабочего листа, без непосредственной вставки этой функции в рабочий лист, можно использовать объект Wor ksheetFunction. Ссылка на этот объект имеется в свойстве WorksheetFunction объекта Application. Синтаксис обращения к данному объекту следующий. Application.WorksheetFunction.Имя_функции(Аргументы) Здесь параметр Имя_ функции заменяется именем требуемой функции рабочего листа, а параметр Аргументы — аргументами этой функции. Следующий пример заменяет фраг- мент кода, приведенный выше. LargestValue= _ Application.WorksheetFunction.Max(Range("Al:A10")) Программирование событий Excel В Excel написание кода для обработки событий часто играет более значимую роль, нежели в остальных приложениях пакета Office. Изменение значения лишь одной ячейки, используемой при вычислении формулы или построении диаграммы, может привести к существенным последствиям для всей рабочей книги. В VBA программисту предоставле- ны возможности для перехвата событий, управляющих данным процессом. Прежде чем приступать к написанию текста программы, обязательно нужно решить, какой именно объект будет отвечать за обработку интересующего вас события. В Excel рас- познавать события способны только четыре объекта приложения: диаграммы, отдельные рабочие листы, рабочие книги и приложение Excel в целом. Если требуется написать код, отвечающий на некоторое событие, связанное с диаграммой, такой код лучше разместить в процедуре обработки события диаграммы. Однако для событий, являющихся ответом на изменения в рабочем листе, имеется несколько доступных вариантов. Хотя некоторые события Excel распознают лишь определенные объекты, большинство событий образует восходящую иерархию от объекта Worksheet к объектам Workbook и Application. Например, внесенные в рабочий лист изменения инициируют событие Change (Изменение) объекта Worksheet, который в свою очередь инициирует событие Sheetchange (Изменение листа) для объектов Workbook и Application. Учитывая сказанное выше, следует определить, где именно лучше всего разместить код процедуры обработки интересующего события — в объекте рабочего листа, рабочей книги или при- ложения. При выборе можно руководствоваться следующими замечаниями. Если код должен выполняться только в ответ на изменения, внесенные в одном конкретном рабочем листе, его лучше поместить в процедуру обработки события данного рабочего листа. 336 Часть 4. Создание приложений в MS Office
Если код должен выполняться при внесении изменений в любой из рабочих листов определенной книги, его следует поместить в процедуру обработки события данной рабочей книги. Если же код должен выполняться при внесении изменений в любую из открытых рабочих книг, его следует поместить в процедуру обработки события приложения. Использование процедур обработки событий Написание процедуры обработки события для любого из объектов Excel в сущности ничем не отличается от написания кода обработки события для формы или элемента управления VBA. Чтобы создать процедуру обработки события для любого объекта, вы- полните следующие действия. 1. Откройте окно редактирования кода для требуемого объекта (дважды щелкнув мы- шью на его имени в окне проектов). 2. Укажите объект, выбрав его имя в раскрывающемся списке Object в левом верхнем углу окна кода. 3. Выберите в раскрывающемся списке Procedure, в правом верхнем углу окна кода, то событие, для которого должен быть написан код (рис. 13.12). 4. В окне появляется “каркас” процедуры обработки выбранного события. Рис. 13.12. Окно кода с заготовкой процедуры обработки события Change объекта Worksheet Кроме написания самого кода, единственным сложным моментом может быть от- крытие окна редактирования кода для требуемого объекта (см. п. 1 в приведенном выше списке). Для объектов Worksheet, Workbook и Chart, занимающих отдельный рабочий лист, никаких сложностей здесь нет — как уже указывалось выше, необходимо просто дважды щелкнуть на имени соответствующего объекта в окне проектов. В случае диаграмм, внедренных в рабочий лист, а также объектов Application, си- туация сложнее. Для того чтобы сделать такие объекты доступными из окна проектов, требуется написать специальные модули классов. Так, для того чтобы можно было обрабатывать события, связанные с объектом Applica- tion, предварительно следует добавить в проект модуль класса, в котором объект класса Ap- plication будет объявлен как способный обрабатывать события. Например, пусть этот модуль класса называется EventClassModule. Тогда в него следует добавить такую строку кода: Public WithEvents Арр As Application Глава 13. Программирование на VBA в Excel 337
где объектная переменная Арр класса Application объявляется открытой (Public) и способной обрабатывать события (WithEvents). Теперь, когда создана требуемая объектная переменная, ее имя появится в раскрываю- щемся списке Object (в левом верхнем углу окна кода). Если выбрать ее в этом списке, в списке Procedure (справа) можно будет выбрать то событие, которое должно обрабаты- ваться, и написать для него соответствующую процедуру (рис. 13.13). Рис. 13.13. Вставка заготовки процедуры обработки требуемого события в модуль класса EventClassModule Однако, для того чтобы написанная процедура обработки события могла работать в приложении, в одном из его программных модулей необходимо создать объектную пере- менную с типом EventClassModule и связать ее с системным объектом Application, представляющим приложение Excel. Например, в некоторый программный модуль при- ложения можно поместить следующий код. Dim X As New EventClassModule ’ Объявление объектной переменной X Sub InitializeApjb () ’ Инициализация переменной Set Х.Арр = Application End Sub Теперь, после вызова процедуры InitializeApp в любом из модулей проекта, объ- ектная переменная Арр будет содержать ссылку на объект Application, представляю- щий приложение Microsoft Excel, и подпрограмма обработки события, присутствующая в его модуле класса, будет использоваться для перехвата и обработки соответствующих событий по мере их возникновения. Объем этой книги не позволяет детально рассмотреть аналогичный вопрос и в отноше- нии встроенных диаграмм, однако при необходимости информацию по этой теме можно найти в справочной системе VBA (тема Using Events with Embedded Charts). Можно лишь добавить, что общая схема действий будет аналогичной, а используемые объекты, естественно, другие. Обработка внесения изменений в рабочий лист Если необходимо, чтобы программа реагировала на действия, выполняемые пользо- вателем на рабочем листе, требуется обрабатывать события Change, Calculate и Se- lectionchange для объектов Worksheet или соответствующие события Sheetchange, 338 Часть 4. Создание приложений в MS Office
SheetCalculate и SheetSelectionChange для объектов Workbook и Application. Для запуска пользовательских процедур, когда сами рабочие листы или диаграммы акти- визированы или не активизированы, используются события Activate и Deactivate. События Change и SheetChange Событие Change (а значит, и Sheetchange) инициируется каждый раз, когда зна- чение любой ячейки или нескольких ячеек рабочего листа изменяется после действий пользователя или обновления ссылки. Однако изменения в вычисляемых значениях не приводят к инициированию данного события. В процедуре обработки этих событий мож- но установить адрес ячейки, значение которой было изменено, а затем предпринять те или иные действия. Например, в следующем примере (листинг 13.6) проверяются измененные значения внутри диапазона, называемого Target, на предмет их попадания в опреде- ленные пределы (4 < п < 11). Такие значения выделяются с помощью шрифта с большим кеглем, полужирным начертанием и зеленым цветом (рис. 13.14). Рис. 13.14. Результат обработки подпрограммой Worksheet—Change диапазона ячеек D3:G14 Листинг 13.6. Анализ значений ячеек заданного диапазона Private Sub Worksheet-Change(ByVai Target As Range) Dim oCell as Range For Each In Target If oCell > 4 And oCell < 11 Then With oCell.Font .Bold = True .Size = 16 .Color = RGB(0, 255, 0) End With End If Next oCell End Sub Глава 13. Программирование на VBA в Excel 339
Обратите внимание на то, что здесь Target может быть не одной ячейкой, а диапазоном, поскольку операции заливки, удаления и вставки могут применяться одновременно к нескольким ячейкам. Для корректной обработки как отдельных ячеек, так и некоторых диапазонов, процедура события Change должна включать в себя структуру For Each... Next, только тогда она будет применима как к отдельной, так и к нескольким ячейкам. В действительности события Change и Shee tChange могут генерироваться даже тогда, когда собственно значение ячеек не изменялось. Данные события генерируются, когда ° пользователь инициализирует процесс редактирования ячейки (после щелчка в панели формул или нажатия клавиши <F2>), даже если сразу после этого он прекратил редак- тирование, не внеся никаких изменений, т.е. просто нажав клавишу <Enter>, щелкнув на кнопке Ввод или в любом другом месте на рабочем листе. События не генерируются, если пользователь прекращает редактирование нажатием клавиши <Esc> или щелчком на кнопке Отмена. События Calculate и SheetCalculate Событий Calculate, генерируемое как объектом Worksheet, таки объектом Chart, генерируется при каждом обновлении программой Excel рабочего листа или диаграммы. Событие SheetCalculate для объектов Workbook и Application генерируется в ответ на событие Calculate. Если режим автоматического пересчета включен, данное событие генерируется, как только изменяется значение любой ячейки, т.е. одновременно с событи- ем Change. Если автоматический пересчет отключен, событие Calculate генерируется лишь тогда, когда пользователь инициализирует пересчет содержимого рабочего листа нажатием клавиши <F9>. Процедуры обработки для событий Calculate и SheetCalculate могут исполь- зоваться для изменения рабочего листа в соответствии с результатами вычислений. На- пример, если известно, что пересчет может изменить элементы упорядоченного списка,, целесообразно использовать процедуру события Worksheet_Calculate для переупо- рядочения списка после выполнения вычислений. Поскольку данные процедуры не со- общают, какая из ячеек была изменена в процессе вычислений, необходимо указывать в программном коде адреса ячеек, которые требуется изменить. События Selectionchange и SheetSelectionChange При каждом перемещении активной ячейки, а также при расширении или сжатии выделенной области, Excel генерирует событие Selectionchange для объекта Work- sheet. Параллельно генерируется событие SheetSelectionChange для объектов Workbook и Application. Процедуры обработки для данных событий можно ис- пользовать для организации обратной связи с текущим выделением. В приведенном ниже примере событие SheetSelectionChange рабочей книги используется для ото- бражения в левой верхней ячейке текущего листа адреса активной ячейки, а также для помещения имени рабочего листа и адреса выделения в строку состояния (рис. 13.15). Обратите внимание на то, как аргумент Sh позволяет идентифицировать и вести работу с текущим листом. Private Sub Workbook_SheetSelectionChange(ByVai Sh As Object, _ ByVai Target As Excel.Range) Sh.Range(”Al”) = ActiveCell.Address Application.StatusBar = Sh.Name & & Target.Address End Sub 340 Часть 4. Создание приложений в MS Office
Рис. 13.15. Результат выполнения процедуры обработки события Sheet Selectionchange объекта Workbook Для того чтобы приведенный выше пример заработал, его программный код следует поместить в определенное место. В окне проектов редактора VBA дважды щелкните на элементе Эта книга, чтобы открыть окно кода модуля рабочей книги. Далее в списке Object этого окна (слева вверху) выберите объект Workbook, а в списке Procedure (справа вверху) — событие SheetSelectionChange. В модуль будет вставлена за- готовка процедуры обработки этого события. Все, что осталось — это поместить в за- готовку две строки исполняемого кода: Sh. Range ("Al") = ActiveCell .Address и Application. StatusBar = Sh.Name & & Target .Address. Перейдите в окно рабочей книги Excel и убедитесь, что процедура работает, выделяя произвольные диапазоны на ее разных листах. Несколько усложнив код, можно добиться, например, того, чтобы в случае попадания на определенном рабочем листе заданной ячейки или диапазона в новое выделение ото- бражалось пользовательское диалоговое окно (рис. 13.16). Private Sub Worksheet_SelectionChange( _ ByVai Target As Excel.Range) If Target.Address = "$B$2" Then MsgBox "Вы нашли нужную ячейку — $В$2!" End If End Sub Глава 13. Программирование на VBA в Excel 341
Рис. 13.16. Вывод окна сообщения из процедуры обработ- ки события Selectionchange объекта Worksheet Работа с диаграммами Программирование динамических диаграмм Создание диаграмм является одним из ключевых свойств приложения Excel. При этом пользователь может выбирать из целого множества разнообразных типов диаграмм, под- ходящих практически к любым вариантам наборов данных и потребностям их визуализа- ции. Существуют такие общие типы, как гистограммы, линейные графики, круговые диа- граммы, и более специализированные, такие как диаграммы рассеивания или биржевые диаграммы. VBA предоставляет инструменты для полного управления многими аспектами отображения диаграмм — цветом фона, текста и линий, видом заголовков и т.д. В Excel поддерживается создание диаграмм двух типов — диаграмм на отдельных ли- стах и диаграмм, встроенных в существующие рабочие листы. В первом случае каждая диаграмма отображается на отдельном листе, называемом листом диаграммы (chart sheet). Лист диаграммы содержит только одну диаграмму и не содержит колонок и строк данных. Во втором случае отображаемая диаграмма встраивается в стандартный рабочий лист. Но в обоих случаях диаграммы управляются одинаково. Листы диаграмм представляются коллекцией Charts, которая содержит объект Chart для каждого листа диаграммы заданной рабочей книги (объект Workbook) или активной рабочей книги (объект Application). Ниже приведен оператор, с помощью которого на печать выводятся все листы диаграмм рабочей книги Sales, xsl. Workbooks("Sales.xsl").Charts.Printout Добавить новый лист диаграммы в коллекцию можно с помощью метода Charts. Add коллекции Charts. Как и в других коллекциях, каждому листу диаграммы в коллекции Charts можно присвоить имя, с помощью которого можно будет обращаться к этому объекту; пример показан в листинге 13.7. Результат выполнения кода этого листинга по- казан на рис. 13.17. Листинг 13.7. Создание нового листа диаграммы в рабочей книге Public Sub AddChart() Dim Pro As Excel.Chart Set Pro = Charts.Add Pro.Name = "Продажи" End Sub 342 Часть 4. Создание приложений в MS Office
Каждая диаграмма» помещенная на рабочий лист, также представлена объектом Chart, однако он присутствует в нем не отдельно, а в объекте Chartobject, являющимся кон- тейнером для объектов Chart. В отличие от диаграммы на собственном листе, встроен- ная диаграмма может отображаться с разными размерами и в разных позициях. Свойства объекта Chartobject как раз и задают внешний вид й размеры встроенной диаграммы. Каждый объект Worksheet имеет коллекцию Chartobjects, в которой содержится по одному объекту ChartOb j ect для каждой помещенной на этот лист диаграммы. Для того чтобы добавить на рабочий лист новую встроенную диаграмму, нужно использовать метод Add коллекции ChartOb j ects. Chartobjects.Add (Left, Top, Width, Height) Здесь аргументы Left и Top задают позицию левого верхнего угла диаграммы относи- тельно верхнего левого угла рабочего листа. Аргументы Width и Height задают размер диаграммы (ширина и высота соответственно). Все четыре аргумента являются обязатель- ными и измеряются в точках (points) (1 точка = 1/72 дюйма). Создание диаграммы с помощью VBA Для создания диаграммы с помощью инструментов пользовательского интерфейса Excel (это самый простой способ создания диаграммы в Excel) необходимо выделить Глава 13. Программирование на VBA в Excel 343
исходные данные на рабочем листе (рис. 13.18), а затем нажать клавишу <F11>. По- сле этих действий будет создана новая диаграмма, расположенная на отдельном листе (рис. 13.19). Рис. 13.18. Исходные данные для получения диаграммы Давайте рассмотрим программный код, сгенерированный посредством записи макро- сов при построении диаграммы на основе исходных данных, показанных на рис. 13.18. Charts.Add ActiveChart.SetSourceData Source:=Sheets("Лист!").Range(B3:F12) ActiveChart.Location Where:=xlLocationAsNewSheet Здесь, в первой строке, коллекция Charts является коллекцией всех листов диаграмм в рабочей книге, и, как каждая коллекция, она имеет метод добавления нового элемента — Add. Таким образом после выполнения первой строки кода Charts .Add в коллекцию Charts будет добавлен новый, пока еще пустой лист диаграммы, который Excel авто- матически делает активным. Для обращения к текущей активной диаграмме можно ис- пользовать как объект Chart (например, Charts ("Диаграмма!")), так и объект VBA ActiveChart. 344 Часть 4. Создание приложений в MS Office
Рис. 13.19. Новая диаграмма, расположенная на отдельном листе Во второй строке приведенного выше сгенерированного кода определяется диапазон исходных данных для диаграммы с помощью метода SetSourceData. Следует отметить, что VBA содержит соответствующие методы для всех действий, которые можно выпол- нить посредством пользовательского интерфейса. Так, для того чтобы задать диапазон исходных данных диаграммы, необходимо щелкнуть на ней правой кнопкой мыши и вы- брать команду контекстного меню Выбрать данные (Source Data). На экране появится диалоговое окно Выбор источника данных (рис. 13.20). Здесь в поле Диапазон данных для диаграммы можно указать диапазон исходных данных диаграммы. Полный синтаксис метода SetSourceData следующий. SetSourceData (Source, PlotBy) Здесь Source — это ссылка на диапазон ячеек, a PlotBy — константа, принимающая значение xlColumns (ряды данных в столбцах) или xlRows (ряды данных в строках). Следует отметить, что в нашем коде аргумент PlotBy отсутствует, так как при записи ма- кроса программа сочла возможным опустить его, поскольку структура исходных данных предполагает, что ряды данных расположены в столбцах. Глава 13. Программирование на VBA в Excel 345
Выбор источника данных Диапазон данных для диаграммы: Рис. 13.20. Диалоговое окно для определения диапазона исходных данных диаграммы В третьей строке рассматриваемого кода используется метод Location. Синтаксис этого метода следующий. Location (Where, Name) Здесь константа Where может принимать значения xlLocationAsNewSheet (на но- вом листе диаграммы), xlLocationAsNewObject (на рабочем листе) и xlLocation- Automatic (автоматический выбор), a Name — это строка, которая определяет следующее: имя нового листа, на котором будет размещена диаграмма (параметр where имеет значение xlLocationAsNewSheet); имя рабочего листа, на котором будет размещена встроенная диаграмма (параметр Where имеет значение xlLocationAsNew). ЯМЦ Полезно будет отметить следующее: так как использование метода Charts .Add под- разумевает, что новая диаграмма будет размещаться на новом листе, последняя строка М3 сгенерированного макрорекодером кода является лишней, из ваших подпрограмм ее можно удалить. Поскольку объекты диаграмм Excel способны распознавать большое количество собы- тий, многие из которых связаны с манипуляцией мышью, их в принципе можно рассма- тривать как специализированные элементы управления ActiveX, помещенные в рабочую книгу. Сам объект диаграммы генерирует события Activate, Deactivate и Calculate. Перечислим еще несколько событий, для которых возможно написание подпрограмм обработки. DragOver и DragPlot. Генерируются, когда объекты перемещаются над внедрен- ной диаграммой или опускаются на нее соответственно. Mouse Down, MouseUp и Мои s eMove. Генерируются в ответ на действия мыши: нажатие левой кнопки, отпускание левой кнопки и перемещение указателя соот- ветственно. 346 Часть 4. Создание приложений в MS Office
Select. Генерируется при выделении пользователем какой-либо части диаграммы. В подпрограмме обработки можно определить тип и характеристики выделенного элемента, а затем выполнить необходимые действия. Serieschange. Генерируется, когда пользователь изменяет значение элемента данных на самой диаграмме (а не исходные значения, содержащиеся в рабочем листе). Резюме В этой главе обсуждались способы использования в VBА-программах функциональ- ных возможностей приложения Microsoft Excel. Спектр этих возможностей весьма широк, поэтому мы начали с рассмотрения особенностей объектной модели этого приложения. В главе были описаны методы работы и основные функции таких важных объектов Excel, как Workbook, Worksheet, Range, и диалоговых окон приложения. Затем подробно обсуждались вопросы программирования пользовательских функций и использования в VBА-программах встроенных функций Excel. Далее подробно, на конкретных примерах, рассматривался такой важный вопрос, как создание подпрограмм обработки событий, ис- пользование которых позволяет разрабатывать приложения, реагирующие на любые дей- ствия пользователя. В завершение кратко обсуждался такой важный вопрос, как создание диаграмм и основные способы управления ими. Тестовые задания Ниже приведено несколько тестовых заданий, предназначенных для закрепления из- ложенного в этой главе материала. В каждом задании вам предлагается вопрос и несколь- ко вариантов ответа на него, один (или несколько) из которых является правильным, а остальные — нет. Укажите правильный ответ. 1. Какая форма записи вызова метода создания новой рабочей книги является до- пустимой в среде VBA при работе в уже открытом приложении Excel: a)Excel.Application.Workbooks(New); 6)Application.Workbooks.Add; в)Application.Workbooks.Create; r) Workbooks. Add. 2. Какая форма записи вызова метода открытия уже существующей рабочей книги яв- ляется допустимой в среде VBA при работе с приложением Excel, неявно открытым из другого приложения MS Office: a)Workbooks.Open(Имя_файла); б)Application.Workbooks.Open(Имя_файла); в)Excel.Application.Workbooks.Open(Имя_файла) ; г)Application.Workbooks(Имя_файла). 3. Для идентификации требуемого диапазона в программе могут использоваться сле- дующие методы: а) стандартная ссылка на ячейку; Глава 13. Программирование на VBA в Excel 347
б) текущее положение курсора; в) имя диапазона; г) содержимое ячеек диапазона. 4. Свойства объекта Range позволяют с помощью единственного оператора выпол- нять с ячейками диапазона следующие операции: а) записывать в них разные новые значения; б) записывать в них одно и то же новое значение; в) изменять их значения с учетом текущего; г) задавать элементы форматирования ячеек диапазона; д) проверять текущее значение ячеек диапазона. 5. Программирование процедур обработки событий возможно для следующих объек- тов Excel: a) Application; б) Range; в) Cell; г) Worksheet; д) Window. 348 Часть 4. Создание приложений в MS Office
Глава 14 Программирование на VBA в Word В этой главе... ♦ Объектная модель Word ♦ Доступ к документам Word с помощью VBA ♦ Управление параметрами и окнами Word ♦ Объект View ♦ Использование объектов Selection и Range ♦ Работа с текстом ♦ Поиск и замена информации ♦ Использование переменных документа ♦ Резюме Microsoft Word 2010 — это специализированная программа для работы с текстовыми документами. Когда другому офисному приложению требуется работать с текстом, оно практически всегда обращается к функциональным возможностям объектов, предостав- ляемых приложением Microsoft Word. Документ Word является идеальным местом для объединения различных элементов из других офисных приложений, например отфор- матированного отчета и диаграммы Excel, слайда из PowerPoint или некоторых данных из Access. В этой главе будут рассмотрены самые важные элементы объектной модели Word, предназначенные для создания документов и работы с ними. Для получения более подробных сведений можно обратиться к справочной системе VBA или дополнительной литературе. Объектная модель Word Ключевым в объектной модели Word является объект Application (равно как и в объектных моделях остальных приложений Microsoft Office). Этот объект содержит все остальные объекты Word (рис. 14.1). Поскольку объект Application занимает цен- тральное место в объектной модели приложения, при программировании на языке VBA в Word не требуется явно указывать его имя при работе со многими другими важными объектами. Не следует забывать о роли, которую играет этот объект, поскольку он необ- ходим при работе со свойствами и методами самого приложения, а также при обращении к некоторым другим объектам.
Непосредственно под объектом Application размещается коллекция Documents, содержащая объекты Document для каждого открытого документа (рис. 14.2). Объект Document является центром всего, что происходит в приложении Word, и большая часть настоящей главы будет посвящена именно ему. Остальные компоненты Word, с которыми придется работать, подчинены объекту Document. Рис. 14.2. Фрагмент структурной схемы объекта Document приложения Word Рис.. 14.1. Фрагмент объектной модели приложения Microsoft Word. Темным выде- лены только объекты, а светлым — объек- ты и коллекции. Стрелки указывают на существование подчиненной подсхемы Напомним, что для работы с объектом прежде всего необходимо получить ссылку на него. При этом программе может потребоваться либо создать новый экземпляр указан- ного объекта, либо просто вернуть ссылку на уже существующий экземпляр. Доступ к документам Word с помощью VBA Если созданная VBA-процедура функционирует непосредственно в документе, то объ- ект этого документа должен быть явно указан в коде. Иногда требуемые действия можно реализовать и неявным образом, используя объект Selection, о котором мы будем го- ворить ниже в этой главе, однако в большинстве случаев потребуется явно идентифици- ровать целевой объект. Обычно типичная VBA-процедура в Word выполняет все свои действия в том доку- менте, который в данный момент открыт для редактирования. В этом случае для указания активного документа можно использовать объект Ac t iveDocumen t. Например, чтобы за- крыть активный документ, не требуется получать ссылку на объект редактируемого в дан- ный момент документа, достаточно просто обратиться к объекту ActiveDocument. ActiveDocument.Close ’Закрытие активного документа 350 Часть 4. Создание приложений в MS Office
При работе с определенным документом, который в данный момент времени не ак- тивен, следует обращаться к нему как к члену коллекции Documents, состоящей из всех документов, открытых в настоящее время в Word. Как и в случае с любой другой коллек- цией объектов в VBA, можно обратиться к отдельному документу в коллекции, используя значение его свойства Name, которое в данном случае совпадает с именем файла (только с именем файла, а не с полным путем к нему’). Documents("Отчет за ноябрь.doc") Поскольку имя файла вновь создаваемого документа неизвестно заранее и пользова- тель может определить или изменить его в любой момент работы программы, в этом случае удобнее создать переменную, которая будет содержать имя файла. После этого можно использовать эту переменную для указания объекта данного документа, на- пример Documents(strDocHMn). Кроме того, к документу можно обращаться по его индексному номеру: Docu- ments (5) это, например, обращение к пятому документу в коллекции Documents. Следует отметить, что применение данного метода достаточно ограничено, поскольку редко когда заранее известен индексный номер того документа, с которым требуется работать. Можно поступить иначе: с помощью индексных номеров узнать имена откры- тых документов, а затем выбрать требуемый. Например, следующий оператор помещает в переменную s trDocMMH имя файла третьего открытого документа. strDocMMH = Documents(3).Name Создание, открытие и закрытие документов Для создания нового документа используется метод Add коллекции объектов Documents. Его синтаксис следующий. Dim MyDocl as Word.Document Set MyDocl = Documents.Add[Шаблон, Новый_Шаблон] Здесь Шаблон — необязательный аргумент, определяющий имя шаблона, на основе кото- рого будет создан новый документ. Необязательный аргумент Новый_Шаблон указывает, будет ли создаваемый документ сам являться шаблоном (значение True) или он будет обычным документом (значение False). Если оба аргумента опущены, создается обыч- ный документ на основании шаблона Normal. Можно одним оператором создать новый документ и сразу же присвоить ему некоторое имя. Dim MyDoc As Word.Document Documents.Add.SaveAs("Отчет за октябрь.doc") ’Создание документа Set MyDoc = Documents("Отчет за октябрь.doc") ’Получение ссылки на него Если документу во время его создания не присваивается имя, это имя следует при- своить при первом его сохранении (подробнее об этом будет сказано ниже). Для открытия уже существующего документа используется метод Open коллекции объектов Documents. Dim MyDoc As Word.Document Set MyDoc = Documents.Open(Имя_файла) Глава 14. Программирование на VBA в Word 351
Здесь аргумент Имя_файла задает полный путь и имя файла открываемого документа. Если заданный файл не существует или не является допустимым документом Word, воз- никает ошибка. Для активизации уже открытого документа следует использовать метод Activate коллекции объектов Documents. Предположим, что в VBA-программе требуется активи- зировать определенный документ, который в момент ее запуска или открыт, или закрыт. Используйте код, подобный показанному ниже. Для активизации открытого документа или открытия его, если этот документ еще не открыт, можно использовать процедуру, при- веденную в листинге 14.1. Листинг 14.1. Активизация документа Word Public Sub DocActivateOrOpen() Dim Имя_Файла, Путь As String Dim Документ As Document Dim Открыт As Boolean Имя_Файла = "Отчет за октябрь.docx" ' Имя требуемого файла Путь = "С:\Отчеты\" ' Путь к папке с отчетами ’Проверка, открыт ли уже требуемый файл For Each Документ In Documents If Документ.Name = Имя_Файла Then Открыт = True ’Да, требуемый файл открыт End If Next Документ ’ Активизация документа с именем "Отчет за октябрь" If Открыт = True Then ’ Файл уже открыт Documents(Имя_Файла).Activate Else ’ Открытие файла Documents.Open FileName:=Путь & Имя_Файла End If End Sub Для закрытия документа используется метод Close объекта Document. Синтаксис его следующий (здесь Документ — ссылка на объект закрываемого документа). Документ. Close (Сохранить, Формат, Переслать) Здесь аргумент Сохранить указывает, должен ли документ быть сохранен перед закры- тием. Возможными значениями этого аргумента являются константы: wdDoNotSave- Changes (не сохранять документ), wdPromptToSaveChanges (запросить сохранение изменений — принимается по умолчанию) и wdSaveChanges (сохранить изменения). Аргумент Формат определяет тип формата, в котором будет сохранен документ. Воз- можными значениями этого аргумента являются константы: wdO г igi па 1 Do cume nt For- mat (исходный формат документа), wdPromptUser (запросить пользователя) и wdWord- Document (формат документа Word — принимается по умолчанию). Аргумент Переслать допускает значения True либо False (принимается по умол- чанию) и определяет, должен ли документ отсылаться следующему получателю в списке рассылки (routing). Значение True не будет иметь смысла, если документ не содержит присоединенного к нему списка рассылки. 352 Часть 4. Создание приложений в MS Office
Все открытые документы можно одновременно закрыть, используя метод Close кол- лекции Documents. Он имеет те же аргументы, которые были описаны выше для ме- тода Close объекта Document. Управление параметрами и окнами Word Иногда в процессе работы с компонентами Word недостаточно сосредоточиться ис- ключительно на объекте Document и его подобъектах. В некоторых случаях потребуется иметь дело непосредственно с объектом Application и другими объектами, которые в иерархии объектов Word не подчинены объекту Document. К таким объектам, в частно- сти, относятся глобальные параметры настройки приложения, некоторые полезные диа- логовые окна, а также средства работы с окнами и находящимися в них инструментами. При работе с приложением Word его объект Application будет доступен автомати- чески — достаточно просто указать его имя: Application. Если доступ к объектам Word осуществляется из другого приложения Office, потребуется сначала создать экземпляр приложения Word, а затем использовать в обращениях ссылку на него. Dim MyWord As Word.Application Set MyWord=New Word.Application Переопределение параметров приложения Word Приложение Word имеет множество параметров, контролирующих различные аспек- ты работы программы. При непосредственной работе с приложением доступ к этим параметрам осуществляется с помощью диалогового окна Параметры Word. Оно имеет несколько вкладок, на которых устанавливаются различные параметры, определяющие те или иные аспекты работы программы. Многие из параметров, доступные в этом диа- логовом окне, являются глобальными, поскольку оказывают влияние на работу прило- жения в целом, тогда как другие параметры применяются только к активному документу. Глобальные параметры являются свойствами объекта Options, в то время как параметры, влияющие на отдельный документ, будут свойствами объекта Document. Для получения доступа к параметрам уровня приложения используется объект Op- tions, ссылка на который хранится в одноименном свойстве объекта Application. Например, для включения режима печати скрытого текста можно использовать следую- щий оператор. Options.PrintHiddenText = True В общем случае рекомендуется сохранять исходные значения всех параметров прило- жения, значения которых изменяются в программе, и восстанавливать их перед завер- шением работы приложения. Диалоговые окна приложения Word В VBA-программах можно использовать для своих целей множество диалоговых окон, имеющихся в приложении Word. Доступ к этим окнам осуществляется через коллекцию Dialogs, которая является свойством объекта Application (см. рис. 14.1). Для исполь- зования некоторого диалогового окна прежде всего нужно создать ссылку на это диало- говое окно. Глава 14. Программирование на VBA в Word 353
Dim Диалог As Dialog Set Диалог = Dialogs(Тип_окна) Здесь аргумент Тип_окна определяет конкретное диалоговое окно, доступ к которому требуется получить. В библиотеке типов Word содержится список заранее заданньпс кон- стант в форме wdDialogXXXX, где ХХХХ определяет конкретное диалоговое окно. В боль- шинстве случаев (но не во всех) имя ХХХХ связано с именем соответствующего диалого- вого окна в английской версии приложения. Например, wdDialogFileOpen определяет диалоговое окно открытия файла. После того как ссылка на требуемое диалоговое окно будет получена, для его отобра- жения можно использовать методы Show или Display этого объекта. Синтаксис этих двух методов практически одинаков. Окно.Show(Таймаут) Окно.Display(Таймаут) Здесь аргумент Таймаут определяет время, по истечении которого данное диалоговое окно следует закрыть, если пользователь не работал с ним. Важно помнить, что единицами измерения времени здесь являются миллисекунды. Если этот аргумент опущен, диалоговое окно отображается до тех пор, пока пользователь сам его не закроет. Когда диалоговое окно имеет вкладки, можно потребовать при его открытии сразу выбрать одну из них. Для ее указания используется свойство DefaultTab объекта Dia- log. Требуемое значение этому свойству задается с помощью дополнительной констан- ты, которая имеет вид wdDialogXXXXTabyyyy, где ХХХХ определяет диалоговое окно, а уууу — его отдельную вкладку. Так, константа wdDialogFormatFontTabCharacterSpacing определяет вкладку Интервал диалогового окна Шрифт. При этом общая последователь- ность операторов будет выглядеть, например, так. Dim Диалог As Dialog Set Диалог = Dialogs(wdDialogFormatFont) ’ Выбор окна Диалог.DefaultTab = wdDialogFormatFontTabCharacterSpacing Диалог.Show Следует отметить, что при использовании метода Show изменения и любые действия, выполненные в данном диалоговом окне, вступают в силу автоматически, обычным спо- собом. В противоположность этому, при использовании метода Display выполненные пользователем изменения и действия не вступают в силу автоматически. Ваша программа сама должна получить от объекта диалогового окна (после его закрытия) информацию о внесенных пользователем изменениях, а затем поступить с ними требуемым образом. Оба метода возвращают значение типа Long, определяющее, какая кнопка использо- валась для закрытия окна. Возможные значения приведены в табл. 14.1. Таблица 14.1. Значения, которые могут возвращаться методами Show и Display Значение Описание___________________________________________________________ -2 Кнопка Close “1 Кнопка ОК или ее эквивалент (например, кнопка Open в диалоговом окне открытия файла) О Кнопка Cancel >0 Другая командная кнопка (1 — первая кнопка, 2 — вторая и т.д.) 354 Часть 4. Создание приложений в MS Office
Следующий пример показывает, как диалоговое окно Open можно открыть из про- граммного кода. Dim Открыть_файл as Dialog Set Открыть_файл = Dialogs(wdDialogFileOpen) Открыть_файл.Show В этом случае, если в раскрывшемся диалоговом окне пользователь выберет некото- рый файл и щелкнет на кнопке Open, указанный файл будет открыт, причем новый объект Document для него создается автоматически, без каких-либо дополнительных действий со стороны вашей программы. При использовании метода Display пользователю также будет предоставлена возможность выбрать в раскрывшемся диалоговом окне требуемый файл, однако в программный код потребуется включить процедуру, которая будет его от- крывать. Обычно для этого используется метод Execute объекта Dialog. Иначе говоря, можно считать, что метод Show равноценен методу Display с после- дующим выполнением метода Execute. Использование метода Display для вывода встроенных диалоговых окон будет полезным в тех случаях, когда диалоговое окно вы- водится для получения необходимой информации от пользователя, однако, прежде чем переходить к дальнейшей обработке, ее желательно проверить. В приложении Word имеется около 295 встроенных диалоговых окон. Информацию о них можно получить с помощью справочной системы редактора VBA, выполнив поиск по фразе Built-in Dialog Boxes, а затем выбрав из предложенного на панели задач списка ссылку Built-in Dialog Box Argument List (рис. 14.3). На этой странице справки перечисле- ны все доступные в Word диалоговые окна и приведены их аргументы. Рис. 14.3. Окно справочной системы редактора VBA с результатами поиска по фразе Built-in Dialog Boxes Глава 14. Программирование на VBA в Word 355
Обращение к окнам документов из программного кода Если в VBA-программе работа с Word осуществляется как со скрытым приложением, то обращаться к его окнам и панелям не потребуется. Однако если VBA-приложение пред- полагает вывод на экран окна Word, с тем чтобы пользователь мог выполнить в нем те или иные необходимые действия, обращение к окнам и панелям Word из программного кода, скорее всего, будет неизбежным. Каждый открытый документ Word содержит, как минимум, одно окно, причем поль- зователь может открыть столько окон, сколько ему необходимо для работы с данным документом. Каждое из подобных окон — самостоятельный объект с соответствующим набором свойств. В объектной модели Word объект Application содержит коллекцию Windows (см. рис. 14.1), а членами этой коллекции являются объекты Window — по одному для каждого открытого окна (рис. 14.4). Кроме того, каждый объект Document содержит свою собственную коллекцию объектов windows (см. рис. 14.2). Естественно, каждый объект окна Window в коллекции Document.Windows одновременно присутству- ет и в коллекции Application. Windows. [Window | -[Panes | Црапе | ^Zoom -[Document | ► ~j Selection | -[View | Puc. 14.4. Фрагмент структурной схемы объекта Window приложения Word Из программного кода VBА-приложения проще всего обращаться к тому окну, в ко- тором редактируемый документ был открыт во время запуска процедуры. Для ссылок на это окно используется объект Activewindow. Для определения окна непосредственно в программном коде следует ссылаться на него как на члена одной из коллекций Win- dows. При работе с глобальной коллекцией объектов Windows не нужно дополнительно указывать объект Application. Однако при обращении к коллекции объектов Windows некоторого документа указывать имя объекта этого документа нужно обязательно. Окно в коллекции можно идентифицировать по его имени или индексному номеру. Имя окна совпадает с именем документа, который в нем отображается, — за исключением тех случа- ев, когда для одного документа открыто сразу несколько окон. В этом случае после имени 356 Часть 4. Создание приложений в MS Office
документа следует ставить точку с запятой, а затем номер окна. Типичные примеры записи ссылок на объекты Window приведены в табл. 14.2. Таблица 14.2. Типичные ссылки на объекты Window Ссылка______________________Комментарии_______________________________________ Windows (’’Отчет за ноябрь”) Ссылка на окно по его имени. Действительна, если для докумен- та Отчет за ноябрь в данный момент открыто только одно окно Windows (’’Реестр; 2”) Ссылка на окно по его имени. Указывает на второе окно доку- мента Реестр Documents (’’Реализация - Указывает на четвертое окно в коллекции Windows документа doc”) . windows (4) Реализация Объект Window имеет множество свойств, как определяющих внешний вид соответ- ствующего окна, так и предназначенных для работы с его содержимым. Большая часть этих свойств может принимать только одно из двух допустимых значений — True или False. Например, вывести вертикальную полосу прокрутки в окне текущего активного документа можно с помощью следующего оператора. ActiveWindow.DisplayVerticalRuler = True Подобные операторы можно использовать для включения или выключения различных свойств, таких как DisplayScreenTips (отображение подсказок) или DisplayRulers (отображение линеек). Полезно будет напомнить, что с помощью ключевого слова Not можно изменить текущее значение логической переменной или свойства на обратное. На- пример, изменить на обратное текущее значение свойства, управляющего отображением в окне линеек, можно следующим образом. ActiveWindow.DisplayRules = Not ActiveWindow.DisplayRules । С помощью свойств Left, Top, Height и Width можно изменять размер и располо- жение окна, которое не развернуто на весь экран. Объект Window имеет несколько методов, которые позволяют управлять горизонталь- ной и вертикальной прокруткой документа для отображения конкретных его частей. Так, метод SmallScroll используется для медленной, a LargeScroll — для быстрой про- крутки документа. Window.SmallScroll (Down, Up, ToRight, ToLeft) Window.LargeScroll (Down, Up, ToRight, ToLeft) Здесь аргументы Down, Up, ToRight, ToLeft метода указывают количество единиц прокрутки в соответствующем направлении. В методе SmallScroll единицей является расстояние, на которое смещается содержимое экрана при щелчке на стрелке полосы про- крутки (приблизительно одна строка). В методе LargeScroll единицей прокрутки явля- ется содержимое одного экрана. Если опущены все аргументы, оба метода осуществляют прокрутку документа вниз на одну единицу. Для постраничной прокрутки содержимого документа используется метод Rage- Scroll. Window.PageScroll(Down, Up) Глава 14. Программирование на VBA в Word 357
Здесь аргументы Down и Up определяют количество страниц, на которое выполняется про- крутка. Если аргументы опущены, выполняется прокрутка документа на одну страницу вниз. Для прокрутки до заданной позиции документа используется метод ScrollIntoView. Window.ScrollIntoView(Obj, Start) Здесь аргумент Obj определяет объект Range или Shape, к которому нужно переместить- ся. Аргумент Start не обязателен, он определяет, должен ли левый верхний угол фраг- мента, указанного аргументом Obj, совпадать с левым верхним углом экрана (Start = True, принимается по умолчанию) или же должны совпадать правые нижние углы фраг- мента и экрана (Start = False). Объект View В Word каждый объект Window-имеет объектное свойство View, содержащее ссылку на объект одноименного класса (см. рис. 14.4). Свойства объекта View определяют многие аспекты отображения окна или его области. Некоторые полезные свойства объекта View приведены в табл. 14.3. Таблица 14.3. Некоторые свойства объекта View Свойство Нвзнвчвнив Fullscreen Управляет режимом отображения окна в стандартном или полноэкранном варианте ShowAll Определяет отображение в документе всех непечатаемых знаков и соответствует флажку Показывать все знаки форматирования в группе Всегда показывать эти знаки форматирования на экране на вкладке Экран диалогового окна Параметры Word. Из программного кода можно также включить или отклю- чить отображение отдельных непечатаемых символов, а также других элемен- тов, таких как выделение текста или отображение границ. Для управления подобными элементами используются различные свойства, названия которых начинаются с Show — например ShowBookmarks (закладки) или ShowHigh- light (выделение) TableGridlines Type Управляет отображением сетки таблицы Определяет способ представления информации в окне, который задается щелч- ком на кнопках Разметка страницы, Режим чтения, Структура и так далее в группе Режимы просмотра документа на вкладке Вид ленты приложения. Допустимыми значениями свойства являются следующие константы: wdMas- terView, wdNormalView, wdOutlineView, wdPrintView, wdWebView, wdReadingView и wdPrintPreview. Для изменения способа представления документа в окне достаточно соответствующим образом изменить значение данного свойства. Например, оператор Activewindow.View.Туре = wd- PrintView вызывает переключение активного окна в режим предварительного просмотра Использование объектов Selection и Range Объект Selection (рис. 14.5) относится к области окна, а не документа, и пред- ставляет собой выделенный в документе текст. Это может быть таблица, текстовое окно, фрагмент текста, изображение или что-нибудь другое, что можно выделить с помощью 358 Часть 4. Создание приложений в MS Office
мыши или клавиатуры. Если в документе ничего не выделено, то объект Selection представляет текущее расположение точки вставки, т.е. текстового курсора. Доступ к это- му объекту осуществляется через цепочку объектов Application, Window и Рапе, а не через объект Document (см. рис. 14.4). Рис. 14.5. Фрагмент структурной схемы объекта Selection приложения Word Объект Selection может представлять содержимое различных типов, поэтому целе- сообразно сначала проверить, данные какого типа были выделены в документе, и лишь потом выполнять их обработку. В противном случае можно получить самые неожиданные результаты или даже сообщение об ошибке. Сведения о типе выделенных в документе дан- ных помещаются в свойство Туре объекта Selection. По значению свойства Туре можно определить тип текущего выделения. Например, приведенный ниже фрагмент кода про- веряет, является ли выделенная область обычным текстом, прежде чем вырезать ее из доку- мента с помещением в буфер обмена, а затем вставить вырезанное на одну страницу выше. With Selection ’ Работаем с текущим выделением в документе If .Туре = wdSelectionNormal Then ’ Выделен текстовый блок .Cut ’ Выделенный текст вырезается в буфер обмена ’ Перемещение в документе на страницу вверх .GoTo What:=wdGoToPage, Which:=wdGoToPrevious, Count:=1 .Paste ’ Текст из буфера обмена вставляется в документ End If End With Глава 14. Программирование на VBA в Word 359
Все допустимые значения, которые может принимать свойство Туре объекта Selec- tion, определяются глобальными константами, приведенными в табл. 14.4. Таблица 14.4. Допустимые значения свойства Туре Константа Что выделено e документе wdNoSelection Ничего не выбрано wdSelectionBlock Вертикальный блок текста wdSelectionColumn Столбец в таблице wdSelectionFrame Рамка wdSelectionInlineShape Графическое изображение в тексте wdSelectionIP Только точка вставки wdSelectionNormal Обычное выделение фрагмента текста wdSelectionRow Строка таблицы wdSelectionShape Изображение, не помещенное в текст Действия, которые можно выполнять над объектом Selection, условно разделяют на две категории — изменение выделения так, чтобы оно включало другую часть документа, и изменение текста внутри выделения. Объект Selection имеет свойства, содержащие информацию о выделенном тексте, и методы, с помощью которых этим текстом можно манипулировать. Таких свойств и методов довольно много, они достаточно подробно опи- саны в справочной системе редактора VBA Word. Объект Range При редактировании документа в окне приложения Word предварительно необходимо поместить указатель мыши в нужное место или выделить в нем определенный фрагмент и только после этого можно добавлять, удалять или форматировать текст. Однако при ра- боте с Word из VBA-программ необходимость подобных действий можно исключить, если использовать объекты Range (диапазоны). Объект Range используется для представления непрерывной области (диапазона) в документе Word. Диапазон определяется позицией первого и последнего входящего в него символа. Примером диапазона является место вставки, фрагмент текста, а также весь документ Word вместе с непечатаемыми символами, такими как символы пробела и абзаца. Использование объекта Range позволяет создавать более эффективный код за счет упрощенного способа обращения к требуемым элементам документа Word. В VBA-программах с помощью объекта Range можно помечать требуемую часть документа, однако эта отметка будет существовать только до тех пор, пока работает та процедура, в которой она была создана. Самое важное здесь то, что объекты Range со- вершенно независимы от текущего положения курсора ввода или выделенной части доку- мента (объект Selection), которые пользователь видит в окне приложения. Более того, в одном документе этих объектов может быть создано сразу несколько. По своему на- значению этот объект очень похож на объект Selection. После создания объекта Range можно манипулировать определяемым им текстом с помощью операторов языка VBA, представляющих собой полные аналоги любых команд редактирования Word, — точно так же как при использовании объекта Selection. Внутренняя структура объекта Range показана на рис. 14.6. 360 Часть 4. Создание приложений в MS Office
[Range | -[Characters . | -[Columns | Ц Column | -[Borders | Ц Border -|Cells |> Shading | -[Fields | Field | ~|HnO I ► ~~|Font | -[ListFormat | -jListParagraphs | Ц Paragraph [ -j Par agr aphFor mat | -[Paragraphs | -(Ro*s -[Sections | -[Sentences | -[Shading | -Is»1* I -| Subdocuments | Ц Subdocument | -[Tables | -[Words | Puc. 14.6. Фрагмент структурной схемы объекта Range приложения Word Определить объект Range в программном коде можно одним из двух следующих способов: с помощью свойства Range объектов различных классов, определяющих различ- ные элементы документа (абзац, сноска, ячейка таблицы и пр.); с помощью метода Range объекта Document. Открытый документ Word уже содержит объекты Range, соответствующие многим его элементам. Для каждого его абзаца или таблицы, отдельной ячейки таблицы, коммента- рия или колонтитула (и это далеко не полный список) объекты Range создаются авто- матически. Например, для доступа к объекту Range, соответствующему первому абзацу активного документа, достаточно указать объектную ссылку следующего вида. ActiveDocument.Paragraphs(1).Range Поскольку в открытом документе Word подобные стандартные диапазоны уже суще- ствуют, можно использовать объектные ссылки на них напрямую, не применяя каких- либо дополнительных переменных. Это очень удобно в тех случаях, когда отдельная операция выполняется над определенным диапазоном в целом. Например, приведенный ниже оператор копирует вторую таблицу в документе в буфер обмена, используя метод Сору объекта Range. ActiveDocument.Tables(2).Range.Copy Глава 14. Программирование на VBA в Word 361
Если несколько операторов используют один и тот же диапазон, то для упрощения кода программы и ускорения ее выполнения можно использовать конструкцию With... EndWith. Ниже приведен пример кода, с помощью которого выполняется сортировка абзацев в третьем разделе документа, после чего второе предложение в нем выделяется полужирным шрифтом. With ActiveDocument.Sections(3).Range .Sort SortOrder:=wdSortOrderAscending .Sentences(2).Bold = True End With Если в процедуре один и тот же диапазон используется в нескольких инструкциях, которые не следуют одна за другой, то полезно поместить ссылку на него в объектную переменную. Это упростит код программы и будет способствовать повышению скорости ее выполнения. Для работы с нестандартным диапазоном прежде всего следует создать собственный объект Range. Для этого можно использовать метод Range объекта Document. Его син- таксис следующий. Документ.Range[Start, End] Здесь Start и End — необязательные аргументы, задающие позицию символов начала и конца диапазона. Если эти аргументы опущены, метод возвращает диапазон, в котором содержится весь документ. В любом открытом документе можно определить сколько угод- но объектов Range, используя для этого метод Range документа. Требуется лишь указать начальную и конечную точки каждого диапазона в терминах расположения соответствую- щих символов в документе. ActiveDocument.Range(Start:= 10, End:=20) Это выражение представляет собой объектную ссылку на диапазон, который начи- нается с 11-го символа и заканчивается 20-м символом в активном документе. Числовое значение, определяющее расположение символа, на самом деле указывает на позицию справа от данного символа. Например, значение 0 соответствует первому символу в до- кументе, а значение 10 указывает на точку между 10-м и 11-м символами. Word считает все символы в документе, включая скрытые и непечатаемые знаки. Для создания диапазона, который будет указывать лишь место расположения в до- кументе и не будет содержать никакого текста, присвойте начальному и конечному значе- ниям, определяющим диапазон, одно и то же число. Для включения в объект Range всего документа достаточно вызвать метод Range этого документа без указания каких-либо аргументов или же воспользоваться свойством Content представляющего его объекта Document. Работа с текстом Объекты Range и Selection являются основой для практически любых операций, которые можно выполнять с текстом с помощью VBA в Microsoft Word. Некоторые из доступных в этом приложении операций можно применять к документам в целом, одна- ко в общем случае, прежде чем вносить в документ какие-либо изменения, необходимо определить диапазон или выделить ту область, к которой они будут применены. 362 Часть 4. Создание приложений в MS Office
Объекты Range и Selection представляют в программе непрерывные последо- вательности символов, над которыми можно выполнять различные операции, поэтому у них много общих свойств и методов. Однако некоторые свойства и методы применимы только к выделенным областям (Selection), а другие — только к диапазонам (Range). Принципиальное отличие в том, что объект Selection соответствует выделению в об- ласти окна: тексту, графическому изображению или любому другому объекту, в то время как объекты Range существуют только в программе, независимо от выделенной области, и всегда содержат только текст. Объект Selection имеет смысл использовать в тех случаях, когда программа зависит от действий пользователя — например, он должен указать текст, над которым следует вы- полнить определенные действия, или, наоборот, когда программа должна показать поль- зователю, какой именно текст будет изменяться. Во всех остальных случаях программной обработки документа удобнее исйользовать объекты Range — они обеспечивают большую скорость выполнения программ и работа с ними незаметна для пользователя. Это очень важный момент, поскольку Word автоматически обновляет содержимое экрана при каж- дом, изменении содержимого выделенной области, а при изменении текста в диапазоне (т.е. в объекте Range) содержимое экрана не обновляется. Более того, изменения диа- пазонов не отражаются и в выделенных областях, созданных пользователем. Дополнительно следует отметить, что объекты Selection и Range можно создавать один из другого. Иногда эта возможность оказывается чрезвычайно полезной, так как некоторые функции редактирования работают только с диапазонами. И наоборот, един- ственный доступный способ отобразить новое содержимое диапазона пользователю — это выделить его. Для выделения диапазона, представленного объектом Range, используется его метод Select. Например, для объекта Диапазон 1 соответствующий оператор имеет вид Диапазон! .Select. Аналогичным образом для создания диапазона, представляюще- го собой текстовое содержимое выделенной в документе области, используется свойство Range объекта Selection. Приложение Microsoft Word предоставляет в распоряжение программиста ряд методов для перемещения и изменения размеров диапазонов или выделенных областей. Напри- мер, метод Expand увеличивает указанный диапазон или выделенную область, добавляя блок текста в их конец. Блок, который может представлять собой символ, слово, абзац, раздел или что-нибудь другое, определяется значением аргумента, указанного при вызове метода. Например, для добавления к выделенной области слова, которое следует непо- средственно за ней, необходимо использовать такой оператор. Selection.Expand(wdWord) При каждом вызове метода Expand к выделению можно добавить только один блок, определяемый указанным аргументом. Добавление подобных блоков в начало диапазо- на или выделенной области не допускается. Word позволяет переопределять начало и конец диапазона или выделенной области. Так, метод Move изменяет расположение диапазона или выделенной области. Работа этого метода начинается с того, что диапазон или выделение сжимаются к точке их начала или конца — в зависимости от значения аргумента. В результате точка начала и конца будет указывать на одну и ту же позицию в документе и обрабатываемая область не будет со- держать никакого текста. Далее метод Move перемещает “сжатый” объект соответственно заданному аргументу (на один символ, одно слово, одно предложение и т.д.) в указанном Глава 14. Программирование на VBA в Word 363
направлении (к началу или концу документа). Метод возвращает числовое значение, ука- зывающее, на сколько единиц перемещение было действительно выполнено. По оконча- нии перемещения можно воспользоваться методами Expand, MoveStart или MoveEnd для наполнения объекта текстом, начиная с новой позиции его начальной точки (которая в этот момент совпадает с его конечной точкой). Методы MoveStart и MoveEnd изменяют, соответственно, положение начальной или конечной точки диапазона или выделенной области. При этом “сжатие” диапазона, как в методе Move, не выполняется, что позволяет использовать эти методы для расширения (или сужения) обрабатываемой области. Приведенная ниже инструкция перемещает начало выделенной области на два слова ближе к концу документа, сокращая тем самым ее размер. Selection.MoveStart Unit := wdWord, Count := 2 Все методы, в имени которых присутствует слово Move, изменяют лишь расположен ние диапазона или выделенной области, но не перемещают текст, который содержится в указанном объекте. Еще одна пара методов, StartOf и EndOf, перемещает начало или конец диапазона либо выделенной области. Метод StartOf перемещает начало обрабатываемой области назад, к началу текущего блока, тип которого определяется заданным параметром, тогда как метод EndOf перемещает конец объекта вперед, к концу текущего блока. Оба метода имеют два аргумента. Первый определяет тип блока, к началу (или концу) которого пере- мещается граница области. Второй аргумент может принимать одно из двух допустимых значений. Первое, именованная константа wdMove, определяет, что указанным образом следует переместить обе границы выделенной области — и верхнюю, и нижнюю (при- нимается по умолчанию). Второе, именованная константа wdExtend, указывает на то, что следует переместить только верхнюю (StartOf) или нижнюю (EndOf) границу вы- деленной области. Selection.StartOf Unit := wdSentence, Extend := wdMove Здесь обе границы выделенной в документе области перемещаются к началу того пред- ложения, в котором они расположены. Если при использовании методов StartOf и EndOf перемещаемая сторона выделен- ной области уже находится в той позиции, к которой предпринимается попытка ее переместить, ничего не происходит. Достаточно часто при обработке документа возникает необходимость сжать диапазон или выделенную область в одну точку, которая не содержит никакого текста. Подобное сжатие необходимо, когда в документ требуется вставить поле, таблицу или какой-либо другой элемент, поместив его до или после выделенной области или диапазона, не изменяя выделенного текста. (При вставке некоторого элемента в “несжатый” диапазон или вы- деленную область он заменит текст, содержавшийся в данной области.) Для сжатия диа- пазона или выделенной области предназначен метод Collapse. Область можно сжать к ее начальной или конечной точке, что определяется необязательным аргументом Direction. Так, оператор Selection. Collapse сжимает выделенную область к ее начальной точке, тогда как оператор, приведенный ниже, сожмет выделенную область к ее конечной точке. Selection.Collapse(Direction:=wdCollapseEnd) 364 Часть 4. Создание приложений в MS Office
Удаление, копирование и вставка текста Для удаления из документа всего текста, содержащегося в диапазоне или выделенной области, можно воспользоваться методом Delete соответствующего объекта. Если же не- обходимо удалить текст и поместить его в буфер обмена, следует использовать метод Cut. Метод Сору просто копирует в буфер обмена текст из диапазона или выделенной области, не оказывая на него никакого влияния. Метод Paste позволяет вставить текст, помещенный в буфер обмена, в любой диапазон или выделенную область. Если указанный объект назначе- ния не был предварительно сжат, вставленный текст заменит исходный текст в объекте. Следует отметить, что использование буфера обмена для вставки или копирования текста нельзя считать эффективным приемом. В VBA-программах удобнее использовать для этой цели свойства Text или FormattedText диапазона или выделенной области. Для копирования достаточно присвоить соответствующему свойству области назначения значение аналогичного свойства копируемой области. Не забывайте, что если вставляе- мый элемент не должен заменить текст, уже существующий в области назначения, то по- следняя должна быть предварительно сжата. Приведенный ниже фрагмент кода передает текст из выделенной области в сжатый диапазон, связанный с закладкой в документе. Поскольку здесь используется свойствр Text, в новое место копируется только сам текст; при этом теряется любое его форматирование, присутствующее в исходной области. Для передачи вместе с текстом и его форматирования вместо свойства Text следует исполь- зовать свойство FormattedText. Dim Вставка As Range ’ Объявление рабочей переменной With ActiveDocument.Bookmarks(”3акладка1”) Set Вставка = ActiveDocument.Range(Start:=.Start, _ End:=.Start) ’Диапазон сжат End With Вставка.Text = Selection.Text 'Копирование текста Свойства объектов диапазона или выделенной области, приведенные в табл. 14.5, определяют внешний вид содержащегося в них текста. Все эти свойства соответствуют аналогичным командам форматирования текста программы Word. Таблица 14.5. Свойства, определяющие форматирование текста в выделенной области Свойство________Описание___________________________________________________ Borders Представляет собой коллекцию объектов Border, описывающих параметры отдельных элементов рамки вокруг текста в выделенной области Font Содержит ссылку на объект, описывающий параметры символьного формати- рования текста в выделенной области. К ним относятся Name, Size и Bold Paragraph Format Содержит ссылку на объект, описывающий параметры форматирования абза- цев текста в выделенной области. К ним относятся Lef tindent, Linespac- ing и др. Style Содержит имя стиля символа или абзаца, примененного к тексту в диапазоне или выделенной области TabStops Тип и расположение точек табуляции. Доступ к этим свойствам можно полу- чить только с помощью объектов Paragraph, а не напрямую через диапазоны или выделенные области Глава 14. Программирование на VBA в Word 365
Поиск и замена информации Как объект Selection, так и объект Range имеют свойство Find, которое содержит ссылку на объект Find, принадлежащий данному диапазону или выделенной области. Для отыскания с помощью объекта Find заданного текста или форматирования опреде- ленного типа необходимо выполнить следующие действия. 1. Получите ссылку на объект Find интересующего диапазона или выделенной об- ласти. Если необходимо просмотреть весь документ, воспользуйтесь свойством Content объекта Document: ActiveDocument. Content. Find. 2. Требуемым свойствам (Text, Style, Font, Format и т.д.) объекта Find присвой- те необходимые значения в соответствии с тем, что именно требуется найти и как следует проводить поиск. 3. Для выполнения поиска вызовите метод Execute объекта Find. Например, чтобы найти в выделенном на экране фрагменте документа слово “поставка”, можно ис- пользовать следующий код. With Selection.Find .ClearFormatting ’Поиск без учета форматирования .Text = "поставка" ’Отыскиваемый текст .Execute ’Выполнение поиска End With В приведенном выше примере используются два метода объекта Find, на которых сле- дует остановиться подробнее. Метод ClearFormatting удаляет из свойств объекта Find сведения об отыскиваемых параметрах форматирования, которые были установлены. В результате следующая операция поиска будет выполнять поиск заданного текста, без анализа особенностей его форматирования. Хорошей практикой можно считать предва- рительный вызов данного метода при каждом использовании объекта Find — это гаран- тирует, что любые условия учета форматирования при поиске из предыдущих операций будут удалены. Метод Execute выполняет поиск очередного вхождения искомого текста или форматирования в указанном диапазоне или выделенной области. После выполнения этого метода сначала следует определить, было ли найдено то, что требовалось. Для по- добной проверки предназначено свойство Found объекта Find, имеющее логический тип данных. Пример использования этого свойства в операторе If...Then показан ниже. If .Found = True Then ’Выполнение требуемых действий с найденным текстом Else ’Отображение сообщения о том, что образец не найден End If Объект Replacement используется, когда выполняется поиск с заменой. Ссылка на этот объект присутствует в одноименном свойстве объекта Find. Свойства объекта Re- placement (Text, Style, Font и пр.) содержат новые значения, на которые заменяются соответствующие характеристики текста, предварительно найденного с помощью метода Execute объекта Find. Следующий фрагмент кода заменяет все экземпляры слова “поставка” словом “отгрузка” в части документа, выделенной на экране на данный момент. 366 Часть 4, Создание приложений в MS Office
With Selection.Find .ClearFormatting ’Очистка форматирования при поиске .Text = "поставка” ’Искомый текст With .Replacement .ClearFormatting ’Очистка форматирования при замене .Text = "отгрузка" ’Текст замены End With ’Выполнение поиска и замены всех вхождений .Execute Replace := wdReplaceAll ’Метод объекта Find End With Обратите внимание на то, что в вызове метода Execute объекта Find может присут- ствовать аргумент Replace, который указывает, следует ли заменить все обнаруженные экземпляры искомого текста или только первый. Для поиска текста с определенным форматированием используются соответствующие свойства объекта Find. При необходимости задать форматирование для замещающего текста можно использовать аналогичные свойства объекта Replacement. Представленный ниже код проводит поиск абзацев, которым в данный момент на- значен стиль Цитата, после чего назначает им стиль Обычный. With Selection.Find .ClearFormatting .Style = "Цитата" .Text = ’”’ With .Replacement .ClearFormatting .Style = "Обычный" . Text = ’’ ’’ End With .Execute Replace := wdReplaceAll .ClearFormatting .Replacement.ClearFormatting End With л“4 Для поиска любого текста с определенным форматированием поместите требуемые V'/ значения в соответствующие свойства объекта Find и присвойте его свойству Text значение, равное пустой строке; т.е. укажите вместо значения только пару кавычек. Чтобы изменить форматирование найденного текста, не изменяя сам текст, поместите пустую строку в качестве значения в свойство Text объекта Replacement. Использование переменных документа В отличие от остальных приложений Microsoft Office, Word позволяет определять в VBA-программах специальные переменные документа, которые сохраняются вместе с до- кументом. Переменные документа — удобное средство сохранения любых используемых VBA-программой значений данных между сеансами редактирования. Переменные документа^создаются и используются как члены коллекции Variables в данном документе. Как и обычные документы, переменные документа характеризуются собственными именами, но могут хранить в себе только строковые значения. Приведенный Глава 14. Программирование на VBA в Word 367
ниже оператор присваивает значение переменной документа Срок_реализации обычной переменной Установленный_срок. Dim Установленный_срок As String . Установленный_срок = _ ActiveDocument.Variable("Срок_реализации").Value Для создания новой переменной используется метод Add коллекции Variables, как показано ниже. Documents("Отчет за ноябрь").Variables.Add _ Name := "Дата_обработки", Value := "25.05.2010" При попытке создать уже существующую переменную документа будет выдано со- общение об ошибке, поэтому рекомендуется предварительно проверить существование соответствующего имени и лишь затем создавать новую переменную. Если необходимая переменная уже существует, достаточно будет считать ее текущее значение; если нет — можно создать эту переменную и присвоить ей исходное значение. Данный прием иллю- стрируется следующим примером. ’Поиск переменной в коллекции по ее имени Dim DocVar As Variable Dim Текущее_число_ознакомившихся As String For Each DocVar In ActiveDocument.Variables If DocVar.Name = "Число_ознакомившихся" _ Then Docindex = DocVar.Index Next DocVar If Docindex = 0 Then ’Переменная не существует ActiveDocument.Variables.Add _ Name := "Число_ознакомившихся", Value := "1" Текущее_число_ознакомившихся = "1" Else ’Переменная уже существует Текущее_число_ознакомившихся = _ ActiveDocument.Variables(Docindex).Value End If Резюме В этой главе обсуждались способы использования в VBA-программах функциональ- ных возможностей приложения Microsoft Word. Спектр этих возможностей весьма широк, поэтому мы начали с рассмотрения особенностей объектной модели этого приложения. Далее обсуждались средства доступа из программ к документам Word, а также особенно- сти управления параметрами и окнами приложения. Затем были рассмотрены важнейшие функции и способы их использования для основных объектов Word — View, Selection, Range, Find и Replace. Подробно обсуждались такие важные вопросы, как работа с текстом документа, осуществляемая в VBА-приложениях с помощью свойств и методов объектов Range и Selection. В завершение кратко рассматривался такой важный во- прос, как сохранение данных VBA-программ в переменных документа, работа с которыми поддерживается в Word. 368 Часть 4. Создание приложений в MS Office
Тестовые задания Ниже приведено несколько тестовых заданий, предназначенных для закрепления из- ложенного в этой главе материала. В каждом задании вам предлагается вопрос и несколь- ко вариантов ответа на него, один (или несколько) из которых является правильным, а остальные — нет. Укажите правильный ответ. 1. Многие объекты (Selection, Range, View, Variables и др.), с которыми обычно ведется работа в VBA-программах в Word, подчинены непосредственно объекту: a) Application; б) Document; в) Dialog; г) System; д) Window. 2. Для указания активного документа удобнее всего использовать объект: a) ActiveDocument; б) Application; в) Documents; г) View. 3. Для открытия из VBA-программы некоторого диалогового окна следует использо- вать метод: a) Open; б) Create; в) Show; г) Display; д) Add. 4. Объект View позволяет управлять: а) видимой на экране частью документа; б) количеством открытых в приложении окон документов; в) наличием требуемых панелей инструментов в окне; г) различными аспектами отображения окна или его части; д) параметрами поиска и замены текста. 5. Различия между объектами Selection и Range состоят в следующем: а) объект Range является свойством объекта Selection; б) объект Selection может быть только один, а объектов Range — несколько; в) объектов Selection может быть несколько, а объект Range — только один; г) объект Selection отображается на экране, а объект Range — нет; д) объекты Range и Selection зависят от выделенной на экране части документа. Глава 14. Программирование на VBA в Word 369
Глава 15 Программирование на VBA в Outlook В этой главе... ♦ Объектная структура Outlook ♦ Манипулирование папками и их содержимым ♦ Обработка почтовых сообщений ♦ Управление событиями Outlook ♦ Календарь ♦ Резюме Microsoft Outlook 2010 — очень многофункциональная программа, основное назначе- ние которой — получение и отправка сообщений электронной почты и участие в группах новостей Интернета. Если вы работаете в компании или рабочей группе, то можете ис- пользовать Outlook в качестве клиента Exchange Server — программной системы компании Microsoft, предназначенной для обмена сообщениями и совместной работы, отправки и получения электронной почты, а также совместного использования данных различных типов. Однако наряду с этим в Outlook реализована поддержка календаря, списка заданий, адресной и записной книжек. У этого приложения программисты чаще всего используют средства работы с электронной почтой, тем не менее и другие функциональные возмож- ности Outlook также доступны из VBA-программ. В этой главе будут рассмотрены вопросы использования функций приложения Outlook, касающихся работы только с электронной почтой и календарем. Объектная структура Outlook Основными объектами приложения Outlook являются папки (folders) и элементы (items). Элементы — это объекты, хранящие информацию. Примерами такой информа- ции являются почтовые сообщения, назначения задач и заметки. Папки — это место для хранения элементов, а также других папок. Папки приложения Outlook организованы в иерархическую структуру, напоминающую файловую структуру диска, однако папки Outlook — не то же самое, что обычные дисковые папки. Как и во всех приложениях пакета Office, на вершине иерархии объектной модели Outlook находится объект Application (рис. 15.1). Уровнем ниже располагается коллек- ция Session, объединяющая объекты Namespace, служащие для доступа к элементам и папкам приложения.
| Application object -[Assistance object -jCOMAddlns collection LfCQMAddln object -[Explorers collection Ц Explorer object ~ -j CommandBars collection IjCommandBar object -[CurrentFolder object -[CurrentView object ~| Panes collection ^-jPane object -[Selection object -[inspectors collection ^-[inspector object ~| CommandBars collection 1-jCommandBar object ~| Currentitem object -j Languagesettings object -[Reminders collection | ^Reminder object | ~| Session collection | ' ^NameSpace object | ~~|AddressLists collection | I-[AddressList object | I—| AddressEntries collection | ^AddressEntry object -[Folders collection | ' Ц Folder object | Puc. 15.1. Фрагмент объектной модели приложения Microsoft Outlook 2010 При работе в среде приложения Outlook объект Application будет доступен для VBA-программы в любое время в качестве неявной ссылки, но если доступ к функциям Outlook осуществляется из среды другого приложения Office 2010, то предварительно на него нужно получить ссылку. Если в списке ссылок выбрана библиотека объектов Outlook, для создания этой ссылки можно использовать ключевое слово New. Dim OutlookApp As Outlook.Application Set OutlookApp = New Outlook.Application Кроме того, для получения ссылки на объект Application приложения Outlook можно также использовать функцию GetObj ect, которая не требует наличия в проекте ссылки на библиотеку объектов Outlook. Dim OutlookApp As Object Set OutlookApp = GetObject(Outlook.Application) Outlook — это одно из двух однопользовательских (single-use) приложений пакета Microsoft Office 2010, поэтому в каждый момент времени на компьютере может существо- вать только один экземпляр этого приложения. (Вторым однопользовательским приложе- нием Office является PowerPoint.) Таким образом, независимо от того, какой из методов используется, New или GetOb j ect, результат будет одинаковым: если Outlook не запущен, будет создан новый скрытый экземпляр этого приложения; а если запущен — будет воз- вращена ссылка на уже существующий экземпляр объекта Application. Глава 15. Программирование на VBA в Outlook 371
Все существующие в Outlook данные доступны через объект Name Space (Простран- ство имен). Исходно приложение Outlook было спроектировано для работы с различными источниками данных, и каждый источник был связан с отдельным пространством имен. Однако в настоящее время Outlook поддерживает только один источник данных — MAPI. Для получения ссылки на объект NameSpace используется метод GetNameSpace объекта Application. Dim OutlookNamSp As Outlook.NameSpace Set OutlookNamSp = Application.GetNameSpace("MAPI") Поскольку Outlook является однопользовательским приложением, иногда полезно для хранения ссылки на его объекты приложения и на пространства имен использовать гло- бальные переменные. После помещения в них ссылок эти переменные можно будет ис- пользовать в различных VBA-процедурах, везде, где требуется доступ к функциональным возможностям Outlook. В листинге 15.1 представлена функция Startout look, которая инициализирует глобальные переменные для объектов Application и NameSpace при- ложения Outlook и возвращает значение True при успешном завершении инициализации или же False — в противном случае. Листинг 15.1. Функция StartOutlook Public Function StartOutlook() As Boolean On Error GoTo Cannotlnitialize StartOutlook = True 'Подготовка результата Set OutlookApp = New Outlook.Application Set OutlookNamSp = OutlookApp.GetNamespace("MAPI") Done: Exit Function Cannotlnitialize: StartOutlook = False 'Запуск Outlook невозможен Resume Done End Function Однако, для того чтобы использовать эту функцию, программа вначале должна про- верить, не инициализирован ли уже Outlook, и, только если это приложение еще не за- пущено, вызвать функцию StartOutlook, например, так. Public Sub CheckAppO Dim OutlookApp As Object If OutlookApp Is Nothing Then If StartOutlook = False Then MsgBox "He удается запустить приложение Outlook" End If End If End Sub Манипулирование папками и их содержимым Папки в Outlook представлены объектами Folder. Используя метод Ge t De fault - Folder объекта NameSpace, можно получить ссылку на указанную стандартную папку Outlook. Синтаксис его следующий. 372 Часть 4. Создание приложений в MS Office
Obj.GetDefaultFolder(itemtype) Здесь аргумент Obj — это ссылка на объект Namespace, а аргумент i temtype — кон- станта, определяющая тип папки, ссылку на которую требуется получить. Возможные значения этого аргумента перечислены в табл. 15.1. Таблица 15.1. Некоторые допустимые значения аргумента itemtype метода GetDefaultFolder Константа Элемент olFolderCalendar olFolderContacts olFolderDeletedlterns olFolderDrafts olFolderlnbox olFolderJournal olFolderNotes olFolderOutbox olFolderSentMail olFolderTasks Календарь Адресная книга Папка Удаленные Папка Черновики Папка Входящие для сообщений электронной почты Элементы журнала Заметки Папка Исходящие для сообщений электронной почты Папка Отправленные для сообщений электронной почты Назначенные задачи Например, для того чтобы вычислить ссылку на папку Inbox (Входящие), необходимо выполнить следующие операторы. Dim ПапкаТпЬох As Folder Dim ns As NameSpace Set ns = GetNameSpace("MAPI") Set Папка1пЬох = ns.GetDefaultFolder(olFolderlnbox) Папки, не являющиеся стандартными в Outlook (т.е. созданные пользователем), содер- жатся в коллекции Folders. Каждая папка верхнего уровня является членом коллекции Folders объекта NameSpace. В свою очередь, каждая из этих папок верхнего уровня со- держит собственную коллекцию Folders и так далее, пока не будет достигнута папка, которая не содержит подпапок. Для получения доступа к некоторому уже существующему элементу Outlook исполь- зуется коллекция Items объекта Folder. Коллекция Items содержит одну запись для каждого элемента в данной папке. Требуемый элемент может быть задан своим индекс- ным номером или значением свойства, определяемого для данного типа элементов по умолчанию. Для сообщений электронной почты таким свойством является их тема. В сле- дующем примере показано, как получить ссылку на первое сообщение в папке Входящие с темой Отчет по продажам. Dim Отчет As Outlook.Mailltem Dim ns As NameSpace Set ns = GetNameSpace("MAPI") Set Отчет = ns.GetDefaultFolder _ (olFolderlnbox).Items("Отчет по продажам") При просмотре элементов в папке Inbox нужно принять во внимание то, что эта папка может содержать элементы, не являющиеся сообщениями электронной почты. Глава 15. Программирование на VBA в Outlook 373
Обработка почтовых сообщений Сообщения электронной почты в приложении Outlook представлены объектом Mail- Item. При создании прикладных VBA-приложений в среде Microsoft Office работа с по- чтовыми сообщениями чаще всего осуществляется в двух направлениях — выборка ин- формации из поступающих сообщений или создание и отправка новых сообщений. По умолчанию приложение Outlook помещает все входящие почтовые сообщения в папку Inbox (Входящие). Если требуется немедленно получать оповещение о пришед- шем новом сообщении, то для этой цели можно использовать событие NewMail — под- робнее о нем будет сказано чуть ниже. Чтобы получить доступ к поступившему сообще- нию, сначала нужно вызвать метод GetDefaultFolder объекта NameSpace, который возвращает ссылку на папку Inbox, после чего через коллекцию Items этой папки можно будет обратиться к любым сообщениям в ней. Объект Mail Item имеет множество свойств. Те свойства, которые представляют определенный интерес при работе с входящими сообщениями, описаны в табл. 15.2. Об- ращаясь к этим свойствам, можно для каждого сообщения получить информацию о том, кто и когда его отправил, какова его тема, каково его содержание и т.д. Таблица 15.2. Некоторые свойства объекта Mailltem, используемые при обработке входящих сообщений Свойство Описание Attachments Коллекция объектов Attachment, представляющих документы или ссылки, вложенные в сообщение Body CreationTime HTMLBody Importance Текст сообщения (если оно создано в виде обычного текста) Дата и время создания сообщения (в формате Date) Текст сообщения (если он создан в формате HTML) Уровень важности сообщения. Возможные значения: olImportanceHigh (высокий), olImportanceLow (низкий) и olImportanceNormal (обычный) Received!ime Recipients Saved Дата и время получения сообщения (в формате Date) Коллекция объектов Recipient, содержащих адреса получателей сообщения Булево значение, указывающее, сохранялось ли сообщение после его последней модификации SenderName SentOn Subject To UnRead Имя отправителя сообщения (псевдоним, присвоенный его адресу) Время отправки сообщения (в формате Date) Тема сообщения Список получателей сообщения, элементы которого отделяются точкой с запятой Булево значение, указывающее, что сообщение не открывалось Объект Mai 11 tern имеет множество методов, позволяющих выполнять такие действия, как удаление, копирование и перемещение сообщений, создание ответов и пересылка пришедших сообщений другим адресатам. Эти методы кратко описаны в табл. 15.3. Для пересылки сообщения необходимо выполнить метод Forward представляющего его объекта, в результате чего будет создана копия сообщения, затем заполнить свойство Recipient (а при необходимости и другие его свойства), после чего выполнить метод Send. В следующем примере первое сообщение в папке Входящие пересылается получа- телю Вс. Иванов. 374 Часть 4. Создание приложений в MS Office
Dim NS As Outlook.NameSpace Dim Входящие As Outlook.Folder Dim Пересылка As Outlook.Mailltem Set NS = Application.GetNamespace("MAPI") Set Входящие = NS.GetDefaultFolder(olFolderlnbox) Set Пересылка = Входящие.Items(1).Forward Пересылка.Recipients.Add "Вс. Иванов" Пересылка.Send Таблица 15.3. Методы объекта Mailltem Метод Описание Copy Создает копию сообщения и возвращает ссылку на соответствующий объект Delete Удаляет сообщение Display Создает новый объект Inspector и отображает в нем сообщение Forward Создает копию сообщения для пересылки по другому адресу Move (Destination) Перемещает сообщение в заданную папку. Аргумент Destination является ссылкой на объект класса Folder, представляющий папку на- значения Printout Выводит сообщение на печать Reply Создает копию сообщения, переадресованную его отправителю ReplyAll Создает копию сообщения, переадресованную как отправителю, так и всем остальным получателям исходного сообщения SaveAs (Path, Type) Сохраняет сообщение в файле, заданном аргументом Ра th. Необязатель- ный аргумент Туре задает формат сохраняемого файла. Чаще всего ис- пользуются такие значения этого аргумента, как olDoc (документ Word), olHTML (формат HTML), olMSG (формат сообщения — принимается по умолчанию), olRTF (формат RTF) и olTXT (текстовый формат) Для того чтобы ответить на сообщение, сначала следует выполнить метод Reply его объекта — создается копия сообщения, причем в коллекции Recipients этой копии уже будут содержаться объекты, представляющие отправителей исходного письма. В теле копии сообщения будет содержаться текст исходного сообщения, отформатированный согласно текущим установкам приложения Outlook (например, в начало каждой строки может быть помещен символ Далее при необходимости можно добавить в тело ко- пии сообщения некоторый дополнительный текст и отослать эту копию. В следующем примере программа создает и отсылает ответ на первое сообщение в папке Inbox. Dim NS As Outlook.NameSpace Dim Входящие As Outlook.Folder Dim Ответ As Outlook.Mailltem Dim temp As String Set NS = Application.GetNamespace("MAPI") Set Входящие = NS.GetDefaultFolder(olFolderlnbox) Set Ответ = Входящие.Items(1).Reply temp = Ответ.Body temp = "Спасибо за приглашение!" & vbCRLF & temp Ответ.Body=temp Ответ.Send Глава 15. Программирование на VBA в Outlook 375
Создание и отправка сообщений Приложение Outlook делает процесс создания и отправки сообщения электронной по- чты предельно простым. Основными действиями в этом случае являются следующие. 1. Создание нового объекта Mail Item. 2. Добавление одного или нескольких получателей в его коллекцию Recipients. 3. Помещение темы сообщения в свойство Sub j ect объекта Mail Item. 4. Помещение текста сообщения в свойство Body. 5. Выполнение метода Send объекта Mail Item. В табл. 15.4 перечислены и кратко описаны те свойства объекта MaiII tern, которые имеют отношение к созданию и отправке сообщений электронной почты. Таблица 15.4. Свойства объекта Mailltem, используемые при создании и отправке почтовых сообщений Свойство Описание Attachments Коллекция объектов Attachment, представляющих вложенные в со- общение файлы вес Имена получателей скрытой копии сообщения, отделяемые точкой с запятой Body Текст сообщения (если оно в текстовом формате) СС Имена получателей копии сообщения, отделяемые точкой с запятой HTMLBody Текст сообщения (если оно в формате HTML) ReadReceiptRequested Принимает значение True при запросе на подтверждение получения Recipients Коллекция объектов Recipient, представляющих получателей со- общения SaveSentMessageFolder Определяет папку приложения Outlook, куда помещаются копии от- правленных сообщений. По умолчанию это папка Отправленные Sent Принимает значение True для уже отправленных сообщений. В про- тивном случае — False To Список псевдонимов получателей, отделяемых точкой с запятой Работа с получателями сообщений Каждый получатель сообщения представлен объектом Recipient в коллекции Re- cipients. Это справедливо как для получателей, адреса которых помещены в графу То (Кому), так и для тех, чьи адреса помещены в графы получателей скрытой и простой копий (ВСС и СС). С точки зрения программы эти типы получателей отличаются только значением свойства Туре соответствующего объекта Recipient. Для добавления полу- чателя в коллекцию используется метод Add. Синтаксис его следующий. Obj.Recipients.Add(Name) Здесь аргумент Obj представляет объект класса Mailltem, а аргумент Name — псевдо- ним получателя. Следует отметить, что псевдоним получателя — это не то же самое, что адрес получателя электронной почты, который содержится в свойстве Address объекта Recipient. В приведенном ниже примере показано, как добавить нового получателя со- общения, указав сначала его псевдоним, а затем и собственно адрес электронной почты. 376 Часть 4. Создание приложений в MS Office
Письмо.Recipients.Add(”Bc. Иванов”) Письмо.Recipients("Вс. Иванов").Address= _ vsivanoff@mail.ru Можно задать получателя только его свойством Name и уже впоследствии найти его электронный адрес, обратившись к адресной книге. Основные свойства объекта Recipient описаны в табл. 15.5. Таблица 15.5. Свойства объекта Recipient Свойство Описание Address Электронный адрес получателя Name Псевдоним (экранное имя) получателя Resolved Если адрес определен (т.е. найден в адресной книге), это свойство при- нимает значение True Type Определяет тип получателя. Возможные значения: olBCC, о ICC, olTo и olOriginator Для удаления получателя используется метод Delete. В следующем фрагменте из кол- лекции Recipients удаляется получатель Вс. Иванов. Сообщение.Recipients("Вс. Иванов").Delete Для определения адреса получателя по его имени используется метод Resolve. Этот метод выполняет поиск в адресной книге записи с заданным псевдонимом получателя и, найдя такую запись, помещает электронный адрес получателя в свойство Address, одновременно помещая в свойство Resolved значение True. Метод Resolve возвра- щает True в случае успеха и False в случае неудачи поиска. В следующем примере в сообщение добавляется получатель, проводится попытка автоматически определить его адрес и, если она заканчивается неудачей, на экран выводится сообщение, предлагающее заполнить поле адреса вручную. Dim Сообщение As Mailltem Dim Получатель As Recipient Set Сообщение = OutlookApp.Createltem(olMailltem) Set Получатель = Сообщение.Add("Вс. Иванов") If NOT Получатель.Resolve Then Сообщение.Display Если свойство Address устанавливается явным образом, необходимость в его разре- шении отпадает. Работа с адресной книгой Приложение Outlook может иметь несколько адресных книг. Доступ к ним осуществля- ется с помощью коллекции AddressLists объекта NameSpace (см. рис. 15.1), который содержит по одному объекту Addres sLi s t для каждой доступной адресной книги. Ниже приведен пример получения списка доступных адресных книг. Dim АК As Outlook.AddressList For Each AK In NS.AddressLists Debug.Print AK.Name Next Глава 15. Программирование на VBA в Outlook 377
Каждый объект AddressList имеет коллекцию AddressEntries, элементами которой являются объекты AddressEntry, создаваемые для каждой записи в адресной книге. Каждый объект AddressEntry имеет коллекцию свойств, самыми важными из которых являются Name и Address, содержащие псевдоним и электронный адрес записи. Существует также свойство Di splay Туре, определяющее тип записи. Самыми важными являются два его возможных значения — olUser, указывающее, что запись создана для отдельного адресата, и olDistList, указывающее, что запись будет списком рассылки и имеет собственную коллекцию AddressEntries. Список рассылки позволяет хранить вместе связанные записи адресной книги и быстро отправлять сообщения всем членам этой группы. В процедуре (листинг 15.2) одно и то же сообщение отправляется всем получателям, адреса которых присутствуют в указанной адресной книге. Листинг 15.2. Отправка сообщения по всем адресам в адресной книге Public Sub SendToAll(Текст As String, _ Тема As String, АдКнига As String) Dim OutlookNamSp As Outlook.NameSpace Dim Книга As Outlook.AddressList Dim Адресат As Outlook.AddressEntry Dim Сообщение As Outlook.MailItem Dim Получатель As Outlook.Recipient 'Получение ссылки на адресное пространство Outlook Set OutlookNamSp = Application.GetNamespace("MAPI") 'Создание нового сообщения Set Книга = NS.AddressList(АдКнига) Set Сообщение = OutlookApp.Createltem(olMailltem) Сообщение.Subject = Тема Сообщение.Body = Текст 'Формирование списка получателей For Each Адресат In Книга.AddressEntries Set Получатель = Сообщение.Recipients.Add(Адресат.Name) Получатель.Resolve Next 'Отправка созданного сообщения Сообщение.Send End Sub Работа с вложенными файлами Сообщения электронной почты могут иметь одно или несколько вложений — файлов или ссылок на файлы, которые являются частью сообщения. Объект Mailltem имеет коллекцию Attachments, состоящую из объектов Attachment для каждого вложения в данное сообщение. В свойстве Count этой коллекции содержится количество вложенных в сообщение объектов. Для проверки наличия в сообщении вложений можно использо- вать следующий оператор. If myMailltem.Attachments.Count > 1 Then (Обработка вложенных файлов) End If 378 Часть 4. Создание приложений в MS Office
Каждый объект Attachment имеет коллекцию свойств, которые кратко описаны в табл. 15.6. Таблица 15.6. Свойства объекта Attachment Свойство Описание DisplayName Название, отображаемое в окне Outlook под значком вложения, когда сообщение выводится на дисплей. Может отличаться от имени вложенного файла FileName Имя вложенного файла PathName Полный путь к файлу, определяемому вложенной ссылкой. Это свойство имеет смысл только для вложенных ссылок Type Тип вложения. Допустимые значения: olByValue (вложенный файл) и olByRef- erence (вложена ссылка на файл) Для извлечения вложения из полученного сообщения и сохранения его в виде файла используется метод SaveAsFile. Синтаксис его следующий. Obj.SaveAsFile(Path) Здесь аргумент obj — это ссылка на объект Attachment, а аргумент Path определяет путь, согласно которому сохраняется файл с вложением. В следующем примере вложение заданного сообщения сохраняется с использованием имени файла вложения и значения константы SAVEPATH в качестве пути сохранения. Dim Сообщение As Outlook.Mailltem Dim Вложение As Outlook.Attachment ... (Получение ссылки на объект Сообщение) For Each Вложение in Сообщение.Attachments If Вложение.Type = olByValue Then Вложение.SaveAsFile(SAVEPATH & ate.FileName) End If Next Для добавления вложения к почтовому сообщению используется метод Add коллекции Attachments. Синтаксис его следующий. Obj.Attachments.Add(Source, Type, Position, DisplayName) Здесь аргумент obj является ссылкой на объект Maili tern, a Source — обязательный ар- гумент, задающий путь к файлу, помещаемому в сообщение в качестве вложения. Туре — необязательный аргумент, определяющий тип вложения, который может иметь одно из двух допустимых значений: olByValue (прикрепляется сам файл) или olByReference (прикрепляется ссылка). Posi tion — необязательный аргумент, определяющий позицию вложения в сообщении (по умолчанию вложение помещается в конец сообщения). Нако- нец, DisplayName — необязательный аргумент, присваивающий вложению псевдоним, отображаемый на экране вместо имени файла вложения. Если этот аргумент опущен, на экране отображается имя самого файла. В следующем фрагменте к заданному сообщению добавляются два вложения — рабо- чая книга Excel и документ Word. Dim Сообщение As Outlook.Mailltem ... (Получение ссылки на объект Сообщение) Глава 15. Программирование на VBA в Outlook 379
Сообщение.Save ’Предварительное сохранение сообщения With Сообщение.Attachments .Add "с:\Сбыт\Продажи.xls", olByValue, , "Текущие продажи" Add "c:\C6biT\0T4eT.doc", olByValue, , "Отчет за неделю" End With Компания Microsoft рекомендует сохранять сообщение перед каждым добавлением или удалением вложений. Управление событиями Outlook Один VBA-проект в Outlook может состоять из нескольких модулей, в том числе моду- лей классов и форм пользователя. Каждый проект всегда содержит модуль класса с именем ThisOutlookSession, который связан с объектом Application приложения Outlook. События Outlook уровня приложения автоматически доступны в этом модуле класса. По своему назначению модуль ThisOutlookSession аналогичен объектам ThisDocument и ThisWorkbook в приложениях Word или Excel. Некоторые события в Outlook представлены на уровне приложения, поэтому они будут автоматически доступны в модуле ThisOutlookSession. Эти события ассоциированы с приложением Outlook в целом или с объектами верхнего уровня этого приложения. При необходимости обработки этих событий следует создать соответствующие процедуры. Описание некоторых из этих событий приведено ниже. Событие ItemSend возникает при отправке сообщения пользователем или автомати- чески, методом Send. Синтаксис подпрограммы его обработки следующий. Sub Application_ItemSend(Item As Object, Cancel As Boolean) Здесь аргумент Item является ссылкой на отправляемый объект. Аргумент Cancel из- начально имеет значение False. Если в процедуре обработки он устанавливается в True, операция отправки отменяется. Событие NewMail возникает при получении сообщения электронной почты. Его син- таксис следующий. Sub Application_NewMail() Событие Quit возникает при закрытии, а событие Startup — при запуске приложе- ния Outlook, причем после того, как загружены все программы-надстройки. Синтаксис процедур обработки этих событий следующий. Sub Application_Quit() Sub Application_Startup() Программы в VBA-проекте могут использовать эти события для выполнения необ- ходимой инициализации при запуске приложения или выполнения всех обязательных операций выгрузки и сохранения данных при его закрытии. zgL Подобно другим приложениям пакета Microsoft Office, для того чтобы в проек- те можно было выполнять обработку событий в среде Outlook, в модуле класса ThisOutlookSession нужно объявить экземпляр прилржения Outlook с ключевым словом WithEvents. 380 Часть 4. Создание приложений в MS Office
Календарь Календарь в приложении Outlook может использоваться для составления расписания одноразовых и повторяющихся событий. При этом можно также отослать сообщение одному или нескольким получателям по электронной почте. При поступлении такого приглашения встреча автоматически добавляется в календарь получателя, а сообщение о получении автоматически возвращается исходному отправителю. Для работы с календа- рем следует получить ссылку на папку Calendar приложения Outlook и при этом передать в качестве аргумента константу olFolderCalendar методу GetDefaultFolder. Dim olApp As Outlook.Application Dim MAPINameSpace As Outlook.NameSpace Dim Календарь As Outlook.Folder Set MAPINameSpace= olApp.GetNameSpace("MAPI”) Set Календарь= MAPINameSpace.GetDefaultFolder(olFolderCalendar) Все элементы в папке Calendar являются объектами Appointment I tern. Эти объек- ты могут представлять одноразовое напоминание, встречу, какое-либо регулярное событие и т.д. Приглашение на встречу представлено объектом Meetingitem. Когда пользователь приложения Outlook приглашает на некоторое событие, каждому из приглашенных по- сылается объект Мее ting Item, содержащий такие детали встречи, как место и время. Если получатель принимает приглашение, для этого события у него создается объект Meetingitem и добавляется в папку Calendar. Таким образом все назначения и встречи представлены объектами Meetingitem, объект Meetingitem используется только для приглашений на встречу и ответов на такие приглашения. Информация о повторяющихся событиях, например еженедельных планерках по по- недельникам в 9:00, содержится в объектах Recurrencepattern. А отклонения от регу- лярных событий (например, перенос следующей планерки на среду в 10:00) заносятся в объект Exception. Свойства объекта Appointment Item содержат информацию о назначении. Чаще все- го используемые свойства этого объекта описаны в табл. 15.7. Таблица 15.7. Свойства объекта Appointmentitem Свойство Описание AllDayEvent Принимает значение True для значений, занимающих весь день. Время начала и конца игнорируется Body Основное тело назначения Categories Содержит информацию о категории назначения. При наличии не- скольких категорий они разделяются запятыми CreationTime Содержит дату и время создания назначения (тип — Date) Duration Продолжительность события (в минутах) End Содержит дату и время окончания события (тип — Date) Importance Определяет важность назначения. Возможные значения определяются константами — olImportanceLow (небольшая важность), ollmpor- tanceNormal (обычная важность), olImportanceHigh (высокая важность) IsRecurring В случае повторяющегося назначения принимает значение True Location Место проведения Глава 15, Программирование на VBA в Outlook 381
Окончание табл. 15.7 Свойство Описание Meetingstatus Содержит состояние назначения. Возможные значения — olNon- eMeeting (назначение без приглашения других людей), olMeeting (назначение с участием других людей), olMeetingReceived (при- глашение на встречу получено, но еще не принято) и olMeetingCan- celled (событие было отмечено) Recurrencestate Определяет регулярность события — olApptNotRecurring (одно- разовое событие), olApptMaster (основа повторяющегося события), olApptOccurence (повторение регулярного события), olApptEx- ception (одноразовое отклонение от повторяющегося события) RemihderMinutes- BeforeStart Remi hde rOve r r i de- Default Время (в минутах), отведенное для напоминания пользователю перед началом события Булево значение, определяющее, будет ли установка свойств Remih- der PlaySound и RemihderSoundFile заменять исходные установки напоминаний приложения Outlook RemihderPlaySound Булево значение, определяющее, должен ли проигрываться звуковой файл, заданный в свойстве RemihderSet Булево значение, определяющее, будет ли отображаться напоминание перед наступлением события RemihderSoundFile Имя и путь звукового файла, который должен проигрываться при напо- минании (если RemihderPlaySound=True) Start Subject Дата/время начала назначения (формат — Date) Тема назначения Объект Appointment Item содержит методы, осуществляющие различные действия над назначениями (табл. 15.8). Таблица 15.8. Методы объекта Appointmentitem Метод Описание ClearRecurrencePattern Close Copy Delete Display GetRecurrencePattern PrintQut Save SaveAs (filename, type) Изменяет характер события (регулярно заменяется одноразовым) Закрывает окно назначения, если оно отображается на экране Создает дубли назначения Удаляет назначение Отображает назначение на экране Возвращает объект RecurrencePatternObj ect для назначения Выводит назначение на заданный принтер Сохраняет новое или измененное назначение в папке Calendar Сохраняет назначение в файле заданного типа на диске. Возможны- ми значениями аргумента type являются: olTXT (текстовый файл); olRTF (формат RTF); olTemplate (шаблон outlook); olMSG (со- общение Outlook); olVCal (формат виртуального календаря). Если аргумент опущен, используется формат сообщения Outlook Новое назначение создается с помощью метода Create Item объекта Application. Dim NewAppt As Outlook.AppointmentItern Set NewAppt=olApp.Createltem(olAppointmentltem) 382 Часть 4. Создание приложений в MS Office
Для получения доступа к существующему назначению используется коллекция Items папки Calendar. Назначение можно найти, используя его индекс (позицию в папке) или тему. Однако поиск назначения по индексу вряд ли полезен, так как место назначения редко запоминается пользователем. Поэтому чаще всего выполнять поиск назначения приходится по теме. Ниже приведен пример поиска назначения по теме Подведение итогов года. Dim NewAppt As Outlook.Appointmentitem Set NewAppt=CalendarFolder.Items ("Подведение итогов года ") Следует отметить, что такой подход имеет два недостатка. Первый проявляется в тех случаях, когда существует несколько назначений с одинаковой темой; в подобной ситуа- ции возвращается только первое из них. Вторым недостатком является возникновение ошибки в случае, когда назначение с заданной темой не найдено. Данные ошибки можно перехватить и обработать, но лучше избегать получения отдельных назначений приведен- ным выше способом. Вместо этого следует создать цикл, проходящий по всем назначени- ям в папке для нахождения того назначения, которое нас интересует. Это легко сделать с помощью конструкции For Each...Next. Рассмотрим пример, в котором переменная Назначение была объявлена с типом Appointment Item, а переменная Календарь со- держит ссылку на папку Calendar приложения Outlook. Dim Назначение As Appointmentitem For Each Назначение In Календарь.Item ... (отбор требуемых назначений) Next Этот цикл повторяется в пределах всех назначений, имеющихся в папке Calendar. При каждом проходе цикла переменная Назначение ссылается на очередное назначе- ние. В листинге 15.3 в дополнительную переменную Отчет помещается ссылка на первое обнаруженное назначение с темой Персональный отчет. Если такой темы не обнаружи- вается, пользователю на экран выдается соответствующее сообщение. Листинг 15.3. Поиск требуемого назначения в папке Calendar Dim Отчет As Outlook.AppointmentItern Dim Назначение As Outlook.AppointmentItem Dim Found Boolean Found=False For Each Назначение In CalendarFolder.Item If Назначение.Subject = "Персональный отчет" Then Found=True Set Отчет = Appt End If Next If Found Then ' Обработка назначения Else MsgBox "Назначение не найдено!" End If Глава 15. Программирование на VBA в Outlook 383
Новое назначение, создаваемое в программе, будет изначально пустым — его нуж- но заполнить такими деталями, как тема и время начала и конца. (На экране не видно создаваемого в программе назначения, что и необходимо в большинстве случаев.) При необходимости назначение можно вывести на экран пользователю, вызвав метод Dis- play, — это позволит ему просмотреть и заполнить информацию поданному назначению. После этого необходимо щелкнуть на кнопке сохранения или закрытия. Если назначение не выводится на экран пользователю, то для его сохранения нужно вызвать метод Save. В листинге 15.4 показано, как создать новое назначение, заполнить его обязательной ин- формацией, а затем сохранить. Листинг 15.4. Создание и сохранение нового назначения Dim olApp As Outlook.Application Dim Назначение As Outlook.Appointmentitem Set olApp = New Outlook.Application Set Назначение = olApp.Createltem(olAppointmentltem) Назначение . Subj ес^="Обсуждение плана маркетинговых мероприятий" Назначение.Location="KoMHaTa совещаний" Назначение.Start=#16.05.2010 10:00:00# Назначение.End=#16.05.2010 14:00 : 00# Назначение.Вос1у="Вероятно, это совещание затянется" Назначение.Save Резюме В этой главе обсуждались способы использования в VBA-программах функциональ- ных возможностей приложения Microsoft Outlook. Сначала были рассмотрены особен- ности объектной модели этого приложения, которое, в отличие от большинства других приложений Microsoft Office, является однопользовательским, что необходимо учитывать при написании VBA-программ. Далее обсуждались методы манипулирования почтовыми папками и их содержимым — в частности, работа с объектами в коллекциях Folders и Items. Затем рассматривались такие важные вопросы, как обработка отдельных почтовых сообщений, включая их создание и отправку, копирование и перемещение между папками, обработку вложений. Подробно освещались методы указания в сообщении получателей различных категорий, в том числе с использованием адресных книг. Необходимое вни- мание было уделено созданию подпрограмм обработки событий Outlook, использование которых позволяет разрабатывать VBA-приложения, автоматически реагирующие, напри- мер, на факты поступления и отправки сообщений. В завершение кратко рассматривались вопросы работы с папкой Календарь, включая создание назначений и управление ими. Тестовые задания Ниже приведено несколько тестовых заданий, предназначенных для закрепления из- ложенного в этой главе материала. В каждом задании вам предлагается вопрос и несколь- ко вариантов ответа на него, один (или несколько) из которых является правильным, а остальные — нет. Укажите правильный ответ. 384 Часть 4. Создание приложений в MS Office
1. В объектной модели Outlook доступ к объектам почтовых папок и их содержимому осуществляется через объект: a) Folders; б) NameSpace; в) Application; г) Items; д) Windows. 2. В стандартный набор папок, создаваемый приложением Outlook по умолчанию, входят, в частности, следующие папки: а) Отправленные; б) Входящие; в) Прочитанные; г) Исходящие; д) Удаленные. 3. Объект почтового сообщения обладает свойствами, описывающими следующие его а) характеристики: б) тему сообщения; в) текст сообщения; г) отметку об отправке ответа; д) отметку о выполненной пересылке; уровень важности сообщения. 4. Использование адресной книги позволяет автоматизировать такие операции, как: а) отправка ответа на сообщение; б) отправка сообщения группе получателей; в) определение адреса получателя по его псевдониму; г) извлечение и сохранение вложений, имеющихся в почтовых сообщениях; д) систематизация поступающей почтовой корреспонденции. 5. Обработка событий Outlook позволяет создавать VBA-программы, автоматически реагирующие на следующие события: а) поступление почтового сообщения; б) наличие в сообщении компьютерного вируса; в) наличие в сообщении вложений; г) завершение работы приложения; д) открытие почтового сообщения пользователем. Глава 15. Программирование на VBA в Outlook 385
Глава 16 Общие аспекты программирования на VBA в приложениях Microsoft Office В этой главе... ♦ Управление лентой приложения, панелями инструментов и меню ♦ Сохранение значений переменных ♦ Доступ к объектам в других приложениях ♦ Резюме Все приложения Microsoft Office доступны из программ, написанных на языке VBA. Это позволяет как расширять функциональные возможности создаваемых вами прило- жений за счет встроенных функций отдельных приложений Office, так и интегрировать в одной программе функциональность сразу нескольких приложений пакета. В этой главе мы познакомимся с теми возможностями, которые являются общими для всех приложе- ний пакета Microsoft Office. Следует отметить, что, помимо пакета Microsoft Office, язык VBA поддерживает большое вдзМ количество других популярных приложений — например, пакеты AutoCAD, CorelDraw, 0 приложения Adobe Creative Suite (Photoshop, Illustrator, InDsign) и пр. Это позволя- ет интегрировать их функциональные возможности в создаваемые VBA-приложения. Однако рассмотрение объектной модели и доступных функций этих программ выходит за рамки данного самоучителя. Управление лентой приложения, панелями инструментов и меню Приложения Microsoft Office позволяют при необходимости настраивать вид и функ- циональные возможности элементов их пользовательского интерфейса: ленты приложения, панелей инструментов или же набора команд в обычных и контекстных меню. Например, для того чтобы повысить эффективность работы с создаваемым VBA-приложением, полезно сделать так, чтобы окно программы содержало вполне определенный набор инструментов
или же команд меню, для чего потребуется внести соответствующие изменения в набор и содержание вкладок ленты приложения, панели инструментов или меню приложения. В новой версии Microsoft Office 2010 интерфейс пользователя его приложений — Excel, Word, Access, PowerPoint и, частично, Outlook — не претерпел серьезных изменений. Как и в предыдущей версии, практически все элементы управления размещаются на едином компоненте интерфейса, ленте приложения, что упрощает и ускоряет доступ к требуемым пользователю функциям приложения. Практически единственным заметным изменени- ем в интерфейсе приложений является исчезновение кнопки Office и замена ее вкладкой Файл, содержащей меню с примерно тем же набором команд, что был у кнопки Office. Панель быстрого доступа, предназначенная для размещения кнопок вызова тех команд, которые чаще всего требуются пользователю в работе, не претерпела каких-либо измене- ний, зато появилась возможность настраивать вид и функциональность ленты приложе- ния — как в целом, так и ее отдельных вкладок и групп. Именно эти элементы интерфейса наиболее интересны с точки зрения разработчика VBA-приложений. Набор и содержание вкладок ленты приложения можно также настраивать с помощью специальных XML-файлов, содержащих описание компонентов ленты. Эти файлы могут динамически подключаться в процессе работы VBA-программы, вызывая соответствующие изменения в интерфейсе приложения. Более того, язык VBA позволяет подключать и инте- грировать на ленту приложения новые функциональные инструменты пользователя, текст которых может быть написан на языке высокого уровня — например Microsoft С#. Обсуж- дение правил создания XML-файлов и написания пользовательских функций на языке C# выходит далеко за рамки этой книги1, поэтому здесь ограничимся рассмотрением лишь тех методов, которые существовали в прежних версиях Office и обеспечиваются исключительно средствами VBA. Они позволяют управлять созданием пользовательских меню и панелей инструментов, которые отображаются на вкладке Надстройки ленты приложения. В объектной модели VBA панели инструментов представлены объектами класса Com- mandBar, принадлежащими коллекции CommandBars. Поэтому для работы с определен- ной панелью инструментов необходимо указать имя ее объекта в коллекции Command- Bars. Например, для получения ссылки на панель инструментов Standard необходимо использовать следующие операторы. Dim Панель As CommandBar Set Панель = CommandBars("Standard") Для создания объекта пользовательской панели инструментов необходимо использо- вать метод Add коллекции CommandBars. Так, для создания новой панели инструментов с названием УВА__Ордер необходимо использовать следующие операторы. Dim УВАпанель As CommandBar Set УВАпанель = CommandBars.Add(Name:="7ВА_Ордер", _ Position:=msoBarFloating) Объекты панелей инструментов обладают свойствами, с помощью которых можно управлять отображением и размещением панели инструментов на экране. Например, для отображения или сокрытия панели инструментов предназначено свойство Visible. ’ Отображение собственной панели инструментов CommandBars("7ВА_Ордер").Visible = True 1 Подробное описание подобных методов читатель может найти, например, в теме “Overview of the Ribbon User Interface” в справочной системе редактора VBA в Microsoft Office Excel 2010. Глава 16. Общие аспекты программирования на VBA... 387
Как видите, для вывода панели инструментов на экран свойству Visible достаточно присвоить значение True, а для сокрытия — значение False. Для изменения места рас- положения отображенной на экране панели инструментов используются такие свойства, как Position, Row Index и Left. Для того чтобы при необходимости исключить возмож- ность перемещения панели инструментов пользователем, используется свойство Protec- tion. Некоторые сведения об упомянутых выше свойствах приведены в табл. 16.1. Таблица 16.1. Свойства панели инструментов приложения Office Свойство Назначение Допустимые значения Position Определяет место расположения панели задач на экране msoBarFloating — свободное размещение па- нели инструментов на экране; msoBarTop — привязка к верхней границе окна основного приложения; msoBarBottom — привязка к нижней границе окна основного приложения; msoBarLeft — привязка к левой границе окна основного приложения; msoBarRight — привязка к правой границе окна основного приложения Rowindex Left Определяет позицию прикре- пленной панели инструментов по отношению к другим панелям инструментов, прикрепленным к той же стороне Определяет расстояние от лево- го края панели инструментов до левого края экрана Целое число больше 0; msoBarRowFist — панель инструментов являет- ся первой; msoBarRowLast — панель инструментов являет- ся последней Protection Определяет способ защиты па- нели инструментов от действий пользователя msoBarNoProtection — нет защиты; msoBarNoCustomize — запрещена настройка; msoBarNoResize — запрещено изменение раз- меров; msoBarNoMove — запрещено перемещение па- нели; msoBarNoChangeVisible — запрещено сокры- тие/отображен ие; msoBarNoChangeDock — запрещено изменение стороны пристыковки; msoBarNoVerticalDock — запрещена присты- ковка к боковым сторонам окна; msoBarNoHorizonalDock — запрещена при- стыковка к верхней и нижней сторонам окна В любом приложении Office имеются встроенные средства настройки ленты и создания панелей инструментов, позволяющие поместить на них требуемый для работы набор кно- пок. Однако при необходимости с помощью средств VBA можно изменить как внешний вид любой панели инструментов, так и ее реакцию на действия пользователя при возник- новении тех или иных условий. Дополнительно можно размещать на панели инструментов кнопки, которые будут доступны пользователю только в определенных условиях. Обра- титься из программного кода к требуемой кнопке панели инструментов, представляемой в VBA объектом класса CommandBarControl, можно одним из следующих способов. 388 Часть 4. Создание приложений на MS Office
Указав индексный номер кнопки в коллекции объектов Controls той панели ин- струментов, к которой она относится. Индексный номер кнопки соответствует ее расположению на панели инструментов, причем номер 1 присваивается кнопке, рас- положенной в крайнем левом углу (или в крайнем верхнем углу). Пример обращения к объекту, представляющему вторую слева кнопку на панели инструментов \/ВА_Ордер: CommandBars("7ВА_0рдер").Controls(2) Используя свойство Caption (Имя) кнопки. Существует простой способ выяснить значение, которое сохраняется в этом свойстве для любой из кнопок панелей ин- струментов, присутствующих в пользовательском интерфейсе некоторого приложе- ния Microsoft Office. Для этого раскройте меню кнопки Файл и выберите команду Параметры. В раскрывшемся одноименном диалоговом окне перейдите на вкладку Панель быстрого доступа и в списке Выбрать команды из выберите вкладку и груп- пу, в которой находится интересующая вас команда. Далее отыщите в списке команд требуемую, наведите на нее указатель мыши и задержите его на некоторое время. Появится контекстная подсказка, содержащая название панели, группы и кнопки выбранной команды (рис. 16.1). Ниже дан пример обращения к кнопке на панели инструментов \/ВА_Ордер, свойство Caption которой имеет значение Ввести. CommandBars("7ВА_0рдер").Controls("Ввести”) Рис. 16.1. Определение значения свойства Caption кнопки команды Формат по образцу в группе Буфер обмена на вкладке Главная ленты приложения Глава 16. Общие аспекты программирования на VBA... 389
По ссылке на объект требуемой кнопки, которая может быть получена с помощью метода FindControl коллекции CommandBars. Поиск кнопки может выпол- няться по различным критериям, наиболее полезным из которых является указа- ние значения ее свойства Тад. Однако в этом случае появляется дополнительное условие — указанное значение должно быть присвоено свойству Тад кнопки до выполнения поиска. Пример обращения к методу FindControl для получения ссылки на кнопку, свойству Тад которой предварительно было присвоено значение Тад_Ввести: CommandBars.FindControl(,,”Тад_Ввести") В табл. 16.2 приведены наиболее полезные свойства и методы объекта CommandBar- Control, позволяющие настраивать вид и поведение кнопок панелей инструментов из программного кода на VBA. Таблица 16.2. Свойства и методы, позволяющие настраивать элементы управления панелей инструментов с помощью VBA Свойства или метод Действие Доступные параметры для свойств Свойство Enabled Определяет возможность доступа к кнопке True — кнопка активна и доступна для пользователя; False — кнопка неактивна и недоступна пользователю Свойство TooltipText Текст, отображаемый в качестве под- сказки при наведении на элемент указателя мыши Строковое значение Свойство Visible Метод Execute Метод Reset Метод SetFocus Определяет видимость кнопки на па- нели инструментов Вызывает выполнение связанной с данной кнопкой подпрограммы, ко- манды или макроса Возвращает кнопке ее исходный вид и функции Помещает фокус ввода на данную кнопку панели инструментов True — кнопка отображается; False — кнопка не отобража- ется В листинге 16.1 приведен пример подготовки и отображения на экране панели ин- струментов пользователя в приложении Microsoft Excel 2010. Панель содержит кнопку и копию системной кнопки Создать, скопированной с системной панели инструментов Стандартная. Листинг 16.1 Создание пользовательской панели приложения Public Sub PanelCreate() Dim cbarl As CommandBar Dim cControll As CommandBarControl Dim cld As Variant ’ Создание пустой панели инструментов 390 Часть 4. Создание приложений на MS Office
Set cbarl = CommandBars.Add(Name:="Панель1") With cbarl .Enabled = True ' Панель активна .Visible = True ’ Панель видима End With ’ Создание на панели кнопки Set cControll = cbarl.Controls.Add(Type:=msoControlButton) With cControll .Caption = "Кнопка 1" .TooltipText = "Подсказка по назначению кнопки" .Visible = True ’ Кнопка видима End With ’ Копирование на панель системной кнопки создания нового документа cld = CommandBars("Standard").Controls(1).ID '.Получение ИД Set cControll = cbarl.Controls.Add(msoControlButton, cld) End Sub Вид созданной в листинге 6.1 пользовательской панели в окне приложения показан на рис. 16.2. Как видите, в ленточном интерфейсе эта панель отображается на вкладке Надстройки в группе Настраиваемые панели инструментов. Рис. 16.2. Пользовательская панель, отображаемая в окне Excel 2010 по умолчанию, т.е. без использования управляющего ХМL-файла Глава 16. Общие аспекты программирования на VBA... 391
По умолчанию вновь созданная панель будет сохранена в приложении, а значит, будет присутствовать в его интерфейсе и при последующих запусках программы. Для удаления созданной пользовательской панели предназначен метод Delete ее объекта CommandBar. Например, для удаления созданной в листинге 6.1 панели используйте следующий код. Public Sub Очистка() CommandBars ("Панель 1’’) .Delete End Sub Сохранение значений переменных Во время выполнения программы очень часто возникают ситуации, когда необходимо сохранить значения определенных переменных до следующего запуска программы. Среди всех приложений Office только Word предоставляет инструменты для хранения некоторых переменных (с помощью объекта Variable). Однако существует много других приемов, которые помогут решить подобную задачу. Рассмотрим сохранение и получение значений переменных в Excel. При написании программ для большинства приложений Office широкое поле для дея- тельности предоставляют программисту пользовательские свойства документов. В частно- сти, можно использовать средства VBA для создания пользовательских свойств докумен- тов, заполнения их данными, а также получения этих данных при первой необходимости. При этом вовсе не нужно беспокоиться о сохранении этих свойств документа в отдельном файле, так как они автоматически сохраняются вместе с самим документом. Свойства документа включают коллекцию встроенных параметров, к которым можно добавить и собственные. Приложения Word, Excel и PowerPoint используют общую коллекцию Document- Properties для хранения встроенных и дополнительных пользовательских параметров. Каждый параметр документа хранится в отдельном объекте класса Documentproperty. Доступ к параметрам документа в среде этих приложений можно получить, выбрав ко- манду Сведения в меню кнопки Файл, а затем в раскрывшемся окне щелкнув на кноп- ке Свойства (справа вверху) и выбрав в ее меню команду Показать область сведений о документе. При этом в окне документа открывается дополнительная панель, в которой отображаются поля для основных встроенных свойств документа (рис. 16.3). Доступ ко всем свойствам документа предоставляется в диалоговом окне Свойст- ва: документ (рис. 16.4), которое открывается при выборе команды Дополнительные свойства в меню Свойства документа этой панели — как показано на рис. 16.3. (Другой вариант — сразу выбрать команду Дополнительные свойства в меню кнопки Свойства после выбора команды Сведения в меню кнопки Файл.) На вкладке Прочие этого окна можно определить любое количество новых пользовательских свойств любых типов, кото- рые затем использовать в VBA-приложении. Однако существуют и программные средства создания и модификации пользовательских свойств документов, о чем речь пойдет чуть ниже. Отдельные объекты коллекции Document Prope г ties доступны из программного кода через свойства BuiltlnDocumentProperties, для встроенных свойств докумен- тов, и CustomDocumentProperties, для пользовательских свойств документа (при этом запрашиваемые пользовательские свойства должны быть определены в документе, иначе возникнет ошибка). 392 Часть 4. Создание приложений на MS Office
Рис. 16.3. Отображение панели свойств в окне документа Рис. 16.4. Вкладка Прочие диалогового окна Свойства: документ Глава 16. Общие аспекты программирования на VBA... 393
Dim A, В As Documentproperty With ActiveWorkbook ’Обращение ко второму системному свойству (счет от нуля) Set А = .BuiltinDocumentProperties(2) ’Обращение к первому пользовательскому свойству (счет от единицы) Set В = .CustomDocumentProperties(1) End With Для создания нового пользовательского свойства документа в Excel, PowerPoint или Word используется метод Add объекта коллекции CustomDocumentProperties этого документа. Приведенный ниже пример ориентирован на среду Excel, где объект Ac- tiveWorkbook представляет текущий активный документ при выполнении процедуры (в Word и PowerPoint это объекты ActiveDocument и ActivePresentation соответ- ственно). ActiveWorkbook.CustomDocumentProperties.Add _ Name:= ’’Новое свойство”, LinkToContent: = False, _ Type:= msoPropertyTypeString, Value := ’’Значение свойства” В этом случае для сохранения значения в виде пользовательского свойства документа параметру LinkToContent должно быть присвоено значение False. Если же требует- ся, чтобы значение свойства было связано с содержимым ячейки Excel (или закладкой Word), то этому параметру следует присвоить значение True. Параметр Туре определяет тип данных для свойства; в качестве значения допустимо использование таких констант, KaKmsoPropertyTypeNumber, msoPropertyTypeBoolean,msoPropertyTypeDate, msoPropertyTypeFloat или msoPropertyTypeString. Для сохранения или получения информации, хранящейся в виде свойства документа, используется свойство Value объекта Documentproperty. Предположим, что в про- грамме используется пользовательское свойство документа с именем Счетчик кнопок, предназначенное для хранения данных о количестве щелчков мышью, выполненных пользователем на кнопке одной из форм программы. Приведенный ниже фрагмент кода считывает и обновляет значение свойства после каждого щелчка на этой кнопке. With ActiveWorkbook.CustomDocumentProperties(’’Счетчик кнопок") .Value = .Value + 1 End With Существуют также и другие способы сохранения значений переменных. В Access очень удобно сохранять данные, необходимые для работы VBA-программы, непосредственно в таблицах используемой базы данных, а в Excel — в ячейках листа рабочей книги. Един- ственная проблема, связанная с подобным подходом, состоит в том, что в этих случаях данные видны пользователям и, следовательно, их можно будет легко изменить, даже случайно. Для предотвращения подобных несанкционированных действий в программе должны быть предусмотрены необходимые предупреждающие действия. Помимо сказанного выше, в любом поддерживающем язык VBA приложении можно сохранять данные на диске, помещая (а затем считывая) требуемые значения в реестре Windows. Для этого предназначены операторы SaveSetting и GetSetting — подробнее об этом методе мы будем говорить ниже. Кроме того, необходимые программе данные можно сохранять в специальном дисковом файле, для чего будут полезны объекты File- Dialog и FileSearch, рассматриваемые в следующих подразделах. 394 Часть 4. Создание приложений на MS Office
Объект FileDialog Объект FileDialog реализует функции, аналогичные стандартным диалоговым окнам Open и Save любых приложений пакета Office. Существует несколько типов объ- ектов FileDialog, но в каждом приложении Office может присутствовать только один экземпляр такого объекта. Это значит, что экземпляр FileDialog можно создать только для одного типа объекта. Если требуется создать экземпляр этого объекта другого типа, то вначале нужно удалить предыдущий экземпляр, а уж затем создавать новый. Для создания объекта FileDialog используется метод Application . FileDialog. Dim файл As FileDialog Set файл = Application.FileDialog(type) файл.Show 'Отображение диалогового окна на экране Здесь type — константа, определяющая тип создаваемого диалогового окна. Константы, которые могут использоваться в качестве значений этого аргумента, приведены в табл. 16.3. Таблица 16.3. Допустимые значения аргумента метода FileDialog Константа Описание типа диалогового окна msoFileDialogFolderPicker msoFileDialogFilePicker msoFileDialogOpen msoFileDialogSaveAs Позволяет выбрать требуемую папку Позволяет выбрать один или несколько файлов Позволяет выбрать файлы для открытия в используемом при- ложении Позволяет сохранить текущий документ приложения под но- вым именем После создания экземпляра объекта FileDialog программе будут доступны любые его свойства и методы — важнейшие из них представлены в табл. 16.4. Таблица 16.4. Некоторые свойства и методы объекта FileDialog Сеойстео/Метод Описание AllowMultiSelect Присвоение этому свойству значения True разрешает пользователю (свойство) выбирать больше одного файла в диалоговом окне. Если его значение False, пользователю разрешается выбрать только один файл ButtonName (свойство) Определяет текст, отображаемый на командной кнопке действия диало- гового окна. Значением по умолчанию является обычный текст действия данного типа диалогового окна (например, Open для диалогового окна открытия) DialogType (свойство) Хранит значение, идентифицирующее тип данного диалогового окна, указанное при создании объекта. Допустимые значения идентичны опи- санным в табл.16.3 Execute (метод) Выполняет действие, завершающее выбор пользователя в диалоговых окнах Open и SaveAs. Неприменимо к диалоговым окнам FilePicker и FolderPicker Filter index (свойство) Определяет индекс фильтра диалогового окна, применяемого по умол- чанию Filters (свойство) Содержит ссылку на коллекцию FileDialogFilters, которая включает текущие фильтры диалогового окна (если таковые имеются) Глава 16. Общие аспекты программирования на VBA... 395
Окончание табл. 16.4 Ceoucmeo/Memod Описание InitialFileName (свойство) Initialview (свойство) Определяет имя файла, изначально отображаемого в диалоговом окне при его открытии Определяет способ начального отображения информации в диалоговом окне. Допустимые значения: msoFileViewDetails — отображаются имя файла и его размер, тип, даты; msoFileViewList — имена файлов отображаются списком; msoFileViewPreview — в диалоговом окне отображается окно просмо- тра содержимого выбранного файла; msoFileViewPropert ies — в диалоговом окне отображаются свойства выбранных файлов Selectedltems (свойство) Show (метод) Возвращает ссылку на коллекцию FileDialogSelectedltems, содер- жащую все элементы, выбранные пользователем в диалоговом окне Отображает диалоговое окно на экране. Возвращает значение -1, если пользователь выбрал кнопку действия, или 0, если пользователь выбрал кнопку отмены. При выполнении метода Show выполнение программы останавливается до тех пор, пока пользователь не закроет это диалоговое окно Title (свойство) Определяет заголовок диалогового окна. По умолчанию заголовок зави- сит от типа диалогового окна Поиск файлов на диске с помощью свойства FileSearch В новой версии Microsoft Office свойство FileSearch, принадлежащее объекту Ap- plication, может использоваться для поиска на диске файлов, отвечающих определен- ным критериям. Ниже перечислены основные действия, которые осуществляются при подобном поиске. 1. Очистка данных, оставшихся после предыдущего поиска. 2. Задание папки поиска. 3. Указание, нужно ли искать в подпапках. 4. Задание имени искомого файла (при этом можно использовать символы подста- новки). 5. Выполнение поиска. 6. Получение результатов. Объект FileSearch имеет два метода — метод NewSearch, который не имеет аргу- ментов и восстанавливает по умолчанию значения всех параметров поиска (кроме свой- ства Lookin, которое сохраняет свое значение), и метод Execute, который выполняет текущий заданный поиск. Синтаксис этого метода следующий. Application.Execute(SortBy, SortOrder, AlwaysAccurate) Все аргументы метода Execute являются необязательными. Аргумент SortBy опре- деляет порядок сортировки возвращаемого списка файлов. Допустимыми значениями этого аргумента являются константы msoSortByFileName (по именам файлов, принято 396 Часть 4. Создание приложений на MS Office
по умолчанию), msoSortByFileType (по типу файлов), msoSortByLastModified (по времени последнего изменения) или msoSortBySize (по размеру). Аргумент Sortorder задает порядок сортировки: по возрастанию (значение msoSortOrderAscending) или по убыванию (значение msoSortOrderDescending). Аргумент AlwaysAccurate явля- ется булевым значением, определяющим, будет ли поиск ограничен уже индексирован- ными файлами (значение False) или файлы, добавленные после последнего обновления индекса, также будут включены в поиск (значение True, по умолчанию). Метод Execute возвращает значение > 0, если какие-либо файлы были найдены, или значение 0 — в противном случае. После успешно проведенного поиска свойство FoundFiles позволяет получить до- ступ к списку найденных файлов. Свойство FoundFiles .Count содержит количество найденных файлов, так что просмотр этого списка можно выполнить с помощью цикла For Each ... Next. Пример организации поиска файлов приведен в листинге 16.2. Листинг 16.2. Поиск файлов в заданной папке With Application.FileSearch .NewSearch ’ Очистка пред, результатов .Lookin = "C:\My Documents” ’ Указание папки для поиска .SearchSubFolders = True ' Просмотр вложенных папок .FileName = "run" . ’ Определение имени файла .TextOrProperty = "San*" .MatchAllWordForms = True .FileType = msoFileTypeAUFiles ’ Анализируются все файлы If .Execute() > 0 Then ’Выполнение поиска MsgBox "Найдено " & .FoundFiles.Count & " файлов." For i = 1 To .FoundFiles.Count MsgBox .FoundFiles(i) Next i Else MsgBox "Файлы не найдены." End If End With Сохранение информации в реестре Windows Как уже говорилось выше, в любом приложении, поддерживающем язык VBA, можно сохранять данные, записывая, а впоследствии считывая требуемые значения в реестре Windows. Для этой цели в VBA имеется оператор SaveSettings, который автоматически создает заданный вами параметр, если в данный момент в реестре такого не окажется. Синтаксис оператора SaveSettings следующий. SaveSettings приложение, раздел, параметр, значение Здесь аргументы приложение, раздел и параметр — это имена соответствующих уров- ней иерархии реестра. Все установки реестра для одной VBA-программы должны разме- щаться в одной, созданной специально для этой программы ветви реестра (для идентифи- кации этой ветви предназначен аргумент приложение). Сохраняемые в реестре данные можно разбивать на разделы и параметры совершенно произвольно, используя при этом для них произвольно выбранные имена. Глава 16. Общие аспекты программирования на VBA... 397
Например, если вы назвали свою программу “Приветствие” и хотите добавить в реестр параметры, хранящие информацию о том, сколько раз вызывалось ее диалоговое окно, можно использовать для этого следующий оператор. SaveSettings "Приветствие", "Параметры", "Число вызовов", "5" Последний аргумент, "5", задает собственно те реальные данные, которые должны быть помещены в реестр Windows. Для извлечения данных из реестра применяется функция GetSetting. Эта функция предназначена для того, чтобы при необходимости можно было выяснить, какое значение хранится в данный момент в некотором параметре реестра. Синтаксис функции GetSet- ting следующий. GetSetting приложение, раздел, параметр, по_умолчанию Здесь приложение, раздел, параметр — это обязательные аргументы, а по_ умолчанию — необязательный аргумент. Функцию GetSetting можно использовать в программном коде для того, чтобы присвоить возвращаемое ей значение переменной (типа String или Variant). Текущее_Число = GetSetting("Приветствие", "Параметры", _ "Число вызовов") Последний аргумент по_умолчанию определяет значение, которое должна вернуть функция GetSetting, если указанный при ее вызове параметр в реестре не найден. Кроме этого, в языке VBA существуют еще две команды, предназначенные для работы с реестром. Функция GetAllSettings возвращает список всех параметров и их значений в виде двухмерного массива строк. Оператор DeleteSetting позволяет удалить как хранящееся в реестре значение, так и сам параметр. Доступ к объектам в других приложениях Кроме приложений, поддерживающих язык VBA, существует множество других при- ложений, доступ к которым можно получить из VBA-программ. При этом следует пом- нить, что объекты другого приложения можно использовать только в том случае, если оно установлено в системе, т.е. в реестр Windows внесена соответствующая информация. Если это условие выполнено, то для работы с объектами приложения, поддерживающего стандарт СОМ, потребуется выполнить ряд предварительных действий. 1. В редакторе VBA добавить ссылку на объектную библиотеку внешнего приложе- ния. 2. Объявить переменные для объектов внешнего приложения, которые будут исполь- зоваться в программе. 3. Создать экземпляры соответствующих объектов с помощью функции Create- Object. Чтобы информировать редактор Visual Basic об объектной модели внешнего приложе- ния, необходимо добавить и активизировать ссылку на объектную библиотеку этого прило- жения. Для этого в окне редактора Visual Basic выберите команду Tools1^References, после 398 Часть 4. Создание приложений на MS Office
чего откроется диалоговое окно References (Ссылки), показанное на рис. 16.5. Допустим, на вашем компьютере установлено приложение Microsoft Visual FoxPro 9 (СУБД), к объек- там которого необходимо получить доступ из создаваемой вами программы. В этом случае в диалоговом окне References в списке Available References (Доступные ссылки) должна уже присутствовать строка для объектной библиотеки Visual FoxPro 9. Чтобы эта библио- тека стала доступной из среды редактора VBA данного приложения Microsoft Office, нуж- но найти в этом списке соответствующую строку и установить флажок рядом с ее именем (рис. 16.5). Если нужной библиотеки в списке не оказалось, добавьте ссылку на нее в список Available References самостоятельно, воспользовавшись для этого кнопкой Browse (Обзор). References - VBAProject Available References: □ Visual Basic For Applications □ Visual Basic For Applications_________________ □ Volume Shadow Copy Service 1.0 Type Library □ Wave MSP 2.0 Type Library □ webvw 1.0 Type Library □ WECAPI 5.3 Type Library □ WECAPI 6.0 Type Library □ wiaacmgr 1.0 Type Library □ WiaVideo 1.0 Type Library LJ wiaview 1.0 Type Library L J Windows Media Player L Windows Media Player MaHia PlAvAr ГnmnaHhiliH? I а«аг Visual Foxpro 9.0 Type Library Location: C:\Program Files\Microsoft Visual FoxPro 9\vfp9.exe Language: Standard Puc. 16.5. Диалоговое окно References редактора VBA Переменные для объектов из внешних приложений объявляются в VBA-программах стан- дартным образом. Чтобы узнать, какие объекты внешнего приложения доступны, используйте либо обозреватель объектов редактора VBA, либо файл справки этого внешнего приложения. После объявления объектных переменных потребуется создать необходимые объекты с по- мощью операторов Set — это выполняется внутри соответствующих процедур программы. Для создания объектов из внешнего приложения предназначена функция CreateObject. Она открывает соответствующее приложение, которое затем и создает нужный объект. Возвращаемое функцией значение будет ссылкой на объект, которая при- сваивается переменной, указанной в операторе Set. Чтобы открыть внешнее приложение с уже готовым файлом или документом, следует использовать функцию GetOb j ect. По- сле того как объект внешнего приложения будет создан, можно использовать его свойства и методы любым допустимым образом. Следует отметить, что приложение, которое открывается из программного кода на языке VBA, выполняется в скрытом виде — на экране оно не отображается. Это очень удобно, если необходимо использовать в своей программе данные другого приложения, обрабатываемые без вмешательства пользователя. Если все же приложение требуется по- казать пользователю в его обычной форме, то, в зависимости от приложения, нужно либо установить для свойства Visible значение True, либо использовать метод Display. obj SpecialFolder.Display Глава 16. Общие аспекты программирования на VBA... 399
Объекты внешнего приложения могут использоваться в VBА-программе точно так же, как и те, которые принадлежат базовому VBA-приложению. Однако в отношении про- грамм из состава Microsoft Office следует сделать еще одно важное замечание. Большая часть приложений пакета Office предназначена для однократного использования. Это означает, что при каждом выполнении в программе оператора Set, предназначенного для создания объекта Application, создается новый экземпляр подобного приложения. На- пример, следующий оператор создаст новый экземпляр приложения Word независимо от того, существуют ли в настоящий момент в системе другие его экземпляры. Set WordApp = New Word.Application Приложения Word, Access и Excel предназначены для однократного использования. Однако приложения PowerPoint и Outlook поддерживают только многократное использо- вание. Это означает, что может быть запущен только один экземпляр этих приложений, независимо от того, сколько ссылок на их объект Application потребовалось програм- ме. Рассмотрим следующий оператор. Set OutlookApp = New Outlook.Application В отличие от Word, если приложение Outlook уже запущено, будет возвращена ссылка на действующий экземпляр, а новый экземпляр объекта будет создан только в том случае, если это приложение еще не запущено. Резюме В этой главе обсуждались возможности использования в VBА-программах некоторых функциональных возможностей, общих для всех приложений Microsoft Office. Сюда от- носятся средства манипулирования из программ панелями инструментов и меню базовых приложений и доступ к системным окнам поиска и открытия файлов. Дополнительно обсуждались такие важные вопросы, как сохранение данных VBA-программ в пользова- тельских свойствах документов, в реестре Windows и в файлах на дисках. В завершение было описано, как из VBA-программы можно получить доступ к объектам других, внеш- них, приложений, установленных в системе. Тестовые задания Ниже приведено несколько тестовых заданий, предназначенных для закрепления из- ложенного в этой главе материала. В каждом задании вам предлагается вопрос и несколь- ко вариантов ответа на него, один (или несколько) из которых является правильным, а остальные — нет. Укажите правильный ответ. 1. Для определения доступных пользователю возможностей настройки панели ин- струментов предназначено следующее свойство объекта класса CommandBar: a) Visible; б) Rowindex; в) Protection; г) Position. 400 Часть 4. Создание приложений на MS Office
2. Для создания объекта FileDialog требуемого типа предназначен следующий метод: a)Application.FileDialog; б)ActiveDocument.FileDialog; в)CreateObject.FileDialog; г) Display. FileDialog. 3. Для создания пользовательских свойств документа для сохранения в них данных VBA-программы используется следующий метод: a) Comment .Add; б)CommandBars.FindControl; в) Balloon. Show; г)Application.Activate; д)CustomDocumentProperties.Add. 4. Запись данных в реестр Windows осуществляется с помощью следующего оператора: a) GetSetting; б)SaveSettings; в) AddSettings; г) DeleteSetting. 5. Необходимым условием получения доступа к объектам внешних приложений является: а) создание объекта Application этого приложения; б) предварительный запуск этого приложения пользователем; в) добавление в редакторе VBA ссылки на объектную библиотеку приложения; г) запуск этого приложения из редактора VBA. Глава 16. Общие аспекты программирования на VBA... 401
Приложение A Основы программирования для начинающих В этом приложении... ♦ Что такое программа ♦ Понятие о присвоении значения ♦ Управляющие операторы и циклы ♦ Модульное программирование ♦ Резюме Хотя некоторые читатели этой книги наверняка знакомы с программированием на том или ином языке, все же я считаю полезным поместить в книгу небольшое приложение, содержащее сведения о том, что представляют собой программы, из чего они состоят и каковы основные принципы их выполнения. Другими словами, это приложение содер- жит описание некоторых фундаментальных концепций, оно предназначено для тех, кто никогда не занимался программированием. Совершенно необходимо, чтобы каждый читатель, приступая к чтению основных глав книги, имел ясное представление о том, что в действительности представляет собой про- грамма, и понимал, что значит присвоить значение переменной, как работает условный оператор и для чего предназначен оператор цикла. Для опытных программистов это приложение не будет представлять интереса. Одна- ко читателям, которые не знакомы с языком Basic той или иной его версии, могут быть полезны разделы, где схематично описывается, как в языке VBA реализованы условные операторы и циклы. Что такое программа В сущности, компьютерная программа представляет собой некоторый набор инструк- ций, подобных, например, описанию маршрута движения. Предположим, что вы хотите объяснить кому-либо, как добраться из пункта А (ул. Солнечная) в пункт В (ул. Лесная). Для этого вы подробно описываете ту последовательность действий, которую этот человек должен выполнить, чтобы попасть в интересующее его место. 1. Идите вот по этой стороне улицы и поверните направо на ул. Северную. 2. Пройдите по этой улице два квартала. 3. Поверните направо на ул. Восточную.
4. Пройдите один квартал. 5. Поверните налево, на ул. Озерную. 6. Пройдите два квартала и поверните налево — вы попадете на ул. Лесную. Человек, который строго, шаг за шагом, будет следовать этим инструкциям, непре- менно доберется до Лесной улицы. Теперь предположим, что мы случайно переставили две инструкции — 3 и 5. 1. Идите вот по этой стороне улицы и поверните направо на ул. Северную. 2. Пройдите по этой улице два квартала. 3. Поверните налево на ул. Озерную (должно быть п. 5). 4. Пройдите один квартал. 5. Поверните направо на ул. Восточную (должно быть п. 3). 6. Пройдите два квартала, поверните налево, и вы попадете на ул. Лесную. Теперь тот, кто будет двигаться, следуя данному набору инструкций, скорее всего, заблудится и не достигнет желаемой цели. Отсюда можно сделать вывод, что описание маршрута должно быть недвусмысленным и абсолютно последовательным, иначе оно окажется абсолютно бесполезным, а поставленная цель достигнута не будет. Эти же замечания совершенно справедливы и для компьютерных программ. Поэтому можно утверждать, что программа представляет собой последовательность недвусмыслен- ных инструкций, которые компьютер выполняет одну за другой безо всяких рассуждений. Те инструкции, которые выполняет компьютер, принято называть операторами. Именно они и являются основными “кирпичиками” любой программы. Например, попробуем написать на языке VBA простейшую программу, предназначен- ную для получения суммы двух чисел. Sub Adder () а = 15 Ь = 25 с = а + b End Sub Нетрудно заметить, что сначала в этой программе двум переменным а и ь присваива- ются некоторые числовые константы. Затем значения этих переменных складываются, и результат присваивается переменной с. Теперь перепишем эту программу, переставив местами два оператора. Sub Adder () а = 15 с = a + b b = 25 End Sub В этом случае мы получим совсем другой, очевидно, неправильный результат, посколь- ку сложение в программе выполняется еще до того, как переменной ь присваивается тре- буемое значение. Поэтому переменная с будет иметь значение 15, а не 40, как в первом примере. Приведенный пример совсем прост, но он подчеркивает тот важнейший факт, который каждый программист должен хорошо понимать: в отличие от человека, компьютер совершенно Основы программирования для начинающих 403
бездумно выполняет заданную ему последовательность операторов, причем с очень большой скоростью; полученные результаты и их смысл его совершенно не интересуют. Другими сло- вами, если последовательность операторов (т.е. программа), которую выполняет компьютер, наделе окажется двусмысленной или нелогичной, желаемые результаты достигнуты не будут. Понятие о присвоении значения В предыдущем разделе мы использовали такие, возможно, новые для вас понятия, как “константа”, “переменная” и “присвоить значение”. Давайте уточним, что же означают эти термины и каковы особенности их смыслового наполнения в вычислительной техни- ке. Существует два основных способа, с помощью которых информация может быть пред- ставлена в компьютерных языках, подобных VBA, — непосредственно, в виде константы (явно заданного значения), и символически, в виде переменной. В программе константа представляет собой значение, которое явно задано и не меняется в процессе выполне- ния. В противоположность этому, переменная представляет собой некоторое символиче- ское имя, под которым в процессе выполнения программы могут пониматься различные значения. Связывает эти два понятия тот факт, что в процессе выполнения программы значение-константа может быть присвоено переменной, как показано на рис. АЛ. Присвоение а = 15 Переменная Константа (Ячейка памяти) (Значение) Рис, А,1, Выполнение оператора присваивания значения переменной a Очень важно ясно представлять себе, что происходит в компьютере, когда он выпол- няет операцию присваивания значения. Переменная, в действительности, — это симво- лическое обозначение или метка, которую компьютер связывает с определенной областью памяти (ячейкой), куда, собственно, и помещается значение константы. Обратимся к рис. А.2, на котором иллюстрируется выполнение программы из трех операторов при- сваивания. Первые два оператора а = 15 и b = 2 5 указывают компьютеру на необходи- мость поместить в две различные ячейки памяти, обозначенные как а и Ь, два конкретных числовых значения — 15 и 25 соответственно. Третий оператор, с = а + Ь, указывает компьютеру на необходимость просуммировать те значения, которые в данный момент хранятся в ячейках памяти, обозначенных как а и Ь, и поместить результат в ячейку памя- ти, обозначенную как переменная с. Знак равенства в операторе присваивания значения следует понимать как операцию “заменить значением” или “присвоить результат”. Очень важно понимать, что в данном случае использование знака “равно” совершенно отличается по смыслу от его использова- ния в математических равенствах. Различие так велико, что некоторые специалисты в об- ласти компьютерных наук неоднократно предлагали заменить знак равенства стрелкой. angle <- 45 404 Приложение А
Ячейки памяти Программа Рис. А.2. Размещение переменных в памяти компьютера и присваивание им значений констант Это больше соответствует смыслу выполняемой операции. По этой же причине в таких языках, как Pascal или MathCad, используется сочетание символов т.е. тот же оператор будет выглядеть так. angle := 45, Это явно отличает данную запись от математического равенства. Почему же так важно учитывать это отличие? Прежде всего, потому, что в левой части оператора присваивания может присутствовать только переменная, и только одна. Имен- но поэтому в языке VBA оба приведенных ниже оператора будут ошибочными. а + b = с 3 = х - у + 99 С другой стороны, хотя оператор х = х + 1 нельзя считать правильным алгебраиче- ским равенством, он является совершенно корректным оператором присваивания. После выполнения этого оператора в ячейку памяти, обозначенную как переменная х, будет по- мещено значение, на единицу большее его прежнего значения. Безусловно, компьютеры способны обрабатывать не только числовую информацию. Например, им приходится оперировать именами переменных, метками операторов, идентификаторами файлов, которые состоят из цифр, а также из букв и других символов. Подобная буквенно-цифровая информация называется строками. В языке VBA значение строковых констант принято заключать в кавычки. Переменные, в которых хранятся по- добные значения, называются строковыми переменными. Ниже приведен пример операто- ра присваивания строковой константы "Louis Armstrong" строковой переменной п. n = "Louis Armstrong" После выполнения этой операции в ячейке памяти, обозначенной как переменная п, будет находиться значение, представляющее собой строку символов "Louis Armstrong". Управляющие операторы и циклы К этому моменту вы уже должны ясно понимать, что любая программа представляет со- бой последовательность недвусмысленных, четко выраженных инструкций, которые ком- пьютер выполняет строго последовательно. В действительности сказанное выше следует понимать так: “Программа представляет собой последовательность недвусмысленных, Основы программирования для начинающих 405
четко выраженных инструкций, которые компьютер выполняет строго последовательно, если только он не получит указаний поступить как-то иначе". Существует два способа потребовать от программы отклониться от строго последова- тельного выполнения операций — поместить в программу оператор управления или опе- ратор цикла. Благодаря этим конструкциям вычислительная мощь программ значительно возрастает. Специалисты в области компьютерных наук математически доказали, что лю- бые алгоритмы численных вычислений могут быть реализованы с помощью некоторой комбинации операторов трех типов: присваивания, управления и цикла. Операторы управления Операторы управления, которые иначе называются операторами ветвления, в про- цессе своего выполнения анализируют некоторое условие. Исходя из результатов анализа оператор завершается выполнением того или иного действия. Простейшим оператором выполнения в языке VBA является оператор If - Then (Если-To). Предположим, необходимо вычислить абсолютную величину некоторого числа. Математическое определение гласит, что если число больше нуля или равно ему, то его абсолютное значение равно ему самому. Если число отрицательное, то его абсолютное значение равно этому же числу, но без знака “минус”. Чтобы написать программу вычис- ления абсолютного значения числа, воспользуемся операторами If - Then. If а < О Then а = - а End if Поскольку изначально язык VBA задуман как очень простой для понимания, смысл приведенного выше оператора должен быть вам вполне ясен. “Если значение (перемен- ной) а < 0, то (переменной) а присваивается ее же значение, но с обратным знаком, иначе ничего делать не надо” (Тот, кто достаточно хорошо знает английский язык, сможет прочесть и перевести этот оператор как обычное английское предложение.) В соответ- ствии с принципом выполнения оператора присваивания, результатом выполнения этой программы всегда будет абсолютное значение числа, исходно находившегося в перемен- ной а, помещенное в ту же переменную а. Иначе говоря, если исходно в переменной а находится положительное число или нуль, программа проверяет это и ничего больше не делает. Если же исходно в переменной а отрицательное число, программа обнаруживает это и заменяет его на обратное. Операторы управления могут использоваться и для реализации нескольких действий, выбираемых в зависимости от результатов анализа условия. В этом случае одно действие предпринимается, если условие выполняется, а другое — если оно не выполняется. Пред- положим, необходимо определить знак некоторого числа. Для написания такой програм- мы воспользуемся оператором If - Then - Else (Если-To-Иначе). If а < 0 Then s = -1 Else s = 1 End if Если значение переменной а меньше нуля, то переменной s будет присвоено значе- ние -1 — математический эквивалент отрицательного знака. Если же значение перемен- ной а будет больше нуля или равно ему, то переменной s будет присвоено значение 1. 406 Приложение А
Циклы Под циклом в языке VBA понимается такой оператор или последовательность опера- торов, которые могут выполняться многократно. Простейшей формой оператора цикла является оператор For - Next (Для-Следующее). Предположим, что необходимо вычислить сумму первых п положительных целых чи- сел. Для решения этой задачи воспользуемся оператором For - Next. х = О For i = 1 to n x = x + i Next i Поскольку язык VBA очень прост для понимания, вы, полагаю, уже догадались, что происходит при выполнении этой программы. Предположим, что переменной п присвоено значение 5. После того как в первом операторе программы переменной х было присвоено значение 0, начинается выполнение оператора цикла (строка For) и переменной i при- сваивается исходное значение 1. Затем в программе выполняется следующий оператор, согласно которому значение переменной х увеличивается на 1. Поскольку исходное значе- ние х равно нулю и цикл выполняется в первый раз, то значение переменной х будет равно 1. Следующим в программе выполняется оператор Next. При выполнении этого оператора компьютер увеличивает значение переменной i на 1, и теперь оно становится равным 2. Затем компьютер возвращает управление оператору For, поскольку полученное значение переменной i пока еще меньше п (т.е. 5). Аналогичным образом цикл будет повторяться до тех пор, пока условие цикла не окажется выполненным, т.е. i окажется больше 5. Как только это условие достигнуто, выполнение цикла будет завершено, а управление передано оператору, который следует за оператором Next. В нашем примере значение переменной х, полученное после завершения выполнения цикла, будет равно 15. Модульное программирование Ознакомившись с базовыми операторами любого из языков программирования — операторами присваивания, управления и цикла, — мы получили инструментарий, до- статочный для написания любой сколь угодно сложной программы. И действительно, математики доказали, что этих трех типов операторов достаточно для того, чтобы реали- зовать любой вычислительный алгоритм. Однако написать большую программу как нечто единое целое очень сложно — слишком много элементов потребуется держать в памяти, учитывая существующие взаимосвязи и зависимости элементов между собой. Как и в лю- бой другой области, сложную задачу решать гораздо проще, если удастся разбить ее на несколько более мелких, а значит, более простых подзадач. Именно этой цели и служит понятие модульное программирование. Суть его состоит в разделении сложной компью- терной программы на несколько подпрограмм или процедур, которые объединяются в один или несколько модулей. Процедурой называется последовательность операторов, которая может быть выполнена как единое целое для получения определенного, заранее известного результата. Самой важной характеристикой процедур или программных мо- дулей является то, что они создаются как независимые и, в определенной степени, само- достаточные конструкции. Как правило, подобные модули служат для решения конкрет- ной, четко определенной задачи — именно поэтому они чаще всего представляют собой специализированные, относительно небольшие программы (обычно в пределах от 50 до Основы программирования для начинающих 407
100 операторов). В языках программирования обычно используются два типа подпро- грамм — подпрограммы-процедуры и подпрограммы-функции. Подпрограммы-процедуры обычно возвращают несколько результирующих значений, тогда как подпрограммы- функции — всегда единственный результат. В языке VBA всякая программа должна вклю- чать в себя главную (main) или вызывающую процедуру, которая осуществляет обращение костальным процедурам и функциям по мере необходимости. Иначе говоря, вызывающая процедура организует необходимый вычислительный процесс, обращаясь к другим частям программы в заданной логической последовательности. В процессе написания программ модульное программирование предоставляет немало преимуществ. Во-первых, можно использовать небольшие законченные элементы как строительные конструкции более сложных программ. Это упрощает процесс разработки и делает его доступным для понимания пользователя. Создание таких программ потре- бует меньше времени, поскольку каждая программа может быть написана независимо от других программ и не одним, а разными программистами. Во-вторых, элементы прежде созданных программ можно объединить в библиотеку полезных процедур, которую затем можно использовать при разработке новых программ. Модульный подход к программи- рованию также значительно упрощает отладку и тестирование программ. Наконец, про- цессы сопровождения и модификации программного обеспечения также упрощаются, поскольку для решения новых задач и реализации дополнительных возможностей могут быть разработаны новые процедуры, которые затем легко встраиваются в уже функцио- нирующую программную структуру. Процедуры В упрощенном виде структура любой процедуры выглядит следующим образом. Sub Name ([ arglist ] ) [ операторы] [Exit Sub] [ операторы] End Sub Здесь Name — имя процедуры, arglist представляет собой список аргументов, которые передаются процедуре при ее вызове (отдельные значения в этом списке разделяются запятыми). Словом [операторы] обозначены некоторые группы операторов, выполняемые в теле процедуры. Оператор Exit Sub является командой немедленного выхода и позволяет выйти из процедуры до ее нормального завершения. Оператор End Sub — это оператор нормального завершения процедуры, который обязательно должен быть последним оператором в ее теле. Следует отметить, что в основном тексте книге, в примерах, часто приводится не пол- ный текст программы, а лишь отдельные ее фрагменты, которые важны для понимания излагаемого материала, остальные, несущественные в данном случае операторы, опу- скаются. При этом вместо опускаемых операторов в текст примера вставляется строка с многоточием, обозначающая, что в этом месте листинга может находиться произволь- ная последовательность любых операторов, которые выполняют действия, не имеющие особого значения для обсуждаемой в данный момент темы. [Оператор!] [Оператор N] 408 Приложение А
Понятно, что это могут быть и операторы ветвления, цикла, безусловного перехода и пр. Поэтому в примерах отделяемые строкой с многоточием операторы никогда не вы- полняются непосредственно один за другим. Вызов процедур осуществляется с помощью оператора Call, который имеет следую- щий синтаксис. Call Name ([arglist] ) При выполнении оператора Call управление передается указанной в нем процедуре. После того как выполнение этой процедуры будет завершено, управление возвращается оператору, непосредственно следующему за оператором Call. Ниже приведен простой пример программы, в которой для вычисления суммы двух чисел используется процедура Add. Sub SimpleAddition() ] ’присваивание значений I а = 15 I Ь = 28 I ’ вычисление суммы Вызывающая подпрограмма Call Add (а, b, с) I ’отображение результата I MsgBox с I End Sub J Sub Add (a, b, c) c = a + b End Sub После того как в вызывающей процедуре переменным а и Ь присваиваются числовые значения, оператор Call передает управление процедуре Add. В теле этой процедуры вы- полняется сложение значений переменных а и Ь. Результат этого сложения записывается в переменную с, причем переменные а, Ь и с были переданы процедуре Add в качестве вход- ных параметров. По завершении процедуры Add управление возвращается вызывающей процедуре, а именно оператору MsgBox, который выводит полученный результат. Таким образом, процедура Add получает входную информацию через список аргументов (перемен- ные а и Ь), выполняет определенные вычисления (сложение чисел) и возвращает результат в вызывающую подпрограмму, опять же через список аргументов (переменная с). Процедуры-функции Как и обычные процедуры, процедуры-функции представляют собой независимые под- программы, которые принимают на вход аргументы и выполняют заданную последова- тельность действий. Однако процедуры-функции отличаются от обычных процедур тем, что их вызов осуществляется с помощью указания в текущем операторе их имени, а не с помощью оператора Call. По завершении они возвращают единственное значение, которое подставляется в текущий оператор вместо имени процедуры. Упрощенная схема построения процедуры-функции приведена ниже. Function name ([arglist] ) [statements] [name = expression] Основы программирования для начинающих 409
[Exit Function] [statements] [name = expression] End Function Здесь name представляет собой имя, присвоенное процедуре-функции; arglist — это список аргументов, которые передаются функции при ее вызове; [statements] — некоторая группа операторов, выполняемых в теле функции; Exit Function — оператор, позволяющий при необходимости немедленно выйти из процедуры-функции, не дожидаясь ее нормального завершения. Обратите внимание на то, что возвращаемое значение из процедуры-функции задается присваиванием этого значения имени данной функции. Любое количество подобных операторов присваивания может присутствовать в произвольном месте в пределах процедуры-функции. Вызов процедуры-функции осуществляется указанием имени этой функции, за ко- торым следует список передаваемых ей аргументов. Ниже приводится пример простой программы, в которой процедура-функция используется для сложения двух чисел. Sub SimpleAddition() ] ’присваивание значений | а = 15 I Ь = 28 I ’ вычисление суммы Вызывающая подпрограмма с = Add (a, b) I ’отображение результата I MsgBox с I End Sub J Function Add (a, b) Add = a + b End Function В главной процедуре переменным а и b присваиваются числовые значения, затем в следующем операторе присваивания указание имени процедуры-функции Add вызывает передачу управления указанной функции. После выполнения сложения и присваивания результата имени функции управление возвращается главной подпрограмме, где получен- ный из процедуры-функции результат присваивается переменной с. В следующем опе- раторе этот результат выводится на экран с помощью функции MsgBox. Таким образом процедура-функция получает исходные данные через список аргументов (переменные а и Ь), выполняет требуемые действия (суммирует их значения) и возвращает результат через собственное имя (Add). Следовательно, процедуры-функции могут использовать- ся в правой части произвольных выражений, подобно тому как мы применяем обычные операции и математические выражения, предполагая, что в дальнейшем расчете будут использоваться значения, полученные при их вычислении. Поскольку процедура-функция (после выполнения) всегда возвращает единственное значение, ее можно вызвать не только отдельно, но и в некотором выражении. Например, предыдущую программу сложения чисел можно упростить следующим образом. Sub SimpleAddition() ’присваивание значений а = 15 b = 28 410 Приложение А
’вычисление суммы и отображение результата MsgBox Add (а, Ь) End Sub Function Add (a, b) Add = a + b End Function В данном случае процедура-функция Add вызывается непосредственно как аргумент процедуры вывода окна сообщения. Обратите внимание: в приведенных выше примерах появляются строки с текстом, опи- сывающим действия, которые будут далее выполняться в программе, — это коммента- рии, текст, предназначенный для прочтения человеком и не являющийся программным кодом, а потому игнорируемый компилятором. Подробнее об этом говорится в главе 4, в разделе “Комментарии”. Аргументы процедур Список аргументов является основным средством передачи информации между вызы- вающей программой и процедурой. Всю совокупность передаваемых процедуре аргумен- тов называют ее списком параметров, а каждый из аргументов — параметром процедуры. Двусторонний обмен информацией между процедурой и вызывающей ее программой проиллюстрирован на рис. А.З. а = 15 Ь = 28 Call Sum (а, Ь, с) MsgBox с а а Sub Sum (х, у, z) z = х + у End Sub Рис. А.З. Типичная схема обмена информацией между вызывающей программой и процедурой Процедуре необходимо получить данные для обработки, а затем вернуть результат своих вычислений вызывающей программе, чтобы последняя могла его использовать. Таким образом, исходные данные и полученные результаты передаются между процеду- рой и вызывающей программой. Процедура получает исходное значение из вызывающей программы через свой список параметров. После завершения выполнения процедуры вычисленное значение суммы будет помещено в переменную с вызывающей процедуры. Список параметров можно понимать как окно, через которое информация избирательным образом передается между вызывающей программой и вызываемой процедурой. Основы программирования для начинающих 411
Обратите внимание на то, что имена переменных-аргументов в вызывающей про- грамме могут отличаться от имен переменных-аргументов в вызываемой процедуре. Хотя это и не обязательно, одинаковые имена также можно использовать; выбор различных имен переменных-аргументов на рис. А.З подчеркивает модульную природу процедур (в действительности можно использовать различные наборы переменных с различными именами). Обмен значениями между процедурами осуществляется механизмом вызова процедуры языка VBA. Резюме В этом приложении мы ознакомились с основными понятиями программирования и выяснили, что представляют собой и как используются константы, переменные и опе- раторы. Программа — это четко определенная последовательность действий, которые должны быть выполнены компьютером. Каждое действие в программе задается некото- рым оператором. Для написания программы любой сложности достаточно трех основных типов операторов: присваивания, управления и цикла. При написании сложных про- грамм целесообразно разбивать основную задачу на несколько более простых подзадач, каждая из которых решается отдельно от других. Для организации подобной модульной структуры программ используются подпрограммы-процедуры и подпрограммы-функции, отличающиеся способом вызова и количеством возвращаемых результатов. Тестовые задания Ниже приведено несколько тестовых заданий, предназначенных для закрепления из- ложенного в этом приложении материала. В каждом задании вам предлагается вопрос и несколько вариантов ответа на него, один (или несколько) из которых будет правиль- ным, а остальные — нет. Укажите правильный ответ. 1. Что из указанного ниже является элементами программ: а) операторы; б) константы; в) флажки; г) числа; д) текст. 2. Укажите, что является результатом выполнения оператора присваивания: а) изменение значения переменной на заданное значение; б) изменение значения константы на вычисленное значение; в) передача управления подпрограмме; г) вывод сообщения на монитор компьютера. 3. Для чего предназначен оператор цикла: а) для передачи управления подпрограмме; б) для вычисления суммы чисел; в) для организации многократного выполнения группы операторов; 412 Приложение А
г) для выбора одного из вариантов дальнейших действий в зависимости от выпол- нения заданного условия. 4. В чем состоит основное назначение модульного программирования: а) сокращение размеров программ; б) упрощение решения задачи за счет разбиения ее на подзадачи; в) ускорение выполнения вычислений; г) создание библиотек полезных подпрограмм. 5. Чем отличаются между собой подпрограммы-процедуры и подпрограммы- функции: а) принципами выполнения операций; б) набором используемых операторов; в) принципами передачи параметров; г) методом вызова и количеством возвращаемых результатов. Основы программирования для начинающих 413
Приложение Б Команды меню редактора VBA В этом приложении кратко описываются команды, входящие в состав всех стандарт- ных меню редактора VBA. Для каждой из команд приводится их назначение и комбинация клавиш их ускоренного вызова (если таковая имеется). В табл. Б. 1 перечислены команды меню File (Файл). Таблица Б.1. Команды меню File Команда Клавиши Назначение Save (Сохранить) <Ctrl+S> Сохранение текущего проекта Import File (Импорт файла) <Ctrl+M> Импортирование в данный проект модуля, экспортиро- ванного из другого проекта Export File (Экспорт файла) Remove (Удалить) <Ctrl+E> Сохранение текущего модуля, формы или класса в фор- мате текстового файла для импортирования в другой проект Удаление модуля или формы из проекта Print (Печать) <Ctrl+P> Распечатка модуля или формы Close and Return to... (Закрыть и вернуться в...) <Alt+Q> Закрытие редактора VBA с возвращением в окно основ- ного приложения В табл. Б.2 представлены команды меню Edit (Правка). Таблиц Б.2. Команды меню Edit Команда Клавиши Назначение Undo ... (Отменить...) Redo ...(Вернуть...) <Ctrl+Z> Отмена команды, которая была выполнена последней Возврат выполнения команды, которая была отменена последней операцией Undo Cut (Вырезать) <Ctrl+X> Вырезание выделенного текста или объекта с помеще- нием его в буфер обмена Windows Сору (Копировать) <Ctrl+C> Копирование выделенного текста или объекта с по- мещением его копии в буфер обмена Windows Paste (Вставить) <Ctrl+V> Вставка текста или объекта из буфера обмена Widows в текущий модуль или форму Clear (Очистить) <Del> Удаление выделенного текста или объекта из модуля или формы Select АП (Выделить все) <Ctrl+A> Выделение всего текста в модуле или всех объектов в форме Find (Найти) <Ctrl+F> Поиск в модуле указанного текстового фрагмента
Окончание табл. Б. 2 Команда Клавиши Назначение Find Next (Найти далее) <F3> Повторение последней операции Find Replace (Заменить) <Ctrl+H> Замена указанного текста в модуле другим текстом Indent (Увеличить отступ) <Tab> Смещение всего выделенного фрагмента текста впра- во на один интервал табуляции Outdent (Уменьшить отступ) <Shift+Tab> Смещение всего выделенного фрагмента текста влево на один интервал табуляции List Properties, Methods (Список свойств, методов) <Ctrl+J> Открывает окно списка, отображающего все свойства и методы доступных объектов List Constants (Список констант) <Ctrl+Shift+J> Открывает окно списка, отображающего все доступ- ные именованные константы VBA Quick Info (Сведения) <Ctrl+I> Выводит всплывающую подсказку, отображающую правильный синтаксис указанного выражения Parameter Info (Параметры) <Ctrl+Shift+I> Выводит всплывающую подсказку, отображающую перечень параметров указанной процедуры, функции или метода Complete Word (Закончить слово) Bookmarks (Закладки) <Ctrl+Space> Автоматически завершает слово, набор которого был начат в текущей строке кода. Если набираемое слово пока неочевидно, раскрывается окно со списком воз- можных вариантов Подменю, включающее четыре команды работы с закладками, позволяющими помечать строки текста, а затем быстро переходить к ним при необходимости. Toggle Bookmark — установить/удалить закладку на текущем операторе; Next Bookmark — перейти к следующей закладке; Previous Bookmark — перейти к предыдущей закладке; Clear All Bookmarks — удалить все закладки В табл. Б.З описаны команды меню View (Вид). Таблица Б.З. Команды меню View Команда Клавиши Назначение Code (Программа) <F7> Вывод на экран окна Code, с исходным текстом про- грамм на языке VBA Object (Объект) <Shift+F7> Вывод на экран окна Project Explorer Definition (Описание) <Shift+F2> Вывод на экран окна Object Browser с определением синтаксиса процедуры или функции Last Position (Вернуться к последней позиции) <Ctrl+Shift+F2> Переход на последнюю позицию в модуле Object Browser (Просмотр объектов) <F2> Вывод на экран окна Object Browser с перечнем до- ступных в данный момент библиотек, содержимое которых представляется в этом окне Immediate Window (Окно отладки) Locals Window (Окно локальных переменных) <Ctrl+G> Вывод на экран окна Immediate отладчика VBA Вывод на экран окна Locals отладчика VBA Команды меню редактора VBA 415
Окончание табл. Б.З Команда Клавиши Назначение Watch Window (Окно контрольного значения) Вывод на экран окна Watch отладчика VBA Call Stack (Стек вызова) <Ctrl+L> Вывод на экран окна Call Stack отладчика VBA Project Explorer (Окно проекта) <Ctrl+R> Вывод на экран окна Project Explorer Properties Window (Окно свойств) <F4> Вывод на экран окна Properties Toolbox (Панель элементов) Tab Order (Последова- тельность перехода) Toolbars (Панели инструментов) Вывод на экран панели инструментов Toolbox Вывод на экран окна Tab Order, используемого при создании диалоговых окон Вывод на экран окна Toolbars, предназначенного для настройки панелей инструментов редактора VBA Microsoft <приложение> <Alt+Fll> Переключение в окно базового приложения Microsoft Office В табл. Б.4 описаны команды меню Insert (Вставка). Таблица Б.4. Команды меню Insert Команда Назначение Procedure (Процедура) UseForm (Форма) Module (Модуль) Class Module (Модуль класса) File (Файл) Вставка в текущий модуль новой процедуры Добавление в проект новой формы Добавление в проект нового модуля Добавление в проект нового модуля класса Вставка в модуль содержания текстового файла В табл. Б.5 описаны команды меню Format (Формат). Таблица Б.5. Команды меню Format Команда Назначение Align (Выровнять) Открывает подменю подкоманд, позволяющих выравнивать вы- бранные в форме объекты по отношению друг к другу и к границам формы Make Same Size (Выровнять размер) Size to Fit (Подогнать размер по содержимому) Size to Grid (Подогнать размер по сетке) Horizontal Spacing (Интервал по горизонтали) Vertical Spacing (Интервал по вертикали) Center in Form (Разместить по центру в форме) Открывает подменю подкоманд, позволяющих сделать размер вы- деленных объектов одинаковым по высоте и/или ширине Изменяет ширину и высоту объекта так, чтобы они соответствовали размеру его содержимого Изменяет ширину и высоту объекта так, чтобы они совпадали с бли- жайшими линиями сетки разметки формы Открывает подменю команд, позволяющих заданным образом уста- новить горизонтальный интервал для выбранных объектов Открывает подменю команд, позволяющих заданным образом уста- новить вертикальный интервал для выбранных объектов Открывает подменю команд, позволяющих заданным образом изме- нить положение выбранных объектов относительно центра формы 416 Приложение Б
Окончание табл. Б. 5 Команда Назначение Arrange Buttons (Выровнять кнопки) Group (Группировать) Ungroup (Разгруппировать) Order (Порядок) Открывает подменю команд, позволяющих автоматически выровнять командные кнопки по нижней или правой стороне формы Позволяет связать несколько объектов формы в одну группу Отменяет группировку объектов, прежде связанных вместе с помо- щью команды Group Открывает подменю команд, позволяющих изменять относительное расположение перекрывающихся объектов в форме в направлении сверху вниз В табл. Б.6 описаны команды меню Debug (Отладка). Таблица Б.6. Команды меню Debug Команда Клавиши Назначение Compile (Компилировать) Выполняет компиляцию проекта, выбранного в дан- ный момент в окне Project Explorer Step Info (Шаг с заходом) <F8> Осуществляет пошаговое выполнение исходного кода (по одному оператору) с отображением на экране кода вызываемых процедур и функций (если он доступен) Step Over (Шаг с обходом) <Shift+F8> Осуществляет пошаговое выполнение исходного кода (по одному оператору) с выполнением вызываемых процедур и функций как одного оператора Step Out (Шаг с выходом) <Ctrl+Shift+F8> Осуществляет выполнение всех оставшихся операторов в программном коде данной процедуры без остановок Run to Cursor (Выполнить до текущей позиции) Add Watch (Добавить контрольное значение) <Ctrl+F8> Осуществляет выполнение всех операторов — от те- кущего и вплоть до того оператора, в котором сейчас находится курсор Открывает диалоговое окно, в котором можно задать переменную или выражение, значение которых будет непрерывно контролироваться и отображаться в окне Watch при выполнении операторов исходного кода программы Edit Watch (Изменить контрольное значение) <Ctrl+W> Открывает диалоговое окно редактирования перемен- ных и выражений, созданных командой Add Watch Quick Watch (Контрольное значение) <Shift+F9> Позволяет быстро добавить контролируемое выражение, просто указав курсором интересующий элемент кода Toogle Breakpoint (Точка останова) <F9> Добавляет или удаляет точку останова для оператора, указанного курсором Clear All Breakpoints (Снять все точки останова) <Ctrl+Shift+F9> Удаляет все точки останова, установленные в модуле Set Next Statement (Задать следующую инструкцию) Show Next Statement (Показать следую- щую инструкцию) <Ctrl+9> Позволяет изменить обычную последовательность выполнения операторов программы с помощью пря- мого указания курсором той строки исходного кода, которая должна выполняться следующей Позволяет подсветить в окне Code ту строку кода, которая будет выполняться следующей Команды меню редактора VBA 417
В табл. Б.7 описаны команды меню Run (Запуск). Таблица Б.7. Команды меню Run Команда Клавиши Назначение Run Macro (Запуск подпрограммы) <F5> Запускает макрос или подпрограмму, которая редактируется в данный момент Break (Прервать) Reset (Сброс) Design Mode (Конструктор) <Ctrl+Break> Прерывает выполнение запущенной VBA-программы Сбрасывает все переменные уровня модуля в исходное со- стояние Включает или выключает режим проектирования для редак- тора VBA В табл. Б.8 описаны команды меню Tools (Сервис). Таблица Б.8. Команды меню Tools Команда Назначение References (Ссылки) Выводит на экран диалоговое окно References, в котором можно установить ссылки на необходимые библиотеки объектов, библиотеки типов или другой VBA-проект Additional Control (Дополнительные элементы) Macros (Макросы) Выводит на экран диалоговое окно Additional Control, которое позволяет по- местить на панель инструментов новые элементы управления, дополнительно к уже существующим Выводит на экран диалоговое окно Macros,предназначенное для создания, редактирования, выполнения или удаления макросов Option (Параметры) Выводит на экран диалоговое окно Options, предназначенное для установки различных параметров функционирования редактора VBA project Properties (Свойства проекта) Digital Signature (Цифровая подпись) Выводит на экран диалоговое окно Project Properties, предназначенное для установки различных свойств проекта Выводит на экран диалоговое окно Digital Signature, в котором для проекта можно задать сертификат цифровой подписи В исходном состоянии меню Add-Ins (Надстройки) содержит единственную команду Add-In Manager, которая выводит на экран одноименное диалоговое окно, предназначен- ное для управления использованием и поведением программ-надстроек, подключаемых к редактору VBA. В табл. Б.9 описаны команды меню Window (Окно). Таблица Б.9. Команды меню Window Команда Назначение Split (Разделить) Позволяет разделить окно Code на две части, в каждой из которых можно независимо работать с различными фрагментами текста одно- го и того же модуля Tile Horizontally (По горизонтали) Tile Vertically (По верикали) Автоматически упорядочивает все открытые в окне редактора VBA окна, располагая их рядом по горизонтали Автоматически упорядочивает все открытые в окне редактора VBA окна, располагая их одно под другим, по вертикали 418 Приложение Б
Окончание табл. Б. 9 Команда Назначение Cascade (Каскадом) Автоматически упорядочивает все открытые в окне редактора VBA окна, располагая их так, чтобы каждое окно было видно хотя бы ча- стично Arrange Icons (Упорядочить пиктограммы) Автоматически упорядочивает пиктограммы окон, свернутых в окне редактора VBA Единственная полезная команда меню Help предоставляет доступ к справочной си- стеме редактора VBA. Ей назначена стандартная в среде Windows клавиша <F1>, кото- рая хорошо известна всем пользователям, имеющим опыт работы в этой операционной системе. Команды меню редактора VBA 419
Приложение В Ответы на тестовые задания Глава 1 Вопрос Правильные ответы Разделы по данному материалу I б Что такое VBA 2 а Что такое VBA 3 в Макросы и их создание 4 а, б Код макросов и его редактирование 5 б, г, д Объектная структура языка VBA Глава 2 Вопрос Правильные ответы Разделы по данному материалу I а, б, д Окна редактора VBA и их настройка 2 в Запуск редактора VBA 3 а Вызов справки 4 б, г Окна редактирования кода и редактирования форм Глава 3 Вопрос Правильные ответы Разделы по данному материалу I в Общий вид создания VBA-программы 2 а Общие принципы построения VBA-программы 3 б Написание новых макросов и процедур 4 б, в, д Выполнение VBA-программы 5 б Обработка ошибок Глава 4 Вопрос Правильные ответы Разделы по данному материалу I б Типы данных 2 б, в, д Типы данных 3 а, г Типы данных 4 б, в Массивы 5 б, г Комментарии
Глава 5 Вопрос Правильные ответы Разделы по данному материалу I б Выражения в языке VBA 2 а Совместимость типов данных 3 а, г Арифметические операторы 4 в Строковые операторы 5 г Приоритеты выполнения операций Глава 6 Вопрос Правильные ответы Разделы по данному материалу I б Оператор безусловного перехода GoTo 2 а Оператор условного перехода if...Then 3 б Оператор Select...Case 4 в Операторы циклов 5 б, г Операторы циклов Глава 7 Вопрос Правильные ответы Разделы по данному материалу I б Основные понятия о процедурах VBA 2 г Основные понятия о процедурах VBA 3 а, б, г, е Аргументы процедур 4 а Функции языка VBA 5 в Ошибки выполнения Глава 8 Вопрос Правильные ответы Разделы по данному материалу I а Что такое объект 2 в Свойства и методы объектов 3 б Свойства и методы объектов 4 г Коллекции и контейнеры 5 в Работа с объектами в программе Глава 9 Вопрос Правильные ответы Разделы по данному материалу I а, г Математические функции 2 в, г Функции преобразования данных 3 б, ж Функции преобразования данных 4 а, в Функции даты и времени 5 б, г Строковые функции Ответы на тестовые задания 421
Глава 10 Вопрос Правильные ответы Разделы по данному материалу 1 б Формы пользователя 2 б, в, д Элементы управления в формах 3 а, в, е, ж Свойства элементов управления 4 б, г Общие методы и события элементов управления 5 в Общие методы и события элементов управления Глава 11 Вопрос Правильные ответы Разделы по данному материалу 1 а, в, г Типы файлов 2 в Типы файлов 3 г Ввод и вывод данных в файлы последовательного доступа 4 а Работа с файлами произвольного доступа 5 б, г, д, ж Работа с файлами как с объектами Глава 12 Вопрос Правильные ответы Разделы по данному материалу 1 б, Г, д Перехват и обработка ошибок 2 б Перехват и обработка ошибок 3 а Перехват и обработка ошибок 4 в Отладка приложений 5 г, д Специализированные окна отладчика Глава 13 Вопрос Правильные ответы Разделы по данному материалу 1 б, г Объектная структура Excel 2 в Объект Workbook 3 а, в Объект Range 4 б, г Объект Range 5 а, г Программирование событий Excel Глава 14 Вопрос Правильные ответы Разделы по данному материалу 1 б Объектная модель Word 2 а Доступ к документам Word с помощью VBA 3 в, г Управление параметрами и окнами Word 4 г Объект View 5 а, б, г Использование объектов Selection и Range 422 Приложение В
Глава 15 Вопрос Правильные ответы Разделы по данному материалу 1 б Объектная структура Outlook 2 б, г, д Манипулирование папками и их содержимым 3 а, б,д Обработка почтовых сообщений 4 б, в Работа с адресной книгой 5 а, г Управление событиями Outlook Глава 16 Вопрос Правильные ответы Разделы по данному материалу 1 в Управление лентой приложения, панелями инструментов и меню 2 а Сохранение значений переменных 3 д Сохранение значений переменных 4 б Сохранение значений переменных 5 в Доступ к объектам в других приложениях Приложение А Вопрос Правильные ответы Разделы по данному материалу 1 а, б Что такое программа 2 а Понятие о присвоении значения 3 в Управляющие операторы и циклы 4 б Модульное программирование 5 г Процедуры-функции Ответы на тестовые задания 423
Предметный указатель D Do - Loop 108 Е Excel 311 встроенные функции 335 выделение 329 диаграммы 342 диалоговые окна 332 диапазон 321 объектная модель 312 пользовательские функции 333 программирование событий 336 рабочие книги 316 рабочий лист 319, 338 ячейки 327 F For - Next 104 вложение 106 For Each - Next 107 Function 122 G GoTo 96 I If-Then 98 If-Then-Else 98, 99 If-Then-Elself 100 M Microsoft Office 386 сохранение переменных 392 управление лентой 386 О Outlook 370 адресная книга 377 вложения 378 календарь 381 объектная модель 370 папки 372 почтовые сообщения 374 управление событиями 380 S Select Case 102 VBA 21,386 Макрос 22 вызов процедур 120 выполнение процедур 120 доступ к объектам прложений 398 класс объекта 29 классы 138 метка 97 объектная структура 29 объектное выражение 158 объект 130 программирование в Excel 311 процедура 113 работа с файлами 254 строки 70 типы данных 67 управление файлами 266, 273 файловые объекты 269 функции 122 математические 169 даты и времени 176 финансовые 187 форматирования данных 172 преобразования данных 170 проверки типов 175 прочие 188 строковые 180 циклы 104 экранные формы 192
VBA-приложение разработка 48 Visual Basic редактор 21 W Word 349 диалоговые окна 353 документ 351, 356 объектная модель 349 параметры приложения 353 переменные документа 367 поиск и замена информации 366 работа с текстом 362 управление окнами 353 А Автоматическая подсказка 299 Аргументы процедуры 115 функции 123, 126 Аргумент 114, 409, 411 значение по умолчанию 116 именованный 117 необязательный 116 обязательный 116 передача 116 по значению 119 по ссылке 118 список 115 тип 115 Б Библиотека типов 156 Булевы значения 69 В Вложение функций 126 Вызов процедур 120, 121 Выражение 86 объектное 158, 159 д Данные булевы (логические) 69 даты и время 69, 177 пользовательского типа 79 специальные символы 185 строковые 184 текстовые 70 типа Variant 70 форматирование 172 символы-заполнители 173 числовые 68 Даты и время 69 Диалоговое окно Import File 52 Add Procedure 143 Additional Controls 236 Edit Watch 305 Export File 51, 154 Import File 154 Macros 120 Member Option 125 Options 60 Project Explorer 28 Project Properties 39 Запись макроса 23, 25 Макрос 26, 27, 54 Настройка клавиатуры 58 Настройка 37 Сообщения об ошибке 127 Ж Журнал ошибок 290 3 Запись 255 Знак операции 86, 88, 91 Значение Empty 86, 123 Nothing 123 Null 86, 89, 123 Предметный указатель 425
и Иерархия объектов 154 Именованные форматы 172 Импорт класса 154 Инкапсуляция 29, 130, 139 К Класс 29, 138 FileSystemObject 273 TextStream 271 UserForm 192 импорт 154 методы 146 модуль 139 свойства 140 события 147 члены 138 экспорт 154 Ключевое слово ByVai 119 Elself 100 End Function 123 Function 123 New 157, 158, 161 Nothing 157 Optional 116 ParamArray 115, 116 Preserve 76 Private 114, 146 Public 73, 114, 146 Set 157 Static 775 ThisDocument 159, 160 ThisWorkbook 160 With Events 149 Код выражение 86 комментарии 81, 82 отступы 81 символ продолжения строки 81 Коллекция 135 доступ 163 использование 160 метод Add 135,161 Close 162 Item 161 расширение 161 свойство Count 135, 160 Комментарии 81, 82 использование 83 Конкатенация 92 Константа 77, 404 внутренняя 78 литеральная 78 определения цвета 222 символическая 78 Контейнер 136 Л Литерал 7? Личная книга макросов 28 м Макрос 22, 50, 54 выполнение 27 запись 24 код 26, 28 модуль 28 редактирование 26 создание 22 сохранение в модуле 27 Массив 74 динамический 76, 77 индекс элемента 74 многомерный 74 статический 75 Метка 97 Метод 133, 134, 146 Hide 196 Show 195 аргументы 134 Модульное программирование 407 преимущества 408 Модуль 27, 50, 80 класса 139 макрос 28 426 Предметный указатель
создание 50 удаление 51 экспорт 57 О Область действия процедуры 114 Обработка ошибок 282 строк 186 Обработчик ошибок 283, 284 Объектная модель 136 Объектная библиотека 398 модель 159, 349 Объектное выражение 158, 159 Объектные переменные 755 Объект 29, 130 ActiveDocument 394 ActivePresentation 394 ActiveWorkbook 394 AddressList 377 Application 138, 158, 312, 350, 370 Attachment 378 Chart 315 Debug 301 Document 350 Drive 275 Err 284 File 276 FileDialog 395 Folder 275,372 Mailltem 374 Namespace 370 NameSpace 372 Range 314,321,360 Recipient 376 Selection 350, 358 TextStream 271 UserForm 195, 197 View 358 Window 358 Workbook 315 Worksheet 314, 319 доступ 137, 159 идентификация 158 иерархия вложения 136 иерархия 154 инкапсуляция 130 класс 138 коллекции 160 коллекция 135 контейнер 136 методы 29, 130, 133 родовой 136 свойства 29, 131 доступ 131,133 связывание 756 событие 29, 30 события 137 создание 757 сообщения 29 ссылка 154, 155 получение 158 экземпляр 29, 138 Объявление процедур 114 Окно Call Stack 306 Immediate 300 Locals 302 Object Browser 125, 163 Properties 193, 194 Quick Watch 306 Watches 303,304 контролируемых выражений 303 свойств 193 сообщения об ошибке выполнения 294 Оператор 49, 403 AppActivate 189 Call 117,121,409 Close 258 Date 777 Dim 72, 155 Do - Loop 108 Do Until 108 Do While 108 DoEvents 196 End 114 Предметный указатель 427
End Sub 408 Erase 77 Event 149 Exit Do 109 Exit For 106 Exit Function 284 Exit Sub 283 For-Next 104,407 For Each - Next 107 ForEach - Next 163 Function 122 Get 263,265 GoTo 96 If-Then 98,406 If-Then-Else 98,406 Input # 259 Is 159 Like 92 Load 195 LSet 187 Mid 187 On Error 283 Open 256 Option Explicit 140 Option Private Module 73, 115 Print 300 Put 262,265 RaiseEvent 149 ReDim 77 Resume 288 RSet 187 SaveSettings 397 Seek 264 Select Case 102 Set 123, 157, 158, 161 SetAttr 268 Stop 293,296 Sub 114 Time 177 Unload 195, 196 With-End With 162 Write# 258 арифметический 88 безусловного перехода 96 ветвления 406 вложение операторов 99 выбора 102 конкатенации 93 логический 89 приоритет 93 присваивания 73, 87 определение понятия 404 сравнения 91 строковый 92 управления 406 управляющий 96 условного перехода 96 цикла 104, 406 вложение 106, 109 счетчик 104 условие 108 Операция дизъюнкции 90 знак 86 импликации 91 исключающее ИЛИ 90 конъюнкции 89 логического отрицания 90 эквивалентность 90 Отладка 292 контролируемые выражения 304 пошаговое выполнение 297 пошаговый режим 296 Ошибка выполнения 61, 127, 282 код ошибки 287 компиляции 281 логическая 61, 282 модуля класса 289 непредвиденная 291 несовпадения типов 87 окно сообщения 127 перехват 281, 283 синтаксическая 60 специальные 289 п Панель быстрого доступа 57 428 Предметный указатель
инструментов Debug 292 Toolbox 193, 199 Передача аргумента 116 по значению 119 по ссылке 118 Переменная 71, 404 локальная 115 область действия 73 объектная 155 объявление 72, 157 освобождение 157 присвоение значения 404 имени 71 статическая 115 строковая 405 Перехватошибок 283 Подпрограмма 113, 408 обработки ошибок 128 Приложение объектная модель 136 Приоритет операторов 93 Программа 48, 49, 402, 404, 405 вызывающая 411 выполнение 54, 96 назначение комбинации клавиш 58 обработка ошибок 60 определение понятия 403 переменная 71 прерывания 290 создание кнопки запуска 55 тестирование 49 читабельность 81 Программирование 402 модульное 407, 408 Программы надежные 282 Проект 50 Процедура-функция 409 возвращаемое значение 410 вызов 410 Процедура 49, 50, 113, 408 аргументы 114, 115, 116 вызов 120 вызывающая 408 выполнение 54, 120 добавление в модуль 52 описания 125 доступа к свойству 141 комментирование 82 область действия 114 обработки события 114, 137, 230 объявление 114 определение понятия 407 ошибка выполнения 127 параметры 411 передача аргументов 116 поиск при вызове 121 процедура-функция 409 свойств 114, 141 создание 51 типы ИЗ функция 122 Р Регистрация ошибок 290 Редактор VBA 32 вызов справки 45 интерфейс 32 комбинации клавиш 34 меню 35, 414 обозреватель объектов 40 окно 33 Immediate 300 редактирования форм 42 свойств 44 программного кода 41 проектов 38 панели инструментов 35 параметры компиляции 61 редактор форм 42 средство Quick Info 299 Реестр Windows 397 сохранение информации 397 Режим прерывания 293 Родовой объект 136 Предметный указатель 429
с Function 122 Свойства объекта 131 Связывание позднее 156 раннее 156 Символы-заполнители 173 Символ 91 служебные 186 шаблона 92 Событие 30, 137, 147 BeforeUpdate 234 Initialize 147 Terminate 147 UserForm_Terminate 196 перехват 149 пользовательское 148 Создание методов 146 объектов 157 свойства класса 140 Сообщения Windows 138 Список параметров 411 Справка контекстная 128 Сравнение выражений 92 строк 91 Ссылка на объект 154, 155 получение 158 Строка 70, 405 Счетчик 104 Long 88 Object 123, 155 Variant 89, 155 автоматическое преобразование 87 библиотека типов 156 несовпадение 87 определенный пользователем 79 совместимость 87 Точка останова 293, 294 постоянная 296 У Управление файлами 273 Управляющие операторы 96 Условие перехода 98 Ф Файл 254, 266 бинарный 264 закрытие 258 запись 255 объектный доступ 269 открытие 256 последовательного доступа 258 произвольного доступа 262 типы 255 управление 273 Форма 42, 192, 202 добавление элементов управления 200 модальная 196 отображение 195 Т пример проектирования 237 события 226 Текстовые данные 70 Текстовый поток 271 Тестирование 49, 289 подпрограммошибок 290 рекомендации 292 Типы данных 67 Тип Boolean 89 Date 88 Double 88 управление порядком перехода 224 элементы управления 193 Функция 113, 122, 169 Choose 188 Chr 185 CreateObject 158, 399 DateAdd 177 DoEvents 189 Format 172 символы-заполнители 173 430 Предметный указатель
GetAttr() 268 GetObject() 158 GetSetting 398 Ilf 188 InputBox 183 Len 189 Lof() 263 RGB 189 Rnd 189 Seek() 263 Switch 188 TypeName 189 аргументы 123, 126 вложенная 126 возвращаемое значение 122 встроенная математические 169 даты и времени 176 финансовые 187 форматирования 172 преобразования данных 170 проверки типов 175 прочие 188 строковые 180 добавление описания 125 ошибка выполнения 127 тип 123 ц Цвет 189 Цикл 104,407 ч Числовые данные 68 э Экземпляр объекта 29, 138 Экранная форма отображение 195 события 226 Экспорт класса 154 Элемент управления 43, 49, 193 RefEdit 220 Выключатель 213 Кнопка 214 Набор вкладок 216 Набор страниц 215 Надпись 207 Переключатель 213 Поле со списком 209 Поле 208 Полоса прокрутки 217 Рамка 214 Рисунок 218 Список 211 Счетчик 217 Флажок 212 выделение 201 выравнивание 204 дополнительные 235 маркеры размеров 43, 200 общие методы и события 225 Предметный указатель 431
MICROSOFT EXCHANGE SERVER 2010 ПОЛНОЕ РУКОВОДСТВО Рэнд Моримого Майкл Ноэл Крис Амарис Эндрю Аббейт Марк Вайнхардт Рэнд Моримого www.williamspubHshing.com Майкл Ноэл Крис Амарис Эндрю Аббейт . ', Марк Вайнхардт : Технический редактор Гай Ярдени Microsoft Exchange Server 2010 www.williamspublishing.com ISBN 978-5-8459-1655-6 Эта книга представляет собой исчерпывающее руководство по проектированию, развертыванию, управлению и поддержке любых сред Exchange Server 2010, независимо от их размеров и сложности. В книге подробно рассматривается широчайший спектр вопросов, в том числе построение высокопроизводительной архитектуры производственной среды Exchange Server с минимальными затратами, ее максимальная защита, миграция из Exchange Server 2003/2007 и Active Directory 2000/2003 в Exchange Server 2010 и Active Directory 2008, использование диспетчера Microsoft Operations Manager и PowerShell для мониторинга и автоматизации, интеграция с SharePoint 2007 и Office Communication Server 2007, репликация групп доступности баз данных (DAG), резервное копирование и восстановление, оптимизация сред Exchange Server и многое другое. Книга рассчитана на пользователей и администраторов средней и высокой квалификации. в продаже
Программирование VBA в Microsoft Office 2010 Самоучитель №1 ПО программированию на языкеVBA в Microsoft Office 2010 Подробно, Доступно, Эффективно! Эта книга поможет вам изучить основные принципы программирования на языке VBA (Visual Basic for Applications) и получить необходимые навыки для создания собственных программ на этом языке. Главная ее цель — помочь читателю самостоятельно научиться программировать в среде приложений Microsoft Office 2010. Для восприятия материала книги не требуется знакомства с другими языками программирования и наличия программистского опыта. Более того, в ней имеется специальное приложение, в котором просто и доходчиво объясняется, что такое программирование, и излагаются те концепции, на основании которых создаются любые программы. Книга предназначена для индивидуального обучения, написана простым, доступным языком и рассчитана на пользователей с любым уровнем компьютерных знаний. Однако она будет полезна и тем, кто уже располагает определенным опытом программирования и хотел бы систематизировать или пополнить свои знания об особенностях программирования на языке VBA. Посетите “Диалектику” в Интернете по адресу: www.dialektika.com ISBN 978-5-8459-1663-1