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

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

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

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

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

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

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

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

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

Типичный сценарий — проверка входных условий в начале метода. Если данные не подходят, нет смысла выполнять остальной код:

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

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

Возврат; // выходим, нечего проводить

КонецЕсли;

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

Сообщить("Документ помечен на удаление");

Возврат;

КонецЕсли;

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

// ...

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

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

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

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

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

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

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

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

КонецЕсли;

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

Прервать; // дальнейшая обработка бессмысленна

КонецЕсли;

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

КонецЦикла;

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

Как остановить зависшую процедуру через отладчик

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

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

Порядок действий при зависании
  1. 1
    Откройте конфигуратор и меню «Отладка» → «Подключение»
  2. 2
    Найдите зависший сеанс в списке и подключитесь к нему
  3. 3
    Нажмите «Остановить» для прерывания выполнения
  4. 4
    Изучите стек вызовов и значения переменных, найдите причину цикла
  5. 5
    Исправьте условие выхода из цикла и перезапустите сеанс

На клиент-серверной базе, где отладка на сервере отключена или недоступна, остаётся вариант завершить сеанс через консоль кластера серверов 1С. Это грубый способ: все незавершённые транзакции откатятся, а несохранённые данные пользователя пропадут.

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

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

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

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

1c
Задание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ИдентификаторЗадания);
Если Задание <> Неопределено И Задание.Состояние = СостояниеФоновогоЗадания.Активно Тогда
    Задание.Отменить();
КонецЕсли;

ВызватьИсключение — когда нужно остановить всю цепочку вызовов

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

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

Если Не ПроверитьДоступ() Тогда

ВызватьИсключение "Недостаточно прав для записи данных";

КонецЕсли;

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

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

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

Сравнение способов остановки

Возврат

Досрочный выход из текущей процедуры или функции. Вызывающий код продолжает работу. Основной штатный способ.

Прервать

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

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

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

Остановка отладки / завершение сеанса

Внешнее принудительное прерывание. Используется при зависании, риск потери несохранённых данных.

Типичные ошибки при прерывании выполнения

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

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

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

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

Как проверить, что выполнение действительно прекращено

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

После отмены фонового задания проверьте его состояние: оно должно измениться на «Отменено пользователем». Если задание продолжает числиться активным, возможно, отмена не была обработана, и безопаснее дождаться завершения или перезапустить сервер 1С в крайнем случае.

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

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

Строка Возврат в коде
Норма

Управление возвращается в точку вызова, последующий код процедуры не выполняется

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

Код после Возврат в той же ветке — мёртвый фрагмент

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

Состояние «Отменено» или «Завершено»

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

Задание остаётся активным после вызова Отменить()

Транзакции после исключения
Норма

Транзакция откачена, блокировок нет

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

Записи заблокированы, пользователи получают ошибки ожидания

Итог

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

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

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

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

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

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

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

Можно ли остановить процедуру по нажатию кнопки пользователем?

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

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

Сама по себе генерация исключения транзакцию не откатывает. Если исключение перехватывается блоком Попытка...Исключение, откат нужно выполнить явно вызовом ОтменитьТранзакцию(). Если исключение не перехвачено и выполнение завершается аварийно, незавершённая транзакция откатывается платформой автоматически.

Как остановить зависший сеанс без конфигуратора?

В клиент-серверном варианте откройте консоль кластера серверов 1С, найдите сеанс в списке и завершите его. В файловой базе других пользователей можно отключить через «Администрирование» → «Активные пользователи» при наличии прав администратора. Учтите, что несохранённые данные сеанса будут потеряны.

Почему код после Возврат всё равно выполняется?

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