VBA (Visual Basic for Applications) – язык программирования фирмы Microsoft, интегрированный в приложения MS Office: Word, Excel, Outlook, Access, PowerPoint, FrontPage, Visio, Project, а также в огромное число прикладных программ других производителей.
Основное назначение языка – предоставить пользователям возможность создать надстройку над приложением, позволяющую эффективно решать собственные задачи. Они могут быть как простейшими, сиюминутными, так и представлять собой проекты колоссальной сложности. Однако литература имеется в изобилии только для двух программ: Access и Excel. Если для первой VBA – язык разработки приложений в среде СУБД, то во втором случае причина, скорее всего, лежит в финансовой обеспеченности задач разработки макросов.
При этом наиболее востребованным инструментом для большинства пользователей остается Microsoft Word, о котором литературные источники по VBA лишь упоминают. В связи с этим, именно данная программа и будет обсуждаться в первую очередь. См. также возможные задачи.
Прежде чем начинать создание макроса, нужно четко сформулировать, что и как он должен делать, а в особо сложных случаях даже построить алгоритм его работы на бумаге.
Основным средством создания макросов является запись последовательности действий с помощью команды меню Сервис–Макрос–Записать (Tools–Macro–Record...) Причем это крайне мало зависит от квалификации пользователя.
После этого выводится диалог
в котором надо указать название макроса (можно изменить позднее), место его хранения (обычно шаблон, чаще всего Normal.dot), подключение к кнопке панели инструментов или горячей клавише (необязательно и можно исправить) и желаемое описание. Запись действий начинается после завершения работы с диалогом. Вместо него выводится простейшая панель
позволяющаяя приостановить запись или прекратить её.
После завершения записи макрос готов к исполнению. Если была задана кнопка или горячая клавиша, то запустить макрос можно с их помощью. Иначе – через диалог (Alt+F8).
Надо заметить, что если в настройках программы указано запрашивать сохранение шаблона, то при отказе от него (во время закрытия программы) макрос будет потерян!
Этот вопрос никогда не возникает у тех, кто пытается ограничить себя просто записью последовательности нажатия клавиш. Для тех же, кто любит работать с комфортом, понимание ответа позволит избавить себя от многих мучений.
В-нулевых, это учит программировать! Это не описка. Данная причина важнее всех, так как пользователь, разработавший алгоритм действий, намного быстрее поймет то, что записалось в программе, чем кто бы то ни было другой. А любые малопонятные мелочи всегда можно разобрать отдельно с помощью Справки.
Во-первых, при записи макроса могут быть допущены тривиальная ошибка: нажата не та клавиша, а начинать все с начала зачастую слишком накладно. В обычной жизни мы выполним отмену (Ctrl+Z или Alt+BackSpace) для команды, либо вернем курсор на место, если переместили его не туда. Точно также можно поступить и при записи макроса. Недостаток заключается в том, что тогда будут выполняться бессмысленные действия, отнимающие время. Это не беда, хотя аккуратному человеку крайне неприятно. Лучше поправить ошибку, что означает удаление лишних строк и исправление некоторых значений команд. (Еще один аргумент в пользу заблаговременного продумывания действий.)
Во-вторых, большинство макросов модифицируют содержание документа и делают это почти мгновенно. Это значит, что их случайный запуск может пройти незамеченным с весьма печальными последствиями. Избежать этого можно, включив диалог подтверждения запуска.
В-третьих, значительная часть макросов требует ветвления или многократного повторения, что может быть запрограммировано только вручную.
В-четвертых, есть ситуации, когда надо указать множество условий для выполнения программы, а тогда без достаточно сложных диалогов обойтись не удастся. Иначе – запись и запуск множества макросов.
В-пятых, запись макросов ЗАПРОГРАММИРОВАНА людьми, но не все ситуации могут решаться однозначно. Пример: полужирное начертание. С точки зрения нормального человека оно либо включено (True), либо нет (False). Но средой предусмотрен и третий вариант: переключить, то есть сделать наоборот (wdToggle). Кто-то из особо умных программистов сделал его командой по умолчанию. То есть мы записали выключение, но работать как задумано оно будет только если до этого был полужирный текст.
Список можно продолжать до бесконечности для особо упёртых...
Справка позволяет многократно упростить работу по редактированию и доработке макропрограмм. Наиболее эффективный способ её использования – установить курсор на слове в тексте программы и нажать горячую клавишу F1. К сожалению, качество подсказки и возможность поиска в ней за несколько последних версий MS Office существенно снизились.
В связи с тем, что возможно создание двух типов результатов: макросов и форм, внешний вид редактора может несколько различаться.
Диалоги являются абсолютно необходимым средством для повышения управляемости и гибкости макропрограмм.
Они представлены двумя командами: MsgBox (диалог с кнопками) и InputBox (для ввода значений).
Для начинающих программистов этого вполне достаточно.
Синтаксис команд:
MsgBox(prompt[, buttons] [, title] [, helpfile, context])
InputBox(prompt[, title] [, default] [, xpos] [, ypos] [, helpfile, context])
Можно заметить, что отдельные элементы весьма схожи и повторяются:
prompt – единственный обязательный элемент (он задает текст сообщения, выводимого внутри окна диалога);
title – заголовок окна, обобщающий вопрос диалога;
helpfile... – ваша подсказка, обсуждение (и создание) которой выходит за рамки изучаемого материала.
Диалог предназначен для ввода единичного символьного (строкового) значения. Как видно из основного синтаксиса:
InputBox(prompt[, title] [, default] [, xpos] [, ypos]),
обязательным является только поясняющий текст (prompt).
Появляется возможность указать значение по умолчанию (default), пренебрегать которым не стоит. Ведь во многих случаях оно может быть предсказано и пользователю не придется заниматься утомительным вводом.
Также можно указать в твипсах (1/20 часть пикселя) координаты окна (xpos, ypos). Если соответствующие координаты опущены, то диалог центрируется относительно горизонтали и опускается примерно на треть экрана по вертикали.
Использовать команду следует в виде функции, так как введенное значение обязано быть присвоено переменной.
Dim x As Single x = InputBox("Введите значение x для подстановки")
Результат будет выглядеть так:
Если внимательно посмотреть на текст программы, то закономерным будет вопрос: переменной x (числового типа Single) будет передаваться строковое значение, что является ошибочным?
Однако в VBA это будет обработано правильно, если пользователь введет любое число: преобразование пройдет само собой. Если же он введет буквы или нажмёт кнопку отмены (Cancel), то переменной будет присваиваться строковое значение, что породит ошибку:
Избежать подобной ситуации можно двумя способами, предоставляющими различные возможности.
Решение 1
x = Val(InputBox("Введите значение x для подстановки"))
Здесь сразу происходит преобразование типа возвращаемого значения функцией Val(). В результате при вводе букв они будут:
При нажатии на кнопку Cancel будет возвращена пустая строка (""), преобразуемая в 0.
Если такой ввод допустим в принципе, то нет возможности прекратить выполнение программы без дополнительного запроса пользователю.
Решение 2
Dim x As Single, xVal As String xVal = InputBox("Введите значение x для подстановки") If xVal = "" Then Exit Sub x = Val(xVal)
В данном случае создаётся дополнительная переменная (xVal), в которой хранится результат ввода. Что мы имеем в результате?
К сожалению, объектная модель Word и Excel не совпадают, в связи с чем приходится говорить, что в Excel можно воспользоваться ещё одним способом:
Dim x As Variant x = Application.InputBox(Prompt:="Введите значение x для подстановки", Type:=1)
В этой ситуации пользователь сможет ввести данные только указанного типа (числового). Если можно вводить несколько типов, то следует задать тип как сумму соответствующих типов: 1+2 (либо сразу 3) – можно вводить цифры и символы.
Атрибут buttons представляет собой сумму трех (реже – более) целых чисел, означающих: набор кнопок, картинку, кнопку по умолчанию. Последняя довольно важна, так как многие пользователи невнимательно относятся к надписям в диалоге, и гораздо разумнее активизировать для него ту кнопку, нажатие на которую требуется чаще. Вместо чисел можно использовать системные переменные памяти. Подробная информация приведена в таблице.
Переменная Word | Значение | Описание |
vbOKOnly | 0 | Вывести только кнопку OK |
vbOKCancel | 1 | Вывести кнопки OK и Cancel |
vbAbortRetryIgnore | 2 | Вывести кнопки Abort, Retry и Ignore |
vbYesNoCancel | 3 | Вывести кнопки Yes, No и Cancel |
vbYesNo | 4 | Вывести кнопки Yes и No |
vbRetryCancel | 5 | Вывести кнопки Retry и Cancel |
vbCritical | 16 | Вывести картинку Critical Message ![]() |
vbQuestion | 32 | Вывести картинку Warning Query ![]() |
vbExclamation | 48 | Вывести картинку Warning Message ![]() |
vbInformation | 64 | Вывести картинку Information Message ![]() |
vbDefaultButton1 | 0 | По умолчанию активна 1‑я кнопка |
vbDefaultButton2 | 256 | По умолчанию активна 2‑я кнопка |
vbDefaultButton3 | 512 | По умолчанию активна 3‑я кнопка |
vbDefaultButton4 | 768 | По умолчанию активна 4‑я кнопка |
vbApplicationModal | 0 | Диалог модален для Word: для продолжения работы в приложении и самого макроса нужно нажать на одну из кнопок |
vbSystemModal | 4096 | Диалог модален для Windows: все приложения прекращают работу до тех пор, пока пользователь не нажмет на одну из кнопок |
vbMsgBoxHelpButton | 16384 | Добавляет в диалог кнопку Help (Справка) |
VbMsgBoxSetForeground | 65536 | Переводит окно диалога на передний план (практическое применение неизвестно) |
vbMsgBoxRight | 524288 | Надписи выравниваются вправо |
vbMsgBoxRtlReading | 1048576 | Для языков, читаемых справа налево |
Как видно, если не задавать для кнопок ничего, то получится диалог с кнопкой ОК и без пиктограммы. Кстати, он является одним из наиболее часто используемых вариантов для вывода информации о результатах работы программы как в процессе её отладки, так и при обычном режиме работы.
Пример: MsgBox "Значение х достигло " & xТак как можно вывести диалог с большим разнообразием кнопок, требуется помочь программе разобраться, какая из них была нажата. В этом случае команда запускается в виде функции, возвращающей значение (целое число) переменной в памяти. Далее можно проанализировать его и принять решение о дальнейших действиях
Ниже приведен список значений, возвращаемых функцией MsgBox() в зависимости от нажатой в диалоге кнопки.
Значение | Константа Word | Надпись на кнопке |
1 | vbOK | OK |
2 | vbCancel | Cancel |
3 | vbAbort | Abort |
4 | vbRetry | Retry |
5 | vbIgnore | Ignore |
6 | vbYes | Yes |
7 | vbNo | No |
Пример:
Dim RunMacro As Byte 'Задать целочисленную переменную минимального размера RunMacro = MsgBox("Заменить дефисы в документе?", 4 + 48, "Замена дефисов") 'Запустить диалог с кнопками Yes+No и картинкой "Внимание!" 'Целое число, соответствующее нажатой кнопке, запомнить в RunMacro If RunMacro = 6 Then 'Нажато Yes Selection.HomeKey Unit:=wdStory 'Перейти на начало документа и продолжить программу после End If Else 'Нажато не Yes (No для нашего примера) Exit Sub 'Выйти из программы, не делая ничего End If ... Основная программа
Диалог будет выглядеть так:
Можно сказать, что в нем допущена интерфейсная ошибка, так как нажатие клавиши Esc не позволит закрыть диалог. Для комфортности лучше использовать одновременно кнопки кнопки Yes, No и Cancel. Для доработки понадобится только заменить в тексте программы 4 на 3: ведь нажатие на Cancel обработается также, как и No (выход из программы).
Идеальным решением было бы добавление кнопки Cancel, как показано ниже.
RunMacro = MsgBox("Заменить дефисы в документе?", 3 + 48, "Замена дефисов")
Чтобы дать указания макросу для выполнения действий со сложными условиями необходимо создание экранных форм. Они ничем не отличаются от любых диалогов во всех программах.
Но! Вспомните, сколько раз вам приходилось выискивать нужный пункт в диалоге или пытаться осознать, о чем вас спрашивают.
Правила создания диалогов крайне просты: всё запрошено, но сделано это кратко и понятными словами.
К сожалению, использование форм достаточно сложно и не входит в основной курс изучения и будет обсуждаться только с профильной группой.
Учтите, что приводимые ссылки не решат всех ваших проблем. Но, может, вы поймете, что офисное программирование не только доступно каждому. Это – серьезный бизнес, где никто не горит желанием поделиться своими знаниями и навыками. Вы же можете на уроках освоить достаточно многое, чтобы дальше не зависеть ни от кого и развиваться в пределах личных потребностей.
Большинство заданий дается и разбирается на уроках. Приведенное здесь можно использовать для дополнительной тренировки.