К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как перейти к следующей итерации цикла в 1С

Как пропустить текущую итерацию цикла в 1С с помощью оператора Продолжить: синтаксис, примеры для Для и Пока, отличия от Прервать, типичные ошибки и FAQ.

Во встроенном языке 1С переход к следующей итерации цикла выполняется оператором Продолжить (английский вариант — Continue). Он немедленно завершает текущий проход цикла и передаёт управление в начало: для цикла Для — к увеличению счётчика, для цикла Пока — к проверке условия. Код, расположенный после Продолжить внутри тела цикла, в текущей итерации не выполняется.

Оператор применяется, когда часть элементов коллекции или часть диапазона нужно пропустить по условию: не обрабатывать помеченные на удаление документы, пропускать пустые строки таблицы значений, игнорировать элементы с нулевым количеством. Без Продолжить пришлось бы оборачивать всю логику обработки в громоздкое Если ... Тогда ... КонецЕсли;, что ухудшает читаемость кода.

Ниже разобраны синтаксис, типовые сценарии для разных видов циклов, отличия от оператора Прервать, ограничения и ошибки, которые чаще всего допускают начинающие разработчики.

Синтаксис оператора Продолжить

Оператор записывается одним словом с точкой с запятой и может использоваться внутри любого цикла: Для ... Цикл, Для Каждого ... Из ... Цикл и Пока ... Цикл. Обычно его помещают внутрь условия Если, чтобы пропуск срабатывал только для определённых элементов.

Для Каждого Строка Из ТаблицаДокументов Цикл

Если Строка.ПометкаУдаления Тогда

Продолжить; // помеченные документы пропускаем

КонецЕсли;

// основная обработка строки

ОбработатьДокумент(Строка.Ссылка);

КонецЦикла;

Оператор можно писать и на английском синтаксисе — Continue;. Оба варианта полностью равнозначны, выбор зависит от настроек конфигуратора и принятого в проекте стиля. Смешивать русские и английские ключевые слова в одном модуле технически можно, но на практике это затрудняет чтение кода.

bsl
Если Строка.Количество = 0 Тогда
	Продолжить; // переходим к следующей итерации
КонецЕсли;

Переход к следующей итерации в цикле Для

В цикле со счётчиком Для Счетчик = 1 По 10 Цикл оператор Продолжить сначала увеличивает счётчик на шаг, затем проверяет, не вышел ли он за границу диапазона, и только потом начинает новую итерацию. Это значит, что бесконечного цикла из-за Продолжить здесь возникнуть не может — счётчик движется в любом случае.

Для Н = 1 По 10 Цикл

Если Н % 2 = 0 Тогда

Продолжить; // чётные числа пропускаем

КонецЕсли;

Сообщить(Н); // выведет 1, 3, 5, 7, 9

КонецЦикла;

Типовой сценарий — обход массива или табличной части по индексу с пропуском «плохих» позиций. Например, при обработке табличной части документа строки с нулевой суммой не требуют движений по регистрам, и их разумно пропустить в самом начале итерации, не наращивая вложенность условий.

Продолжить в цикле Для Каждого

Цикл Для Каждого — самый частый контекст использования Продолжить, потому что именно так обходят коллекции: строки таблицы значений, выборку из запроса, элементы справочника, строки дерева значений. Оператор передаёт управление механизму обхода, который берёт следующий элемент коллекции.

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

Если Не ЗначениеЗаполнено(Выборка.Контрагент) Тогда

Продолжить; // записи без контрагента не обрабатываем

КонецЕсли;

СформироватьОтгрузку(Выборка.Ссылка);

КонецЦикла;

Обратите внимание: в цикле по выборке запроса Продолжить корректно вызывает Следующий() — позиционирование на следующую запись происходит автоматически, отдельно дублировать вызов не нужно. Это частая ошибка: разработчик вручную вызывает Выборка.Следующий() перед Продолжить и теряет каждую вторую запись.

Типичные ошибки
01
Ручной вызов Выборка.Следующий() перед Продолжить — в результате пропускаются записи выборки
02
Продолжить в цикле Пока без изменения условия — цикл становится бесконечным
03
Ожидание, что Продолжить выходит из вложенного внешнего цикла — оператор действует только на ближайший цикл
04
Помещение кода после Продолжить в той же ветке условия — этот код никогда не выполнится

Продолжить в цикле Пока: риск бесконечного цикла

Цикл Пока — единственный, где неосторожное использование Продолжить приводит к зависанию. Оператор передаёт управление на проверку условия, и если до этого в итерации не изменились переменные, влияющие на условие, цикл будет крутиться бесконечно.

Н = 0;

Пока Н < 10 Цикл

Н = Н + 1; // сначала двигаем счётчик

Если Н % 2 = 0 Тогда

Продолжить; // безопасно: Н уже увеличено

КонецЕсли;

Сообщить(Н);

КонецЦикла;

Правило безопасности простое: всё, что приближает завершение цикла (инкремент счётчика, чтение следующей записи, изменение флага), должно выполняться до Продолжить. Если пропуск стоит раньше изменения состояния — перестройте порядок строк или замените цикл на Для.

Чем Продолжить отличается от Прервать

Эти два оператора часто путают, но их поведение противоположно. Продолжить завершает только текущую итерацию и идёт дальше по коллекции, а Прервать (англ. Break) полностью выходит из цикла, и оставшиеся элементы не обрабатываются вовсе.

