Уокенбах Формулы в Excel
.pdfПеременные, описанные типом Date, показывают даты в соответствии с кратким системным форматом даты, а время отображается в соответствии ссистемным форматом времени (либо 12-часовым, либо 24-часовым). Системные настройки можно изменить с помощью аплета Язык и региональные стандарты папки Панель управления в Windows.
Использование выражений присвоения
Выражением присвоения называется оператор VBA, в котором вычисляется результат и присваивается переменной или объекту. Выражением называется комбинация ключевых слов, операторов, переменных и констант, которая возвращает строки, числа и объекты. Выражение может выполнить вычисление, оперировать символами или проверять данные.
Если у вас не возникало трудностей с созданием формул в Excel, то при создании выражений в VBA тоже их не должно добавиться. При введении формулы на рабочем листе в Excel результат отображается в ячейке. Подобно этому выражение VBA можно присвоить переменной или использовать его в качестве значения операнда.
В VBA в качестве оператора присвоения используется знак равенства (=). Обратите внимание на следующие примеры присвоения (выражения расположены справа от знака равенства):
х = 1
X = X + 1
х = (у * 2) / (z * 2) MultiSheets = True
В выражениях часто используются функции. Это могут быть встроенные функции VBA, функции рабочих листов Excel или пользовательские функции, созданные в VBA. О встроенных функциях VB А рассказывается далее в этой главе.
Главную роль в VBA играют операторы. Математические действия описываются уже знакомыми операторами, а именно: суммирования (+), умножения (*), деления (/), вычитания (-), возведения в степень (л ) и объединение строк (&). Менее известный оператор, например, обратная косая (\), используется при целочисленном делении, а оператор Mod используется в модульной арифметике. Оператор Mod возвращает остаток деления двух целых чисел. Например, результат следующего выражения равняется 2:
17 Mod 8
Возможно, вам уже знакома функция MOD. Заметьте, что в VBA Mod является оператором, а не функцией.
VBA поддерживает операторы сравнения, используемые в формулах Excel: равно (=), больше чем (>), меньше чем (<),больше или равно (>=), меньше или равно (<=) и неравно ( о ) . Кроме того, VBA предлагает полный набор логических операторов, приведенных в табл. 24.2. Читайте справочную систему, чтобы получить дополнительную информацию и примеры по работе этих операторов.
[Таблица 24.2. Логические операторы VBAЧ ; ч"^хкр:'';^''^ ЛТГ"^ЙШЩ$$5
Оператор |
Действие |
N o t |
Выполняет логическое отрицание ввыражении |
And |
Выполняет логическое объединение двух выражение |
or |
Выполняет логическое вычитание двух выражений |
х о г |
Выполняет логическое исключение вдвух выражениях |
520 |
Часть VI.Разработкапользовательских функций |
|
Окончаниетабл. 242 |
Оператор |
Действие |
E q v |
Выполняет логическое приравнивание двух выра |
imp |
Выполняет логическое включение двух выражен |
Приоритет выполнения операторов в VBA такой же, как и в Excel. Но можно поставить круглые скобки и изменитьего.
Использование массивов
Массивом называется группа элементов одного типа с одним именем; обращение к определенному элементу массива осуществляется с помощью его имени и индекса элемента. Например, определим массив из 12 строковых переменных, в котором каждая переменная является именемодного из 12 месяцев. Если массив назвать MonthNames, то к первому элементу можно обратиться, написав MonthNames (0),ковторому — MonthNames (1) итак далее доMonthNames(11).
Объявление массива
Массив объявляется оператором Dimили Public, каки обычная переменная. В массиве можно объявить сразу несколько элементов. Дляэтого нужно указать первый индекс, а затем ключевое слово То и последний индекс — все в круглых скобках. Например, вот какобъявляется массив, состоящий из 100 целых чисел:
Dim MyArrayd To 100) As Integer
При объявлении массива можно указать только первый его элемент, приэтом в VBA (по умолчанию) предполагается, что 0 — первый элемент. Следовательно, выражения ниже приводят к одинаковому результату:
Dim MyArray(0 to 100) As Integer Dim MyArray(lOO) As Integer
В обоих случаях массив состоит из 101 элемента.
Если первым элементом для всех массивов, в которых указан только их последний элемент, должна выступать единица, то перед любой процедурой в модуле введите следующее выражение:
Option Base I
Если такое выражение присутствует в модуле, то следующие два выражения выдадутодинаковый результат (в обоих описывается массив из 100элементов):
Dim MyArrayd to 100) As Integer Dim MyArray(lOO) As Integer
Описание многомерных массивов
В предыдущем разделе приведены примеры одномерных массивов. Массивы в VBA могут иметь до 60 размерностей, хотя редко используется больше 3-х (3-Dмассив). В следующем выражении описывается двумерный (2-D) массив, состоящий из 100 целых чисел:
Dim MyArrayd To 10, 1 То 10) As Integer
Глава24. Принципыпрограммированияна VBA |
521 |
Такой массив похож на матрицу размером 10x10. Чтобы обратиться к определенному элементу двухмерного массива, следует указать два индекса. Вот как присвоить значение элементу вышеописанного массива:
МуАггау(3,4) =12 5
В динамическом массиве нетзаранее заданного количества элементов. В случае динамического массива вкруглых скобках ничего не ставится:
Dim MyArray() As Integer
Однако перед использованием динамического массива в коде необходимо воспользоваться оператором ReDim, чтобы указать VBA, сколько элементов находится в массиве (или ReDim Preserve, если в массиве нужно сохранить существующие значения). Оператор ReDim можно использовать неоднократно, изменяя размерность массива столько раз, сколько это необходимо.
Более подробно массивы рассмотрены далее в этой главе в разделах, в которых повествуется оциклах.
Использование встроенных функций VBA
В VBA есть множество встроенных функций, упрощающих вычисление и выполнение операций. Многие из функций VBA схожи (илиидентичны) с функциями рабочих листов Excel. Например, функция VBA UCase, которая изменяет регистр строкового аргумента с нижнего наверхний, эквивалентен функции ПРОПИСНрабочего листа Excel.
Чтобы отобразить список функций VBA вовремя написания кода, введите VBA и поставьте точку. Редактор VBA отобразит список всех функций (рис. 24.1). Если ничего непроизошло исписок не отобразился, убедитесь, что активизирован параметр Auto List Members. Выберите Tools^Options и перейдите на вкладку Editor. Кроме функций в отображенный список входят встроенные кон-
станты. Функции VBA описаны в справочной системе. Чтобы |
просмотреть |
справку, подведите указатель кимени функции инажмите клавишу |
<F1>. |
^VBAProfect (ВоокЗ)
-r:> Мю-osoft Excel Objects
§Sheet 1 (Sheet 1) ThisWorkbook
-; -1** Modules
,$£ VBAProject (Book4)
-?,лMicrosoft Excel Objects
§Sheet1 (Sheet 1) ThisWorkbook
j(General) |
1REVERSETEXT |
zl |
|
/ei-sed |
|
|
t) |
|
l - TextLen • •o 1 Step -1 |
|
|
REVERSETEXT • |
REVERSETEXT С vba. |
|
1--Л LTrim$
\ Math
>Щ
i-л Midi ил MidB i:^MtdB$ ;-Л Minute
Рис. 24.1.Отображения спискафункций VBA вредакторе VBA
522 |
Часть VI. Разработка пользовательских функций |
Ниже приведено выражение, в котором вычисляется квадратный корень с помощью функции Sqr, а результат присваивается переменной х.
х = Sqr(MyValue)
Имея представление о функциях VBA, можно избавить себя от большого объема работы. Например, рассмотрим процедуру функции REMOVESPACES, о которой рассказывалось в начале этой главы. В этой функции для проверки каждого символа строки используется цикл For-Next, а затем создается новая строка. Намного проще (и более эффективно) использовать функцию Replace. Ниже приведена новая версия процедуры функции.
Function REMOVESPACES(cell) As String
1 |
Удаляет |
пробелы из ячейки |
|
REMOVESPACES = Replace(cell, " ", "") |
|
End |
Function |
|
Функция Replace появилась в VBA в Excel 2000. Этой функции нет в болееранних версиях Excel.
Вкоде VB А можно использовать многие (но не все) функции рабочего листа Excel. Чтобы
ввыражении VBA использовать функцию рабочего листа, предверьте имя функции словом WorksheetFunction и точкой.
Для совместимости с более ранними версиями Excel вместо WorksheetFunctionиспользуйте Application. Объект WorksheetFunction появился в Excel 97, он не поддерживается в Excel95. Следующие выражения являютсяэквивалентными:
Result = Application.Max(х, у, z) Result = WorksheetFunction.Max(x, y, z)
Нижеприведенный код демонстрирует использование функцииExcel в выражении VBA. Редко используемая в Excel функция Римское (Roman) преобразует десятичные числа вримские.
DemValue = 1999
RValue = WorksheetFunction.Roman(DecValue)
Переменная RValue содержит строку МСМХСIX. Пользователей приводит в замешательство тот факт, что в Excel нет функции преобразования римских чисел в их десятичный эквивалент. Конечно, можно создать такую функцию. Но стоит ли?
Важно понять,что функцииExcel, для которых представлен эквивалент в VBA, нельзяиспользовать. Например, в VBA нет функции рабочего листа SQRT, потому что в VBA есть собственная версия этой функции— Sqr. Таким образом, следующее выражение вызовет ошибку:
х = Application.SQRT(12 3) 'ошибка
Управление выполнением кода
Некоторые процедуры VBA выполняются от начала и до конца кода. Однако иногда нужно контролировать процесс выполнения, пропуская одни выражения, выполняя другие несколько раз и проверяя условия, чтобы определить, что же будет выполнено далее.
В этом разделе рассмотрено несколько способов контроля за выполнением процедур VB А:
•Конструкция If-Then
• Конструкция Selec t Case
Глава 24. Принципыпрограммирования на VBA |
523 |
•Цикл For-Next
•ЦиклDo While
•ЦиклDo Until
•Выражение On Error
Конструкция If-Then
Вероятно, наиболее часто используемой конструкцией в VBA является If-Then. Эта конструкция является единственным случаем, где выражению предоставляется возможность выбора. В конструкции If-Then используется следующий синтаксис:
If условие Then выполняемые в случае истинности операторы [Else выполняемые в случае ложности операторы]
Конструкция If-Then выполняет один или несколько операторов в зависимости от справедливости условия. Оператор Else вводить необязательно. Если он добавлен, то выполняются специальные операторы даже в случае ложности условия.
В примере следующей процедуры функции структура If-Then представлена без оператора Else. Этопример со временем суток. Время суток выражено дробным значением— например, полдень записывается как0,5. Функция Time в VBA возвращает значение, которое показывает время суток, задаваемое системными часами. В следующем примере функция начинается с присвоения пустой строки переменной GreetMe. Выражение If-Then проверяет время суток. Если время дополудня, точасть Then выполняется ифункция возвращает значение Good Morning.
Function GreetMe()
GreetMe = ""
If |
Time < 0.5 Then GreetMe = "Good Morning" |
End |
Function |
В следующей функции используется две конструкции If-Then. Эта функция возвращает либо Good Morning,либо Good Afternoon:
Function GreetMe()
If |
Time < 0.5 Then GreetMe = "Good Morning" |
If |
Time >= 0.5 Then GreetMe = "Good Afternoon" |
End |
Function |
Обратите внимание, что во второй раз в конструкции If-Then использовался символ >= (больше или равно). Вэтом случае при выполнении функцииучитывается точное время 12:00.
Другим способом является использование в конструкции If-Then оператора Else. Например:
Function GreetMe()
If Time < 0.5 Then GreetMe = "Good Morning" Else _ GreetMe = "Good Afternon"
End Function
Заметьте, что в этом примере используется символ продолжения строки (пробел и подчеркивание); If - Then - Else является одним выражением.
Далее приведен еще один пример использования конструкции If-Then. Процедура функции вычисляет скидку в зависимости от количества (предполагается целое число) товара. Онапринимает один аргумент (количество) и, с учетом этого значения, возвращает соответствующую скидку.
Function Discount(quantity)
If quantity <= 5 Then Discount = 0
524 |
Часть VI. Разработка пользовательских функ |
If quantity >= 6 Then Discount = 0.1 If quantity >= 25 Then Discount = 0.15 If quantity >= 50 Then Discount = 0.2 If quantity >= 75 Then Discount = 0.25
End Function
Обратите внимание, что в этой процедуре выражение If-Then всегда выполняется, а значение Discount изменяется по мере выполнения функции. Возвращаемое значение является конечным.
Во всех приведенных выше примерах конструкции If-Then в выражении Then используется один оператор. Но часто бывает нужно выполнить несколько действий, если условие является верным. Воспользоваться конструкцией If-Then можно и в этом случае, но для обозначения последней операции в блоке Then нужно использовать выражение End If. Ниже приведен пример выполнения двух выражений в случае, когда условие справедливо.
If |
х > 0 |
Then |
у |
= 2 |
|
z |
= 3 |
|
End |
If |
|
Можно |
использовать много операторов в конструкции If-Then-Else. Следующий |
|
пример демонстрирует два выражения при истинном условии и два других выражения — при ложном:
If |
х > 0 Then |
у |
= 2 |
z= 3
Else
у= -2
z= -3 End If
Конструкция Select Case
Конструкция S e l e c t Case используется для предоставления выбора из двух и более опций. Эта конструкция является альтернативой конструкции If-Then-Else. В ней используется следующий синтаксис:
Select Case логическое выражение
[Case список выражений-п
[операторы-п])
[Case Else
[олераторы_по__умолчанию] ] End Select
В следующем примере конструкции S e l e c t Case показан другой способ написания кода из примера GreetMe, представленный в предыдущем разделе:
Function GreetMe() Select Case Time
Case Is < 0.5
GreetMe = "Good Morning" Case 0.5 To 0.75
GreetMe = "Good Afternoon" Case Else
GreetMe = "Good Evening" End Select
End Function
Глава24. Принципыпрограммированияна VBA |
525 |
А вот пример с функцией Discount, в этот раз с использованием конструкции S e l e c t Case:
Function Discount(quantity) Select Case quantity
Case Is <= 5 Discount = 0
Case 6 To 24 Discount = 0.1
Case 25 To 49 Discount = 0.15
Case 50 To 74 Discount = 0.2
Case Is >=75 Discount = 0.25
End Select End Function
Под оператором Case можно вводить любое количество операций; всеони выполняются, если условие верно.
Создание цикла операторов
Циклическая обработка — это процесс повторения группы операторов VBA в процедуре. Количество повторений (итераций) можно задать самому или определить наоснове значений переменных в программе. VBA предлагает несколько конструкций циклов:
•Цикл For-Next
•Цикл Do While
•Цикл Do Unt i 1
Цикл For-Next
В цикле For-Next используется следующий синтаксис:
For счетчик = начало То конец [Step шаг]
[операторы] [Exit For]
[ опера торы] Next [счетчик]
В приведенном ниже примере показано использование цикла For-Next, в котором нет необязательного оператора Step и выражения Exit For.Функция возвращает сумму всех целых чисел в диапазоне (включительно), заданном двумя аргументами.
Function Sumlnteger(first, last) total = 0
For num = first To last total = total + sum
Next num
Sumlnteger = total End Function
А следующая строка возвращает число 55 — сумму всех целых чисел от 1до10.
=SumIntegers(1,10)
526 |
Часть VI. Разработка пользовательскихфунк |
В этом примере num (счетчик переменных в цикле) начинается с первой переменной и увеличивается на 1при каждом повторе цикла. Цикл завершается, когда num равно последней переменной. Переменная t o t a l складывает все значения num, которыеоно принимало во время выполнения цикла.
При использовании цикла For-Next следует иметь ввиду, что счетчик в цикле — не обычная переменная, аособый тип переменной. Поэтому значение счетчика в цикле в коде между операторами For иNext можно изменять. Однако это не очень хорошая идея — при ее реализации могут возникнуть проблемы. Будьте внимательны иследите, чтобы счетчик переменных вцикле кода не изменился.
Чтобы пропустить определенные итерации цикла, воспользуйтесь оператором Step. Ниже приведена функция вычисления суммы чисел между первым ипоследним аргументами через одно значение.
Function Sumlntegers2(first, last) total = 0
For num = first Tolast Step 2 total = total + sum
Next num
Sumlntegers2 = Total End Function
Следующая строка возвращает значение 25, которое является суммой 1, 3, 5, 7и 9.
=SumIntegers2(1,10)
В цикле For-Next может содержаться один или несколько операторов Exit For. Когда встречается этот оператор, цикл тот час же завершается, как показано вследующем примере:
Function RowOfLargest(с) NumRows = Rows.Count
MaxVal = WorksheetFunction.Max (Columns(c)) For r = 1 To NumRows
If Cells (r, c) = MaxVal Then RowOfLargest = r
Exit If Next r
End Function
Функция RowOf Largest принимает номер столбца (от 1 до256) в качестве аргумента и возвращает номер строки с наибольшим значением в этом столбце. Функция начинается с получения количества строк втаблице (значение отличается взависимости отверсии Excel). Это число присваивается переменной NumRows. Максимальное значение встолбце вычисляется функцией MAX Excel, иэто значение присваивается переменной MaxVal.
Цикл For-Next проверяет каждую ячейку встолбце. Если обнаруживается ячейка, равная MaxVal, то номер строки (переменная г,счетчик вцикле) присваивается имени функции, а выражение Exit Forзавершает цикл. Если ненаписать выражение Exit For, цикл продолжит проверять все ячейки столбца, начто может потребоваться довольно много времени!
В предыдущем примере использовались сравнительно простые циклы. Но бывают ситуации, когда в цикле используется несколько сложных выражений, а иногда один цикл For-Next вкладывается вдругой. Далее показан код VBA, вкотором массив 10x10x10 инициализируется значениями -1. Дляэтого используются вложенные циклы For-Next. Когда завершится выполнение трех циклов, каждому из 1000 элементов МуАггау присваивается значение -1.
Dim |
МуАггау(1 to10, lto 10, 1 to 10) |
For |
I = 1 To 10 |
|
For j = 1 To 10 |
Глава24. Принципыпрограммированияна VBA |
527 |
For к = 1 To 10
MyArrayCE, j, k) = -1
Next к
Next j
Next i
ЦИКЛ D OWhile
Другой циклической конструкцией, предлагаемой VBA, является Do While. В отличии от цикла For-Next, Do While выполняется, пока не выполнится определенное условие. В цикле Do While используется следующий синтаксис:
Do [While условие] [операторы]
[Exit Do]
[операторы]
Loop Или:
Do
[операторы]
[Exit Do]
[операторы]
Loop [While условие]
Как видно, в VBA можно поставить условие While в начале или в конце цикла. Разница между этими двумя синтаксисами заключается в выполнении условий. Цикл первого варианта синтаксиса может невыполниться ни разу. Во втором варианте синтаксиса условие всегда выполняется хотя быодин раз.
В следующем примере приведена функция RowOf Largest, записанная с использованием цикла Do While (первый вариант синтаксиса).
Function RowOfLargest(с) NumRows = Rows.Count
MaxVal = Application.Max(Column(c)) r = 1
DoWhile Cells(г, с) о MaxVal r = r + 1
Loop
RowOfLargest = r End Function
Первым значением переменной г является 1,затем оно увеличивается в цикле Do While. Цикл продолжает выполняться, пока не встретится значение ячейки, равное MaxVal. Затем цикл прекращается и функции присваивается значение г. Обратите внимание, что если максимальное значение расположено в первой строке, то цикл выполняться не будет.
В приведенной ниже процедуре использован второй вариант синтаксиса Do While. Цикл всегда выполняется хотя быодин раз.
Function RowOfLargest(с) NumRows = Rows.Count
MaxVal = Application.Max(Columns(c)) r = 0
Do
r = r + 1
Loop While Cells(г, с) о MaxVal RowOfLargest = r
End Function
528 |
Часть VI. Разработка пользовательскихфунк |
В цикле Do While может содержаться один илинесколько операторов Exit Do. Когда встречается оператор Exit Do, цикл сразу прерывается.
Цикл Do Until
Структура цикла Do U n t i l очень похожа на конструкцию Do While. Разница заметна только при выполнении условий. В цикле Do While операторы выполняются, пока условие верно. В цикле Do U n t i l операторы выполняются до техпор, пока условие не станетверным. В цикле Do U n t i l используется такой синтаксис:
Do [Until условие] [операторы]
[Exit Do]
[операторы]
Loop Или:
Do
[ опера торы]
[Exit Do]
[операторы]
Loop [Until условие]
В следующем примере показано применение первого варианта синтаксиса цикла Do U n t i l . В этом коде проще разобраться, поскольку в немнетотрицательного сравнения, используемого в цикле Do While.
Function RowOfLargest(с)
NumRows |
= Rows.Count |
|
MaxVal |
= Application.Max(Columns(c)) |
|
r |
= 1 |
|
Do |
U n t i l ( r , c) = MaxVal |
|
|
r = r + 1 |
|
Loop |
|
|
RowOfLargest = r |
||
End Function
И, наконец, эта же процедура с использованием второго варианта синтаксиса циклаDo U n t i l .
Function RowOfLargest(с) NumRows = Rows.Count
MaxVal = Application.Max(Column(c)) r = 0
Do
r = r + 1
Loop Until Calls(r, c) = MaxVal RowOfLargest = r
End Function
Оператор On Error
Несомненно, прииспользовании функций в формулах в Excel иногда случалось так, что формула возвращала значение ошибки (например, #ЗНАЧ!). Значение ошибки появляется в следующих случаях:
Глава 24. Принципы программирования на VBA |
529 |
