Разработка и Конфигурация · 11 мин
Как прервать цикл в 1С: Прервать, Продолжить и другие способы
Как прервать цикл в 1С: операторы Прервать, Продолжить и Возврат, примеры кода для циклов Для, Пока и обхода коллекций, типичные ошибки и советы.
Во встроенном языке 1С цикл прерывается оператором Прервать (английский синтаксис — Break). Он мгновенно завершает выполнение ближайшего цикла Для, Пока или цикла обхода коллекции Для Каждого, и управление передаётся на первую строку после КонецЦикла. Это стандартный механизм платформы, работающий одинаково в тонком клиенте, толстом клиенте и на сервере.
Кроме полного прерывания, в 1С есть оператор Продолжить (Continue), который не завершает цикл, а досрочно переходит к следующей итерации, и оператор Возврат, который завершает всю процедуру или функцию целиком. Выбор между ними зависит от задачи: найден ли нужный элемент, нужно ли пропустить часть данных или прервать вообще всю обработку.
Ниже разобраны синтаксис каждого оператора, практические примеры, поведение во вложенных циклах и типичные ошибки, которые приводят к лишним проходам по данным или некорректным результатам.
Оператор Прервать: синтаксис и базовый пример
Оператор Прервать пишется внутри тела цикла, обычно внутри условия Если. Как только условие выполняется, цикл завершается немедленно — оставшиеся итерации не выполняются.
Для Каждого Строка Из ТаблицаТоваров Цикл
Если Строка.Артикул = ИскомыйАртикул Тогда
НайденнаяСтрока = Строка;
Прервать;
КонецЕсли;
КонецЦикла;
В этом примере перебор строк прекращается сразу после нахождения нужного артикула. Без Прервать цикл прошёл бы по всем строкам таблицы, что на больших объёмах данных даёт лишнюю нагрузку и замедляет обработку.
Важно понимать: Прервать не возвращает значение и не отменяет уже выполненные действия внутри цикла. Всё, что было сделано на предыдущих итерациях (запись в реквизиты, добавление строк, вызовы процедур), сохраняется.
Сч = 0;
Пока Сч < 1000 Цикл
Сч = Сч + 1;
Если Сч > Лимит Тогда
Прервать;
КонецЕсли;
КонецЦикла;Оператор Продолжить: пропуск итерации без выхода из цикла
Оператор Продолжить (Continue) прерывает только текущую итерацию: весь код ниже него в теле цикла пропускается, и начинается следующий проход. Сам цикл продолжает работать.
Для Каждого Строка Из ТаблицаТоваров Цикл
Если Строка.Количество = 0 Тогда
Продолжить; // нулевые остатки не обрабатываем
КонецЕсли;
// основная обработка строки
СуммаИтог = СуммаИтог + Строка.Сумма;
КонецЦикла;
Такой приём делает код чище, чем оборачивание всей логики в большой блок Если ... КонецЕсли. Проверки-фильтры выносятся в начало итерации, а основная логика остаётся без лишней вложенности.
Признак правильного выбора: если после срабатывания условия цикл должен обработать оставшиеся элементы — нужен Продолжить; если дальнейший перебор бессмысленен — Прервать.
Прервать или Продолжить
Полностью завершает цикл. Подходит, когда нужный элемент найден или дальнейшая обработка невозможна.
Пропускает текущую итерацию, цикл работает дальше. Подходит для фильтрации неподходящих элементов.
Завершает всю процедуру или функцию. Подходит, когда после выхода из цикла в ней больше ничего не выполняется.
Выход из всей процедуры: оператор Возврат
Если после прерывания цикла в процедуре или функции не осталось полезной работы, вместо связки «Прервать + проверка флага после цикла» проще сразу использовать Возврат. В функции оператор может сразу вернуть результат.
Функция НайтиКонтрагентаПоИНН(ИНН)
Для Каждого Строка Из ТаблицаКонтрагентов Цикл
Если Строка.ИНН = ИНН Тогда
Возврат Строка.Ссылка;
КонецЕсли;
КонецЦикла;
Возврат Неопределено;
КонецФункции;
Такой подход особенно удобен в функциях поиска: не нужны промежуточные переменные-флаги и проверки после КонецЦикла. Код короче и читается однозначно.
Ограничение: Возврат завершает именно текущую процедуру или функцию. Если после цикла нужно выполнить завершающие действия (закрыть файл, зафиксировать транзакцию, вывести сообщение), использовать Возврат внутри цикла нельзя — сначала Прервать, затем общий завершающий код.
Прерывание вложенных циклов
Ключевое ограничение платформы: Прервать завершает только тот цикл, в котором непосредственно находится, — ближайший внутренний. Внешний цикл продолжает работу. Механизма «прервать два уровня сразу» во встроенном языке нет.
Стандартное решение — переменная-флаг, которую проверяет внешний цикл:
НужноПрервать = Ложь;
Для Каждого Документ Из СписокДокументов Цикл
Для Каждого Строка Из Документ.Товары Цикл
Если Строка.Сумма > Лимит Тогда
НужноПрервать = Истина;
Прервать; // выход из внутреннего цикла
КонецЕсли;
КонецЦикла;
Если НужноПрервать Тогда
Прервать; // выход из внешнего цикла
КонецЕсли;
КонецЦикла;
Альтернатива без флага — вынести вложенную логику в отдельную функцию и выходить из неё через Возврат. Это упрощает код, когда уровней вложенности три и больше: цепочка флагов быстро становится источником ошибок.
Прерывание цикла при обходе результата запроса
Частый сценарий — обход выборки из запроса. Здесь Прервать работает так же, но есть нюанс с производительностью: если нужна только одна строка, лучше ограничить выборку самим запросом (ВЫБРАТЬ ПЕРВЫЕ 1), а не перебирать тысячи строк с последующим прерыванием.
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Если Выборка.Заблокирован Тогда
Прервать;
КонецЕсли;
// обработка записи
КонецЦикла;
При обходе выборки, сгруппированной по итогам (обход по группировкам), Прервать завершает только текущий уровень обхода. Вложенные выборки внутри группировки прерываются независимо, поэтому логику выхода нужно продумывать для каждого уровня отдельно.
Если цикл ищет единственный элемент в большой таблице значений, часто быстрее использовать метод Найти() или НайтиСтроки() вместо ручного перебора с Прервать — код короче, а поиск оптимизирован платформой.
Как аварийно остановить выполняющийся цикл в отладке
Если код уже запущен и цикл «завис» (например, бесконечный Пока из-за ошибки в условии), прервать выполнение можно штатными средствами конфигуратора. В режиме отладки используйте команду «Остановить» (прекращает отлаживаемый сеанс) или сочетание клавиш остановки выполнения в меню «Отладка».
Для длительных серверных операций в пользовательском режиме платформа предоставляет механизм прерывания: длительные действия можно прервать сочетанием Ctrl + Break (в толстом клиенте) либо через кнопку прерывания, если обработка её поддерживает. В фоновых заданиях выполнение останавливается через консоль заданий или административные инструменты кластера.
Если цикл выполняет запись в базу внутри транзакции, аварийная остановка сеанса откатит незавершённую транзакцию — данные не останутся в полузаписанном состоянии. Но если запись шла отдельными транзакциями на каждой итерации, часть данных уже зафиксирована, и это нужно учитывать при повторном запуске обработки.
Проверка результата после прерывания цикла
После выхода из цикла через Прервать полезно явно проверить, был ли найден результат, или цикл завершился естественным образом. Для этого перед циклом инициализируют переменную значением Неопределено или Ложь, а после цикла анализируют её состояние.
НайденнаяСтрока = Неопределено;
Для Каждого Строка Из ТаблицаТоваров Цикл
Если Строка.Артикул = ИскомыйАртикул Тогда
НайденнаяСтрока = Строка;
Прервать;
КонецЕсли;
КонецЦикла;
Если НайденнаяСтрока = Неопределено Тогда
Сообщить("Товар с указанным артикулом не найден");
КонецЕсли;
Такая проверка отделяет две ситуации: «элемент найден, цикл прерван досрочно» и «цикл прошёл полностью, элемента нет». Без неё легко принять пустое значение за корректный результат и получить ошибку дальше по коду.
Как проверить результат
Содержит найденное значение, заданное перед Прервать
Равна Неопределено — элемент не найден, а код дальше это не обрабатывает
Обработаны все элементы либо цикл прерван на найденном
Часть элементов пропущена из-за ошибочного Прервать вместо Продолжить
Транзакция зафиксирована или отменена явно
Цикл прерван, а транзакция осталась открытой
Часто задаваемые вопросы
Чем отличается Прервать от Продолжить в 1С?
Прервать полностью завершает цикл — управление переходит на строку после КонецЦикла. Продолжить завершает только текущую итерацию и сразу начинает следующую, цикл продолжает работать. Первый используют, когда дальнейший перебор не нужен, второй — когда нужно пропустить отдельные элементы.
Как прервать сразу два вложенных цикла?
Одним оператором — никак: Прервать завершает только ближайший цикл. Используйте переменную-флаг, которую внешний цикл проверяет после внутреннего, либо вынесите логику в отдельную функцию и выходите из неё оператором Возврат.
Работает ли Прервать в цикле Пока и в обходе выборки запроса?
Да, оператор работает во всех видах циклов встроенного языка: Для, Для Каждого и Пока, включая обход выборки запроса через Пока Выборка.Следующий() Цикл. Синтаксис и поведение идентичны.
Можно ли прервать цикл из вызываемой процедуры?
Напрямую нет — Прервать действует только в том методе, где написан. Вызываемая процедура может вернуть признак (например, значение Истина), а основной цикл проверит его и выполнит Прервать самостоятельно.
Как остановить зависший бесконечный цикл в пользовательском режиме?
Если сеанс не отвечает, выполнение можно прервать штатными средствами: в конфигураторе — остановкой отлаживаемого сеанса, в пользовательском режиме — механизмом прерывания длительных операций или завершением сеанса через консоль кластера. Незавершённые транзакции при этом откатываются.
Что быстрее: перебор с Прервать или метод Найти()?
Для поиска одного элемента в таблице значений метод Найти() обычно предпочтительнее: код короче и поиск выполняется оптимизированным механизмом платформы. Ручной перебор с Прервать оправдан, когда условие поиска сложное и не сводится к равенству значений.
Что важно запомнить
Цикл в 1С прерывается оператором Прервать, переход к следующей итерации — Продолжить, выход из всей процедуры — Возврат. Прервать завершает только ближайший цикл, поэтому для вложенных конструкций нужен флаг или вынос логики в функцию. После досрочного выхода всегда проверяйте, найден ли результат, и следите за состоянием транзакций.