Циклы позволяют выполнить одну или несколько строк кода несколько раз. VBA поддерживает следующие циклы:
For...Next For Each...Next Do... Loop
Конструкция For . . . Next. Когда число повторений известно заранее, используют цикл For . . . Next. В цикле For используется переменная, называемая переменной цикла или счетчиком цикла, которая увеличивается или уменьшается на заданную величину при каждом повторении цикла. Синтаксис этой конструкции следующий:
For counter = start To end операторы Next
Параметры 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 t = t + dt If t <= -1 Then f(i) = -1 ElseIf t > 1 Then f(i) = 1 Else f(i) = t End If Call out("a" & (2 + i), i) : Call out("b" & (2 + i), t) : Call out("c" & (2 + i), f(i)) Next i End Sub
Конструкция For Each . . . Next
Цикл For Each . . . Next похож на цикл For . . . Next, но он повторяет группу операторов для каждого элемента из набора объектов или из массива, вместо повторения операторов заданное число раз. Он особенно полезен, когда неизвестно, сколько элементов содержится в наборе.
Синтаксис конструкции цикла For Each . . . Next таков:
For Each element In group операторы Next element
Следует помнить следующие ограничения при использовании цикла 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 условие операторы Loop
Выполняя этот цикл, 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 p = -p * x m = p / i s = s + m Call out("a" & (2 + i), i) : Call out("b" & (2 + i), Abs(m)) : Call out("c" & (2 + i), s) i = i + 1 Loop End Sub
Другая разновидность конструкции Do . . . Loop сначала выполняет операторы тела цикла, а затем проверяет условие после каждого выполнения. Эта разновидность гарантирует, что операторы тела цикла выполнятся по крайней мере один раз:
Do операторы Loop While условие
Две другие разновидности конструкции цикла аналогичны предыдущим, за исключением того, что цикл выполняется, пока условие ложно (False):
Цикл не выполняется вообще или выполняется много раз:
Do Until условие
операторы Loop
Цикл выполняется по крайней мере один раз:
операторы
Loop Until условие
Можно помещать структуры управления внутрь других структур управления (например, блок If . . . Then внутрь цикла For . . . Next). Говорят, что структура управления, помещенная внутрь другой структуры управления, является вложенной.
Глубина вложения управляющих структур в VBA не ограничена. Для улучшения читаемости кода принята практика смещения тела конструкции принятия решения или цикла в программе в случае использования вложенных структур управления.
При вложении в цикл одного или несколько других циклов говорят о вложенных циклах, в которых различают внешние (охватывающие) и внутренние (вложенные) циклы.
Рассмотрим пример суммирования элементов Aij матрицы A(n,m) построчно.
Sub пример5() Dim a() As Single, s() As Single Dim n As Integer, m As Integer Dim i As Integer, j As Integer Call read("a1", n): Call read("b1", m) ReDim a(1 To n, 1 To m), s(1 To n) "Чтение матрицы For i = 1 To n For j = 1 To m Call readcell(i + 1, j, a(i, j)) Next j Next i "Вычисление For i = 1 To n s(i) = 0 For j = 1 To m s(i) = s(i) + a(i, j) Next j Call outcell(i + 1, m + 1, s(i)) Next i End Sub
Заметим, что первый оператор Next закрывает внутренний цикл For, а последний оператор Next закрывает внешний цикл For. Точно так же и для вложенных операторов If, операторы End If автоматически применяются для закрытия ближайшего к нему оператора If. Вложенные структуры Do . . . Loop работают подобным же образом: самый дальний оператор Loop соответствует самому дальнему оператору Do.
При вводе/выводе элементов двумерного массива на рабочий лист Microsoft Excel удобно применять пользовательские процедуры ввода/вывода:
Sub readcell(i As Integer, j As Integer, val As Variant) val = Лист1.Cells(i, j).Value End Sub Sub outcell(i As Integer, j As Integer, val As Variant) Лист1.Cells(i, j).Value = val End Sub
где I - номер строки, j - номер столбца рабочего листа.
Выход из структур управления
Оператор Exit позволяет выходить непосредственно из цикла For, цикла Do, процедуры Sub или процедуры Function. Синтаксис оператора Exit прост:
For counter = start To end [блок операторов] [блок операторов] Next Do [(While | Until} условие] [блок операторов] [блок операторов] Loop
Exit For внутри цикла For и Exit Do внутри цикла Do могут появиться сколько угодно раз.
Оператор Exit Do работает со всеми разновидностями синтаксиса цикла Do.
Операторы Exit For и Exit Do применяются, если необходимо завершить цикл немедленно, не продолжая дальнейших итераций или не ожидая выполнения блока операторов в теле цикла.
При использовании оператора Exit для выхода из цикла значения переменной цикла зависят от того, каким образом завершается выполнение цикла:
При нормальном завершении цикла значение переменной цикла имеет на единицу больше верхней границы числа циклов
При преждевременном завершении цикла переменная цикла сохраняет свое значение, которое она получила с учетом обычных правил
При завершении цикла по концу набора переменная цикла имеет значение Nothing (Ничего), если она является переменной типа object (Объект), или значение Empty (Пусто), если она является переменной типа Variant
Какие либо действия процедуры повторяющиеся заданное количество раз или пока выполняется или не выполняется некоторое условие называют циклом .
Процесс выполнения все операторов, заключенных в структуру цикла, один раз называется итерацией цикла .
Структуры цикла, всегда выполняющиеся заданное количество раз, называются циклами с фиксированным числом итераций . Другие типы структур цикла повторяются переменное количество раз в зависимости от некоторого набора условий. Такие циклы называются неопределенными циклами .
Блок операторов, находящийся между началом и концом цикла называется "тело цикла" .
Самой простой структурой цикла является фиксированный цикл .
Синтаксис
For counter
= Start
To End
Statements
Next [counter
]
Counter
- любая численная переменная VBA
Start
- любое численное выражение, определяет начальное значение для переменной counter
End
- численное выражение, определяет конечное значение для переменной counter
По умолчанию VBA увеличивает переменную counter на 1 каждый раз при выполнении операторов в цикле. Можно задать другое значение (SterSize - любое численное выражение), на которое будет изменяться counter .
Ключевое слово Next сообщает VBA о том, что достигнут конец цикла. Необязательная переменная counter после ключевого слова Next должна быть той же самой переменной counter , которая была задана после ключевого слова For в начале структуры цикла.
Ниже представлен листинг простейшего цикла For..Next , который считает сумму цифр от 1 до 10:
А теперь два варианта цикла For..Next с использованием шага цикла отличного от единицы:
Обратите внимание! При уменьшении счетчика цикла For..Next цикл выполняется, пока переменная счетчика больше или равна конечному значению, а когда счетчик цикла увеличивается, цикл выполняется, пока переменная счетчика меньше или равна конечному значению.
Цикл For Each..Next не использует счетчик цилка. Циклы For Each..Next выполняются столько раз, сколько имеется элементов в определенной группе, такой как коллекция объектов или массив (которые будут рассматриваться позже). Проще говоря, цикл For Each..Next выполняется один раз для каждого элемента в группе.
Синтаксис
For Each Element
In Group
Statements
Next [Element
]
Element
- переменная, используемая для итерации по всем элементам в определенной группе
Group
- это объект коллекции или массив
Statements
- один, несколько или ни одного оператора VBA (тело цикла).
В этом уроке будет рассмотрена работа с циклом For в VBA. Пример работы с циклом For, так же будет продемонстрирован пример создания формул в Excel с помощью макросов.
Цикл For работает по принципу счетчика. For применяется в тех случаях, когда необходимо повторить некоторые действия заранее известное кол-во раз. Например, цикл For часто используется при чтении массивов.
Цикл For
имеет следующий синтаксис:
For
счетчик
=
начало цикла
To
конец цикла
[Step
шаг
]
группа операторов, команд и т.д.
Exit For
Next
счетчик
Рассмотрим пару примеров использования цикла For . В дальнейшем, с этим циклом будем встречаться довольно часто.
Пример 1
Даны два столбца С и Е заполненные числами:
Необходимо сложить числа в столбце С с числами столбца Е следующим образом:
С2+Е21, С3+E20, ..., C21+E2. Результат вывести в столбец D в виде формулы т.е. содержание ячейки результата должно быть "=С2+Е21".
Код макроса выглядит следующим образом (куда прописывать код читаем ):
Sub
Цикл_For()
"константа указывающая предел цикла т.е. до какого значения циклу бежать
Const
n = 21
For
i = 2 To
n
" создаем строку формулу и сохраняем ее в ячейку
Cells(i, 4) = "=C" & CStr
(i) & "+E" & CStr
((n - i) + 2)
" продолжение когда выполняющегося в цикле
Next
i
" остальной код программы
End Sub
Разбираем написанный код:
Ячейке мы присваиваем формулу созданную следующим образом "=C" & CStr
(i) & "+E" & CStr
((n - i) + 2). Знак & - "склеивание" символов, строк. В результате у нас получится формула "=Сn+E((n - i) + 2)" где n = 21, i - счетчик.
Страшно? Это только кажется:)
Все. После выполнения макроса мы получим следующий столбец (выделен), а в каждой ячейке формула:
Пример 2
Теперь рассмотрим цикл с указанным шагом. После расчета прошлого макроса мы получили три столбца, теперь нам необходимо из столбца E вычесть D, в столбец F вывести формулы вычитания. Код макроса следующий:
Sub
Цикл_For_с_шагом()
Const
n = 21
For
i = n To
2 Step
-1
Cells(i, 6) = "=E" & CStr
(i) & "-D" & CStr
(i)
Next
i
End Sub
В данном случае все тоже самое, только цикл теперь "бежит" не от 2, а от 21 до 2 с шагом (Step) -1.
Результат выполнения получим следующий:
Цикл For , в VBA, является не единственным циклом. В дальнейшем будут рассмотрены еще пара вариантов циклов, без которых не обойтись при написании макрокоманд в Excel.
Лабораторные работы по основам программирования
2.1. Табулирование функций, представленных аналитически
и сходящимся рядом
Цель работы
· Закрепление теоретических знаний по основам организации разветвляющихся и циклических структур.
· Приобретение практических навыков программирования с использованием разветвляющихся и циклических структур в системе Visual Basic.
В VB существуют три вида операторов цикла:
· счетный цикл: For…To … Next
· циклы с предусловиями: Do While...Loop, Do Until...Loop, While…WEnd
· циклы с постусловиями:Do...Loop While, Do...Loop Until.
Счетный цикл – позволяет циклически выполнять набор операторов заданное число раз. Его синтаксис следующий:
For счетчик = начало To конец
[операторы ]
[операторы ]
Next [счетчик ]
Параметр счетчик – это числовая переменная (целого, вещественного типа или типа Date, Variant, Currency), которая автоматически увеличивается после каждого повтора. Начальное значение счетчика равно параметру начало, а конечное параметру – конец. Если не указан, то шаг считается равным 1, значение шага можно изменять. Оно может быть положительным или отрицательным числом.
Существуют четыре синтаксические конструкции цикла Do….Loop:
Операторы между ключевыми словами Do … Loop выполняются заданное количество раз в зависимости от условия. Например, в следующем фрагменте программы при C = 100 условие будет выполняться и произойдет вход в цикл. Внутри цикла происходит обращение к процедуре и уменьшение значения C на 1. Далее вновь проверяется условие (C > 0) и операторы цикла выполняются повторно (всего они выполнятся 100 раз), до C = 0. Когда же условие C >0 становится ложным и цикл прекращается.
Do While C > 0
Тот же самый фрагмент программы, выполненный с использованием цикла с предусловием по синтаксису 2:
В данном случае цикл выполняется, пока условие равно False, в отличие от предыдущего случая, то есть продолжается до выполнения условия C = 0.
Операторы циклов по синтаксису 3 и 4 очень похожи на первые два за исключением того, что условие не вычисляется до тех пор, пока цикл не выполнится хотя бы один раз.
В синтаксисах этих циклов можно использовать операторы безусловного выхода из цикла Exit For и Exit Do, позволяющих передать управление оператору, находящемуся за циклом. Например, в следующем фрагменте программы, если начальное значение C окажется >50, то цикл немедленно прекратиться.
Do Until C <= 0
MsgBox “Нач. значение больше допустимого”, ”Ошибка ввода”
Цикл While…Wend использовался в ранних версиях Visual Basic. Его синтаксис следующий:
While <условие>
<Операторы>
В отличии от цикла Do..Loop цикл While ..Wend не имеет второго варианта, в котором проверка условия выполняется в конце цикла. Кроме того, для него нет оператора выхода из цикла, наподобие Exit Do.
Последнее обновление: 30.10.2015
Еще одним видом управляющих конструкций являются циклы. В VB.NET используется несколько видов циклов.
В этом цикл выполняется определенное число раз, причем это число задается счетчиком:
For i As Integer = 1 To 9 Console.WriteLine("Квадрат числа {0} равен {1}", i, i * i) Next
Здесь переменная i выполняет роль счетчика. После слова To мы помещаем максимальное значение счетчика. При каждом цикле значение счетчика увеличивается на единицу. И это значение сравнивается со значением после To . Если эти два значения равны, то цикла прекращает свою работу.
При работе с циклами мы можем увеличивать значение счетчика при каждом проходе не только на единицу, но и вообще на любое число. Для этого нужно либо использовать ключевое слово Step и после него указать шаг цикла, на который будет увеличиваться значение счетчика, либо можно увеличивать счетчик непосредственно в цикле:
For i As Integer = 1 To -9 Step -1 For j As Integer = 1 To 9 Console.WriteLine("Произведение чисел i и j равно {0}", i * j) j += 1 Next Next
Обратите внимание, что в качестве шага в первом цикле выбрано отрицательное значение и значение счетчика с каждым проходом уменьшается на единицу. Во внутреннем цикле счетчик j при каждом проходе увеличивается на 2, так как он по умолчанию увеличивается на единицу, и еще мы явным образом увеличиваем его в цикле на единицу. В итоге внутренний цикл отрабатывает пять раз, а внешний девять, то есть фактически получается 45 циклов.
Цикл For Each осуществляет перебор элементов в определенной группе, например, в массиве или в коллекции. Предположим у нас есть некоторый массив типа Integer и нам надо инициализировать этот массив случайными значениями и затем вывести все его элементы на экран:
"Создаем массив из пяти чисел Dim nums(4) As Integer Dim r As New Random() "инициализируем массив For i As Integer = 0 To nums.Length - 1 nums(i) = r.Next(100) Next "Выводим элементы массива For Each i As Integer In nums Console.Write("{0} ", i) Next
В выражении For Each мы сначала указываем переменную, которая будет принимать значения элементов массива. А после ключевого слова In указываем группу, в которой надо перебрать все элементы.
В цикл While выполняется до тех пор, пока соблюдается определенное условие, указанное после слова While:
Dim j As Integer = 10 While j > 0 Console.WriteLine(j) j -= 1 End While
Цикл Do, также как и цикл While, выполняется, пока соблюдается определенное условие. Однако он имеет разные формы. Так, в следующем примере сначала проверяется условие, а затем выполняется блок кода, определенный в цикле:
Dim j As Integer = 10 Do While j > 0 Console.WriteLine(j) j -= 1 Loop
В данном случае цикл выполняется, пока значение j больше нуля. Но есть еще одна запись, где вместо слова While используется слово Until , а цикл выполняется пока не соблюдено определенное условие, то есть пока значение j не станет меньше нуля:
Dim j As Integer = 10 Do Until j < 0 Console.WriteLine(j) j -= 1 Loop
Если изначально условие, заданное в цикле, неверно, то цикл не будет работать. Но мы можем определить проверку в конце цикла, и таким образом, наш цикл как минимум один раз отработает:
Dim j As Integer = -1 Do Console.WriteLine(j) j -= 1 Loop Until j < 0 "либо Do Console.WriteLine(j) j -= 1 Loop While j > 0
Нередко возникает необходимость не дожидаться окончания цикла, а сразу же выйти из цикла, в случае соблюдения определенного условия. Для этого используют оператор Exit , после которого указывают тип цикла, из которого осуществляется выход, например, Exit Do (Exit While) :
Dim r As New Random() Dim num As Integer = r.Next(100) For i As Integer = 0 To 100 num -= 1 If num < 50 Then Exit For Next Console.WriteLine(num)
Существует и другая задача - осуществить выход не из цикла, а из текущего прохода или итерации и перейти к следующему. Для этого используют оператор Continue , после которого указывают тип цикла, из которого осуществляется выход, например, Continue While:
Dim r As New Random() Dim num As Integer = r.Next(100) For i As Integer = 0 To 10 num -= 7 If num < 50 AndAlso num > 25 Then Continue For End If Console.WriteLine(num) Next
В данном случае мы в каждом проходе цикла вычитаем из num число 7 и затем смотрим, не принадлежит ли число num интервалу от 25 до 50. И если принадлежит, переходим к новой итерации цикла, а если нет, то выводим его на экран.