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

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

Как прервать выполнение процедуры 1С 8.3 программно

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

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

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

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

Оператор Возврат — штатное завершение процедуры

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

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

// Пример раннего выхода

Процедура ПровестиДокумент(ДокументСсылка)

Если ДокументСсылка.Пустая() Тогда

Возврат; // нечего обрабатывать

КонецЕсли;

Если ДокументСсылка.Проведен Тогда

Возврат; // уже проведён

КонецЕсли;

// ... основная логика проведения

КонецПроцедуры

Код, написанный после Возврат на том же уровне ветвления, никогда не выполнится — конфигуратор при проверке модуля может выдать предупреждение о недостижимом коде. Следите, чтобы после оператора не оставалось «мёртвых» фрагментов.

Как прервать выполнение с ошибкой: ВызватьИсключение

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

Процедура ЗаписатьДанные(Параметры)

Если Не Параметры.Свойство("Организация") Тогда

ВызватьИсключение "Не указана организация. Запись невозможна.";

КонецЕсли;

// ... запись данных

КонецПроцедуры

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

Прерывание циклов: Прервать и Продолжить

Для циклов Для...Цикл и Пока...Цикл предусмотрены два управляющих оператора. Прервать полностью завершает цикл и передаёт управление на первую строку после КонецЦикла. Продолжить досрочно завершает текущую итерацию и переходит к следующей.

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

Если Не Строка.Выбран Тогда

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

КонецЕсли;

Если Строка.Сумма > Лимит Тогда

Прервать; // превышен лимит — дальше не обрабатываем

КонецЕсли;

ОбработатьСтроку(Строка);

КонецЦикла;

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

Прерывание цепочки вызовов из вложенной процедуры

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

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

Процедура ВыполнитьОбработку() Экспорт

Попытка

НачатьТранзакцию();

ОбработатьПервыйЭтап(); // внутри может быть ВызватьИсключение

ОбработатьВторойЭтап();

ЗафиксироватьТранзакцию();

Исключение

ОтменитьТранзакцию();

ТекстОшибки = ОписаниеОшибки();

ЗаписьЖурналаРегистрации("Обработка", УровеньЖурналаРегистрации.Ошибка, , , ТекстОшибки);

Сообщить("Обработка прервана: " + ТекстОшибки);

КонецПопытки;

КонецПроцедуры

Как организовать прерывание цепочки вызовов
  1. 1
    В точке обнаружения ошибки вызовите ВызватьИсключение с понятным текстом
  2. 2
    На верхнем уровне оберните запуск в Попытка...Исключение
  3. 3
    Внутри Исключение отмените транзакцию, если она открыта
  4. 4
    Запишите подробности в журнал регистрации и покажите пользователю краткое сообщение
  5. 5
    Проверьте, что после исключения программа находится в согласованном состоянии

Прерывание длительных операций и фоновых заданий

Если процедура выполняется долго (обработка большой таблицы, обмен данными), пользователь может захотеть её прервать. В модальном сценарии платформа сама периодически показывает индикатор и обрабатывает нажатие Ctrl+Break в толстом клиенте, но в управляемом приложении надёжнее проверять состояние вручную.

Для фоновых заданий существует метод ФоновыеЗадания.НайтиПоУникальномуИдентификатору(...).Отменить() — он завершает задание принудительно. Внутри самого задания можно организовать «мягкую» остановку: периодически проверять признак, записанный, например, в константе или хранилище общих настроек, и при его наличии делать Возврат или вызывать исключение.

При длительных операциях на клиенте через ДлительныеОперации (БСП) механизм отмены уже встроен: пользователь нажимает «Отмена» в форме ожидания, и задание завершается. Если вы пишете собственную длительную обработку без БСП, предусмотрите точки проверки отмены между итерациями — иначе прервать её получится только принудительно.

Маршрут решения

Как выбрать способ прерывания

Нужно просто не выполнять остаток процедуры при невыполнении условияИспользуйте Возврат (ранний выход)
Произошла ошибка, о которой должен узнать вызывающий кодВызватьИсключение с текстом ошибки
Нужно выйти из цикла досрочноОператор Прервать
Нужно пропустить часть итераций циклаОператор Продолжить
Требуется остановить фоновое задание извнеМетод Отменить() у объекта фонового задания

Типичные ошибки при прерывании процедур

Самая распространённая ошибка — глушение исключений пустым обработчиком Попытка ... Исключение КонецПопытки; без какой-либо обработки. Ошибка «проглатывается», данные остаются в несогласованном состоянии, а найти причину проблемы потом почти невозможно. Всегда записывайте ОписаниеОшибки() в журнал регистрации.

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

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

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

Проверка результата и отладка

Чтобы убедиться, что прерывание сработало корректно, используйте отладчик конфигуратора: поставьте точку останова на строку с Возврат или ВызватьИсключение и проверьте, какие ветки кода выполняются дальше. Окно «Стек вызовов» покажет, откуда пришло управление и куда оно вернётся.

Полезный приём при отладке исключений — в настройках отладки включить остановку по ошибке (Отладка → Остановка по ошибке). Тогда отладчик остановится ровно в той строке, где возникло или было вызвано исключение, независимо от обработчиков Попытка.

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

Контрольные точки

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

Поведение при раннем выходе
Норма

Код после Возврат не выполняется, вызывающая процедура продолжает работу

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

Выполняются строки после Возврат — значит, оператор в другой ветке условия

Перехват исключения
Норма

Сработал блок Исключение, ошибка записана в журнал регистрации

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

Пользователь видит необработанную ошибку платформы

Состояние транзакции
Норма

После отката данные не изменились, повторный запуск работает

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

Ошибка вложенности транзакций или зависшие блокировки

Отмена фонового задания
Норма

Состояние задания — Отменено, ресурсы освобождены

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

Задание продолжает висеть в активных или падает с ошибкой

Частые вопросы

Чем Возврат отличается от ВызватьИсключение?

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

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

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

Можно ли прервать процедуру по таймеру?

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

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

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

Как прервать обработку, запущенную другим пользователем?

Если это фоновое задание и у вас есть административные права — найдите его через ФоновыеЗадания.НайтиПоУникальномуИдентификатору и вызовите Отменить(). Прервать произвольный код в чужом сеансе напрямую нельзя; можно завершить сеанс целиком через консоль кластера или административные функции БСП.

Работает ли Возврат в модуле формы на клиенте?

Да, оператор Возврат работает одинаково на клиенте и на сервере. Ограничение касается асинхронных вызовов: если процедура вызвана как обработчик оповещения (ПоказатьВопрос, НачатьПомещениеФайла), Возврат завершит только сам обработчик, а не логику, которая инициировала вызов.

Итог

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

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