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