Во второй строке две константы объявлены с помощью одного оператора Const. PIx типы не объявлены, следовательно, эти константы имеют тип Variant. Поскольку значе ние константы никогда не изменяется, ее обычно объявляют с определенным типом.
Область видимости константы зависит от того, в каком месте модуля она объявлена.
•Чтобы константа была доступна только внутри одной процедуры, она должна быть объявлена после оператора Sub или Function. Такая константа называет ся локальной.
•Константа, объявленная перед первой процедурой в модуле, доступна во всех процедурах модуля.
•Чтобы константа была доступа во всех модулях рабочей книги, она должна быть объявлена с ключевым словом Public перед первой процедурой модуля.
Использование в коде именованных констант вместо явно определенных значений и строк предоставляет ряд преимуществ. Например, если в процедуре нужно сослаться на некоторое значение (например, на ставку процента) несколько раз, то лучше объя вить его как константу и применять в выражениях имя константы, а не явное значе ние. Тогда код будет более понятным. Кроме того, изменить значение константы можно в одном операторе, а не в нескольких.
Заставьте себя объявлять все переменные
Чтобы заставить себя объявлять все используемые переменные, включите в первую стро ку модуля VBA следующий оператор:
Option Explicit
Тогда выполнение любой процедуры будет останавливаться при каждой встрече необъяв
ленного имени переменной. Транслятор VBA выведет сообщение об ошибке (Compile
e r r o r : V a r i a b l e n o t d e f i n e d ) |
и вам поневоле придется объявить переменную. |
Использование оператора Option |
E x p l i c i t предотвращает ошибки,, которые трудно обнару |
жить. Допустим, в процедуре используется переменная ОтгрузитьИзделий, однако вы оши бочно ввели одно из обращений к ней как ОтгрузитьИзделй. Транслятор VBA сочтет ее новой переменной со значением о. Никакое сообщение об ошибке сгенерировано не будет, вам о ней сообщит разъяренный клиент, не дождавшийся нужных ему изделий. Если же в модуле
применен оператор Option |
E x p l i c i t , |
подобная ошибка не может остаться незамеченной. |
Чтобы гарантировать вставку оператора O p t i o n |
E x p l i c i t в каждый новый |
модуль VBA, |
установите флажок Require |
Variable |
Declaration |
(Обязательное объявление |
переменных), |
который расположен во вкладке ЕгУ/'/ог(Редактор) диалогового окна (9р//с>/75 (Параметры).
ВСТРОЕННЫЕ КОНСТАНТЫ
В VBA встроено довольно много именованных предопределенных констант, кото рые можно использовать в коде. Допустим, нужно изменить тип активной диаграммы, назначив ей тип графика. Для этого используется следующий оператор (тип графика имеет номер 3):
ActiveChart.ChartType = 3
Однако запомнить номера типов или искать их в справочной системе довольно трудно. Гораздо легче запомнить строку символов, обозначающую тип графика — xlLine. Фактически это именованная константа, имеющая значение 3. Следователь но, оператор, изменяющий тип диаграммы на тип графика, можно записать так:
ActiveChart.ChartType = xlLine
Во время записи макроса в его код вместо явных значений автоматически вводятся встроенные константы.
3 7 0 |
Часть III. Использование VBА |
Использование дат
Конечно, дату можно хранить в строковой переменной, однако тогда она будет не пригодной для операций над датами. Поэтому рекомендуется всегда хранить дату в переменной типа Date.
Переменная типа Date использует 8 байт, в ней можно хранить даты от 1 января 0100 года до 31 декабря 9999 года. Этого диапазона вполне достаточно для самых долгосрочных финансовых прогнозов. Тип Date используется также для хранения данных о времени. В коде VBA дата и время заключаются между двумя символами #.
Диапазон дат, используемых в VBA, намного шире диапазона дат Excel, кото рый начинается с 1 января 1900 года. Поэтому будьте осторожны: в коде VBA, используемом в Excel, не должно быть дат за пределами диапазона Excel.
Ниже приведено несколько примеров объявления переменных и констант типа Date.
Dim Сегодня |
As |
D a t e , |
Начало As Date |
Const |
День |
As |
Date = |
#12/31/1999# ' Это 31 декабря 1999 г . |
Const |
Полдень |
= # 1 2 : 0 0 : 0 0 # |
Даты и время выводятся в формате, определенном в операционной системе. Вы можете изменить параметры форматирования дат и времени в диалоговом окне Свойства: Язык и стандарты, активизируемом с помощью панели управ ления Windows.
Оператор присваивания
Оператор присваивания вычисляет выражение, расположенное справа от знака ра венства, и присваивает результат переменной или объекту, указанным слева от знака равенства. Выражение — это последовательность ключевых слов, операторов, пере менных, констант, чисел, объектов, скобок и т.д., расположенных по определенным правилам. Выражение может вычислять значения, обрабатывать символы, проверять данные и т.д.
Если вы знаете, как создаются формулы Excel, то построить правильное выражение VBA для вас не составит труда. Результат выражения можно присвоить переменной или использовать его в качестве значения свойства. Оператором присваивания VBA является знак равенства (=). Ниже приведено несколько примеров операторов присваивания.
X = 1
X = X + 1
X = {у * 2) / (Z + 2) ЛистСодержитДиаграммы = True
В выражениях допускается использование функций. Это могут быть встроенные функции VBA, функции рабочих листов Excel или процедуры-функции, определенные в модулях УВД. Далее в главе рассматриваются встроенные функции УВД.
В коде УВД используются арифметические операторы и операторы сравнения. К арифметическим относятся хорошо знакомые вам операторы сложения (+), вычита ния (-), умножения (*), деления (/) и возведения в степень (^), а также оператор конкатенации строк (&). Менее известны операторы целочисленного деления (\) и вычисления остатка от деления (Mod).
В кодах УВД поддерживаются те же операторы сравнения, что и в формулах Excel: сравнения (=), больше (>), меньше (<), больше или равно (>=), меньше или равно (<=) и не равно (<>). Кроме того, в УВД представлен полный набор логических опера торов: And, Not, Or и т.д. Приоритеты операторов УВД точно совпадают с приорите-
Глава 14. Принципы программирования на УВД |
3 7 1 |
тами операторов в формулах Excel. Как и в Excel, с помощью скобок можно изменять последовательность выполнения операторов.
Массивы
Массив — это набор элементов одного типа, имеющих общее имя. К отдельному элементу массива можно обратиться с помощью имени массива и индекса элемента. Допустим, определен массив из 12 строковых переменных, в каждой из которых хра нится название месяца. Если назвать массив ИменаМесяцев, ссылка на первый эле мент выглядит так: ИменаМесяцев (0), на второй — ИменаМесяцев (1) и т.д.
Объявление массивов
Массив объявляется с помощью оператора Dim или Public, как и обычная пере менная. В объявлении задается первый индекс, ключевое слово То и последний ин декс — все это в круглых скобках. Ниже приведено объявление массива, содержащего 100 целых чисел.
Dim Массив(1 То 100) As Integer
Если в операторе объявления указан один индекс, то транслятор VBA по умолча нию полагает, что это верхний индекс, а нижний равен 0. Например, следующие два объявления эквивалентны:
Dim |
Массив(О То |
100) |
As I n t e g e r |
Dim |
Массив(100) |
As |
I n t e g e r |
В обоих случаях массив содержит 101 элемент.
Объявление многомерных массивов
в предьщущем разделе были приведены примеры объявления одномерных масси вов. Максимальное количество изменений массива VBA равно 60. Ниже приведен оператор, объявляющий двухмерный массив целых чисел, состоящий из 100 элементов.
Dim Массив2(1 То 10, 1 То 10) As I n t e g e r
Как вы понимаете, этот массив соответствует матрице размерностью 10x10 элемен тов. Чтобы обратиться к отдельному элементу двухмерного массива, нужно указать два индекса. Например, следующий оператор присваивает значение элементу двухмерного массива, объявленного выше:
Массив2 ( 3 , 4 ) = 125
Встроенные функции VBA
в VBA определено довольно много встроенных функций, упрощающих вычисле ния и операции. Многие функции VBA подобны функциям рабочего листа Excel (или идентичны им). Например, функция UCase, которая преобразует символы строкового аргумента к верхнему регистру, эквивалентна функции рабочего листа Excel ПРОПИСН.
Чтобы вывести список функций VBA, введите в окне кода символы VBA. (с точкой в конце). В результате этого редактор Visual Basic выведет подсказ ку— раскрывающийся список, содержащий все встроенные функции VBA. Кроме функций, в списке выводятся имена всех встроенных констант. Каждая функция VBA подробно описана в справочной системе. Для просмотра справ ки по интересующей вас функции установите курсор на ее имени и нажмите клавишу <F1>.
3 7 2 |
Часть III. Использование VBA |
Ниже приведен оператор, вычисляющий квадратный корень переменной у с по мощью функции Sqr. Результат присваивается переменой х.
X = Sqr(у)
В коде VBA можно использовать почти все функции рабочих листов Excel. Для этого перед именем функции рабочего листа должны быть введены имя WorksheetFunction (или Application) и точка*. Ниже приведены два оператора VBA, вычисляющие медиану диапазона AliAlO с помощью функции рабочего листа МЕДИАНА. Приведенные операторы эквивалентны.
X = WorksheetFunction.Median(Range("А1:А10")) X = Application.Median(Range("А1:А10"))
Помните: в коде VBA нельзя применить функцию рабочего листа, для которой есть эквивалентная функция VBA. Например, в коде VBA нельзя вызвать функцию рабочего листа КОРЕНЬ (В оригинальной версии — SQRT), потому что в VBA есть своя версия этой функции — Sqr. Поэтому в результате применения оператора
X = Application . SQRT(у)
ВЫВОДИТСЯ сообщение об ошибке.
Управляющие операторы
в некоторых процедурах VBA выполнение начинается с самого верхнего операто ра, а затем постепенно продвигается строка за строкой вплоть до самого нижнего опе ратора. Однако такие процедуры встречаются редко. В большинстве случаев выполне ние ветвится, т.е. "перескакивает через головы", возвращается назад, часто одни и те же операторы выполняются многократно. Ветвление осуществляется с помощью управляющих операторов, которые, проверяя определенные условия, решают, что нуж но делать дальше.
В этом разделе рассматриваются следующие управляющие конструкции:
•оператор if-Then;
• конструкции Select Case;
• циклы For-Next, For Each-Next;
•операторы on Error.
Конструкция If-Then
Возможно, из всех управляющих операторов наиболее часто в кодах VBA исполь зуется конструкция If-Then. Это одно из средств принятия решений самим кодом. Операторы, расположенные в теле конструкции If-Then, выполняются, если удовле творено определенное условие. Фраза Else не обязательна. Если она есть, то вклю ченные в нее операторы выполняются при неудовлетворении условия.
Ниже приведена процедура Приветствие, содержащая конструкцию If-Then без фразы Else. В примере используется значение текущего времени. В VBA применяется такое же представление дат и времени в виде набора чисел, как и в Excel. Время суток выражено дробным числом, например полдень обозначается числом 0.5. Функция Time возвращает системное время компьютера (время суток). Оператор If-Then используется
*В коде VBA русифицированной версии Excel используются не русские, а исходные (английские) имена функций рабочего листа. Например, функция МЕДИАНА В коде VBA должна быть записана как Median. Конечно, это весьма неудобно, однако этим обеспечивается перено симость кодов VBA между исходными и русифицированными версиями Excel. -— Прим. ред.
Глава 14. Принципы программирования на VBA |
3 7 3 |
для проверки времени суток. Если полдень еще не наступил, то выполняется тело кон струкции Then, в результате чего процедура выводит сообщение "Доброе утро!".
Sub |
Приветствие |
о |
|
If Time < 0.5 |
Then MsgBox "Доброе у т р о ! " |
End |
Sub |
|
В процедуре Приветствие2 используются два оператора If-Then. С их помощью процедура выводит одно из сообщений в зависимости от времени суток.
Sub |
Приветствие2О |
|
|
|
|
If |
Time |
< 0.5 |
Then MsgBox |
"Доброе |
у т р о ! " |
|
If |
Time |
>= 0. |
5 Then |
MsgBox |
"Добрый |
д е н ь ! " |
End |
Sub |
|
|
|
|
|
Обратите |
внимание: во |
второй |
конструкции If-Then используется оператор >=. |
Если бы вместо него был записан оператор >, то ровно в полдень процедура не выве ла бы никакого сообщения. Вероятность этого чрезвычайно мала, попасть ровно в полдень с точностью до микросекунды практически невозможно. Тем не менее в программировании принято всегда записывать операторы сравнения так, чтобы пол ностью покрывать диапазон значений.
Вместо второго оператора if-Then можно применить фразу Else.
Sub |
ПриветствиеЗО |
|
|
|
|
If Time |
< 0.5 Then MsgBox "Доброе |
у т р о ! " _ |
|
|
E l s e |
MsgBox "Добрый |
д е н ь ! " |
|
|
End |
Sub |
|
|
|
|
В процедуре ПриветствиеЗ |
используется |
признак продолжения оператора |
в сле |
дующей строке — пробел и символ подчеркивания; конструкция If-Then-Else |
явля |
ется одним оператором. |
|
|
|
Во всех предыдущих примерах фраза Then (тело условия) содержит единственный оператор. Однако довольно часто при выполнении условия нужно выполнить не сколько операторов. В этом случае, чтобы отметить окончание тела условия, исполь зуется оператор End If. Ниже приведен пример, в котором при удовлетворении усло вия выполняются два оператора.
If |
X > |
о Then |
|
у = |
2 |
|
Z = |
3 |
End |
If |
|
Много операторов может содержать также конструкция If-Then-Else. В следую щем примере первые два оператора выполняются при удовлетворении условия, а по следние два — при неудовлетворении:
If X > о Then у = 2
Z= 3
Else
у= -2
Z= -3 End If
Конструкция Select Case
Конструкция Select Case используется для выбора одного из нескольких вариан тов. Количество вариантов может также равняться двум, в этом случае конструкция Select Case похожа на оператор If-Then-Else. В процедуре Приветствие4 опера тор Select используется для выбора одного из трех вариантов.
3 74 |
Часть III. Использование VBA |
Sub Приветствие4() Select Case Time
Case Is <0.5
MsgBox "Доброе утро!" Case 0.5 To 0.75
MsgBox "Добрый день!" Case Else
MsgBox "Добрый вечер!" End Select
End Sub
После оператора Case можно расположить произвольное количество других опера торов, при выполнении соответствующего условия они все будут выполнены.
Циклы
Циклом называется программная конструкция, обеспечивающая многократное вы полнение набора операторов VBA. Количество итераций цикла может быть известным до начала его выполнения или может определяться во время выполнения цикла в за висимости от значений переменных. Синтаксис VBA предоставляет довольно много различных циклических конструкций, в этом разделе рассматриваются только две из них: циклы For-Next и For Each-Next.
ЦИКЛРОК-КЕХТ
Приведем следующий пример цикла For-Next. Процедура СуммаЦелых вычисляет и выводит сумму целых чисел от 1 до 100.
Sub СуммаЦелых() Сумма = О
For п = 1 То 100 Сумма = Сумма + п
Next п MsgBox Сумма
End Sub
В этом примере переменная п (счетчик цикла) сначала равна 1, а затем, увеличи ваясь с каждой итерацией на 1, становится равной 100, после этого цикл завершается. В переменной Сумма накапливаются значения переменной п, изменяющиеся в итера циях цикла.
Приращение счетчика не обязательно равно 1. Чтобы задать иное приращение, ис пользуется ключевое слово step (шаг). Например, в процедуре СуммаНечетныхЦелых задано приращение счетчика, равное 2:
Sub СуммаНечетныхЦелых() Сумма = О
For п = 1 То 100 Step 2 Сумма = Сумма +п
Next п MsgBox Сумма
End Sub
Используемый в предыдущем примере цикл сравнительно несложный. В теле цик ла расположен всего один оператор. Однако в тело цикла можно включить произ вольное количество операторов, в том числе и другие циклы (в этом случае они назы ваются вложенными). Ниже приведен пример, в котором с помощью вложенных цик лов инициализируется трехмерный массив размерностью 10x10x10. Когда выполнение всех трех циклов завершается, каждый из 1000 элементов массива Массив1 содержит значение -1.
Глава 14. Принципы программирования на VBA |
375 |
Dim Массив!(1 To 10, 1 To 10, 1 To 10) For i = 1 To 10
For j = 1 To 10 For к = 1 To 10
Массив!(i, j, k) = -1 Next к
Next j Next i
ЦИКЛ FOR EACH-NEXT
В процедурах VBA часто необходимы циклы, перечисляющие элементы коллекции. Коллекция -- это набор похожих объектов. Например, коллекция Workbooks состоит из всех открытых рабочих книг. Коллекция charts состоит из всех листов диаграмм, входящих в рабочую книгу. Коллекция Sheets состоит из всех рабочих листов и лис тов диаграмм. Все ряды диаграммы включены в коллекцию SeriesCollection.
Приведенный ниже код выводит имена всех рядов активной диаграммы, причем каждое имя — в отдельном окне сообщений.
Sub |
ИменаРядовО |
|
Dim |
S As S e r i e s |
|
For Each s In ActiveChart.SeriesCollection |
|
MsgBox s.Name |
End |
Next |
s |
Sub |
|
|
|
В предыдущем примере s — это имя переменной. В нем нет ничего особен |
|
|
ного, вы можете заменить его любым другим правильным именем перемен |
|
|
ной, например Ряд. |
Ниже приведен пример цикла, в котором перечисляются все ячейки диапазона и выводится их сумма.
Sub СуммаЯчеек() Dim с As Range
Dim Сумма As Double Сумма = О
For Each с In Range("Al:C100") Сумма = Сумма + с
Next с MsgBox Сумма
End Sub
Обработка ошибок
Во время выполнения кода VBA иногда происходят ошибки. В коде VBA можно задать способы реагирования на ошибки. Во многих случаях ошибку можно просто проигнорировать без вреда для выполняющейся процедуры. Чтобы транслятор VBA игнорировал каждую ошибку и переходил к выполнению следующего оператора, буд то ничего не произошло, нужно расположить в начале процедуры оператор
On Error Resume Next
Процедура УдалениеДиаграммы пытается удалить из рабочего листа диаграмму Диаграмма1. Если такой диаграммы не существует, возникает ошибка. Оператор On Error вынуждает транслятор VBA игнорировать ее и не выводить никаких сообщений об ошибках.
3 7 6 |
Часть III. Использование VBA |
Sub УдалениеДиаграммы() On Error Resume Next
ActiveSheet.ChartObj ects("Диаграмма!").Delete End Sub
Иногда выполняемый код должен выяснить, были сгенерированы ошибки, или нет, и в зависимости от этого что-либо предпринять. Обнаружить прошлые ошибки можно с помощью свойства Number объекта Err, возвращающего количество сгенерированных ошибок. Если значение Err.Number не равно нулю, значит, ошибки происходили.
Приведенная ниже процедура пытается активизировать диаграмму. Если указанной диаграммы не существует, то значение Err.Number не равно нулю и код выводит со ответствующее сообщение.
Sub АктивизацияДиаграммы() On Error Resume Next
ActiveSheet.ChartObject("Диаграмма!).Activate If Err.Number <> 0 Then _
MsgBox "Ошибка: указанной диаграммы не существует!"
End Sub
Можно также задать выполнение кода, начиная с определенной метки, если произошла ошибка. В приведенной ниже процедуре оператор On Error определя ет, что при возникновении ошибки управление передается оператору, обозначен ному меткой ml.
Sub АктивизацияДиаграммы() On Error Goto ml
ActiveSheet.ChartObjects("Диаграмма1").Activate 'Здесь располагаются другие операторы процедуры Exit Sub
ml:
MsgBox "Выполнение прервано!" End Sub
Использование диапазонов
Диаграммы выводят данные, хранящиеся в диапазонах. Следовательно, используя код VBA, нужно уметь работать с диапазонами. Материал этого раздела имеет практи ческую направленность, на полный охват данной темы раздел не претендует. Более подробно о работе с диапазонами вы можете узнать из справочной системы.
Обращение к диапазону
вкоде VBA на диапазон можно сослаться одним из следующих способов:
•как на свойство Range;
•как на свойство Cells;
•как на свойство offset.
Свойство Range
с помощью свойства Range (являющегося одновременно объектом) можно со слаться непосредственно на любую ячейку диапазона, указав адрес или имя ячейки. Приведенный ниже оператор присваивает переменной I n i t значение ячейки А1. Оператор обращается к свойству Value объекта Range.
Init = Range("Al").Value
Глава 14. Принципы программирования на VBA |
3 7 7 |
Кроме свойства Value, у объекта Range есть и другие полезные свойства. Напри мер, следующий оператор с помощью свойства Count подсчитывает количество ячеек диапазона и присваивает его переменной Cnt:
Cnt = Range("А1:СЗ00") . Count
Свойство Cells
Еще один способ обратиться к диапазону состоит в использовании свойства Cells. Свойство Cells принимает два аргумента (номер строки и номер столбца) и возвра щает ссылку на одну ячейку. Следующий оператор присваивает переменной Ячейка значение, хранящееся в ячейке А1:
Ячейка = C e l l s d , 1) .Value
Свойство Offset
Свойство Offset (смещение) возвращает объект Range. Оно используется со вместно с диапазоном, относительно которого вычисляется результирующий сме щенный диапазон. Два аргумента свойства Offset определяют смещение относи тельно верхней левой ячейки исходного диапазона. Первый аргумент определяет смещение по строкам, а второй — по столбцам. Аргументы могут быть положи тельными (смещение вниз или вправо), отрицательными (смещение вверх или влево) или равными нулю.
Приведенный ниже оператор вычисляет значение одной ячейки, расположенной под ячейкой А1 (т.е. ячейки А2), и присваивает его переменной СледующаяЯчейка.
СледующаяЯчейка = R a n g e ( " А 1 " ) . O f f s e t ( 1 , 0 ) . V a l u e
Некоторые полезные свойства диапазонов
в предыдущих примерах использовалось свойство диапазонов Value. Однако, кроме Value, в VEA определены многие, другие свойства диапазонов. В следующих разделах кратко рассматриваются наиболее полезные из них. Более подробную ин формацию о свойствах вы можете найти в справочной системе Excel.
СВОЙСТВО FORMULA
Это свойство возвращает хранящуюся в ячейке формулу в виде строки. Если попытаться обратиться к свойству Formula диапазона, содержащего больше од ной ячейки, то будет возвращено сообщение об ошибке. Если ячейка не содержит формулу, то свойство Formula возвращает значение ячейки. Следующий оператор выводит в окне сообщений формулу ячейки А1, расположенной в активном рабо чем листе:
MsgBox Range("Al").Formula
Кроме того, в VBA определено свойство HasFormula, возвращающее значение True или False в зависимости от того, содержит ли ячейка формулу.
с в о й с т в о ADDRESS
Данное свойство возвращает адрес диапазона в виде строки. По умолчанию оно возвращает адрес как абсолютную ссылку (например, $А$1:$С$12). Приведенный ниже оператор выводит адрес вьщеленного диапазона.
MsgBox Selection.Address-.
3 7 8 |
Часть Ш. Использование VBA |
с в о й с т в о COUNT
Это свойство возвращает количество ячеек диапазона. Следующий оператор выво дит количество ячеек диапазона А1:М200:
MsgBox Range("А1:М200").Count
СВОЙСТВА COLUMNS И ROWS
Данные свойства возвращают столбцы или строки диапазона. Например, сле дующий оператор с помощью свойства Count выводит количество столбцов диа пазона В5:К32:
MsgBox Range ("В5:К32").Columns.Count
Глава 14. Принципы программирования на VBA |
3 7 9 |