КритерийПродолжитьПрервать
Что делаетПропускает остаток текущей итерацииЗавершает весь цикл
Остальные элементыОбрабатываютсяНе обрабатываются
Типовой сценарийПропуск неподходящих элементовЭлемент найден, дальше искать не нужно
Английский синтаксисContinueBreak

Выбирайте по смыслу задачи: если неподходящий элемент — это норма и дальше есть что обрабатывать, нужен Продолжить. Если после находки продолжать обход бессмысленно (например, искомый товар уже найден в таблице), используйте Прервать — это ещё и быстрее на больших коллекциях.

Сравнение вариантов

Продолжить

Когда нужно пропустить часть элементов, но обработать остальные: фильтрация строк таблицы, пропуск пустых значений

Прервать

Когда цель достигнута и дальнейший обход бесполезен: поиск первого подходящего элемента

Условие вокруг кода

Когда пропускаемых элементов мало и ветка обработки одна — иногда читаемее обернуть код в Если без Продолжить

Вложенные циклы и ограничения оператора

Важное ограничение: Продолжить действует только на ближайший цикл, внутри которого он написан. Перейти к следующей итерации внешнего цикла из вложенного напрямую нельзя — в языке 1С нет меток или конструкций вида «continue outer».

Если нужно затронуть внешний цикл, используют обходной приём с флагом: внутренний цикл устанавливает признак, после чего внешний проверяет его и выполняет собственный Продолжить.

Для Каждого Документ Из СписокДокументов Цикл

ЕстьОшибки = Ложь;

Для Каждого Строка Из Документ.Товары Цикл

Если Строка.Количество < 0 Тогда

ЕстьОшибки = Истина;

Прервать; // выходим из внутреннего цикла

КонецЕсли;

КонецЦикла;

Если ЕстьОшибки Тогда

Продолжить; // пропускаем документ целиком

КонецЕсли;

ПровестиДокумент(Документ.Ссылка);

КонецЦикла;

Ещё одно ограничение: Продолжить нельзя использовать вне цикла — компилятор выдаст синтаксическую ошибку при проверке модуля. Также оператор нельзя применить внутри конструкции Попытка ... Исключение, если сам цикл находится снаружи этой конструкции: переход через границу попытки запрещён, и это нужно учитывать при проектировании обработчиков ошибок.

Как проверить, что переход работает правильно

Самый надёжный способ — отладчик конфигуратора. Поставьте точку останова на строке Продолжить и на первой строке следующей итерации, запустите обработку и убедитесь, что выполнение проходит обе точки в ожидаемом порядке, а счётчик или текущий элемент коллекции меняются.

Для прикладной проверки полезно подсчитать, сколько элементов обработано и сколько пропущено. Заведите два счётчика перед циклом, увеличивайте их в соответствующих ветках и после цикла сравните сумму с размером коллекции. Если сумма не сходится — где-то элементы теряются, чаще всего из-за лишнего вызова Следующий() или изменения коллекции во время обхода.

Контрольные точки

Как проверить результат

Сумма обработанных и пропущенных элементов
Норма

Равна общему числу элементов коллекции

Тревожный признак

Сумма меньше — элементы теряются внутри итерации

Время выполнения цикла Пока
Норма

Цикл завершается за предсказуемое время

Тревожный признак

Сеанс зависает — условие не меняется до Продолжить

Поведение во вложенном цикле
Норма

Пропускается итерация именно того цикла, который нужен

Тревожный признак

Продолжить сработал на внутренний цикл вместо внешнего

Отдельно проверьте граничные случаи: пустую коллекцию (цикл не должен выполниться ни разу и не должен упасть), коллекцию из одного элемента и ситуацию, когда пропускаются все элементы подряд. Именно на этих данных чаще всего всплывают ошибки в логике условий.

Итог

Что важно запомнить

Оператор Продолжить пропускает остаток текущей итерации и запускает следующую. Он работает во всех видах циклов 1С, действует только на ближайший цикл и требует осторожности в цикле Пока, где может создать бесконечный цикл. Для полного выхода из цикла используйте Прервать.

Часто задаваемые вопросы

Можно ли использовать Продолжить вне цикла?

Нет. Оператор допустим только внутри тела цикла Для, Для Каждого или Пока. При проверке модуля конфигуратор выдаст синтаксическую ошибку, если оператор стоит в процедуре вне цикла.

Как пропустить итерацию внешнего цикла из вложенного?

Напрямую никак — Продолжить действует только на ближайший цикл. Используйте переменную-флаг: установите её во внутреннем цикле, выйдите из него оператором Прервать, а во внешнем цикле проверьте флаг и выполните своё Продолжить.

Чем отличаются Продолжить и Прервать?

Продолжить завершает только текущую итерацию и переходит к следующему элементу, а Прервать полностью выходит из цикла. Первый нужен для фильтрации элементов, второй — когда цель достигнута и дальнейший обход не имеет смысла.

Почему цикл Пока зависает после добавления Продолжить?

Потому что Продолжить возвращает управление на проверку условия, а переменные условия до этого не изменились. Перенесите инкремент счётчика или чтение следующей записи выше оператора Продолжить в теле цикла.

Можно ли писать Continue вместо Продолжить?

Да, английский вариант Continue полностью эквивалентен русскому. Встроенный язык 1С поддерживает оба синтаксиса, но внутри одного модуля лучше придерживаться одного стиля для читаемости.

Пропускаются ли записи выборки запроса при Продолжить?

Нет, если не вызывать Следующий() вручную. В цикле Пока Выборка.Следующий() оператор Продолжить корректно переходит к следующей записи. Потери возникают только при лишнем ручном вызове Следующий() перед оператором.