Разработка и Конфигурация · 9 мин
Как продолжить цикл в 1С: оператор Продолжить
Как пропустить итерацию цикла в 1С с помощью оператора Продолжить: синтаксис, примеры для Для и Пока, типичные ошибки и альтернативные подходы.
Оператор Продолжить во встроенном языке 1С:Предприятие досрочно завершает текущую итерацию цикла и передаёт управление на начало следующей итерации. Код, расположенный после оператора внутри тела цикла, при этом не выполняется. Это аналог continue в других языках программирования.
Оператор работает одинаково во всех видах циклов 1С: Для … Цикл, Для Каждого … Из … Цикл и Пока … Цикл. Он применяется, когда по условию часть элементов коллекции или шагов нужно пропустить, не прерывая обход целиком.
Важно понимать разницу между двумя операторами управления циклом: Продолжить пропускает только текущую итерацию, а Прервать полностью выходит из цикла. Путаница между ними — одна из самых частых причин логических ошибок в обработках данных.
Синтаксис оператора Продолжить
Оператор не имеет параметров и записывается одним словом внутри тела цикла, обычно внутри условной конструкции Если … Тогда:
Для Каждого СтрокаТовара Из Товары Цикл
Если СтрокаТовара.Количество = 0 Тогда
Продолжить; // переходим к следующей строке
КонецЕсли;
// обработка строки с ненулевым количеством
КонецЦикла;
В англоязычном синтаксисе встроенного языка оператор записывается как Continue. Оба варианта допустимы, но в типовых конфигурациях принят русский синтаксис, и смешивать варианты в одном модуле не рекомендуется.
Оператор действует только на тот цикл, в теле которого он непосредственно находится. Если внутри цикла вызывается процедура или функция, написать Продолжить в ней и повлиять на внешний цикл нельзя — компилятор выдаст ошибку, так как оператор вне цикла недопустим.
Продолжение цикла Для и Для Каждого
В цикле со счётчиком Для после срабатывания оператора Продолжить счётчик увеличивается на шаг и начинается следующая итерация:
Для Сч = 1 По 10 Цикл
Если Сч % 2 = 0 Тогда
Продолжить; // пропускаем чётные числа
КонецЕсли;
Сообщить(Сч); // выведутся только 1, 3, 5, 7, 9
КонецЦикла;
В цикле Для Каждого оператор особенно удобен при обходе табличных частей, коллекций строк и массивов. Типовой сценарий — пропуск помеченных на удаление элементов, пустых строк или строк, не прошедших проверку:
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
Если Не ЗначениеЗаполнено(СтрокаТЧ.Номенклатура) Тогда
Продолжить;
КонецЕсли;
// расчёт суммы, заполнение цены и т.д.
КонецЦикла;
Такой подход делает основной код обработки «плоским»: вместо глубокой вложенности условий вы отсекаете неподходящие элементы в начале итерации и дальше работаете только с валидными данными.
Продолжение цикла Пока: важный нюанс
В цикле Пока оператор Продолжить передаёт управление на проверку условия цикла. Здесь кроется опасность бесконечного цикла: если изменение переменной, влияющей на условие, стоит в конце тела цикла, то после Продолжить оно не выполнится.
// ОШИБКА: бесконечный цикл
Пока Сч <= 10 Цикл
Если Сч = 5 Тогда
Продолжить; // Сч не увеличится, условие не изменится
КонецЕсли;
Сч = Сч + 1;
КонецЦикла;
// ПРАВИЛЬНО: увеличиваем счётчик до Продолжить
Пока Сч <= 10 Цикл
Сч = Сч + 1;
Если Сч = 5 Тогда
Продолжить;
КонецЕсли;
Сообщить(Сч);
КонецЦикла;
Если обходите выборку запроса методом Выборка.Следующий(), вызов Следующий() тоже должен стоять до оператора Продолжить, иначе указатель выборки не сместится и цикл никогда не завершится.
Продолжить во вложенных циклах
Оператор Продолжить действует только на ближайший цикл, в котором он расположен. Во вложенных конструкциях он продолжит внутренний цикл, а внешний продолжит работу в обычном порядке:
Для Каждого Документ Из СписокДокументов Цикл
Для Каждого Строка Из Документ.Товары Цикл
Если Строка.Количество = 0 Тогда
Продолжить; // продолжает цикл по строкам, не по документам
КонецЕсли;
КонецЦикла;
КонецЦикла;
Если по условию во внутреннем цикле нужно перейти к следующей итерации внешнего цикла, штатного оператора для этого в 1С нет. Применяют два обходных приёма: флаговую переменную или вынос внутреннего цикла в отдельную функцию с возвратом результата.
- 1Перед внутренним циклом установите флаг: ПропуститьДокумент = Ложь
- 2Во внутреннем цикле при условии установите флаг в Истина и выполните Прервать
- 3После внутреннего цикла проверьте: Если ПропуститьДокумент Тогда Продолжить
- 4Либо вынесите внутренний цикл в функцию, возвращающую Истина/Ложь, и по результату вызовите Продолжить во внешнем цикле
Альтернативы оператору Продолжить
Не всегда Продолжить — лучшее решение. Если условие пропуска одно и код обработки короткий, читабельнее инвертировать условие и обернуть тело в Если:
Для Каждого Строка Из Товары Цикл
Если Строка.Количество > 0 Тогда
// обработка
КонецЕсли;
КонецЦикла;
Однако когда проверок несколько (пустая номенклатура, нулевое количество, отрицательная цена), цепочка из нескольких Продолжить в начале итерации читается лучше, чем пирамида вложенных условий. Выбор зависит от количества условий и длины тела цикла.
Продолжить или вложенное условие
Подходит при нескольких условиях пропуска и длинном теле итерации; держит основной код без лишней вложенности
Подходит для одной простой проверки и короткой обработки; при множестве условий приводит к глубокой вложенности
Если данные берутся запросом, отсекайте лишние строки в условии ГДЕ — это быстрее, чем пропускать их в цикле
Отдельная альтернатива — не пропускать данные в цикле вообще, а отфильтровать их заранее: условием ГДЕ в запросе, методом НайтиСтроки() таблицы значений или отбором в динамическом списке. Это снижает объём обхода и упрощает логику.
Типичные ошибки и проверка результата
Первая ошибка — использование Продолжить вместо Прервать и наоборот. Если по условию дальнейший обход бессмыслен (например, нужный элемент уже найден), правильный оператор — Прервать; Продолжить заставит цикл впустую обойти остальные элементы.
Вторая ошибка — код после Продолжить в той же ветке условия: он никогда не выполнится, и конфигуратор при проверке модуля может указать на недостижимый код. Третья — попытка использовать оператор вне цикла, что приводит к ошибке компиляции модуля.
Проверить поведение цикла проще всего в отладчике: поставьте точку останова на строке с Продолжить и на первой строке тела цикла, затем пошагово убедитесь, что после срабатывания оператора выполнение переходит к следующей итерации, а счётчик или указатель выборки изменяется.
Что важно запомнить
Оператор Продолжить пропускает остаток текущей итерации и запускает следующую; он действует на ближайший цикл и работает в Для, Для Каждого и Пока. В цикле Пока заранее изменяйте переменную условия, а для внешнего цикла используйте флаг или функцию.
Частые вопросы
Чем Продолжить отличается от Прервать?
Продолжить завершает только текущую итерацию и запускает следующую, цикл продолжает работу. Прервать полностью выходит из цикла, и выполнение переходит на оператор, следующий за КонецЦикла.
Можно ли использовать Продолжить внутри процедуры, вызванной из цикла?
Нет. Оператор допустим только непосредственно в теле цикла. Из процедуры можно вернуть признак через Возврат, а по нему уже в цикле вызвать Продолжить.
Почему цикл Пока зависает после добавления Продолжить?
Потому что оператор пропускает код, изменяющий условие цикла. Перенесите увеличение счётчика или вызов метода выборки в начало тела цикла, до условия с Продолжить.
Как пропустить итерацию внешнего цикла из вложенного?
Штатного оператора нет. Используйте флаг: во внутреннем цикле установите его и выполните Прервать, а во внешнем проверьте флаг и вызовите Продолжить. Альтернатива — вынести внутренний цикл в отдельную функцию.
Работает ли Продолжить в цикле Для Каждого по табличной части?
Да, оператор работает с любой коллекцией: табличными частями, массивами, таблицами значений, выборками. Следующая итерация получит следующий элемент коллекции.
Что лучше для производительности: Продолжить или отбор в запросе?
Отбор в запросе или через НайтиСтроки обычно эффективнее: лишние строки вообще не попадают в обход. Продолжить оправдан, когда условие пропуска вычисляется только в коде и не выражается отбором.