Цикл For...Next

Предположим, нужно вывести все числа от 1 до 100 по одному на строке. Обычным способом пришлось бы писать 100 строк кода:

Debug.Print 1
Debug.Print 2
...
Debug.Print 100

При помощи циклов то же действие можно выполнить гораздо проще:

Dim k As Integer
For k = 1 To 100
   Debug.Print k
Next k

Иными словами, циклы позволяют выполнить одни и те же инструкции многократно.

Цикл For...Next имеет следующий формат:

For <Переменная> = <Начало> To <Конец> [Step <Шаг>]
    <Инструкции внутри цикла>
Next [<Переменная>]

Здесь присутствуют следующие конструкции:

Выведем все числа от 100 до 1:

Dim k As Integer
For k = 100 To 1 Step -1
   Debug.Print k
Next k

Выведем все четные числа от 0 до 100:

Dim k As Integer
For k = 0 To 100 Step 2
   Debug.Print k
Next k

Выведем значения всех элементов массива в прямом и обратном порядке:

Dim Массив As Variant, i As Integer
Массив = Array(1, 2, 3, 4, 5)
' Выводим значения в прямом порядке
For i = LBound(Массив) To UBound(Массив)
   Debug.Print Массив(i)
Next i
' Выводим значения в обратном порядке
For i = UBound(Массив) To LBound(Массив) Step -1
   Debug.Print Массив(i)
Next i

Умножим значения всех элементов массива на 2:

Dim Массив As Variant, i As Integer
Массив = Array(1, 2, 3, 4, 5)
For i = LBound(Массив) To UBound(Массив)
   Массив(i) = Массив(i) * 2
Next i
Debug.Print Join(Массив) ' 2 4 6 8 10

Один цикл можно вложить в другой цикл. В качестве примера выведем значения всех элементов многомерного массива:

Dim Массив As Variant, i As Integer, j As Integer
Массив = Array(Array(0, 1), Array(2, 3), Array(4, 5))
For i = 0 To 2
   For j = 0 To 1
      Debug.Print Массив(i)(j)
   Next
Next

Цикл For Each...Next

Цикл For Each...Next предназначен для перебора элементов коллекций и массивов. Формат цикла:

For Each <Переменная> In <Коллекция или массив>
    <Инструкции внутри цикла>
Next [<Переменная>]

На каждой итерации цикла переменной <Переменная> будет присваиваться значение текущего элемента коллекции или массива. Обратите внимание на то, что переменная будет содержать копию значения элемента массива, поэтому любое изменение этой переменной внутри цикла не затронет значение самого элемента. Следует также учитывать, что переменная <Переменная> при переборе массивов должна быть объявлена с типом Variant. Тип Variant не может хранить данные пользовательских типов, следовательно цикл For Each...Next нельзя использовать для перебора массивов, содержащих значения пользовательских типов.

Выполним перебор элементов массива:

Dim Массив As Variant, Элемент As Variant
Массив = Array(1, 2, 3, 4, 5)
For Each Элемент In Массив
   Debug.Print Элемент
Next

Теперь выведем названия всех листов в текущей рабочей книге:

Dim Лист As Variant
For Each Лист In Worksheets
   Debug.Print Лист.Name
Next

Инструкция Exit For

Инструкция Exit For позволяет прервать выполнение циклов For...Next и For Each...Next досрочно. Для примера произведем поиск элемента в массиве. При нахождении первого элемента, соответствующего критериям поиска, прервем цикл (листинг 4.5).

Листинг 4.5. Инструкция Exit For

Dim Массив As Variant, i As Integer
Массив = Array(1, 2, 3, 4, 5)
For i = LBound(Массив) To UBound(Массив)
   If Массив(i) = 3 Then
      Debug.Print "Нашли элемент. Индекс " & i
      Exit For
   End If
Next

Примечание

Инструкция Exit For прерывает выполнение цикла, а не программы, т. е. далее будет выполнена инструкция, следующая сразу за циклом.

Цикл Do...Loop и инструкция Exit Do

Цикл Do...Loop предназначен для выполнения инструкций неопределенное количество раз. Формат цикла:

Do
   <Инструкции внутри цикла>
Loop

Внутри тела цикла необходимо предусмотреть условие, при котором цикл должен завершиться, иначе цикл будет бесконечным. Завершить выполнение цикла позволяет инструкция Exit Do. Инструкция Exit Do прерывает выполнение цикла, а не программы, т. е. далее будет выполнена инструкция, следующая сразу за циклом.

Цикл Do...Loop совместно с инструкцией Exit Do удобно использовать для получения неопределенного заранее количества данных от пользователя. В качестве примера просуммируем неопределенное количество чисел (листинг 4.6).

Листинг 4.6. Суммирование неопределенного количества чисел

Dim Сумма As Long, Значение As Variant
Сумма = 0
Do
   Значение = InputBox("Введите число или слово 'stop' " _
                       & vbCr & "для получения результата")
   If Значение = "stop" Or Значение = "" Then
      Exit Do                 ' Выход из цикла
   End If
   If IsNumeric(Значение) = False Then
      MsgBox "Ошибка. Вы ввели не число"
   Else
      Сумма = Сумма + CLng(Значение)
   End If
Loop
MsgBox "Сумма чисел равна: " & Сумма

Циклы Do While...Loop и Do Until...Loop

Выполнение инструкций в цикле Do While...Loop продолжается до тех пор, пока логическое выражение истинно. Формат цикла:

