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

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

Как завершить цикл в 1С: Прервать, Продолжить и Возврат

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

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

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

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

Какие операторы завершают цикл в 1С

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

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

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

Оператор Прервать: досрочный выход из цикла

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

НайденнаяСтрока = Неопределено;

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

Если СтрокаТовара.Номенклатура = ИскомаяНоменклатура Тогда

НайденнаяСтрока = СтрокаТовара;

Прервать;

КонецЕсли;

КонецЦикла;

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

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

1c
Для Сч = 1 По 100 Цикл
    Если Сч > 5 Тогда
        Прервать; // цикл завершится на 6-й итерации
    КонецЕсли;
КонецЦикла;

Оператор Продолжить: пропуск итерации, а не завершение

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

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

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

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

КонецЕсли;

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

КонецЦикла;

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

Возврат внутри цикла: выход из процедуры или функции

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

Функция НайтиСтрокуПоНоменклатуре(ТаблицаТоваров, Номенклатура)

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

Если СтрокаТовара.Номенклатура = Номенклатура Тогда

Возврат СтрокаТовара;

КонецЕсли;

КонецЦикла;

Возврат Неопределено;

КонецФункции

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

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

Прервать

Завершает только текущий цикл. Подходит, когда после цикла есть код, который должен выполниться.

Возврат

Завершает всю процедуру или функцию целиком. Удобен в функциях поиска, но неприменим, если после цикла нужна доработка.

Продолжить

Не завершает цикл, а пропускает итерацию. Используется для фильтрации элементов коллекции.

Завершение цикла Пока и защита от бесконечных циклов

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

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

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

// обработка записи

КонецЦикла;

Здесь условие меняется само: метод Следующий() возвращает Ложь, когда записи закончились. Но при ручном управлении счётчиком забыть его изменить очень легко:

Сч = 0;

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

// обработка

Сч = Сч + 1; // без этой строки цикл бесконечный

КонецЦикла;

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

Выход из вложенных циклов

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

Первый — флаг завершения: внутренний цикл устанавливает признак, внешний проверяет его и тоже прерывается:

Найдено = Ложь;

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

Для Каждого Товар Из Склад.Остатки Цикл

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

Найдено = Истина;

Прервать;

КонецЕсли;

КонецЦикла;

Если Найдено Тогда

Прервать;

КонецЕсли;

КонецЦикла;

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

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

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

Надёжный способ убедиться, что цикл завершается правильно, — отладчик конфигуратора. Поставьте точку останова на строке Прервать и на первой строке после КонецЦикла: если выполнение дошло до обеих, прерывание сработало. Дополнительно в табло (Ctrl+Shift+F9) проверьте значения переменных, заполненных в цикле.

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

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

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

Строка после КонецЦикла
Норма

Выполняется после Прервать

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

Не выполняется — сработал Возврат, а не Прервать

Значение переменной-результата
Норма

Содержит найденный элемент

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

Неопределено или перезаписано следующими итерациями

Число итераций в отладчике
Норма

Соответствует позиции найденного элемента

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

Цикл проходит всю коллекцию — Прервать не сработал

Условие цикла Пока
Норма

Меняется на каждой итерации

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

Не меняется — риск бесконечного цикла

FAQ: частые вопросы о завершении циклов в 1С

Можно ли прервать цикл Для Каждого при переборе строк табличной части?

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

Как прервать цикл из вложенной процедуры?

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

Что произойдёт, если написать Прервать вне цикла?

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

Как остановить уже запущенный бесконечный цикл?

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

Есть ли в 1С аналог break с меткой для выхода из внешнего цикла?

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

Влияет ли Прервать на транзакцию, открытую до цикла?

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

Итог

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

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