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

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

Как пропустить итерацию цикла в 1С

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

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

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

Ниже разобран синтаксис, практические примеры для каждого типа цикла, типичные сценарии из учётных задач (пропуск помеченных на удаление объектов, пустых строк, нулевых остатков), а также ограничения и альтернативные подходы.

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

Оператор пишется внутри тела цикла, обычно в ветке условия Если...Тогда. Как только условие выполняется, оставшийся код итерации игнорируется:

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

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

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

КонецЕсли;

// обработка только строк с ненулевым количеством

Сумма = Сумма + Строка.Количество * Строка.Цена;

КонецЦикла;

В английском варианте синтаксиса тот же код выглядит так: For Each ... Do, Continue;, EndDo;. Оба варианта полностью равнозначны и могут смешиваться в одном модуле, хотя на практике так делать не принято.

Как работает Продолжить в разных циклах

Цикл Для...Цикл со счётчиком

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

Для Индекс = 0 По Массив.ВГраница() Цикл

Если Массив[Индекс] = Неопределено Тогда

Продолжить;

КонецЕсли;

ОбработатьЭлемент(Массив[Индекс]);

КонецЦикла;

Цикл Для Каждого...Из...Цикл

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

Цикл Пока...Цикл

В цикле Пока оператор Продолжить отправляет выполнение на проверку условия цикла. Здесь кроется опасность: если изменение переменной, влияющей на условие, стоит после Продолжить, цикл станет бесконечным.

// ОШИБКА: бесконечный цикл

Пока Сч < 10 Цикл

Если Сч = 5 Тогда

Продолжить; // Сч никогда не станет 6

КонецЕсли;

Сч = Сч + 1;

КонецЦикла;

Практические сценарии в учётных задачах

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

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

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

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

Продолжить;

КонецЕсли;

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

Продолжить;

КонецЕсли;

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

КонецЦикла;

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

Порядок действий
  1. 1
    Определите условие, при котором элемент обрабатывать не нужно
  2. 2
    Поставьте проверку условия в начале тела цикла
  3. 3
    В ветке условия напишите оператор Продолжить
  4. 4
    Убедитесь, что в цикле Пока переменная условия изменяется до Продолжить
  5. 5
    Запустите код в отладчике и проверьте, что нужные элементы пропускаются, а остальные обрабатываются

Продолжить и Прервать: в чём разница

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

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

Продолжить (Continue)

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

Прервать (Break)

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

Возврат (Return)

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

Фильтрация в запросе

Условие ГДЕ в запросе отсекает лишние строки ещё до цикла — быстрее и предпочтительнее при работе с большими выборками.

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

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

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

Пропустить = Ложь;

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

Если Строка.Сумма < 0 Тогда

Пропустить = Истина;

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

КонецЕсли;

КонецЦикла;

Если Пропустить Тогда

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

КонецЕсли;

КонецЦикла;

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

Альтернативы: когда Продолжить не нужен

Простое условие с одной веткой часто читается лучше без Продолжить — достаточно инвертировать условие и обернуть обработку в Если. Оператор оправдан, когда проверок-исключений несколько: без него получилась бы «лесенка» вложенных условий.

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

Как проверить результат и типичные ошибки

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

Типичные ошибки
01
Продолжить в цикле Пока до изменения счётчика — бесконечный цикл и зависший сеанс
02
Путаница с Прервать: цикл завершается раньше времени, часть данных не обрабатывается
03
Ожидание, что Продолжить во вложенном цикле пропустит итерацию внешнего — внешний цикл продолжит обработку
04
Дублирование фильтрации: строки уже отобраны в запросе, а в цикле повторно стоит Продолжить с тем же условием
05
Пропуск элементов при параллельном удалении из коллекции — при удалении внутри цикла Для Каждого порядок обхода нарушается
Контрольные точки

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

Количество обработанных элементов
Норма

Совпадает с числом элементов без учёта отфильтрованных

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

Обработано меньше или больше ожидаемого — условие пропуска неверно

Завершение цикла Пока
Норма

Цикл заканчивается за ожидаемое число итераций

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

Код зависает — счётчик не изменяется до Продолжить

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

Пропускается только итерация вложенного цикла

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

Пропускаются данные внешнего цикла без флага-индикатора

Частые вопросы

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

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

Работает ли Продолжить в управляемых формах и на клиенте?

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

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

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

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

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

Что быстрее: Продолжить в цикле или фильтр в запросе?

Фильтр в секции ГДЕ запроса почти всегда предпочтительнее: лишние строки отсекаются на стороне СУБД и не попадают в выборку. Продолжить оправдан, когда условие невозможно выразить в запросе — например, оно зависит от результата функции или от данных, обработанных на предыдущих итерациях.

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

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

Итог

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

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