2.5.2. VBA. Организация циклов
Операторы цикла используются для повторения выполнения действия или группы действий заданное количество раз. Количество повторений (итераций цикла) может быть предопределено или вычислено.
VBA поддерживает циклические конструкции двух видов:
- Циклы с фиксированным числом повторений (циклы со счетчиком).
- Циклы с неопределенными числом повторений (циклы с условием).
Для всех видов циклов используется понятие тело цикла, определяющее блок операторов, заключенных между начальным и конечным операторами цикла. Каждое повторение выполнения операторов тела цикла называется итерация.
Фиксированные циклы
VBA предоставляет две управляющие структуры для организации фиксированного цикла: For … Next (цикл со счетчиком) и For Each … Next (цикл с перечислением).
Оператор For … Next это типовой цикл со счетчиком, выполняющий заданное число итераций. Синтаксис оператора For … Next:
For <счетчик> = <начЗначение> То <конЗначение> [Step <приращение>] <блок операторов> Next [<счетчик>]
Пример использования оператора For ... Next.
Листинг 9. Оператор For … Next
' ЗАДАЧА: Составить программу, которая получает два числа от пользователя. ' Складывает все числа в диапазоне, заданном этими двумя числами, а затем ' отображает результирующую сумму. Sub sample7() Dim i As Integer ‘счетчик цикла Dim sStart ‘начальное значение счетчика Dim sEnd ‘конечное значение счетчика Dim sSum As Long ‘результирующая сумма sStart = InputBox("Введите первое число:") sEnd = InputBox("Введите второе число:") sSum = 0 For i = CInt(sStart) To CInt(sEnd) sSum = sSum + i Next i MsgBox "Сумма чисел от " & sStart & " до " & sEnd & " равна: " & sSum End Sub
Оператор цикла For Each … Next относится к категории операторов объектного типа, т.е. применяется в первую очередь к коллекциям объектов, а также к массивам. Тело цикла выполняется фиксированное число раз, соответствующее числу элементов массива или коллекции. Формат оператора For Each … Next:
For Each <элемент> In <группа> <блок операторов> Next [<элемент>]
Циклы с условием (неопределенные циклы)
Циклы с условием используются в тех случаях, когда повторяющиеся действия нужно выполнять только при определенных условиях. Количество итераций не определено и в общем случае может быть равно нулю (в частности, для циклов с предусловием). VBA предлагает разработчикам несколько управляющих структур для организации циклов с условием:
- Четыре вида циклов Do..Loop, которые различаются типом проверяемого условия и временем выполнения этой проверки.
- Непрерываемый цикл While … Wend.
Цикл Do While … Loop - типичный цикл с предусловием. Условие проверяется до того, как выполняется тело цикла. Цикл продолжает свою работу, пока это <условие> выполняется (т.е. имеет значение True). Так как проверка выполняется в начале, то тело цикла может ни разу не выполниться. Формат цикла Do While … Loop:
Do While <условие> <блок операторов> Loop
Листинг 10. Цикл Do While … Loop
' ЗАДАЧА: Составить программу, которая предусматривает ввод пользователем ' произвольной последовательности чисел. Ввод должен быть прекращен ' только после того, как сумма введенных нечетных чисел превысит 100. Sub sample8() Dim OddSum As Integer ‘сумма нечетных чисел Dim OddStr As String ‘строка с нечетными числами Dim Num ‘для приема вводимых чисел OddStr = "" ‘инициализация выходной строки OddSum = 0 ‘инициализация суммы OddSum Do While OddSum < 100 ‘начало цикла Num = InputBox("Введите число: ") If (Num Mod 2) <> 0 Then ‘проверка на четность OddSum = OddSum + Num ‘накопление суммы нечетных чисел OddStr = OddStr & Num & " " End If Loop 'вывод строки с нечетными числами MsgBox prompt:="Нечетные числа: " & OddStr End Sub
Оператор Do … Loop While предназначен для организации цикла с постусловием. Условие проверяется после того, как тело цикла, будет выполнено хотя бы один раз. Цикл продолжает свою работу, пока <условие> остается истинным. Формат цикла Do … Loop While:
Do <блок операторов> Loop While<условие>
Листинг 11. Цикл с постусловием
' ЗАДАЧА: Составить программу игры "Угадай число". Программа должна случайным ' образом генерировать число в диапазоне от 1 до 1000, пользователь должен ' угадать это число. Программа на каждое вводимое число выводит подсказку ' "больше" или "меньше". Sub sample8() Randomize Timer ' инициализация генератора случайных чисел Dim msg As String ' строка сообщения Dim SecretNumber As Long, UserNumber As Variant Begin: SecretNumber = Round(Rnd * 1000) ' число, сгенерированное компьютером UserNumber = Empty ' число, вводимое пользователем Do ' игровой процесс Select Case True Case IsEmpty(UserNumber): msg = "Введите число" Case UserNumber > SecretNumber: msg = "Слишком много!" Case UserNumber < SecretNumber: msg = "Слишком мало!" End Select UserNumber = InputBox(prompt:=msg, Title:="Угадай число") Loop While UserNumber <> SecretNumber ' проверка If MsgBox("Играть еще? ", vbYesNo + vbQuestion, "Вы угадали!") = vbYes Then GoTo Begin End If End Sub
Циклы Do Until … Loop и Do … Loop Until являются инверсиями ранее рассмотренных циклов с условием. В общем случае они работают аналогично, за исключением того, что тело цикла выполняется при ложном условии (т.е. <условие>=False). Формат цикла Do Until … Loop:
Do Until <условие> <блок операторов> Loop
Формат цикла Do … Loop Until:
Do <блок операторов> Loop Until<условие>
Практическое задание: Перепишите программы из листингов 10 и 11 с использованием инвертированных операторов цикла.
Цикл While … Wend также относится к циклам с условием. Данный оператор полностью соответствует структуре Do While … Loop. Формат цикла While … Wend:
While <условие> <блок операторов> Wend
Отличительной особенностью этого оператора является невозможность принудительного завершения (прерывания) тела цикла (оператор Exit Do не работает в цикле While … Wend).
Прерывание цикла
Для досрочного завершения итерации и выхода из цикла применяется оператор Exit. Этот оператор применим в любой циклической структуре, кроме While ... Wend. Общий синтаксис использования Exit для прерывания цикла таков:
<начало_цикла> [<блок операторов1>] Exit (For | Do) [<блок операторов2>] [Exit (For | Do)] ... <конец_цикла>
При выполнении оператора Exit цикл прерывается, и управление передается оператору, следующему за оператором <конец_цикла>. В теле цикла может присутствовать несколько операторов Exit.
Листинг 12. Принудительный выход из цикла
Sub sample9() For i = 1 To 10000000 If i = 10 Then Exit For ' выход из цикла, когда счетчик достигнет 10 Next End Sub
CC-BY-CA Анатольев А.Г., 31.01.2012