Цикл Do While… Loop в VBA Excel, его синтаксис и описание отдельных компонентов. Примеры использования цикла Do While… Loop.
Цикл Do While… Loop в VBA Excel предназначен для повторения блока операторов пока выполняется заданное условие (возвращается значение True). Синтаксис этого цикла аналогичен синтаксису цикла Do Until… Loop, который повторяется до тех пор, пока условие не выполняется (возвращается значение False).
Синтаксис цикла Do While… Loop существует в двух вариантах, определяющих, когда проверяется условие.
Условие проверяется до выполнения операторов:
Do While condition [ statements ] [ Exit Do ] [ statements ] Loop |
Условие проверяется после выполнения операторов:
Do [ statements ] [ Exit Do ] [ statements ] Loop While condition |
В квадратных скобках указаны необязательные атрибуты цикла Do While… Loop.
Компоненты цикла Do While… Loop
Компонент | Описание |
---|---|
condition | Обязательный атрибут. Условие выполнения цикла. Выражение, возвращающее значение типа Boolean. |
statements | Необязательный* атрибут. Операторы вашего кода. |
Exit Do | Необязательный атрибут. Оператор выхода** из цикла до его окончания. |
*Если не использовать в цикле свой код, смысл применения цикла теряется.
**Очень полезный оператор для цикла Do While… Loop, так как при некоторых обстоятельствах он может стать бесконечным. Если такой риск существует, следует предусмотреть возможность выхода из бесконечного цикла VBA с помощью оператора Exit Do.
Примеры циклов Do While… Loop
Простейшие циклы
Цикл Do While… Loop с условием до исполняемых операторов:
Sub test1() Dim a As Byte Do While a < 10 a = a + 1 Loop MsgBox a End Sub |
Цикл Do While… Loop с условием после исполняемых операторов:
Sub test2() Dim a As Byte Do a = a + 1 Loop While a < 10 MsgBox a End Sub |
В обоих случаях окно MsgBox выведет число 10. Когда значение переменной a будет равно 10, проверяемое условие выдаст значение False, и цикл будет остановлен.
Проход по строкам листа
У двух белок дупла расположены напротив друг друга. В каждом дупле по 100 шишек. В свободное время они бросают шишки в дупло напротив, попадают не всегда. Ниже, в таблице, указано количество шишек, брошенных каждой белкой, и сколько их попало в цель.
Дни | Игрок | Брошено | Попало в цель |
---|---|---|---|
1 день | Белка 1 | 15 | 6 |
1 день | Белка 2 | 12 | 7 |
2 день | Белка 1 | 14 | 8 |
2 день | Белка 2 | 16 | 7 |
3 день | Белка 1 | 20 | 9 |
3 день | Белка 2 | 14 | 6 |
4 день | Белка 1 | 26 | 10 |
4 день | Белка 2 | 13 | 5 |
5 день | Белка 1 | 17 | 4 |
5 день | Белка 2 | 21 | 7 |
Исходя из этих данных необходимо узнать, сколько шишек осталось у Белки 1 в дупле. Для этого необходимо вычесть из 100 шишек количество выброшенных Белкой 1 и прибавить шишки, заброшенные в ее дупло Белкой 2. Вычисления начинаем со второй строки (в первой заголовки) и в условии для цикла Do While… Loop указываем «первая ячейка текущей строки не является пустой». Таблица должна начинаться с первой ячейки рабочего листа «A1», и под ней, как минимум, одна строка должна быть пустой, точнее, первая ячейка этой строки.
Sub test3() Dim i As Long, n As Long i = 2 n = 100 Do While Cells(i, 1) <> «» If Cells(i, 2) = «Белка 1» Then n = n — Cells(i, 3) Else n = n + Cells(i, 4) End If i = i + 1 Loop MsgBox n End Sub |
Результат, выведенный в информационном сообщении MsgBox, будет равен 40. Вы можете скопировать таблицу на рабочий лист книги Excel и поэкспериментировать с кодом VBA.
Бесконечный цикл и Exit Do
Пример бесконечного цикла:
Sub test4() Dim a As Byte Do While a < 10 a = a + 1 If a = 9 Then a = 0 End If Loop End Sub |
При запуске этой процедуры цикл Do While… Loop начинает выполняться бесконечно. Мне приходилось останавливать бесконечные циклы VBA в Excel 2000 и Excel 2016. В Excel 2000 помогло сочетание клавиш Ctrl+Break, а в Excel 2016 при закрытии редактора VBA крестиком появляется окно:
Информационное окно «Microsoft Excel не отвечает»
Ожидать отклика программы нет смысла, поэтому нажимаем «Перезапустить программу» или «Закрыть программу».
Совет: перед запуском процедуры с циклом Do While… Loop, который может стать бесконечным, обязательно сохраните книгу, иначе, при принудительном закрытии редактора VBA ваши изменения будут утеряны. Кроме того, при принудительном закрытии редактора VBA, Excel может отключить макросы. Включите их в окне «Центр управления безопасностью», открыть которое можно по ссылке «Безопасность макросов» на ленте в разделе «Разработчик». Подробнее о включении макросов в разных версиях Excel читайте в статье: Как разрешить выполнение макросов в Excel?.
Пример использования оператора Exit Do:
Sub test5() Dim a As Byte, n As Long Do While a < 10 a = a + 1 n = n + 1 If a = 9 Then a = 0 End If If n = 1000 Then Exit Do End If Loop MsgBox n End Sub |
Когда число итераций цикла дойдет до 1000, он будет завершен, и информационное сообщение MsgBox выведет на экран число повторений цикла Do While… Loop из этого примера.
Содержание
- 1 Оператор цикла «For» в Visual Basic
- 1.1 Цикл «For … Next»
- 1.2 Цикл «For Each»
- 1.3 Оператор прерывания цикла «Exit For»
- 2 Цикл «Do While» в Visual Basic
- 3 Цикл «Do Until» в Visual Basic
Пару недель назад передо мной встала проблема разработки электронной таблицы, просчитывающую диапазоны рабочего времени в зависимости от рабочего графика и производственного календаря. С первого взгляда задача нетрудная, но в ходе проектирования я понял, что избежать использования циклов не удастся. Особую специфику здесь придавало условие заказчика, что готовый продукт должен быть именно
Excel
таблицей БЕЗ макросов и дополнительных модулей (функций пользователя).
Стандартный набор функций Excel не поддерживает ничего похожего на циклы, однако выход нашелся – использование циклических ссылок и итераций.
Первый шаг, чтобы начать работать с циклическими ссылками – это разрешить итеративные вычисления в Excel. В версии Microsoft Office XP это делается в разделе меню «Сервис – Параметры»:
В открывшемся окне активируем соответствующий флажок:
Так же обратите внимание на поле «Предельное число итераций» — оно определяет, сколько раз будет проходить вычисление по всем циклическим ссылкам, если вы сами не поставите ограничение.
!Информация: В Excel 2007 включение итеративных вычислений производится в пункте меню «Файл – Параметры Excel» в разделе «Формулы».
Рассмотрим пример использования итеративных вычислений в виде цикла.
Впишите в ячейку А1 формулу:
Если значение предельного числа итераций равно 100, то результатом вычислений в ячейке А1 будет равно 100. Теперь изменим формулу:
Как видите число итераций мы ограничили числом в ячейке А2, а именно 10. Чтобы проиллюстрировать, как происходят итерации, добавим формулу в ячейку B2:
Как видите, каждый этап итерации (новое значение А1) добавляется к ячейке B1 до тех пор пока происходят итерации.
!Замечание: Возможно, результат в B2 будет не таким – для того, чтобы исправить это сделайте следующее: после ввода формулы в ячейку B1 перейдите в ячейку A1, установите курсор в поле редактирования формулы и нажмите Enter – произойдет пересчет итераций. Для корректной работы итераций необходимо задать ряд дополнительных условий, ограничивающих их количество и задающее условие сброса текущего значения поля в исходное значение. Пересчет всех ячеек с циклическими ссылками происходит каждый раз при изменении ячеек, от которых они зависят.
!Дополнительные ссылки:
Встречаются ситуации, когда от программы VBA требуется совершить несколько раз подряд один и тот же набор действий (то есть повторить несколько раз один и тот же блок кода). Это может быть сделано при помощи циклов VBA.
К циклам VBA относятся:
- Цикл For
- Цикл Do While
- Цикл Do Until
Далее мы подробно рассмотрим каждый из этих циклов.
Оператор цикла «For» в Visual Basic
Структура оператора цикла For в Visual Basic может быть организована в одной из двух форм: как цикл For … Next или как цикл For Each.
Цикл «For … Next»
Цикл For … Next использует переменную, которая последовательно принимает значения из заданного диапазона. С каждой сменой значения переменной выполняются действия, заключённые в теле цикла. Это легко понять из простого примера:
For i = 1 To 10 Total = Total + iArray(i) Next i
В этом простом цикле For … Next используется переменная i, которая последовательно принимает значения 1, 2, 3, … 10, и для каждого из этих значений выполняется код VBA, находящийся внутри цикла. Таким образом, данный цикл суммирует элементы массива iArray в переменной Total.
В приведённом выше примере шаг приращения цикла не указан, поэтому для пошагового увеличения переменной i от 1 до 10 по умолчанию используется приращение . Однако, в некоторых случаях требуется использовать другие значения приращения для цикла. Это можно сделать при помощи ключевого слова Step, как показано в следующем простом примере.
For d = 0 To 10 Step 0.1 dTotal = dTotal + d Next d
Так как в приведённом выше примере задан шаг приращения равный 0.1, то переменная dTotal для каждого повторения цикла принимает значения 0.0, 0.1, 0.2, 0.3, … 9.9, 10.0.
Для определения шага цикла в VBA можно использовать отрицательную величину, например, вот так:
For i = 10 To 1 Step -1 iArray(i) = i Next i
Здесь шаг приращения равен -1, поэтому переменная i с каждым повторением цикла принимает значения 10, 9, 8, … 1.
Цикл «For Each»
Цикл For Each похож на цикл For … Next, но вместо того, чтобы перебирать последовательность значений для переменной-счётчика, цикл For Each выполняет набор действий для каждого объекта из указанной группы объектов. В следующем примере при помощи цикла For Each выполняется перечисление всех листов в текущей рабочей книге Excel:
Dim wSheet As Worksheet For Each wSheet in Worksheets MsgBox "Найден лист: " & wSheet.Name Next wSheet
Оператор прерывания цикла «Exit For»
Оператор Exit For применяется для прерывания цикла. Как только в коде встречается этот оператор, программа завершает выполнение цикла и переходит к выполнению операторов, находящихся в коде сразу после данного цикла. Это можно использовать, например, для поиска определённого значения в массиве. Для этого при помощи цикла просматривается каждый элемент массива. Как только искомый элемент найден, просматривать остальные нет необходимости – цикл прерывается.
Применение оператора Exit For продемонстрировано в следующем примере. Здесь цикл перебирает 100 записей массива и сравнивает каждую со значением переменной dVal. Если совпадение найдено, то цикл прерывается:
For i = 1 To 100 If dValues(i) = dVal Then IndexVal = i Exit For End If Next i
Цикл «Do While» в Visual Basic
Цикл Do While выполняет блок кода до тех пор, пока выполняется заданное условие. Далее приведён пример процедуры Sub, в которой при помощи цикла Do While выводятся последовательно числа Фибоначчи не превышающие 1000:
'Процедура Sub выводит числа Фибоначчи, не превышающие 1000 Sub Fibonacci() Dim i As Integer 'счётчик для обозначения позиции элемента в последовательности Dim iFib As Integer 'хранит текущее значение последовательности Dim iFib_Next As Integer 'хранит следующее значение последовательности Dim iStep As Integer 'хранит размер следующего приращения 'инициализируем переменные i и iFib_Next i = 1 iFib_Next = 0 'цикл Do While будет выполняться до тех пор, пока значение 'текущего числа Фибоначчи не превысит 1000 Do While iFib_Next < 1000 If i = 1 Then 'особый случай для первого элемента последовательности iStep = 1 iFib = 0 Else 'сохраняем размер следующего приращения перед тем, как перезаписать 'текущее значение последовательности iStep = iFib iFib = iFib_Next End If 'выводим текущее число Фибоначчи в столбце A активного рабочего листа 'в строке с индексом i Cells(i, 1).Value = iFib 'вычисляем следующее число Фибоначчи и увеличиваем индекс позиции элемента на 1 iFib_Next = iFib + iStep i = i + 1 Loop End Sub
В приведённом примере условие iFib_Next < 1000 проверяется в начале цикла. Поэтому если бы первое значение iFib_Next было бы больше 1000, то цикл бы не выполнялся ни разу.
Другой способ реализовать цикл Do While – поместить условие не в начале, а в конце цикла. В этом случае цикл будет выполнен хотя бы раз, не зависимо от того, выполняется ли условие.
Схематично такой цикл Do While с проверяемым условием в конце будет выглядеть вот так:
Do ... Loop While iFib_Next < 1000
Цикл «Do Until» в Visual Basic
Цикл Do Until очень похож на цикл Do While: блок кода в теле цикла выполняется раз за разом до тех пор, пока заданное условие выполняется (результат условного выражения равен True). В следующей процедуре Sub при помощи цикла Do Until извлекаются значения из всех ячеек столбца A рабочего листа до тех пор, пока в столбце не встретится пустая ячейка:
iRow = 1 Do Until IsEmpty(Cells(iRow, 1)) 'Значение текущей ячейки сохраняется в массиве dCellValues dCellValues(iRow) = Cells(iRow, 1).Value iRow = iRow + 1 Loop
В приведённом выше примере условие IsEmpty(Cells(iRow, 1)) находится в начале конструкции Do Until, следовательно цикл будет выполнен хотя бы один раз, если первая взятая ячейка не пуста.
Однако, как было показано в примерах цикла Do While, в некоторых ситуациях нужно, чтобы цикл был выполнен хотя бы один раз, не зависимо от первоначального результата условного выражения. В таком случае условное выражение нужно поместить в конце цикла, вот так:
Do ... Loop Until IsEmpty(Cells(iRow, 1))
Урок подготовлен для Вас командой сайта office-guru.ru
Источник: /> Перевел: Антон Андронов
Правила перепечаткиЕще больше уроков по Microsoft Excel
Оцените качество статьи. Нам важно ваше мнение:
Добрый день!
Неделю пытаюсь разобраться с макросами в Excel — выходит признаюсь честно плохо…
Решение задачи так и не нашла. Надеюсь вы сумеете мне подсказать куда конкретнее направить свою активность.
Задача передо мной стоит такая:
ячейка A1 содержит значение, которое я с помощью формул разбиваю на диапазон ячеек (задействовано 276 ячеек) целыми числами. Но при разбивке образуется дельта округления. Так вот мне необходимо эту дельту целыми числами доразнести в уже заполненные формулами ячейки например по порядку.
Например если дельта = 117, а диапазон 276, то в первые 117 ячеек прибавляем по 1, а остальные не трогаем.
Подскажите, пожалуйста, возможно ли вообще это описать для Excel?
На чтение 13 мин. Просмотров 26.4k.
Рамакришна, Источники индийской мудрости
Сейчас … мы идем по кругу
Эта статья содержит полное руководство по VBA Do While и VBA While Loops. (Если вы ищете информацию о циклах VBA For и For Each, перейдите сюда)
Цикл VBA While существует, чтобы сделать его совместимым со старым кодом. Однако Microsoft рекомендует использовать цикл Do Loop, поскольку он более «структурирован и гибок». Оба этих цикла рассматриваются в этом посте.
Для быстрого ознакомления с этими циклами перейдите к таблице быстрого руководства ниже.
Если вы ищете что-то конкретное, вы можете посмотреть содержание ниже.
Содержание
- Краткое руководство по VBA While Loops
- Введение
- Цикл For против цикла Do While
- Условия
- Формат цикла Do
- Цикл Exit Do
- While Wend
- Бесконечный цикл
- Использование функций Worksheet вместо циклов
- Резюме
Краткое руководство по VBA While Loops
Формат цикла | Описание | Пример |
Do While … Loop | Запускается 0 или более раз, пока условие выполняется | Do While result = «Верно» Loop |
Do … Loop While | Запускается 1 или более раз, пока условие выполняется | Do Loop While result = «Верно» |
Do Until … Loop | Запускается 0 или более раз, пока условие не будет выполнено | Do Until result <> «Верно» Loop |
Do … Until Loop | Запускается 1 или более раз, пока условие не будет выполнено | Do Loop Until result <> «Верно» |
While … Wend R |
Запускается 0 или более раз, пока условие истинно. Примечание: этот цикл считается устаревшим. |
While result = «Верно» Wend |
Exit the Do Loop | Завершает Do | Do While i < 10 i = GetTotal If i < 0 Then Exit Do End If Loop |
Введение
Если вы никогда ранее не использовали циклы, тогда вы можете прочитать «Что такое циклы и зачем они вам нужны» из моего поста в журнале For Loop.
Я собираюсь сосредоточиться в основном на Do Loop в этой статье. Как я упоминал выше, мы видели, что цикл While Wend считается устаревшим. Для полноты информации я все равно его включил в эту статью.
Итак, во-первых, зачем нам нужны циклы Do While, когда у нас уже есть циклы For?
Цикл For против цикла Do While
Когда мы используем цикл For Loop, мы заранее знаем, сколько раз мы хотим его запустить. Например, мы можем захотеть запустить цикл один раз для каждого элемента в коллекции, массиве или словаре.
В следующем примере кода мы видим в начале каждого цикла, сколько раз он будет выполняться.
' запускается 5 раз For i = 1 To 5 ' запускается один раз для каждого элемента коллекции For i = 1 To coll.Count ' запускается один раз для каждого элемента в arr For i = LBound(arr) To coll.lbound(arr) ' запускается один раз для каждого значения от 1 до значения в lastRow For i = 1 To lastRow ' запускается один раз для каждого элемента в коллекции For Each s In coll
Цикл Do другой. Он работает:
- В то время как условие верно
- Пока условие не будет выполнено
Другими словами, количество циклов в большинстве случаев не имеет значения.
Итак, что такое условие и как мы их используем?
Условия
Условие — это утверждение, которое оценивается как истинное или ложное. Они в основном используются с операторами Loops и If. При создании условия вы используете такие знаки, как >, <, <>,> =, =.
Ниже приведены примеры условий
Условие | Истина, когда… |
x < 5 | x меньше 5 |
x <= 5 | x меньше либо равен 5 |
x > 5 | x больше 5 |
x >= 5 | x больше либо равен 5 |
x = 5 | x равен 5 |
x <> 5 | x не равен 5 |
x > 5 And x < 10 | x больше 5 И меньше 10 |
x = 2 Or x >10 | x равен 2 ИЛИ больше 10 |
Range(«A1») = «Иван» | Ячейка A1 содержит текст «Иван» |
Range(«A1») <> «Иван» | Ячейка A1 не содержит текст «Иван» |
Вы могли заметить x = 5 как условие. Его следует путать с х = 5, при использовании в качестве назначения.
Например
' означает: значение 6 будет храниться в х x = 6 ' означает: х равен 6? If x = 6 ' означает: х равен 6? Do While x = 6
В следующей таблице показано, как «=» используется в условиях и назначениях.
Использование «=» | Тип | Имеется в виду |
Loop Until x = 5 | Условие | x равен 5? |
Do While x = 5 | Условие | x равен 5? |
If x = 5 Then | Условие | x равен 5? |
For x = 1 To 5 | Присваивание | Установите значение x = 1, затем = 2 и т.д. |
x = 5 | Присваивание | Установите значение x=5 |
b = 6 = 5 | Присваивание и условие |
Присвойте b результату условия 6 = 5 |
x = MyFunc(5,6) | Присваивание | Присвойте х значение, возвращаемое функцией |
Формат цикла Do
Цикл Do можно использовать четырьмя способами, и это часто вызывает путаницу. Однако в каждом из этих четырех способов есть только небольшая разница.
Do всегда в начале первой строки, а Loop всегда в конце последней строки.
Мы можем добавить условие после любой строки.
Do [условие] Loop Do Loop [условие]
Условию предшествует While или Until, которое дает нам эти четыре возможности
Do While [условие] Loop Do Until [условие] Loop Do Loop While [условие] Do Loop Until [условие]
Давайте посмотрим на некоторые примеры, чтобы прояснить это.
Примеры цикла Do
Представьте, что вы хотите, чтобы пользователь ввел список элементов. Каждый раз, когда пользователь вводит элемент, вы печатаете его в «Immediate Window». Когда пользователь вводит пустую строку, вы хотите, чтобы приложение закрывалось.
В этом случае цикл For не подойдет, поскольку вы не знаете, сколько элементов будет вводить пользователь. Пользователь может ввести пустую строку первым или с сотой попытки. Для этого типа сценария вы бы использовали цикл Do.
Следующий код показывает это
Dim sCommand As String Do ' Получить пользовательский ввод sCommand = InputBox("Пожалуйста, введите элемент") ' Печать в Immediate Window (Ctrl + G для просмотра) Debug.Print sCommand Loop While sCommand <> ""
Код входит в цикл и продолжается до тех пор, пока не достигнет строки «Loop While». На этом этапе он проверяет, оценивается ли условие как истинное или ложное.
Если условие оценивается как ложное, то код выходит из цикла и продолжается.
Если условие оценивается как истинное, то код возвращается к строке Do и снова проходит через цикл.
Разница между наличием условия на линии Do и на линии Loop очень проста.
Когда условие находится в строке Do, цикл может вообще не работать. Так что он будет работать ноль или более раз.
Когда условие находится на линии Loop, цикл всегда будет запущен хотя бы один раз. Так что он будет запущен один или несколько раз.
В нашем последнем примере условие находится в строке Loop, потому что мы всегда хотим получить хотя бы одно значение от пользователя. В следующем примере мы используем обе версии цикла. Цикл будет выполняться, пока пользователь не введет букву «н».
Sub GetInput() Dim sCommand As String ' Условие в начале Do While sCommand <> "н" sCommand = InputBox("Пожалуйста, введите элемент для цикла 1") Loop ' Условие в конце Do sCommand = InputBox("Пожалуйста, введите элемент для цикла 2") Loop While sCommand <> "н" End Sub
В приведенном выше примере оба цикла будут вести себя одинаково.
Однако, если мы установим для sCommand значение «н» до запуска цикла «Do While», код не войдет в цикл.
Sub GetInput2() Dim sCommand As String sCommand = "н" ' Цикл не будет работать, поскольку команда "н" Do Whilel sCommand <> "н" sCommand = InputBox("Пожалуйста, введите элемент для цикла 1") Loop ' Цикл все равно будет запущен хотя бы один раз Do sCommand = InputBox("Пожалуйста, введите элемент для цикла 2") Loop While sCommand <> "н" End Sub
Второй цикл в вышеприведенном примере (то есть Loop While) всегда будет запускаться хотя бы один раз.
While против Until
При использовании Do Loop условию должно предшествовать Until или While.
Until и While, по сути, противоположны друг другу. Они используются в VBA аналогично тому, как они используются в английском языке.
Например:
- Оставьте одежду, пока не пойдет дождь
- Оставь одежду, пока не идет дождь
Другой пример:
- Оставайся в постели, пока не станет светло
- Оставайся в постели, пока темно
Еще один пример:
- повторять, пока число не станет больше или равно десяти
- повторить пока счет меньше десяти
Как видите, использование Until и While — это просто противоположный способ написания одного и того же условия.
Примеры Until и While
Следующий код показывает циклы «While» и «Until» рядом. Как видите, единственная разница в том, что условие полностью изменено.
Примечание: знаки <> означают «не равно».
Sub GetInput() Dim sCommand As String ' Условие в начале Do Until sCommand = "н" sCommand = InputBox("Пожалуйста, введите элемент для цикла 1") Loop Do While sCommand <> "н" sCommand = InputBox("Пожалуйста, введите элемент для цикла 1") Loop ' Условие в конце Do sCommand = InputBox("Пожалуйста, введите элемент для цикла 2") Loop Until sCommand = "н" Do sCommand = InputBox("Пожалуйста, введите элемент для цикла 2") Loop While sCommand <> "н" End Sub
- Первый цикл: запускается только в том случае, если sCommand не равен ‘н’.
- Второй цикл: запускается только в том случае, если sCommand не равен ‘н’.
- Третий цикл: будет запущен хотя бы один раз перед проверкой sCommand.
- Четвертый цикл: будет запущен хотя бы один раз перед проверкой sCommand.
Пример: проверка объектов
Примером использования Until и While является проверка объектов. Когда объект не был назначен, он имеет значение Nothing.
Поэтому, когда мы объявляем переменную книги в следующем примере, она имеет значение Nothing, пока мы не назначим ее Workbook.
Противоположностью Nothing не является Nothing, что может сбить с толку.
Представьте, что у нас есть две функции: GetFirstWorkbook и GetNextWorkbook, которые возвращают некоторые объекты книги. Код будет печатать имя рабочей книги до тех пор, пока функции больше не вернут действительную рабочую книгу.
Вы можете увидеть пример кода здесь:
Dim wrk As Workbook Set wrk = GetFirstWorkbook() Do Until wrk Is Nothing Debug.Print wrk.Name Set wrk = GetNextWorkbook() Loop
Написание этого кода с использованием Do While было бы более запутанным, так как условие Not Is Nothing
Dim wrk As Workbook Set wrk = GetFirstWorkbook() Do While Not wrk Is Nothing Debug.Print wrk.Name Set wrk = GetNextWorkbook() Loop
Это делает код более понятным, и наличие четких условий — всегда хорошо. Честно говоря, разница маленькая, и выбор между «While» и «Until» действительно сводится к личному выбору.
Цикл Exit Do
Мы можем выйти из любого цикла Do с помощью оператора Exit Do.
Следующий код показывает пример использования Exit Do
Do While i < 1000 If Cells(i,1) = "Найдено" Then Exit Do End If i = i + 1 Loop
В этом случае мы выходим из цикла Do Loop, если ячейка содержит текст «Найдено».
While Wend
Этот цикл в VBA, чтобы сделать его совместимым со старым кодом. Microsoft рекомендует использовать циклы Do, поскольку они более структурированы.
Из MSDN: «Оператор Do… Loop обеспечивает более структурированный и гибкий способ выполнения циклов».
Формат цикла VBA While Wend
Цикл VBA While имеет следующий формат:
While <Условие>
Wend
While Wend против Do
Разница между циклами VBA While и VBA Do заключается в следующем:
- While может иметь условие только в начале цикла.
- While не имеет версии Until.
- Не существует оператора для выхода из цикла While, как Exit For или Exit Do.
Условие для цикла VBA While такое же, как и для цикла VBA Do While. Два цикла в приведенном ниже коде работают точно так же.
Sub GetInput() Dim sCommand As String Do While sCommand <> "н" sCommand = InputBox("Пожалуйста, введите элемент для цикла 1") Loop While sCommand <> "н" sCommand = InputBox("Пожалуйста, введите элемент для цикла 2") Wend End Sub
Бесконечный цикл
Даже если вы никогда не писали код в своей жизни, я уверен, что вы слышали фразу «Бесконечный цикл». Это цикл, в котором условие никогда не будет выполнено. Обычно это происходит, когда вы забыли обновить счетчик.
Следующий код показывает бесконечный цикл
Dim cnt As Long cnt = 1 'это бесконечный цикл Do While cnt <> 5 Loop
В этом примере cnt установлен в 1, но он никогда не обновляется. Поэтому условие никогда не будет выполнено — cnt всегда будет меньше 5.
В следующем коде cnt обновляется каждый раз, поэтому условие будет выполнено.
Dim cnt As Long cnt = 1 Do While cnt <> 5 cnt = cnt + 1 Loop
Как вы можете видеть, использование For Loop безопаснее для подсчета, поскольку оно автоматически обновляет счет в цикле. Ниже приведен тот же цикл с использованием For.
Dim i As Long For i = 1 To 4 Next i
Это явно лучший способ сделать это. Цикл For устанавливает начальное значение, условие и счет в одну строку.
Конечно, можно использовать бесконечный цикл, используя For — это потребует немного больше усилий 🙂
Dim i As Long ' Бесконечный цикл For i = 1 To 4 ' i никогда не достигнет 4 i = 1 Next i
Работа с бесконечным циклом
Когда у вас бесконечный цикл — VBA не выдаст ошибку. Ваш код будет продолжать работать, а редактор Visual Basic не будет отвечать.
Раньше вы могли выйти из цикла, просто нажав Ctrl и Break. В настоящее время разные ноутбуки используют разные комбинации клавиш. Полезно знать, как это настроено в вашем ноутбуке, чтобы в случае возникновения бесконечного цикла вы могли легко остановить код.
Вы также можете выйти из цикла, убив процесс. Нажмите Ctrl + Shift + Esc. На вкладке Процессы найдите Excel / Microsoft Excel. Щелкните правой кнопкой мыши по этому и выберите «Завершить процесс». Это закроет Excel, и вы можете потерять часть работы — так что гораздо лучше использовать Ctrl + Break или его эквивалент.
Использование функций Worksheet вместо циклов
Иногда вы можете использовать функцию листа вместо цикла.
Например, представьте, что вы хотите добавить значения в список ячеек. Вы можете сделать это с помощью цикла, но было бы более эффективно использовать функцию таблицы Sum. Это быстрее и экономит много кода.
Использовать функции рабочего листа очень просто. Ниже приведен пример использования Sum и Count.
Sub WorksheetFunctions() Debug.Print WorksheetFunction.Sum(Range("A1:A10")) Debug.Print WorksheetFunction.Count(Range("A1:A10")) End Sub
В следующем примере используется цикл для выполнения того же действия. Как видите, это гораздо более длинный способ достижения той же цели.
Sub SumWithLoop() Dim total As Long, count As Long Dim rg As Range For Each rg In Range("A1:A10") ' Total total = total + rg ' Count If rg <> "" Then count = count + 1 End If Next rg Debug.Print total Debug.Print count End Sub
Резюме
Цикл Do While
- Цикл Do можно использовать 4 способами.
- Его можно использовать в начале или в конце, Do While .. Loop, Do … Loop While
- Может использоваться с Until в начале или в конце, Do Until .. Loop, Do … Loop Until
- While и Until используют противоположные условия друг к другу.
- Бесконечный цикл происходит, если ваше условие выхода никогда не будет выполнено.
- Иногда использование функции рабочего листа более эффективно, чем использование цикла.
Цикл While Wend
- Цикл Wend Wend устарел, и вы можете вместо этого использовать цикл Do.
A loop is an essential concept for any programming language, and VBA follows the same approach. You can use loops to repeat an action until a specified condition is reached, or move through objects in a group, e.g. all worksheets in a workbook. A loop is an essential concept for programming. In this guide, we’re going to show you how to create a VBA loop in Excel.
Download Workbook
VBA loops can be useful to automate tasks. For example, you may need to protect or unprotect every worksheet at once, iterate a calculation for a specific number of times, or loop cells and store their values into an array until you find an empty cell. The rest is up to your needs and imagination.
VBA has two main loop categories:
- For…Next Loops
- Do Loops
In generally, while For…Next loops are designed for specific amount of iterations, Do loops are good for iterating based on a condition. However, you can modify and configure both loop types by their individual keywords. Let’s see the loop types with examples.
For…Next VBA Loop
For…Next (also known as For) loops are where you start to create VBA loops in Excel. A For loop is a basic concept of a loop structure in all programming languages. A For…Next loop is good for if you want to iterate you code certain amount of times, and for when you need to use the counter. For example, if you want to check cells from A1 to A10, a counter clicks from 1 to 10 can work in that case. Let’s see its syntax and an example.
Syntax
For counter = start To end [ Step step ]
[ statements ]
[ Exit For ]
[ statements ]
Next [ counter ]
Part | Description |
counter | Required. Numeric variable used as a loop counter. The variable can’t be a Boolean or an array element. |
start | Required. Initial value of counter. |
end | Required. Final value of counter. |
step | Optional. Amount counter is changed each time through the loop. If not specified, step defaults to one. |
statements | Optional. One or more statements between For and Next that are executed a specific number of times. |
Example 1 – Basic Form
In the first example of For…Next loop, we attempt to write serial numbers into the cells in A1:A10. In this code, For…Next loop sets values from 1 to 10 into the variable i. After the variable gets its value, you can use it in the code. We used the variable to specify the row numbers and cell values. Finally, the Next row increases the variable’s row by 1, and cycle goes on until the variable is equal to 11.
Sub FillSerialNumbers() Dim i As Integer For i = 1 To 10 ActiveSheet.Cells(i, 1) = i Next i End Sub
Example 2 – Step
By default, For…Next loop increases its counter variable by 1 for each loop. You can change this property by using the step argument. To specify a step argument, use the Step keyword after the end argument and enter a number. Step can be either a positive or negative.
The following code is a modified version of the first example. Step 2 argument is added to loop. In this loop, the variable i can only take «1, 3, 5, 7, 9» values.
Sub FillSerialNumbers_Step2() Dim i As Integer For i = 1 To 10 Step 2 ActiveSheet.Cells(i, 1) = i Next i End Sub
Remember to choose appropriate start and end arguments when you need to use a negative step value. For example, For I = 10 To 1 Step -1
Example 3 – Nested Loops
You can create loops within other loops. VBA executes all iterations in an inner loop, for each iteration of the outer loop. This type of structure can be helpful if you want add additional dimensions into your code. For example, while one loop is counting rows, other can count the columns. You need three loops to fill a three-dimensional data array.
The important point is using different counter variables for each loop. Otherwise, there will be leaps for the counter values. Let’s see an example for nested For…Next loops.
The following code contains 2 For…Next loops which is using variables named i and j. In the statement panel, i and j are used as row and column numbers respectively.
In the first run, i becomes 1 and j becomes 2. After code is executed in the j-loop, while i keeps its value (1), j becomes 3. This cycle goes on until j becomes 7. After this, i becomes 2 and j returns back to 2.
Sub FillSerialNumbers_Nested() Dim i As Integer, j As Integer For i = 1 To 10 For j = 2 To 6 ActiveSheet.Cells(i, j) = i * j Next j Next i End Sub
Since j gets numbers between 2 and 6, only columns from B to F are filled.
Example 4 – Exit For
You may want to exit a loop when a certain condition is met. Let’s say we do not want to fill cells if i * j is more than 18. To achieve this, we can use Exit For statement.
The following code uses Exit For in the inner loop. Please note that, Exit For works for only the loop it’s in. Thus, when i * j > 18 condition is met, VBA continues to run the outer loop (i-loop).
Sub FillSerialNumbers_ExitFor() Dim i As Integer, j As Integer For i = 1 To 10 For j = 2 To 6 If i * j > 18 Then Exit For ActiveSheet.Cells(i, j) = i * j Next j Next i End Sub
Example 5 — For Each
A For Each loop is a more specialized version of the For…Next loops. For Each loops can iterate for elements in a list. These elements can be values in an array, cells in a range, or worksheets in workbook. For Each loops doesn’t need a counter, each element is stored in a variable to be used in the code.
Let’s take another example. This time there isn’t a counter variable, but a range object c. For Each loop assigns each cell in the range «A1:C8» to element c, at each iteration. Also, since there is no counter value, we need to increase an integer by 1 in the code.
Sub FillSerialNumbers_ForEach() Dim c As Range, i As Integer i = 0 For Each c In ActiveSheet.Range("A1:C8") i = i + 1 c = i Next c End Sub
This is the last example for the For…Next loops of our how to create a VBA loop in Excel guide. Let’s now move on to the Do loops.
Do VBA Loop
A Do loop looks at whether a condition is met to continue cycling through, or stop a loop. Do loops are more flexible than For…Next loops. On the other hand, this flexibility comes with some complexities.
A Do loop starts with Do and finishes with Loop keywords. You can define a condition for one of these statements. If you specify a condition with Do, VBA looks at the condition first; otherwise, the code block in the loop is executed and the condition is evaluated at the end. This flexibility presents 2 syntaxes.
Also, Do loops can use While and Until keywords to specify the action when a condition is met. If you use the While keyword, the loop continues to work if condition is met. On the other hand, the Until keyword stops the loop.
Syntax
Do [{ While | Until } condition ]
[ statements ]
[ Exit Do ]
[ statements ]
Loop
Or, you can use this syntax:
Do
[ statements ]
[ Exit Do ]
[ statements ]
Loop [{ While | Until } condition ]
Part | Description |
condition | Optional. Numeric expression or string expression that is True or False. If condition is Null, condition is treated as False. |
statements | One or more statements that are repeated while, or until, condition is True. |
Example 1 – Do While
Do While loop iterates its statements as long as the specified conditions are valid. We can modify our first example to work with a Do loop.
In the following example, the Do loop works as many iterations as the variable i is equal or less than 10.
Sub FillSerialNumbers_DoWhile() Dim i As Integer i = 1 Do While i <= 10 ActiveSheet.Cells(i, 1) = i i = i + 1 Loop End Sub
Caution: If you use a loop like this, remember to add a code to change the value of the variable. Otherwise, the code will be stuck in an infinite loop because the variable i will always remain less than 10.
Example 2 — Do Until
This time the loop continues «until» the condition is met. Once it does, the loop ends.
Sub FillSerialNumbers_DoUntil() Dim i As Integer i = 1 Do Until i > 10 ActiveSheet.Cells(i, 1) = i i = i + 1 Loop End Sub
Example 3 – Loop While
You can use conditions after Loop as well. In this scenario, you ensure that the statements are executed at least once before condition validation.
Loop While iterates the loop if the supplied condition is met.
Sub FillSerialNumbers_DoLoopWhile() Dim i As Integer i = 1 Do ActiveSheet.Cells(i, 1) = i i = i + 1 Loop While i <= 10 End Sub
Example 4 – Loop Until
Use Loop Until statement when you need to check the condition after the statements, and want to continue the loop «until» the condition is met.
Sub FillSerialNumbers_DoLoopUntil() Dim i As Integer i = 1 Do ActiveSheet.Cells(i, 1) = i i = i + 1 Loop Until i > 10 End Sub
That’s all! You can now create your own VBA loop to automate your Excel tasks in no time.
Владимир Пользователь Сообщений: 8196 |
Добрый день. «..Сладку ягоду рвали вместе, горьку ягоду я одна.» |
The_Prist Пользователь Сообщений: 14181 Профессиональная разработка приложений для MS Office |
Во-первых, сравнивать Do…Loop и If — неправильно. Одна является конструкцией цикла, а вторая условия. Так же Do … Loop применяется вместе с Find для определения всех найденных значений(пример есть в офф.справке по методу Find-FindNext). Применить иной цикл не представляется возможным именно с Find, т.к. неизвестно заранее сколько значений будет найдено. При этом часто такой подход применяется для одновременной замены или удаления найденного, что дополнительно усложняет выполнение задачи иными средствами. Правда, в Do .. Loop надо очень аккуратно относится к условиям, дабы не завесить ПК. Поэтому часто в этот цикл вставляется DoEvents, чтобы можно было прервать цикл, если он «ушел в бесконечность»(условие недостижимо вследствие ошибки программиста). Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
TheBestOfTheBest Пользователь Сообщений: 2366 Excel 2010 +PLEX +SaveToDB +PowerQuery |
в Do Loop не всегда будет первый проход, в For Next — всегда. Неизлечимых болезней нет, есть неизлечимые люди. |
The_Prist Пользователь Сообщений: 14181 Профессиональная разработка приложений для MS Office |
#4 23.04.2015 12:36:35
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
||||
Hugo Пользователь Сообщений: 23249 |
#5 23.04.2015 12:45:24 Практически никогда не использую Do…Loop.
Ну или можно сделать наоборот. |
||
Hugo Пользователь Сообщений: 23249 |
#6 23.04.2015 12:49:55 Или вот что где-то говорил Казанский: Есть несколько особенностей циклов, которые не освещаются в литературе подробно, и ускользают даже от внимательного читателя. Вот, навскидку: 1. Цикл For Each можно использовать не только для перебора элементов коллекции (например, коллекции ячеек в диапазоне), но и для перебора элементов массива. Причем массив может формироваться «тут же» функцией Array или Split. Этот фрагмент перевернет названия перечисленных листов:
или
2. Цикл Do…Loop вполне может использоваться без While или Until, если предусмотрен выход из цикла с помощью Exit Do. Этот фрагмент будет выдавать сообщение, пока пользователь не нажмет «Отмена» или «крестик»:
3. После «нормального» выхода из цикла For Each, переменная цикла содержит Nothing. Это можно использовать для определения того, как произошел выход из цикла — после перебора последнего элемента или по Exit For. Этот фрагмент определяет, содержится ли в книге лист с заданным именем:
|
||||||||
Do loop использую, когда точно не знаю рамок применения цикла, а использовать дополнительную переменную не представляется возможным (примерно как в ответе The Priest про find). Если все же возникает необходимость использовать Do loop, надо быть осторожным в том смысле, что нужно обновлять условие, которое идет для сравнения в while, until. Если обновление сравниваемой переменной задано некорректно, мы можем попасть в бесконечный цикл (infinite loop). Именно по этой причине в любых циклах (в том числе и в for loop, если рамки слишком большие) желательно использовать DoEvents, как уже сказано выше. For loop обычно имеет конечные рамки, которые задаются жесткими цифрами (hardcoded values) либо переменными, значения которых мы как-то изначально получаем. Типичный пример — прогон массивов. Вообще надо, где удобно, уходить от циклов, используя при этом блок on error resume next — on error goto 0. Например алгоритм перебора файлов, который имеет линейную комплексность, может стать по комплексности константой, но это уже совсем другая история. С уважением, |
|
The_Prist Пользователь Сообщений: 14181 Профессиональная разработка приложений для MS Office |
#8 23.04.2015 13:15:21
здесь не соглашусь. Обходы ошибок это не совсем правильный вариант. Если есть вариант без этого — лучше использовать его. Почему нет, если все используют и горя не знают? Все просто: по умолчанию в настройках VBE установлено: Tools-Options-вкладка General-Breack on unhandled Errors. Но если кто-то сменит и установит: Breack on All Errors — то On Error Resume Next будет бесполезен.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
||||
TheBestOfTheBest Пользователь Сообщений: 2366 Excel 2010 +PLEX +SaveToDB +PowerQuery |
#9 23.04.2015 13:24:17
Перепутал с Do…until Изменено: TheBestOfTheBest — 23.04.2015 18:52:10 Неизлечимых болезней нет, есть неизлечимые люди. |
||
The_Prist Пользователь Сообщений: 14181 Профессиональная разработка приложений для MS Office |
#10 23.04.2015 13:30:32
Вы ничего не перепутали, когда писали, что у Next всегда будет проход, а у Loop нет? Вы либо определитесь — будет ли проверка условия, либо изучите мат.часть. Любой цикл сначала оценивает условия и входные данные. И после этого уже либо будет проход цикла(хотя бы одна итерация) — либо нет. Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
||||
TheBestOfTheBest Пользователь Сообщений: 2366 Excel 2010 +PLEX +SaveToDB +PowerQuery |
#11 23.04.2015 13:34:09
Тогда и вы учите матчасть
Неизлечимых болезней нет, есть неизлечимые люди. |
||||
The_Prist Пользователь Сообщений: 14181 Профессиональная разработка приложений для MS Office |
#12 23.04.2015 13:36:31
а это кто писал?
Уверены, что это я должен сделать? И в Вашем последнем примере кода лишь подтверждение моих слов. В приведенном примере Do сначала оценивает входные данные и условия. Т.к. в Вашем примере условия идут после прохода и отсутствуют в начале(специфика конструкции) — идет первый проход цикла и после сопоставление условия. For … Next лишен такой возможности и обязан всегда определять для начала входные условия(границы итераций) и только после этого принять решение — делать проход или нет. Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
||||
TheBestOfTheBest Пользователь Сообщений: 2366 Excel 2010 +PLEX +SaveToDB +PowerQuery |
Прочтите пост #9 Неизлечимых болезней нет, есть неизлечимые люди. |
Владимир Пользователь Сообщений: 8196 |
Хватит ругаться, ребята. «..Сладку ягоду рвали вместе, горьку ягоду я одна.» |
The_Prist Пользователь Сообщений: 14181 Профессиональная разработка приложений для MS Office |
#15 23.04.2015 13:53:05
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
|
TheBestOfTheBest Пользователь Сообщений: 2366 Excel 2010 +PLEX +SaveToDB +PowerQuery |
#16 23.04.2015 14:05:52
Неизлечимых болезней нет, есть неизлечимые люди. |
|
The_Prist Пользователь Сообщений: 14181 Профессиональная разработка приложений для MS Office |
#17 23.04.2015 14:24:03 Ну давайте разбираться. Вы изначально писали про Next. На это и была львиная доля ответов. Которые Вы читали вскользь, не пытаясь понять, что помимо непосредственно условий истинности(i<> и т.п.) есть входные данные. Чтобы Вы ни думали, но перед выполнением цикла сначала оцениваются входные данные: И именно исходя из этих данных VBE определяет — надо делать первый проход или нет. В случае с Do вообще неверно утверждать ни наличие прохода ни его отсутствие не приводя конкретный тип конструкции Do.
Я уже не стал приводить примеры вообще без проверки условий, опирающиеся на флаги. Там и так понятно, что в любом случае будет проход. И чтобы не было недопонимания: проходом лично я считаю в данном случае инструкции, расположенные между Do и Loop и между For и Next. Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
||
TheBestOfTheBest Пользователь Сообщений: 2366 Excel 2010 +PLEX +SaveToDB +PowerQuery |
#18 23.04.2015 14:34:38 Тогда к вам такой вопрос, конструкция test5() имеет цикл?
Имеет. Изменено: TheBestOfTheBest — 23.04.2015 14:39:24 Неизлечимых болезней нет, есть неизлечимые люди. |
||
The_Prist Пользователь Сообщений: 14181 Профессиональная разработка приложений для MS Office |
#19 23.04.2015 14:46:39
Во-первых все началось с того, что утверждали-то Вы обратное. Нет?
Вы бы хотя бы мои сообщения читали. Я же сам выше привел циклы и расписал какие из них будут иметь минимум один проход, а какие нет. Да, в приведенном Вами последнем примере будет в любом случае один проход. Но как это опровергает мои утверждения? Я вот этого не пойму. Еще раз написать? СНАЧАЛА ПРОВЕРЯЮТСЯ ВСЕ ВХОДНЫЕ ДАННЫЕ для определения цикла в принципе. Вводные данные, если угодно. Do имеет несколько реализаций и VBE должен сначала понять какая перед ним в данный момент. Если сразу после Do нет условия — значит сначала будет выполнен проход в любому случае. Если условие есть — то будет проверено это условие и после этого принято решение — делать проход или нет. Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
||||
The_Prist Пользователь Сообщений: 14181 Профессиональная разработка приложений для MS Office |
#20 23.04.2015 14:48:49
В споре рождается истина Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
||
vikttur Пользователь Сообщений: 47199 |
Вот же как хорошо получается! Двое спорят, а истину, которая рождается, все на ус мотают |
TheBestOfTheBest Пользователь Сообщений: 2366 Excel 2010 +PLEX +SaveToDB +PowerQuery |
#22 23.04.2015 14:58:11
Мне показалось, что формулировка «Любой цикл сначала оценивает условия и входные данные» некорректна, т.к. в test5() условие оценивается в конце цикла. Вы сами об этом пишите. Про входные данные не знаю, таких в коде я не вижу, есть оператор/конструкция Do…Loop и условие, приставленное к Do или к Loop. Как написано, так VBA и исполняет. Может вы дадите ссылку где написано про «Любой цикл сначала оценивает условия и входные данные», я поизучаю матчасть. Могу вот что еще добавить. Организация For Next всегда требует счетчика, с соответствующими заморочками (объявление переменных, присвоение значений TO и STEP), Do же этого не требует, здесь надо следить за условием, которое не требует счетчика. Изменено: TheBestOfTheBest — 23.04.2015 15:19:02 Неизлечимых болезней нет, есть неизлечимые люди. |
||
The_Prist Пользователь Сообщений: 14181 Профессиональная разработка приложений для MS Office |
#23 23.04.2015 15:18:47 Я уж и не знаю как написать-то, чтобы Вы поняли…
ни на какие мысли не наводит? Вы чуть передохните, обдумайте и заново перечитайте тему. Под входными данными в данном случае я понимаю конкретизацию цикла: это For … Next, Do … Loop, Do While … Loop и т.д.
Ведь Вы ответили человеку, который Do впервые видит. И ответили мало того, что изначально неверно, так и потом не конкретизировали, а отнесли все реализации циклов Do в одну свалку(а-ля они все имеют по-любому один проход). Это же неверно. Что я и пытаюсь до Вас донести. А ссылку на матчасть не дам, т.к. это на MSDN все расписано, но не в таком явном виде и не для VBA конкретно… Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
||||
TheBestOfTheBest Пользователь Сообщений: 2366 Excel 2010 +PLEX +SaveToDB +PowerQuery |
#24 23.04.2015 15:38:02
Разве утверждение ниже не верно?
Написано «может организовать», а не «должен организовать» — я это поправил и извинился за прежний ляп. Конкретику дал в коде. Я бы очень хотел увидеть официальный источник, где есть такие формулировки «Под входными данными в данном случае … конкретизацию цикла : это For … Next, Do … Loop, Do While … Loop и т.д.» или «Любой цикл сначала оценивает условия и входные данные…». Жду ссылку. Неизлечимых болезней нет, есть неизлечимые люди. |
||||
The_Prist Пользователь Сообщений: 14181 Профессиональная разработка приложений для MS Office |
#25 23.04.2015 16:14:07
Ждите. Я Вам ничего не должен и не собираюсь при таком подходе вообще Вам что-то давать или разъяснять. Я уже писал, что именно я имел под входными данными: наличие условия или его отсутствие. Т.е. признак, указывающий на тип цикла. Раз читать и вдумываться не хотите — есть MSDN — лопатьте сами, упрямства Вам не занимать. Расценивать это можете тоже как хотите. Мне уже отсюда видно, что бесполезно до Вас пытаться что-то донести. Поэтому лопатьте офф.источники и ищите там все, что душе угодно. Также можете дальше смело делать ляпы на форумах и не обращать внимания, когда Вас пытаются корректно поправить. Кстати, раз уж Вы первый на конкретные слова стали обращать внимание(типа «я же написал может» — несмотря на то, что я и не отрицал этого):
Вы уверены?
нет счетчика, нет To. Так же нет Step — он по умолчанию указан как 1. При этом директиву Option Explicit я убрал из модуля. И все работает без объявления. По-Вашему, Next всегда требует объявления переменных, а Do нет? А что отвечает за обязательное объявление переменных не напомните? Может имелось ввиду наличие некоей переменной цикла все же? Может все же чуть отдохнете и вдумаетесь в тему в целом? Может тогда поймете о чем я вообще тут писал. Циклы бывают разные и нельзя мерить единым мерилом и единые утверждения для них лепить. Равно как и сравнить какой лучше — всякий хорошо по своему в зависимости от задачи. Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
||||||
Максим Зеленский Пользователь Сообщений: 4646 Microsoft MVP |
#26 23.04.2015 16:18:30 Не пойму предмет спора…
Я думаю, компилятор всяко должен понять, какая конструкция использована — с условиями в начале и/или в конце, затем проверить их — либо в начале, либо в конце. Он же не построчно компилирует (как буквальный перевод), а по смыслу (литературно), нет? F1 творит чудеса |
|
TheBestOfTheBest Пользователь Сообщений: 2366 Excel 2010 +PLEX +SaveToDB +PowerQuery |
#27 23.04.2015 16:23:11
Да счетчик цикла. Без переменной x конструкция работать не будет. Или x не переменная? Хорошо, хорошо, я сдаюсь. Ваше эго круче. PS Кстати «директиву Option Explicit я убрал из модуля. И все работает без объявления.» — у меня не работает, говорит переменная не определена Изменено: TheBestOfTheBest — 23.04.2015 17:11:42 Неизлечимых болезней нет, есть неизлечимые люди. |
||
MCH Пользователь Сообщений: 3875 |
Прикольная дискуссия здесь. По существу вопроса Владимира: Для себя использую обычно конструкцию Do While условие:Loop заменяю на While условие:Wend, если это возможно (привычка экономии двух символов обусловленна решением олимпиадных задач по программированию) Изменено: MCH — 23.04.2015 17:08:36 |
The_Prist Пользователь Сообщений: 14181 Профессиональная разработка приложений для MS Office |
#29 23.04.2015 18:47:59
Началось с поста 3, где прозвучало утверждение, что For … Next в отличие от Do .. Loop всегда будет делать минимум один проход. Я подумал, что скорее всего опечатка — но после первого примера был как бы…Отправлен проверять свое опровержение. После того, как TheBestOfTheBest понял ошибку я уже пытался рассказать, что каждый цикл — разный. И нельзя однозначно сказать ни про Do … Loop, ни про For … Next, если не указать конкретную конструкцию.
А я тут ничем не мерялся и в мыслях этого не держал. Я уже пояснил причину своих сообщений Вам — Вы выкладываете утверждения, которые не всегда верны(по крайней мере в преподнесенном Вами изложении). Почитайте со стороны — не скажешь ведь, не зная, что имелось ввиду не отсутствие шага и наличие счетчика, а наличие переменной цикла(без которой For … Next немыслим). И тем более не скажешь, что имелось ввиду наоборот Do … Loop, а не For … Next. Если Option Explicit закомментирована или вообще отсутствует(что, собственно говоря для проекта равнозначно) — VBE не станет ругаться на необъявленную переменную, а просто применит к переменной с необъявленным типом директиву DefVar(т.е. тип Variant). И это справедливо для всех версий офиса и для VB(.NET не берем). Попробуйте скомпилировать проект после изменений. Вероятно некоторый глюк имеется в файле или в офисе в целом.
Переменная. Но, мне кажется, что это не Ваши слова, а мои. Ваши слова звучали иначе:
Разница налицо. И опять же — утверждение Ваше безаппеляционное и без каких-либо оговорок. И как следствие неверное в этом преподнесении. Если брать For i = n To k — то-таки да. Но не в целом для For … Next. О чем я опять же и написал. В общем: я на этом откланиваюсь, для меня тема исчерпана(в части циклов, по крайней мере). Торжество эго оставлю Вам. Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
||||||||
TheBestOfTheBest Пользователь Сообщений: 2366 Excel 2010 +PLEX +SaveToDB +PowerQuery |
#30 23.04.2015 19:30:16 Какjе-то недопонимание The_Prist. Вы в коде test5() переменную х использовали? Использовали. Я об этом же написал: «Организация For Next всегда требует счетчика,…» У вас в цикле он неявный и как следствие необъявленный, да еще и не число, а объект. Ну и что? Функция счетчика не пропала, система сама её реализовала, как впрочем и TO и STEP. Да, если не ставить Option Explicit ругаться не будет (у меня заругался на другое), но счетчик при этом не исчез, переменная не исчезла. Повторюсь: Не вижу безапелляционности, тем более для начинающего кодера VBA. Неизлечимых болезней нет, есть неизлечимые люди. |
0 / 0 / 0 Регистрация: 07.08.2016 Сообщений: 47 |
|
1 |
|
Excel Как пробежаться по столбцу неопределённого размера с помощью цикла, пока не встретится пустая ячейка?24.12.2018, 02:34. Показов 5744. Ответов 3
Подскажите как пробежаться по столбцу неопределённого размера с помощью цикла да тех пор пока не встретится пустая ячейка?
0 |
snipe 4038 / 1423 / 394 Регистрация: 07.08.2013 Сообщений: 3,541 |
||||
24.12.2018, 03:51 |
2 |
|||
Сообщение было отмечено repository как решение Решение
2 |
repository 0 / 0 / 0 Регистрация: 07.08.2016 Сообщений: 47 |
||||
24.12.2018, 18:28 [ТС] |
3 |
|||
но надо добавить скобки
без них почему то бесконечно циклирует
0 |
95 / 91 / 16 Регистрация: 13.04.2015 Сообщений: 545 |
|
24.12.2018, 19:32 |
4 |
repository, мне кажется не нужно использовать цикл!
1 |
IT_Exp Эксперт 87844 / 49110 / 22898 Регистрация: 17.06.2006 Сообщений: 92,604 |
24.12.2018, 19:32 |
4 |
При выполнении VBA программы (VBA, Visual Basic for Applications) может потребоваться повторить какой-то фрагмент кода несколько раз. Для выполнения этой задачи существуют циклы.
Синтаксис языка Visual Basic предусматривает следующие их типы:
- For.
- Do While.
- Do Until.
Давайте проанализируем отличия между ними во всех подробностях.
Содержание
- Цикл типа For
- For … Next
- Цикл For Each
- Конструкция Exit For
- Цикл Do While
- Цикл Do Until
Цикл типа For
Выделяют несколько отдельных типов цикла For. Существует тип For … Next и For Each.
For … Next
Цикл For … Next опирается на переменную, которая увеличивается по окончании каждой итерации в определенном диапазоне. И каждый раз происходит выполнение определенного кода. Проще всего изобразить принцип работы цикла этого типа на легком фрагменте кода.
For i = 1 To 10
Total = Total + iArray(i)
Next i
В приведенном варианте кода в рамках цикла определяется переменная, увеличивающая содержащееся в ней число на единицу после каждого выполнения фрагмента кода (это и называется итерацией).
Здесь не указан размер шага, поэтому циклом используется стандартный размер 1. Выполняется такое количество итераций, которое позволяет сделать так, чтобы значение прошло от 1 до 10. Но если потребуется использовать разные размеры шагов, необходимо использовать слово Step. Приведем пример для наглядности.
For d = 0 To 10 Step 0.1
dTotal = dTotal + d
Next d
В описанном варианте цикла определенный размер шага – 0,1, поэтому значение переменной d изменяется по числовому ряду 0.0, 0.1, 0,2 и так далее, пока значение переменной не достигнет 10.
Вы также можете использовать отрицательные числа для задания величины шага, как демонстрируется в этом фрагменте кода.
For i = 10 To 1 Step -1
iArray(i) = i
Next i
В данном примере кода указан размер шага -1. Следовательно, числовой ряд соответствующей переменной будет следующим: 10, 9, 8 — вплоть до единицы.
Цикл For Each
Цикл For Each аналогичен For Next, за исключением того, что последний проходит по числовому ряду значений, а For Each осуществляет требуемую последовательность действий для всех объектов, принадлежащих к заданной группе. Например, следующий код показывает, как пользователь мог бы применить цикл For Each.
Dim wSheet As Worksheet
For Each wSheet in Worksheets
MsgBox «Found Worksheet: » & wSheet.Name
Next wSheet
Этот код будет выполняться для каждого листа, входящего в состав документа, над которым работает человек.
Конструкция Exit For
Этот оператор предназначен для окончания работы цикла до выполнения всех итераций. При определенных условиях интерпретатор останавливает цикл и начинает выполнять линию кода, следующую за ним.
Например, если ставится задача найти определенное значение массива, можно использовать цикл для перебора всех его элементов до тех пор, пока оно не будет найдено. Если же необходимое значение обнаруживается, в дальнейшем нет надобности продолжать поиски, поэтому цикл завершается.
Рассмотрим еще один пример, который хорошо отображает работу оператора Exit For. Здесь цикл анализирует 100 объектов, интерпретатор сравнивает каждый из них со значением переменной dValue1s. Если оно равно dVal1, то цикл завершается.
For i = 1 To 100
If dValues1(i) = dVal1 Then
indexVal = i
Exit For
End If
Next i
Цикл Do While
Характерная особенность цикла Do While – выполнение содержащегося в нем кода осуществляется до того момента, пока истинно определенное условие. Это хорошо демонстрирует следующий пример функции Sub, где этот цикл используется, чтобы напечатать числа, входящие в последовательность Фибоначчи, пока число в переменной больше 1000.
‘ Sub procedure to list the Fibonacci series for all values below 1,000
Sub Fibonacci()
Dim i As Integer ‘ counter for the position in the series
Dim iFib As Integer ‘ stores the current value in the series
Dim iFib_Next As Integer ‘ stores the next value in the series
Dim iStep As Integer ‘ stores the next step size
‘ Initialise the variables i and iFib_Next
i = 1
iFib_Next = 0
‘ Do While loop to be executed as long as the value of the
‘ current Fibonacci number exceeds 1000
Do While iFib_Next < 1000
If i = 1 Then
‘ Special case for the first entry of the series
iStep = 1
iFib = 0
Else
‘ Store the next step size, before overwriting the
‘ current entry of the series
iStep = iFib
iFib = iFib_Next
End If
‘ Print the current Fibonacci value to column A of the
‘ current Worksheet
Cells(i, 1).Value = iFib
‘ Calculate the next value in the series and increment
‘ the position marker by 1
iFib_Next = iFib + iStep
i = i + 1
Loop
End Sub
В этом фрагменте видно, что на старте прописано условие iFib_Next < 1000. Если iFib_Next становится больше 1000, то цикл автоматически завершается.
Есть еще один вариант: выполнение последовательности действий хотя бы один раз, несмотря на то, что изначальное условие ложное. Для этого необходимо условие разместить в конце.
Do
Loop While iFib_Next < 1000
Цикл Do Until
Этот тип напоминает Do While, но здесь код выполняется до тех пор, когда условие не становится правдивым. То есть, в прошлом варианте изначально условие истинное, пока в ходе выполнения действий оно не станет ложным. Здесь – наоборот. Это хорошо демонстрирует такой пример:
iRow = 1
Do Until IsEmpty(Cells(iRow, 1))
‘ Store the current cell value in the dCellValues array
dCellValues(iRow) = Cells(iRow, 1).Value
iRow = iRow + 1
Loop
Эта подпрограмма извлекает значения ячеек, входящих в одну колонку, пока не обнаружится пустая.
Точно так же, как в предыдущем примере, если условие IsEmpty(Cells(iRow, 1)) ставится в начале цикла, он будет запущен, лишь если есть заполненная ячейка.
Если же необходимо запустить цикл всего один раз, даже если исходное условие не соответствует действительности, его необходимо поместить в самый конец.
Do
.
.
.
Loop Until IsEmpty(Cells(iRow, 1))
Циклы – это эффективный инструмент, позволяющий автоматизировать повторяющиеся действия. Он может использоваться для программирования самых разнообразных задач. Это значительно облегчает работу с большими объемами данных.
Если коротко подвести итоги, цикл For используется, если нужно повторить определенный фрагмент кода какое-то количество раз. Do While и Do Until используются для похожих задач. В первом случае, пока условие истинно, код будет повторяться. Во втором же — повтор будет производиться, пока оно не станет истинным.
Оцените качество статьи. Нам важно ваше мнение: