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