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