<Начальное значение>
Do While <Условие>
   <Инструкции внутри цикла>
   <Приращение>
Loop

Последовательность работы цикла Do While...Loop:

  1. Переменной-счетчику присваивается начальное значение.
  2. Проверяется условие, если оно истинно, выполняются инструкции внутри цикла, иначе выполнение цикла завершается.
  3. Переменная-счетчик изменяется на величину, указанную в параметре <Приращение>.
  4. Переход к пункту 2.

Выведем все числа от 1 до 100, используя цикл Do While...Loop (листинг 4.7).

Листинг 4.7. Вывод чисел от 1 до 100

Dim i As Integer
i = 1                 ' <Начальное значение>
Do While i < 101      ' <Условие>
   Debug.Print i      ' <Инструкции внутри цикла>
   i = i + 1          ' <Приращение>
Loop

Внимание!

Если <Приращение> не указано или условие содержит ошибку, то цикл будет бесконечным. Чтобы прервать бесконечный цикл, следует нажать комбинацию клавиш <Ctrl>+<Break>.

Выполнение инструкций в цикле Do Until...Loop продолжается до тех пор, пока логическое выражение ложно. Формат цикла:

<Начальное значение>
Do Until <Условие>
   <Инструкции внутри цикла>
   <Приращение>
Loop

Выведем все числа от 100 до 1, используя цикл Do Until...Loop (листинг 4.8).

Листинг 4.8. Вывод чисел от 100 до 1

Dim i As Integer
i = 100               ' <Начальное значение>
Do Until i < 1        ' <Условие>
   Debug.Print i      ' <Инструкции внутри цикла>
   i = i - 1          ' <Приращение>
Loop

С помощью циклов Do While...Loop и Do Until...Loop можно создать бесконечный цикл, указав в параметре <Условие> значение True или False соответственно. Выведем все числа от 1 до 100, используя бесконечный цикл (листинг 4.9).

Листинг 4.9. Вывод чисел от 1 до 100

Dim i As Integer
i = 1
Do While True                 ' Или Do Until False
   If i > 100 Then
      Exit Do                 ' Выход из цикла
   End If
   Debug.Print i
   i = i + 1
Loop

Обратите внимание на условие, оно не содержит операторов сравнения. Проверка на равенство выражения значению True выполняется по умолчанию.

Циклы Do...Loop While и Do...Loop Until

Выполнение инструкций в цикле Do...Loop While продолжается до тех пор, пока логическое выражение истинно. Но в отличие от цикла Do While...Loop условие проверяется не в начале цикла, а в конце. По этой причине инструкции внутри цикла Do...Loop While выполнятся минимум один раз. Цикл имеет следующий формат:

<Начальное значение>
Do
   <Инструкции внутри цикла>
   <Приращение>
Loop While <Условие>

Последовательность работы цикла Do...Loop While:

  1. Переменной-счетчику присваивается начальное значение.
  2. Выполняются выражения внутри цикла.
  3. Переменная-счетчик изменяется на величину, указанную в параметре <Приращение>.
  4. Проверяется условие, если оно истинно, происходит переход к п. 2, а если нет — выполнение цикла завершается.

Выведем все числа от 1 до 100, используя цикл Do...Loop While:

Dim i As Integer
i = 1
Do
   Debug.Print i
   i = i + 1
Loop While i < 101

Цикл Do...Loop Until аналогичен циклу Do...Loop While, но выполнение инструкций продолжается до тех пор, пока логическое выражение ложно. Инструкции внутри цикла Do...Loop Until выполнятся минимум один раз. Цикл имеет следующий формат:

<Начальное значение>
Do
   <Инструкции внутри цикла>
   <Приращение>
Loop Until <Условие>

Выведем все числа от 1 до 100, используя цикл Do...Loop Until:

Dim i As Integer
i = 1
Do
   Debug.Print i
   i = i + 1
Loop Until i > 100

Цикл While...Wend

Выполнение инструкций в цикле While...Wend продолжается до тех пор, пока логическое выражение истинно. Формат цикла:

<Начальное значение>
While <Условие>
   <Инструкции внутри цикла>
   <Приращение>
Wend

Последовательность работы цикла While...Wend:

  1. Переменной-счетчику присваивается начальное значение.
  2. Проверяется условие, если оно истинно, выполняются инструкции внутри цикла, иначе выполнение цикла завершается.
  3. Переменная-счетчик изменяется на величину, указанную в параметре <Приращение>.
  4. Переход к пункту 2.

Выведем все числа от 1 до 100, используя цикл While...Wend (листинг 4.11).

Листинг 4.10. Вывод чисел от 1 до 100

Dim i As Integer
i = 1
While i < 101
   Debug.Print i
   i = i + 1
Wend

Оператор GoTo

С помощью оператора безусловного перехода GoTo можно передать управление в любое место программы. Оператор имеет следующий формат:

GoTo <Метка>

Значение в параметре <Метка> должно быть допустимым идентификатором. Место в программе, в которое передается управление, помечается одноименной меткой, после которой указывается двоеточие. В качестве примера имитируем цикл и выведем числа от 1 до 100:

Dim i As Integer
i = 1
BLOCK_START:
   If i > 100 Then GoTo BLOCK_END
   Debug.Print i
   i = i + 1
   GoTo BLOCK_START
BLOCK_END:

Совет

Следует избегать использования оператора GoTo, так как его применение делает программу слишком запутанной и может привести к неожиданным результатам.

Предыдущая статья Все статьи Следующая статья