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

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

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

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

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

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

Досрочный выход из процедуры оператором Возврат

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

Типичный сценарий — проверка входных условий в начале процедуры (так называемый «защитный» стиль):

Процедура СформироватьОтчет(Период, Организация)

Если Не ЗначениеЗаполнено(Период) Тогда

Сообщить("Не указан период отчета");

Возврат;

КонецЕсли;

Если Не ЗначениеЗаполнено(Организация) Тогда

Сообщить("Не указана организация");

Возврат;

КонецЕсли;

// Основная логика формирования отчета

...

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

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

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

Оператор Прервать досрочно завершает выполнение цикла (Для, Для Каждого, Пока) и передает управление на первую строку после цикла. Это не выход из процедуры, а только выход из цикла — частая путаница у начинающих разработчиков.

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

Если СтрокаТовара.Остаток = 0 Тогда

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

КонецЕсли;

Если СтрокаТовара.Ошибка Тогда

Прервать; // при первой ошибке прекращаем обход

КонецЕсли;

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

КонецЦикла;

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

Для выхода из вложенных циклов используют флаг или оборачивание в функцию с Возврат:

Найдено = Ложь;

Для Каждого Организация Из СписокОрганизаций Цикл

Для Каждого Документ Из СписокДокументов Цикл

Если Документ.ПометкаУдаления Тогда

Найдено = Истина;

Прервать;

КонецЕсли;

КонецЦикла;

Если Найдено Тогда

Прервать;

КонецЕсли;

КонецЦикла;

Аварийное прерывание через исключения

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

Функция ЗаписатьДокумент(ДокументОбъект)

Попытка

ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);

Исключение

ИнфоОшибки = ИнформацияОбОшибке();

ВызватьИсключение("Не удалось провести документ: "

+ ИнфоОшибки.Описание);

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

КонецФункции

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

Прерывание длительной операции по команде пользователя

Платформа 1С 8.3 не позволяет принудительно остановить произвольный код извне в тот же момент: обработка на клиенте или сервере выполняется до завершения. Однако разработчик может предусмотреть штатную точку прерывания — обработку ожидания с проверкой нажатия Esc или вызов метода ОбработкаПрерыванияПользователя().

Метод ОбработкаПрерыванияПользователя() вызывается внутри длительного цикла на толстом клиенте и позволяет пользователю прервать процесс комбинацией Ctrl+Break. В тонком клиенте и веб-клиенте этот метод недоступен, поэтому для длительных операций рекомендуется выносить работу в фоновое задание.

Счетчик = 0;

Для Каждого Элемент Из БольшаяКоллекция Цикл

ОбработатьЭлемент(Элемент);

Счетчик = Счетчик + 1;

Если Счетчик % 100 = 0 Тогда

ОбработкаПрерыванияПользователя();

КонецЕсли;

КонецЦикла;

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

Порядок действий для прерывания по Esc/Ctrl+Break
  1. 1
    Вынесите длительный цикл в отдельную процедуру
  2. 2
    Добавьте вызов ОбработкаПрерыванияПользователя() с периодичностью, например раз в 100 итераций
  3. 3
    Оберните запись данных в транзакцию, чтобы прерывание не оставило частично записанные данные
  4. 4
    Протестируйте: запустите обработку и нажмите Ctrl+Break — процесс должен остановиться с сообщением
  5. 5
    Проверьте в журнале регистрации, что незавершенных транзакций не осталось

Остановка фонового задания

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

// Запуск

ПараметрыЗадания = Новый Массив;

ПараметрыЗадания.Добавить(Период);

Задание = ФоновыеЗадания.Выполнить(

"ОбщийМодуль.ДлительнаяОбработка.Выполнить",

ПараметрыЗадания, , "Загрузка данных");

// Прерывание

Задание.Прервать();

Метод Прервать() не уничтожает задание мгновенно: платформа завершает его в ближайшей безопасной точке, поэтому фактическая остановка может занять несколько секунд. Состояние задания после этого меняется на СостояниеФоновогоЗадания.Прервано.

В типовых конфигурациях на БСП фоновые задания видны в разделе «Администрирование — Обслуживание — Регламентные и фоновые задания», где активное задание можно выделить и отменить кнопкой. В файловой базе без сервера 1С часть механизмов фонового выполнения работает иначе — длительные операции выполняются в том же сеансе, и прервать их можно только предусмотренной обработкой прерывания.

Сравнение способов прерывания

Возврат

Штатный досрочный выход из процедуры или функции. Не подходит для сигнализации об ошибке и не прерывает вызывающий код.

Прервать

Выход только из ближайшего цикла. Не выходит из процедуры и не работает вне цикла.

ВызватьИсключение

Аварийная остановка всей цепочки вызовов с откатом транзакции. Требует обработки Попытка/Исключение для контролируемого поведения.

ФоновыеЗадания.Прервать

Остановка фонового задания извне. Работает только для заданий, запущенных как фоновые, и не мгновенно.

Прерывание выполнения при отладке

В конфигураторе остановить выполняющийся код можно кнопкой «Остановить» (Shift+F5) в меню «Отладка». Это полностью завершает отлаживаемый сеанс кода: стек вызовов сбрасывается, выполнение прекращается. Команда «Прервать» (пауза) позволяет приостановить выполнение в произвольной точке и посмотреть текущее состояние, после чего можно продолжить или остановить.

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

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

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

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

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

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

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

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

Состояние «Прервано» или «Завершено», новых ошибок нет

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

Задание остается «Активно» спустя минуты после команды прерывания

Журнал регистрации
Норма

Записи об откате транзакции или штатном завершении

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

Ошибки «Конфликт блокировок» или обрывы транзакций

Данные в базе
Норма

Объекты либо полностью записаны, либо не изменены

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

Часть связанных объектов записана, часть — нет

Итог

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

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

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

Можно ли прервать процедуру, выполняющуюся на сервере, с клиента?

Напрямую — нет: серверный вызов выполняется до завершения. Решение — запускать длительную операцию как фоновое задание, которое можно прервать методом Прервать() или из консоли заданий, пока клиент остается свободным.

Чем отличается Прервать от Возврат?

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

Как прервать все вложенные циклы сразу?

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

Что произойдет с транзакцией при вызове ВызватьИсключение?

Если исключение не перехвачено внутри транзакции, платформа автоматически откатывает транзакцию целиком — все изменения, сделанные в её рамках, отменяются. Если исключение перехвачено блоком Попытка/Исключение внутри транзакции, отката не происходит, и это нужно обрабатывать осознанно.

Почему Ctrl+Break не останавливает мою обработку?

Обработка прерывания пользователя работает только если в коде периодически вызывается метод ОбработкаПрерыванияПользователя(), и только на толстом клиенте. Без этого вызова платформа не проверяет нажатие клавиш во время выполнения.

Опасно ли завершать сеанс пользователя, у которого «зависла» обработка?

Это крайняя мера. Незавершенная транзакция будет откачена, но откат большого объема изменений может занять время и удерживать блокировки. Сначала проверьте в консоли кластера, что сеанс действительно выполняет запрос, а не ожидает блокировку, и по возможности дождитесь завершения или прервите задание штатно.