Разработка и Конфигурация · 11 мин
Как принудительно выйти из цикла в 1С
Как выйти из цикла в 1С: операторы Прервать, Продолжить и Возврат, остановка зависшего цикла через отладчик и диспетчер задач, типичные ошибки и советы.
Цикл в 1С может завершаться двумя способами: штатно — когда выполнено условие выхода, и принудительно — когда разработчик или пользователь прерывает его досрочно. Первый случай реализуется встроенными операторами языка, второй требует вмешательства через отладчик или операционную систему, если программа зависла.
Во встроенном языке 1С для управления циклами предусмотрены три ключевых оператора: Прервать, Продолжить и Возврат. Каждый из них решает свою задачу, и неправильный выбор приводит к логическим ошибкам, которые трудно отловить. Отдельная ситуация — бесконечный цикл в уже работающей программе, когда код исправить нельзя и нужно остановить выполнение извне.
Ниже разобраны все сценарии: досрочный выход из цикла в коде, пропуск итерации, выход из вложенных циклов, остановка зависшего сеанса и способы предотвратить бесконечные циклы на этапе разработки.
Оператор «Прервать» — основной способ выйти из цикла
Оператор Прервать немедленно прекращает выполнение текущего цикла и передаёт управление на строку, следующую за КонецЦикла. Он работает одинаково для всех видов циклов: Для ... Цикл, Для Каждого ... Цикл и Пока ... Цикл.
Типичный пример — поиск элемента в коллекции. Как только нужный элемент найден, дальнейший перебор бессмысленен и только тратит время:
Для Каждого Строка Из ТаблицаТоваров Цикл
Если Строка.Артикул = ИскомыйАртикул Тогда
НайденнаяСтрока = Строка;
Прервать;
КонецЕсли;
КонецЦикла;
Важно понимать: Прервать завершает только тот цикл, внутри которого он написан. Если цикл вложен в другой, внешний цикл продолжит работу. Это одна из самых частых причин ошибок — подробнее она разобрана ниже в разделе про вложенные циклы.
Оператор не возвращает значение и не имеет параметров. Его можно вызывать несколько раз в разных ветках условий внутри одного цикла — например, прерывать перебор и при нахождении результата, и при обнаружении ошибочных данных.
Оператор «Продолжить» — пропуск итерации без выхода
Оператор Продолжить не выходит из цикла, а досрочно завершает текущую итерацию и переходит к следующей. Это удобно, когда часть элементов коллекции нужно пропустить: пустые строки, отменённые документы, записи с нулевым количеством.
Для Каждого Строка Из ТаблицаТоваров Цикл
Если Строка.Количество = 0 Тогда
Продолжить;
КонецЕсли;
// обработка только строк с ненулевым количеством
КонецЦикла;
Использование Продолжить позволяет избежать глубокой вложенности условий. Вместо того чтобы оборачивать весь код цикла в большой блок Если ... КонецЕсли, вы отсекаете неподходящие случаи в начале итерации, а основная логика остаётся на первом уровне отступа — такой код проще читать и поддерживать.
Как и Прервать, оператор действует только на ближайший цикл. Во вложенной конструкции Продолжить перейдёт к следующей итерации внутреннего цикла, не затрагивая внешний.
Оператор «Возврат» — выход из цикла вместе с процедурой
Если после нахождения результата вся дальнейшая работа процедуры или функции теряет смысл, правильнее использовать Возврат. Он завершает не только цикл, но и всю процедуру или функцию целиком, независимо от уровня вложенности циклов.
Функция НайтиДокумент(Номер)
Для Каждого Док Из СписокДокументов Цикл
Если Док.Номер = Номер Тогда
Возврат Док;
КонецЕсли;
КонецЦикла;
Возврат Неопределено;
КонецФункции
Это единственный штатный способ «выйти» сразу из нескольких вложенных циклов: Возврат игнорирует вложенность и полностью покидает контекст выполнения. Если результат нужен вызывающему коду, его передают как значение функции.
Ограничение очевидно: Возврат нельзя применять, если после цикла в процедуре ещё есть нужный код — он не выполнится. Перед использованием убедитесь, что вся логика после цикла действительно не требуется, либо вынесите её в отдельную процедуру.
Сравнение вариантов
Досрочный выход из ближайшего цикла. Подходит, когда результат найден, но код после цикла должен выполниться. Не работает для выхода из нескольких вложенных циклов.
Пропуск текущей итерации без выхода из цикла. Подходит для фильтрации элементов при переборе.
Выход из цикла вместе со всей процедурой или функцией. Единственный способ покинуть сразу несколько вложенных циклов, но код после цикла не выполнится.
Выход из вложенных циклов
Встроенного оператора «прервать два уровня цикла» в 1С нет. Если нужно остановить и внутренний, и внешний цикл, применяют один из двух приёмов: флаг завершения или вынос логики в функцию с Возврат.
Приём с флагом выглядит так: перед внутренним прерыванием устанавливается переменная-признак, а внешний цикл проверяет её и тоже прерывается:
НужноПрервать = Ложь;
Для Каждого Строка Из Таблица Цикл
Для Каждого Колонка Из Колонки Цикл
Если УсловиеВыполнено Тогда
НужноПрервать = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если НужноПрервать Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Второй вариант чище: вложенную логику оформляют отдельной функцией, которая возвращает результат через Возврат. Код получается короче, а признак-флаг не нужен. Минус — придётся передавать в функцию все используемые переменные через параметры.
Как остановить зависший цикл в работающей программе
Если цикл зациклился в отладке, остановить его просто: в конфигураторе выполните команду «Отладка → Остановить» или нажмите соответствующую кнопку на панели. Выполнение прервётся, и вы увидите текущую строку кода — это позволит понять, почему условие выхода не срабатывает.
Альтернатива — поставить точку останова внутри цикла и проверять значения переменных на каждой итерации через табло или окно «Вычислить выражение». Чтобы не нажимать продолжение сотни раз, используйте точку останова с условием: она сработает только когда переменная примет подозрительное значение.
Когда зависший сеанс работает не под отладкой, варианты зависят от режима запуска. В файловой базе или толстом клиенте программу закрывают через диспетчер задач Windows: найдите процесс 1cv8.exe или 1cv8c.exe и завершите его. В клиент-серверном варианте администратор может принудительно завершить сеанс через консоль кластера серверов 1С: раздел «Сеансы», выбор нужного сеанса, команда «Удалить».
- 1Определите, где выполняется код: локальный клиент или сервер 1С
- 2Если сеанс под отладкой — остановите выполнение командой «Остановить» в конфигураторе
- 3Если файловая база без отладки — завершите процесс 1cv8 в диспетчере задач, предупредив пользователя
- 4Если клиент-серверный режим — завершите сеанс через консоль кластера серверов
- 5После остановки найдите причину зацикливания и проверьте целостность данных, которые обрабатывал цикл
Как не допустить бесконечного цикла
Бесконечный цикл почти всегда возникает в конструкции Пока ... Цикл, когда условие выхода никогда не становится ложным: забыто изменение счётчика, неверное сравнение, чтение одного и того же значения. В циклах Для и Для Каждого зацикливание возможно, если внутри цикла модифицируется сама перебираемая коллекция.
Надёжная защита — страховочный счётчик итераций. Задайте разумный предел и прерывайте цикл с сообщением об ошибке, если он превышен:
Счетчик = 0;
Пока Не УсловиеВыполнено Цикл
Счетчик = Счетчик + 1;
Если Счетчик > 100000 Тогда
ВызватьИсключение "Превышен предел итераций цикла";
КонецЕсли;
// основная логика
КонецЦикла;
Дополнительные меры: не изменяйте коллекцию, по которой идёт перебор Для Каждого (удаляйте элементы через обход с конца по индексу или собирайте их в отдельный список), всегда проверяйте, что переменная в условии Пока реально меняется внутри тела цикла, и тестируйте алгоритм на граничных случаях — пустой коллекции, одном элементе, повторяющихся значениях.
Проверка результата после принудительного выхода
После штатного прерывания цикла в коде убедитесь, что результат действительно получен: переменная с найденным значением заполнена, а не содержит Неопределено. Частая ситуация — цикл прерван по ошибочному условию, и дальше программа работает с пустым результатом.
После аварийной остановки зависшего сеанса проверьте данные, которые обрабатывал цикл: проведены ли документы, корректны ли остатки регистров, не осталось ли записей с частично заполненными реквизитами. В клиент-серверном режиме полезно просмотреть технологический журнал на предмет ошибок в момент завершения сеанса.
Как проверить результат
Переменная содержит найденное значение или явное Неопределено, обработанное дальше
Переменная пуста, а код дальше использует её без проверки
Документы проведены либо целиком не записаны, остатки согласованы
Частично записанные объекты, расхождения в регистрах
Цикл завершается за ожидаемое число итераций
Время выполнения растёт непропорционально объёму данных
Что важно запомнить
В коде выход из цикла выполняют операторы Прервать (только ближайший цикл), Продолжить (пропуск итерации) и Возврат (выход вместе с процедурой). Зависший цикл останавливают через отладчик, диспетчер задач или консоль кластера — с проверкой данных после. Защита от бесконечных циклов — страховочный счётчик и аккуратная работа с условием выхода.
Частые вопросы
Чем отличается «Прервать» от «Возврат» внутри цикла?
«Прервать» завершает только цикл, и код после него продолжает выполняться. «Возврат» завершает всю процедуру или функцию, поэтому никакой код после цикла уже не выполнится. Выбор зависит от того, нужна ли дальнейшая логика процедуры после выхода.
Как выйти сразу из двух вложенных циклов?
Штатного оператора для этого нет. Используйте переменную-флаг: установите её перед прерыванием внутреннего цикла и проверьте во внешнем. Либо вынесите перебор в функцию и выйдите через «Возврат» — он игнорирует вложенность.
Программа 1С зависла, крутится бесконечный цикл. Что делать пользователю без конфигуратора?
Откройте диспетчер задач Windows (Ctrl+Shift+Esc), найдите процесс 1cv8 и завершите его. В клиент-серверном режиме попросите администратора удалить сеанс через консоль кластера. После перезапуска проверьте, не пострадали ли данные, которые обрабатывались в момент зависания.
Можно ли прервать цикл «Для Каждого»?
Да, оператор «Прервать» работает со всеми видами циклов, включая «Для Каждого». А вот изменять саму коллекцию (добавлять или удалять элементы) во время такого перебора не следует — это приводит к пропускам элементов и ошибкам.
Как найти причину бесконечного цикла?
Запустите сеанс под отладкой, дождитесь зависания и остановите выполнение — конфигуратор покажет строку, где крутится цикл. Проверьте через табло, меняется ли переменная из условия «Пока». Чаще всего причина в забытом изменении счётчика или в условии, которое всегда истинно.
Опасно ли аварийно завершать зависший сеанс 1С?
Да, если в момент остановки выполнялась запись в базу. Незавершённая транзакция откатывается, но логика прикладного кода могла уже частично изменить данные. После аварийной остановки проверьте документы и регистры, которые обрабатывал зависший алгоритм.