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

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

Как прервать функцию в 1С: все способы с примерами

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

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

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

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

Оператор Возврат — основной способ прервать функцию

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

Функция НайтиКонтрагентаПоИНН(ИНН)

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

Возврат Неопределено; // досрочный выход при пустом параметре

КонецЕсли;

Запрос = Новый Запрос("ВЫБРАТЬ ПЕРВЫЕ 1 Ссылка ИЗ Справочник.Контрагенты ГДЕ ИНН = &ИНН");

Запрос.УстановитьПараметр("ИНН", ИНН);

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда

Возврат Выборка.Ссылка;

КонецЕсли;

Возврат Неопределено; // ничего не нашли

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

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

Хорошая практика — проверять входные параметры в начале функции и сразу выходить через Возврат, если условия не выполнены. Такой приём называется «ранний выход» (guard clause): он уменьшает вложенность условий и делает код читабельнее, чем глубокая лестница Если...Иначе...КонецЕсли.

Прервать и Продолжить: управление циклами, а не функцией

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

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

Функция СуммаПоложительныхСтрок(ТаблицаСтрок)

Сумма = 0;

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

Если Строка.Сумма <= 0 Тогда

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

КонецЕсли;

Сумма = Сумма + Строка.Сумма;

Если Сумма > 1000000 Тогда

Прервать; // выходим из цикла, но НЕ из функции

КонецЕсли;

КонецЦикла;

Возврат Сумма;

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

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

bsl
Найдено = Ложь;
Для Каждого СтрокаТЗ Из Таблица Цикл
	Для Каждого Колонка Из СтрокаТЗ Цикл
		Если Колонка = Искомое Тогда
			Найдено = Истина;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	Если Найдено Тогда
		Прервать;
	КонецЕсли;
КонецЦикла;

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

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

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

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

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

КонецЕсли;

// ... основная логика

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

// Вызов с обработкой:

Попытка

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

Исключение

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

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

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

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

Как прервать длительную операцию по требованию пользователя

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

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

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

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

Возврат

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

Прервать / Продолжить

Управление только циклами. Функция продолжает выполняться после цикла.

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

Аварийное прерывание всей цепочки вызовов с откатом транзакции. Для реальных ошибок, не для штатной логики.

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

Прерывание длительной операции пользователем. Требует архитектуры с ДлительныеОперации.

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

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

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

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

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

Как проверить, что прерывание работает правильно

Основной инструмент проверки — отладчик конфигуратора. Поставьте точку останова на строке с Возврат или Прервать, запустите отладку и убедитесь по стеку вызовов, что управление передаётся именно туда, куда ожидается. Шаг «Выход из функции» (Shift+F11) показывает, какое значение возвращается.

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

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

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

Выход из функции
Норма

В отладчике после Возврат управление уходит в вызывающий код, возвращается ожидаемое значение

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

Выполняется код после условия выхода или возвращается Неопределено там, где ожидалось значение

Прерывание цикла
Норма

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

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

Обработка должна была остановиться полностью, но продолжилась — нужен Возврат

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

Данные в базе не изменились, ошибка есть в журнале регистрации

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

Часть объектов записана, часть нет — нарушена структура транзакции

Рекомендации по структуре функций

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

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

Итог

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

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

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

Чем отличается Возврат в процедуре от Возврат в функции?

В функции после оператора указывается возвращаемое значение: Возврат Результат;. В процедуре значение не указывается — только Возврат;. Если в функции не написать Возврат в какой-то ветке, она вернёт Неопределено без предупреждения компилятора.

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

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

Откатится ли транзакция, если просто написать Возврат?

Нет. Оператор Возврат не влияет на транзакции — все изменения, сделанные внутри активной транзакции, останутся незафиксированными, но и не отменёнными до явного ЗафиксироватьТранзакцию или ОтменитьТранзакцию. Автоматический откат происходит только при исключении.

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

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

Работает ли Ctrl+Break для прерывания кода в управляемом приложении?

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

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

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