VBA. Практическое программирование
.pdf
О «быстром» программировании
5.В левой части окна выберите объект Worksheet. Сравните, на сколько изменился список элементов справа для объекта, по сравнению с коллекцией.
6.Выбирая элементы из списка справа, посмотрите, как меняется подсказка в нижней части листа. Если вы нажмете клавишу F1, то Вы сможете получить подробные сведения по выбранному слову.
7.В левой части окна выберите элемент XlChartType (Коллекция констант типов диаграмм). С правой стороны Вы увидите перечень имен всех констант, соответствующих различным типам диаграмм, которые Вам может предоставить Excel. Внизу окна будет показано числовое значение константы.
8.Используя верхний список перейдите в библиотеку VBA. Слева выберите модуль Math. Справа Вы получите полный список встроенных математических функций VBA. Выберите слева модуль ColorConstant. Справа появится список встроенных в язык цветовых констант, о которых мы говорили раньше.
9.Через верхний список перейдите в библиотеку VBAproject. Теперь Вы можете познакомиться с основными элементами, имеющими отношение к Вашему проекту.
О «быстром» программировании
Давайте вспомним наше упражнение, в котором мы с помощью полосы прокрутки создавали возможность бесклавиатурного ввода символов. Обратите внимание, что создать такую программу не очень сложно. Это в первую очередь связано с тем, что мы одновременно использовали и возможности электронной таблицы и возможности языка программирования. Действительно, еще раз отметим, что сама по себе электронная таблица Excel — мощнейший инструмент для переработки самой разной информации. Около ста самых разных вычислительных функций, разнообразие диаграмм, великолепный интерфейс, наличие различных надстроек и дополнительных пакетов, связь с другими приложениями Microsoft Office позволяют решить практически любую задачу. Но все эти задачи успешны, если они связаны с непосредственными действиями пользователя. Основной недостаток заключается в том, что мы не можем без программирования дать компьютеру — нашему исполнителю «запланированное поручение» на несколько шагов вперед. При постоянном решений задач одного и того же
61
2. «Быстрое» программирование
класса такая потребность, в конце концов, появляется. Таким образом, программирование выступает не как самоцель, а как вспомогательное средство, что бы быстрее решить ту или иную задачу. При этом нет необходимости решать комплекс тех проблем, которые возникают при создании проектов в случае чистого программирования — организация ввода и вывода данных, создание вы- числительных процедур, оформление интерфейса и диалога с пользователем, построение графиков и т. д. Мало того, стандартные элементы управления имеют ряд свойств, которые связаны с объектами электронной таблицы, то есть обеспечивают взаимодействие VBA и офисного приложения.
Отметим также, что ячейки ЭТ можно рассматривать как ячейки памяти и, используя формулы и функции, как самой таблицы, так и VBA устанавливать связи между ними, что является достаточно наглядным. Благодаря этой наглядности значительно упрощается процесс отладки программ. И еще раз напомним важную возможность, о которой не стоит забывать — практически все действия, которые предоставлены пользователю в меню электронной таблицы по отношению к ячейкам поддерживаются соответствующими методами и свойствами языка программирования.
Создание пользовательской функции
Следующее наше упражнение, иллюстрирующее очередные возможности VBA — создание пользовательской функции. Это полезно делать в тех случаях, когда необходимой для Вас функции нет в стандартном наборе функций, например формулы теоремы Пифагора. Напомним, что согласно этой теореме, гипотенуза в прямоугольном треугольнике равна корню квадратному из суммы квадратов катетов.
Упражнение 6
1.Откройте чистую рабочую книгу и перейдите в среду программирования VBA.
2.Убедитесь, что в списке рабочих книг в окне Project Explorer есть книга со стандартным именем PERSONAL.XLS. Эта книга шаблонов, как правило, существует на каждом компьютере и в ней хранятся различные макросы, созданные пользователями. Если этой книги нет, то необходимо вернуться в электронную таблицу и записать какой-нибудь простенький макрос с сохранением
62
О «быстром» программировании
его в книге PERSONAL.XLS. Вернувшись в среду программирования в списке рабочих книг увидите PERSONAL.XLS.
3.Двойным щелчком по модулю Module1 книги PERSONAL.XLS вызовите в окне кодов окно для этого модуля.
4.Расположите текстовый курсор внутри окна кодов.Через команды меню Isert/Procedure открываем окно Add Procedure.
5.В этом окне набираем имя процедуры, как всегда предпочи- тая латинский шрифт, например Pifagor.
6.В качестве типа процедуры выбираем Function и нажимаем
OK
7.Теперь в окне кодов появились две строчки
Public Function pifagor()
End Function
8. Вспомнив, что в теореме Пифагора нужно знать значения двух катетов a è b, впечатаем две переменные под этими же именами внутрь скобок
Public Function pifagor(a,b)
9. Теперь пишем саму формулу теоремы Пифагора, и в качестве имени переменной, где будет храниться результат используем имя функции
Pifagor = (a * a + b * b) ^ 0.5
10. Окончательно убеждаемся в том, что в окне модуля книги Module1 книги PERSONAL.XLS записана следующая процедура
Public Function Pifagor(a, b)
Pifagor = (a * a + b * b) ^ 0.5
End Function
11. Переходим на рабочий лист электронной таблицы, размещаем в двух любых ячейках два числа — длины катетов, и для третьей ячейки вызываем мастер функций, а в появившемся окне в категории «Определенные пользователем» находим «нашего» Pifagora. Выбрав эту функцию, убедитесь в ее работоспособности.
Именно таким образом можно электронную таблицу, расположенную на Вашем компьютере обогатить набором необходимых для Вас формул.
63
2. «Быстрое» программирование
Ввод и вывод данных
Наступила пора познакомиться тем, каким образом в VBA можно вводить и выводить данные. Рассмотрим различные варианты.
Ряд элементов управления имеют свойство LinkedCell (Ячейка связи). Если в окне свойств для этого свойства проставить адрес какой-нибудь ячейки, то содержимое этой ячейки и значение Value èëè Text элемента управления будут связаны между собой. Менять это содержимое можно как в элементе управления, так и в ячейке.
Обмен данными с помощью программных кодов происходит в соответствии с правилом: слева от знака ''='' располагается приемник информации, справа — источник. Приводим примеры
Õ1 = Cells(3,8) — в переменную Х1 дублируется содержимое из ячейки, расположенной в 3 строке и 8 столбце.
Cells(3,8) = Õ1 — здесь в ячейку копируется значение переменной. Важно помнить, что старое содержимое ячейки удаляется.
Õ1 = TextBox1.Text — в переменную Х1 копируется текст из элемента управления Text1.
TextBox1.Text = Õ1 в качестве текста в текстовом окне будет представлено содержимое переменной Х1.
Естественно возможны и такие варианты
Cells(3,8) = Label1.Caption
Èëè
Label1.Caption = Cells(3,8)
Кроме того, в VBA существуют специальные функции ввода — вывода данных InputBox и MsgBox. О порядке работы с ними мы познакомим Вас позже.
Âотдельных случаях, когда необходимо собрать разные данные
âодном месте, целесообразно воспользоваться элементом управления UserForm (Пользовательская форма).
Упражнение 7
1.Откройте чистую рабочую книгу.
2.Перейдите на Лист 2 и в ячейку В3 введите три пятерки — 555, затем в ячейку D3 Листа 3 введите три семерки — 777.
64
О «быстром» программировании
3.Через меню Вид/Панели инструментов/Элементы управления откройте панель элементов управления
4.Перейдите в редактор VBA и раскройте, если его нет, окно проектов. Выделите в этом окне строку VBAproject (Книга1). Это книга, в которой Вы работаете.
5.В меню выберите команду Insert/UserForm.
6.После этих действий на экране появится окно с панелью серого цвета, покрытой точечной сеткой. Это и есть пользовательская форма.
7.Через меню View/ToolBox вызовите панель элементов управления, связанную с пользовательской формой
8.Щелчком мыши выделите пользовательскую форму
9.Расположите на этой форме элемент управления Кнопка (CommandButton) и два текстовых окна (TextBox)
10.Откройте окно свойств и если элемент Кнопка выделен, то Вы в этом окне увидите свойства этого элемента.
11.Измените у этого элемента свойство Caption, так чтобы на поверхности кнопки было видно слово «Приветствие»
12.Сделайте двойной щелчок по кнопке и откроется окно кодов для пользовательской формы (ее модуль), в которой будут заготовлены строчки для написания процедуры по щелчок по кнопке
Private Sub CommandButton1_Click()
End Sub
13. Теперь будем вписывать код. Сначала объявляем переменную а как строковую
Dim a As String
Не забывайте следить за типом шрифта. Код пишется латинскими буквами
14. Следующие команды копируют содержимое ячеек из Листа
2 и Листа 3. в текстовые окна
TextBox1.Text = Worksheets(2).Cells(3, 2)
TextBox2.Text = Worksheets(3).Cells(3, 4)
15. Затем вызовем функцию InputBox. Эта функция предлагает пользователю ввести данные (фразы, слова), которые мы запомним в строковой переменной à. Код должен быть таким
a = InputBox(''Как Вас зовут'', ''Знакомство'')
''Как Вас зовут'' — это сообщение для пользователя ''Знакомство'' — это заголовок окна
65
2. «Быстрое» программирование
Пользователь введет свое имя, и оно сохранится в строковой переменной à
16. Теперь вызываем функцию MsgBox, которая просто выводит сообщения, но в сообщение вставим слово «Привет» и имя пользователя
x = MsgBox(''Привет'' & a)
17. Имя, которое ввел пользователь, отправим в ячейки, где у нас были введены цифры.
Worksheets(2).Cells(3, 2) = a
Worksheets(3).Cells(3, 4) = a
18. Общий вид кода
Private Sub CommandButton1_Click() Dim a As String
TextBox1.Text = Worksheets(2).Cells(3, 2) TextBox2.Text = Worksheets(3).Cells(3, 4)
a = InputBox(''Как Вас зовут'', ''Знакомство'') x = MsgBox(''Привет '' & a) Worksheets(2).Cells(3, 2) = a Worksheets(3).Cells(3, 4) = a
End Sub
19.Следующая задача вывести форму вместе с кнопкой на рабочий лист. (Лист1). Для этого в окне проекта выделяем двойным щелчком строку Лист1 (Лист1), и раскрывается окно кодов для этого листа.
20.В верхней строке слева из списка выбираем слово Worksheet (скорее всего, оно там и будет), а справа слово Activate. Тогда редактор предложит написать процедуру под событие «Лист1 стал активным». Вы увидите в окне строки
Private Sub Worksheet_Activate()
End Sub
21. В этой процедуре сделаем так, чтобы пользовательская форма стала видна когда мы откроем Лист1. Полный вид процедуры
Private Sub Worksheet_Activate()
UserForm1.Show
End Sub
22. Программа составлена. Теперь перейдите в рабочую книгу (Лист1), потом откройте лист2 и затем опять откройте (сделайте активным) лист 1. Должна появиться форма. Щелкните по кнопке
66
О «быстром» программировании
и выполните «требования программы». Когда Вы «познакомитесь», проверьте — в ячейках на 2 и 3 листах вместо цифр должен быть текст, введенный при знакомстве.
23. Действий, описанных в пункте 22 можно избежать, если «заказать» процедуру открытия формы под событие Workbook_Open(). Для этого в окне проекта выделяем строчку «Эта книга», в верхней строке окна для кодов выбираем Workbook, а справа выбираем событие Open и создаем процедуру следующего содержания
Private Sub Workbook _Open
UserForm1.Show
End Sub
Форма откроется сразу же при открытии книги.
Данное упражнение иллюстрируется файлами «Ввод-Вывод.xls» и «Ввод-Вывод1.xls».
Быстрое построение графика
Те, кто достаточно хорошо освоил Excel, наверняка представляют себе как можно построить график какой-нибудь функции, где У зависит от Х. Для этого нужно заполнить два столбика — в первом столбике определенное количество значений Х, а во втором — рассчитанные по формуле функции соответствующие значения У. Затем эти два столбика выделяются и с помощью мастера диаграмм строится точечный график. В этом процессе есть одна малоприятная деталь — набор формулы. Вообще, в большинстве языков программирования пользователь созданной программы не может изменять расчетную формулу. Как правило, программирование такой возможности — сложный процесс. Мы расскажем, как просто это можно сделать с помощью VBA.
Сначала об идее — допустим все значения Х, которые нам нужны для построения графика находятся в ячейках А4:А104. Рассчи- танные значения У должны располагаться в диапазоне В4:В104. Для оформления расчетов нам в этот диапазон нужно ввести формулу. Для определенности выберем формулу У=Х^2+X–5. Тогда в ячейке В4 формула будет имеет вид ''=А4^2+A4–5''. Затем, с помощью протаскивания эта формула распространяется на все ячейки диапазона и можно строить график. Но оказывается, что если в объект Range программно вводить формулу, то эта формула будет видоизменена в соответствии с расположением ячеек относительно друг друга. Другими словами, мы пишем формулу только для
67
2. «Быстрое» программирование
первой ячейки, а программа сама ее переделает для остальных. Мало того, мы для удобства пользователя можем создать текстовое окно, куда он будет вводить формулу в естественном виде, а дело программы — превратить ее в расчетную.
Познакомиться с работой этой программы можно в файле «Графики.xls». Код программы с объяснениями предлагается ниже.
Private Sub |
|
CommandButton1_Click() |
|
Dim a As String, b As String, ñ As |
Объявление трех строковых и одной |
String, z As Integer* |
целочисленной переменных |
a = TextBox1.Text |
В переменную а копируем содержимое |
|
текстового окна, то есть формулу. |
If Not a = "" Then |
В дальнейшем процедура будет |
|
работать, если строка а не пустая. |
c = "=" |
В строковой переменной с начинаем |
|
формировать расчетную формулу, |
|
которая начинается со знака «равно» |
z = Len(a) |
Определяем число символов в |
|
формуле. Для этого используем |
|
встроенную функцию VBA— Len() |
For k = 1 To z |
Начинаем цикл, в котором |
|
анализируем каждый символ. |
b = Mid(a, k, 1) |
Для этого по очереди вырезаем из |
|
формулы по символу (используем |
|
функцию VBA — mid()), помещаем его |
|
в переменную b |
If b = "x" Or b = "X" Then b = "a4" |
И если этим символом является х или |
|
Х, то заменяем его на А4 |
c = c + b |
В переменную с добавляем очередной |
|
символ, но теперь вместо х там будет |
|
À4 |
Next k |
Конец конструкции For Next |
End If |
Конец конструкции If EndIf |
Worksheets("Graf"). |
Расчетную формулу вводим в диапазон |
Range("b4:b104") = c |
''b4:b104'' |
End Sub |
|
|
|
* — Из-за технических причин строка кода в таблице может быть разбита на несколько. В программном коде это недопустимо, или используют специальные приемы.
68
О «быстром» программировании
Выделяем ячейку...и получаем массу возможностей
Основная задача этого примера — показать, какие еще возможности VBA можно использовать при вызове процедур через событие. Среди событий рабочего листа обратим внимание на событие SelectionChange, которое запускает процедуру с именем
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
При работе этой процедуры используется переменная с именем Target, а тип этой переменной — Range, то есть диапазон выделенных ячеек. Это означает, что данная процедура в качестве переменной запоминает выделенные ячейки, и открывается возможность программно их обрабатывать. Это представляется удобным в тех случаях, когда в электронной таблице различные данные трудно собрать для обзора в одной зрительной зоне. Как правило, это различные каталоги, подробные списки сотрудников, оборудования и т. д. Было бы неплохо, если бы при выборе какой-нибудь строки появилась возможность увидеть всю строку в компактном виде, и, если есть необходимость, обработать ее. Рассмотрим пример, в котором необходимо отредактировать вопросы теста. (Файл «Вывод в форму»). Так получилось, что в исходном файле вопросы теста, справочная информация и заголовок темы повторяются, в то время как ответы на вопросы расположены в четырех строках, следующих друг за другом. При написании процедуры была поставлена цель — собрать в одном месте заголовок темы, вопрос, 4 ответа, и отметку «+» около правильного ответа. Прежде чем рассматривать коды примера, отметим, что заголовок темы располагается в 1-м столбце, вопрос — в 3-м, справочный материал — в 4-м, ответы — в 5-м, и отметка «+» — в 6-м столбцах. Кроме того каждый новый вопрос начинается в 1-й, 5-й, 9-й и т. д. строке. Для наглядности эти строки выделены желтым цветом. Необходимо, чтобы при щелчке пользователя по любой ячейке из этих строк необходимая информация по его желанию выводилась бы в компактном виде. В этом случае целесообразно применить очень эффективный элемент управления UserForm (Пользовательская форма), на которой, в свою очередь размещались элементы управления Надпись (Label) è Кнопка (CommandButton). Вставляется пользовательская форма в проект через команды меню среды VBA
Insert/UserForm. При этом появляется дополнительный модуль, в котором размещаются процедуры, связанные с событиями самой формы и элементов управления, находящихся на ней.
69
2.«Быстрое» программирование
Познакомимся с кодами
Private Sub |
|
Worksheet_SelectionChange |
|
(ByVal Target As Range) |
|
If Target.Count = 1 Then |
Процедура сработает, если будет |
|
выделена только одна ячейка |
x = Target.Row |
В переменной х запомним номер |
|
строки, в которой выделена ячейка |
If x Mod 4 = 1 Then |
Процедура сработает, если х будет |
|
равен 1, 5, 9, 13 и т. д. |
Cells(1, 8) = x |
Значение х копируется в ячейку H1 |
a$ = Str(x) |
И передается в строковую переменную |
otvet = MsgBox(a$, 1) |
Используется функция MsgBox |
If otvet = 1 Then |
Если пользователь «дает согласие», то |
|
выполняется ряд следующих действий. |
b$ = Cells(x, 3) |
Текст вопроса запоминается в |
|
строковой переменной b$ |
UserForm1.Label1.Caption = |
В различные элементы управления, |
Cells(x, 1) |
расположенные на форме копируется |
|
содержимое ячеек рабочего листа, |
|
имеющих отношение к выбранному |
|
вопросу. |
UserForm1.Label2.Caption = b$ |
|
UserForm1.Label3.Caption = |
|
Cells(x, 4) |
|
UserForm1.Label4.Caption = |
|
Cells(x, 5) |
|
UserForm1.Label5.Caption = |
|
Cells(x + 1, 5) |
|
UserForm1.Label6.Caption = |
|
Cells(x + 2, 5) |
|
UserForm1.Label7.Caption = |
|
Cells(x + 3, 5) |
|
UserForm1.Label8.Caption = |
|
Cells(x, 6) |
|
UserForm1.Label9.Caption = |
|
Cells(x1, 6) |
|
UserForm1.Label10.Caption = |
|
Cells(x + 2,6) |
|
UserForm1.Label11.Caption = |
|
Cells(x + 3,6) |
|
UserForm1.Show |
Форма становится видимой |
|
|
70
