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

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

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

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

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

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

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

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

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

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

Если Документ.Товары.Количество() = 0 Тогда

Сообщить("Документ не содержит строк, проведение отменено");

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

КонецЕсли;

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

...

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

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

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

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

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

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

Если Строка.Номенклатура = ИскомаяНоменклатура Тогда

НайденнаяСтрока = Строка;

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

КонецЕсли;

КонецЦикла;

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

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

Полная остановка обработки через исключение

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

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

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

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

КонецЕсли;

// дальнейшая логика

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

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

Внутри блока Исключение исключение можно перевыбросить оператором ВызватьИсключение без параметров — тогда оно продолжит подниматься выше. Это используют, когда часть ошибки обработали локально (например, записали в журнал регистрации), но останавливать выполнение всё равно нужно.

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

Возврат

Завершает только текущую процедуру или функцию. Подходит для проверки предусловий. Не откатывает транзакцию.

Прервать

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

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

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

Как пользователю прервать выполняющийся код

Иногда требуется остановить уже запущенную длительную обработку, а не спроектировать выход в коде. В толстом клиенте 1С сочетание клавиш Ctrl+Break прерывает выполнение встроенного кода и показывает диалог с возможностью перейти в отладчик. В тонком клиенте и веб-клиенте эта комбинация не работает — там длительные серверные операции можно отменить кнопкой в форме ожидания, если разработчик предусмотрел такую возможность.

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

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

Прерывание в отладчике и флаги остановки в длительных циклах

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

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

Для Каждого Документ Из Выборка Цикл

Если ОбработкаПрерванаПользователем() Тогда

ВызватьИсключение "Обработка отменена пользователем";

КонецЕсли;

// обработка документа

КонецЦикла;

Порядок выбора способа прерывания
  1. 1
    Определите, что нужно остановить: цикл, одну процедуру или всю обработку с записью данных
  2. 2
    Для выхода из цикла используйте Прервать, для пропуска итерации — Продолжить
  3. 3
    Для досрочного выхода из процедуры без записи в базу используйте Возврат
  4. 4
    Если выполняется запись или проведение — используйте ВызватьИсключение, чтобы транзакция откатилась
  5. 5
    Проверьте результат: код после точки прерывания не выполняется, данные в базе не изменились

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

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

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

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

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

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

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

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

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

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

Как прервать проведение документа из кода?

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

Работает ли Ctrl+Break в тонком клиенте?

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

Как остановить зависшее фоновое задание?

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

Откатится ли транзакция при выходе через Возврат?

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

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

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