VBAимеет условный оператор перехода для использования в случаях, когда необходимо выбирать из большого количества различных ветвей кода: операторSelect Case (с его помощью очень удобно реализовывать структуру множественного выбора).Он работает во многом так же, как множество независимых операторовIf ,но он более понятен для того, кто пишет код, и того, кто читает этот код. Этот оператор более эффективен, чем операторIf … Then … Else .
Ключевые слова Select Case используются со многими операторамиCase ,где каждый операторCase проверяет появление другого условия и выполняется только одна из ветвейCase .ВетвьCase может содержать один, несколько или ни одного оператораVBA.
Select Case – управляющий оператор, выполняющий один из нескольких блоков операторов в зависимости от значения выражения.
Select Case Выражение_выбора
[ Case Список_выражений_1
[Блок_операторов_1]
[Case Список_выражений_2 ]
[Блок_операторов_2]]
……………………………………………………………………………
[Case E lse
[Блок_операторов_N]]
E nd S elect
– Выражение_выбора – любое числовое или символьное выражение;
– Список_выражений – каждый из списков представляет собой список логических выражений, отделенных запятыми; имеют тот же тип, что и выражение_выбора;
– Блок_операторов – содержит любое количество операторов VBA.
При выполнении оператора Select Case VBA сначала оценивает Выражение_выбора, а затем сравнивает результат этого выражения с каждым выражением, перечисленным в каждом Списке_выражений. Если значение, представленное с помощью Выражение_выбора совпадает с выражением в Списке_выражений для одного из Case ,VBA выполняет Блок_операторов для этого предложения Case .Если значение Выражение_выбора совпадает более, чем с одним оператором Case ,VBA выполняет только операторы в первом совпадающем предложении Case .Часто Выражение_выбора – это просто имя одной переменной, математическое или численное, а не логическое выражение. Выражения в Списке_выражений – это обычно логические выражения.
После завершения выполнения операторов в первом совпадающем операторе Case VBA продолжает выполнение кода с первого оператора после ключевых слов End Select ,которые обозначают конец Select Case .
Если значение Выражение_выбора не совпадает ни с каким из Case ,а необязательный Case Else присутствует, VBA выполняет операторы, представленные с помощью Блок_операторов_N перед переходом к оператору после Select Case . Блок операторов Case E lse выполняется только в том случае, если Выражения_выбора не удовлетворяет ни одному из условий Case . Обычно используется для обработки нежелательных значений. Действие оператора Select Case поясняется блок-схемой, приведенной на рис. 5.
Рис 5. Блок-схема конструкции Select Case
Элементы Списка _ выражений должны иметь одну из следующих трех форм:
Выражение_1,Выражение_2, …, Выражение_N
Выражение Т o Выражение
I s Выражение с операцией
– Выражение_ – любое числовое, символьное или логическое выражение того же типа, что и выражение выбора;
– Выражение с операцией – выражение, содержащее любую из следующих операций: <, <=, >, >=, < >, =.
Если используется ключевое слово Тo для определения пределов выражения, то меньшее значение должно быть первым. Например, операторы блока Case -1 To -5 не выполняются, если Выражение _ выбора равно -4. Эта строка должна быть написана как Case -5 To -1 .
Операции сравнения можно использовать только с ключевым словом Is , за исключением операции равенства. При отсутствии ключа Is в нужном месте интеллектуальный редактор вставит его.
Можно использовать несколько выражений или пределов в каждом условии Case . Например, Case 1 TO 4, 7 TO 9, 11, 13, Is > n % .
Пример 4. Программа, рассчитывающая скидку в зависимости от суммы покупки.
Sub skidka()
" Определение скидки (в %) в зависимости от
" количества продаваемого товара
Dim skidka As Integer
Dim summa As Single
summa = InputBox ("Введите сумму покупки", "Расчет скидки", 0)
If summa > 0 Then
Select Case summa
Case Is > 1000
Case Is > 500
Case Else
End Select
MsgBox "Скидка" & skidka & "%"
MsgBox "Сумма покупки не указана"
Конструкция Select Case является альтернативой конструкции If . . . Then . . . Else в случае выполнения блока, состоящего из большого набора операторов. Конструкция Select Case предоставляет возможность, похожую на возможность конструкции If . . . Then . . . Else, но в отличие от нее она делает код более читаемым при наличии нескольких вариантов выбора.
Конструкция Select Case работает с единственным проверяемым выражением, которое вычисляется один раз при входе в эту конструкцию. Затем VBA сравнивает полученный результат со значениями, задаваемыми в операторах Case конструкции. Если найдено совпадение, выполняется блок операторов, ассоциированный с оператором Case:
Select Case проверяемое_выражение
[блок_операторовn]]
Каждый список выражений является списком из одного или более значений. Если в одном списке больше одного значения, они отделяются запятыми. Каждый блок операторов содержит несколько операторов или ни одного. Если окажется, что вычисленному значению проверяемого выражения соответствуют значения из нескольких операторов Case, то выполняется блок операторов, ассоциированный с первым оператором Case из всех найденных соответствий. VBA выполняет блок операторов, ассоциированный с оператором Case Else (заметим, что он необязателен), если не найдено ни одного соответствия проверяемого значения выражения и значений из всех списков операторов Case.
Рассмотрим пример вычисления функции
Sub пример2()
Const pi2 = 1.57
Let x = CSng(InputBox("введи x", "Ввод данных", 0))
MsgBox "Неверные исходные данные!"
Call out("D1", z)
Заметим, что конструкция Select Case вычисляет выражение только один раз при входе в нее, а в конструкции If . . . Then . . . Else вычисляются различные выражения для каждого оператора Elself. Конструкцию If . . . Then . . . Else можно заменить конструкцией Select Case, только если оператор If и каждый оператор Elself вычисляют одно и то же выражение.
Операторы цикла. Вложенные циклы
1.Операторы цикла
2.Вложенные циклы
1. Операторы цикла.
Циклы позволяют выполнить одну или несколько строк кода несколько раз. VBA поддерживает следующие циклы:
Конструкция For . . . Next. Когда число повторений известно заранее, используют цикл For . . . Next. В цикле For используется переменная, называемая переменной цикла или счетчиком цикла, которая увеличивается или уменьшается на заданную величину при каждом повторении цикла. Синтаксис этой конструкции следующий:
For counter = start To end
операторы
Параметры counter (счетчик), start (начало цикла), end (конец цикла) и increment (приращение) являются числовыми.
Примечание. Параметр increment может быть как положительным, так и отрицательным. Если он положителен, параметр start должен быть меньше или равен параметру end, иначе цикл не будет выполняться. Если параметр increment отрицателен, то параметр start должен быть больше или равен значению параметра end, чтобы выполнялось тело цикла. Если параметр Step не задан, то значение параметра increment по умолчанию равно 1.
VBA выполняет цикл For в следующей последовательности:
1. Устанавливает значение переменной цикла counter в значение start.
2. Сравнивает значение переменной цикла counter и значение параметра end. Если переменная counter больше, VBA завершает выполнение цикла. (Если значение параметра increment отрицательно, то VBA прекращает выполнение цикла при условии, что значение переменной цикла counter меньше значения параметра end.)
3. Выполняет операторы тела цикла statements.
4. Увеличивает значение переменной цикла counter на 1 или на величину значения параметра increment, если он задан.
5. Повторяет шаги со 2 по 4.
Рассмотрим пример: Вычислить значение функции f(t)
при заданных a, b, n, если t изменяется от a до b с шагом Dt=(b-a)/(n-1).
Sub пример3()
Dim f() As Single
Dim a As Single, b As Single, t As Single, dt As Single
Dim i As Integer, n As Integer
Call read("a1", a) : Call read("b1", b) : Call read("c1", n)
ReDim f(1 To n - 1)
dt = (b - a) / (n - 1) : t = a
Call out("a2", "i") : Call out("b2", "t") : Call out("c2", "f(t)")
For i = 1 To n - 1
If t <= -1 Then
ElseIf t > 1 Then
Call out("a" & (2 + i), i) : Call out("b" & (2 + i), t) : Call out("c" & (2 + i), f(i))
Конструкция For Each . . . Next
Цикл For Each . . . Next похож на цикл For . . . Next, но он повторяет группу операторов для каждого элемента из набора объектов или из массива, вместо повторения операторов заданное число раз. Он особенно полезен, когда неизвестно, сколько элементов содержится в наборе.
Синтаксис конструкции цикла For Each . . . Next таков:
For Each element In group
операторы
Следует помнить следующие ограничения при использовании цикла For Each . . . Next:
Для наборов параметр element может быть только переменной типа variant, общей переменной типа object или объектом, перечисленным в Object Browser
Для массивов параметр element может быть только переменной типа Variant
Нельзя использовать цикл For Each . . . Next с массивом, имеющим определенный пользователем тип, так как переменная типа variant не может содержать значение определенного пользователем типа
Конструкция Do...Loop
Цикл Do применяется для выполнения блока операторов неограниченное число раз. Существует несколько разновидностей конструкции Do . . . Loop, но каждая из них вычисляет выражение-условие, чтобы определить момент выхода из цикла. Как и в случае конструкции If . . . Then условие должно быть величиной или выражением, принимающими значение False (нуль) или True (не нуль).
В следующей конструкции Do . . . Loop операторы выполняются до тех пор, пока значением условия является True (Истина):
Do While условие
операторы
Выполняя этот цикл, VBA сначала проверяет условие. Если условие ложно (False), он пропускает все операторы цикла. Если оно истинно (True), VBA выполняет операторы цикла, снова возвращается к оператору Do While и снова проверяет условие.
Следовательно, цикл, представленный данной конструкцией, может выполняться любое число раз, пока значением условия является не нуль или True (Истина). Отметим, что операторы тела цикла не выполняются ни разу, если при первой проверке условия оно оказывается ложным (False).
Рассмотрим пример: Вычислить сумму ряда
с заданной точностью.
Sub пример4()
Dim e As Single, x As Single, s As Single
Dim m As Single, p As Single, i As Single
Call read("a1", x) : Call read("b1", e)
s = 0: i = 1: m = 1: p = -1
Call out("a2", "i") : Call out("b2", "m") : Call out("c2", "s")
Do While Abs(m) >= e
Call out("a" & (2 + i), i) : Call out("b" & (2 + i), Abs(m)) : Call out("c" & (2 + i), s)
Другая разновидность конструкции Do . . . Loop сначала выполняет операторы тела цикла, а затем проверяет условие после каждого выполнения. Эта разновидность гарантирует, что операторы тела цикла выполнятся по крайней мере один раз:
операторы
While условие
Две другие разновидности конструкции цикла аналогичны предыдущим, за исключением того, что цикл выполняется, пока условие ложно (False):
Цикл не выполняется вообще или выполняется много раз:
Do Until условие
операторы Loop
Цикл выполняется по крайней мере один раз:
операторы
Условия являются очень полезными при программировании, поскольку позволяют нам выполнять действия, в зависимости от установленных критериев (используется такой же принцип как и в IF функции Excel).
Наиболее важной функцией, которая задает условие является IF и сейчас мы посмотрим, как она работает:
If [УСЛОВИЕ ЗДЕСЬ] Then "=> ЕСЛИ условие верно, ТОГДА "Инструкции, если "правда" Else "=> В ПРОТИВНОМ СЛУЧАЕ "Инструкции, если "ложь" End If
Давайте перейдем к практике и вернемся к примеру, который мы использовали в уроке с переменными. Цель этой процедуры была в том, чтобы открыть диалоговое окно, которое бы содержало значение из строки, указанного в ячейке F5 :
Если вы введете букву в ячейку F5 , это повлечет ошибку. Мы хотим предотвратить это.
Sub variables () "Декларирование переменных Dim last_name As String, first_name As String, age As Integer, row_number As Integer "Присвоение значений переменным row_number = Range("F5") + 1 last_name = Cells(row_number, 1) first_name = Cells(row_number, 2) age = Cells(row_number, 3) "Диалоговое окно MsgBox last_name & " " & first_name & "," & age & " лет" End Sub
Давайте добавим условие, которое будет проверять - является ли введенное значение в ячейку F5 числом, перед тем, как код будет выполнен.
Мы воспользуемся функцией IsNumeric для проверки условия:
Sub variables () "Если значение в скобках (ячейка F5) является числовым (И ПОЭТОМУ УСЛОВИЕ IF ЕСТЬ ВЕРНЫМ) тогда "выполнить инструкции, которые следуют после THEN If IsNumeric (Range ("F5")) Then "Декларирование переменных Dim last_name As String, first_name As String, age As Integer, row_number As Integer "Присвоение значений переменным row_number = Range ("F5") + 1 last_name = Cells (row_number, 1) first_name = Cells (row_number, 2) age = Cells (row_number, 3) "Диалоговое окно MsgBox last_name & " " & first_name & "," & age & " лет" End If End Sub
Нам также нужно прописать инструкции, если поставленное нами условие не выполнится:
Sub variables () If IsNumeric (Range ("F5")) Then "Если условие выполняется "Декларирование переменных Dim last_name As String, first_name As String, age As Integer, row_number As Integer "Присвоение значений переменным row_number = Range ("F5") + 1 last_name = Cells (row_number, 1) first_name = Cells (row_number, 2) age = Cells (row_number, 3) "Диалоговое окно MsgBox last_name & " " & first_name & "," & age & " лет" Else "Если условие не выполняется "Диалоговое окно: предупреждение MsgBox "Введенное значение " & Range ("F5") & " не является верным!" "Удаление содержимого ячейки F5 Range ("F5").ClearContents End If End Sub
Теперь нечисловое значения не повлечет никаких проблем.
Работая с нашим массивом, который содержит 16 строк данных, наш следующий шаг будет в проверке является ли переменная row_number: "больше чем или равно 2" и "меньше чем или равно 17".
Но сначала взглянем на операторы сравнения:
и эти полезные операторы:
Теперь давайте добавим одно из выше указанных условий AND между операторов сравнения:
Sub variables () If IsNumeric (Range ("F5")) Then "Если числовое значение Dim last_name As String, first_name As String, age As Integer, row_number As Integer row_number = Range ("F5") + 1 If row_number> = 2 And row_number
Если мы хотим сделать наш макрос более практичным, мы можем заменить 17 на переменную, которая бы содержала количество строк. Это бы позволило нам добавлять и удалять строки из массива без необходимости изменять этот лимит каждый раз.
Для того, чтобы сделать это, мы должны создать переменную nb_rows и добавить эту функцию.
В этом случае, мы используем функцию WorksheetFunction.CountA , которая является аналогом функции COUNTA в самом Excel.
Мы хотим, чтобы эта функция подсчитала количество непустых ячеек в первой колонке по записала полученное значение в переменную nb_rows :
Sub variables () If IsNumeric (Range ("F5")) Then "ЕСЛИ ЧИСЛО Dim last_name As String, first_name As String, age As Integer, row_number As Integer Dim nb_rows As Integer row_number = Range ("F5") + 1 nb_rows = WorksheetFunction.CountA (Range ("A:A")) "Функция подсчета количества строк If row_number > = 2 And row_number
ElseIf
ElseIf дает возможность добавлять дополнительные условия после IF команды:
If [УСЛОВИЕ 1] Then "=> ЕСЛИ условие 1 верно, ТОГДА "Инструкции 1 ElseIf [УСЛОВИЕ 2] Then "=> ЕСЛИ условие 1 неверно, но условие 2 верно, ТОГДА "Инструкции 2 Else "=> ИНАЧЕ "Инструкции 3 End If
Если УСЛОВИЕ 1 выполняется, Инструкция 1 будет выполнена и покинет оператор IF (который начинается с IF и заканчивается End If). Если УСЛОВИЕ 2 принимает значение " ложь ", тогда будет выполнена Инструкция 2 , и если она в свою очередь возвращает " ложь ", тогда Инструкция 3 (под Else ) будет выполнена.
Sub scores_comment () "Переменные Dim note As Integer, score_comment As String note = Range ("A1") "Комментарии, основанные на полученной оценке If note = 6 Then score_comment = "Великолепный бал!" ElseIf note = 5 Then score_comment = "Хороший бал" ElseIf note = 4 Then score_comment = "Удовлетворительный бал" ElseIf note = 3 Then score_comment = "Неудовлетворительный бал" ElseIf note = 2 Then score_comment = "Плохой бал" ElseIf note = 1 Then score_comment = "Ужасный бал" Else score_comment = "Нулевой бал" End If "Комментарий в ячейке B1 Range ("B1") = score_comment End Sub
Select
Существует альтернатива использованию If со многими ElseIf инструкциями, а именно команда Select , которая больше подходит к такого рода ситуаций.
Рассмотрим пример макроса с оператором Select :
Sub scores_comment () "Переменные Dim note As Integer , score_comment As String note = Range ("A1") "Комментарии, основанные на полученной оценке Select Case note "
Стоит отметить, что мы также могли использовать и другие операторы сравнения:
Case Is > = 6 "если значение> = 6
Примеры с различными значениями:
Case Is = 6, 7 "если значение = 6 или 7 Case Is 6, 7 "если значение не равно 6 или 7 Case 6 To 10 "если значение = любому числу от 6 до 10