В процессе разработки на платформе 1С:Предприятие 8.3, особенно при работе с управляемыми формами, программисты часто сталкиваются с необходимостью немедленно прекратить выполнение алгоритма. Это может быть вызвано нарушением логических условий, отсутствием необходимых данных или проверкой прав доступа. В данной статье мы подробно разберем, как правильно завершить работу программного кода на сервере, какие инструменты для этого существуют и в каких ситуациях их следует применять.
Самый простой и очевидный способ прекратить выполнение текущей процедуры или функции — использовать оператор Возврат. Рассмотрим ситуацию, когда выполнение кода должно прекратиться, если определенная переменная не заполнена. Проанализируем пример кода:
&НаСервере
Процедура ВыполнитьОбработкуДанных()
Переменная = ПолучитьЗначение();
Если Переменная = Неопределено Тогда
Сообщить("Данные не найдены, выполнение прервано.");
Возврат;
КонецЕсли;
// Основная логика обработки, которая не выполнится
ЗаписатьДанныеВБазу(Переменная);
КонецПроцедуры
Разберем этот механизм подробнее. Оператор Возврат немедленно прекращает выполнение текущего программного блока и возвращает управление в ту точку, откуда процедура была вызвана. Однако здесь кроется важный нюанс: если ваша процедура вызвана из другой процедуры, выполнение «родительского» кода продолжится. Если у вас глубокая вложенность функций, вам придется прокидывать флаг отмены на самый верхний уровень, что часто называют «пробрасыванием возврата».
Если код выполняется в глубоко вложенных процедурах и вам нужно мгновенно «вылететь» на самый верхний уровень, прервав всю цепочку вызовов, используется оператор ВызватьИсключение. Рассмотрим пример:
&НаСервере
Процедура ГлубокаяПроверка()
Если КритическаяОшибка Тогда
ВызватьИсключение "Обнаружена критическая ошибка! Работа обработки прекращена.";
КонецЕсли;
КонецПроцедуры
Выясним причину популярности этого метода среди разработчиков. Когда срабатывает ВызватьИсключение, платформа генерирует программную ошибку. Это приводит к немедленной очистке стека вызовов. Пользователь увидит стандартное диалоговое окно (часто красного цвета) с текстом, который вы указали.
Важное предупреждение: использование исключений имеет серьезные побочные эффекты. Проанализируем ситуацию с транзакциями. Если ваш код выполняется внутри транзакции (например, в модуле объекта при записи), вызов исключения приведет к полному откату транзакции. Все изменения, внесенные в базу данных до этого момента в рамках текущей транзакции, будут отменены. Поэтому используйте этот метод осознанно.
В управляемых формах для взаимодействия с пользователем на сервере рекомендуется использовать объект СообщениеПользователю. В отличие от обычного метода Сообщить, этот объект позволяет «привязывать» сообщение к конкретному реквизиту формы. Разберем, как это работает в связке с завершением кода:
&НаСервере
Процедура ОбработатьНажатиеКнопки()
Если Реквизит1 = 0 Тогда
Сообщение = Новый СообщениеПользователю();
Сообщение.Текст = "Поле 'Реквизит 1' должно быть заполнено!";
Сообщение.Поле = "Объект.Реквизит1"; // Привязка к полю на форме
Сообщение.Сообщить();
Возврат; // Завершаем работу после вывода сообщения
КонецЕсли;
КонецПроцедуры
Посмотрим на преимущества этого подхода. Сообщение не просто выводится в окно сообщений, но и подсвечивает конкретное поле на форме, помогая пользователю понять, где именно допущена ошибка. Это считается «хорошим тоном» в разработке на 1С. Чтобы не писать такой код вручную для каждого поля, можно применить готовый механизм для настройки контроля заполнения реквизитов в пользовательском режиме.
Для создания надежных систем программисты часто отказываются от резкого прерывания кода через исключения в пользу возвращаемых структур. Давайте проанализируем, как можно реализовать проверку условий более элегантно. Мы создаем функцию, которая возвращает структуру с результатом операции.
&НаСервере
Функция ВыполнитьРасчетНаСервере()
Результат = Новый Структура("Успех, ТекстОшибки", Истина, "");
Если УсловиеОшибки() Тогда
Результат.Успех = Ложь;
Результат.ТекстОшибки = "Недостаточно прав для выполнения операции.";
Возврат Результат;
КонецЕсли;
// ... логика расчета ...
Возврат Результат;
КонецФункции
&НаКлиенте
Процедура КомандаВыполнить(Команда)
РезультатОперации = ВыполнитьРасчетНаСервере();
Если Не РезультатОперации.Успех Тогда
ПоказатьПредупреждение(, РезультатОперации.ТекстОшибки);
Возврат;
КонецЕсли;
Сообщить("Расчет выполнен успешно!");
КонецПроцедуры
Такой подход позволяет избежать «красных окон» ошибок и дает возможность гибко управлять интерфейсом на стороне клиента, например, используя метод ПоказатьПредупреждение, который выглядит гораздо дружелюбнее для конечного пользователя.
Рассмотрим ситуацию, когда мы работаем в стандартных обработчиках событий, таких как ПередЗаписью или ОбработкаПроверкиЗаполнения. В этих процедурах платформа предоставляет специальный параметр Отказ. Для детального освоения последовательности их вызова и правильного размещения обработчиков полезно использовать инструмент для визуального изучения событий платформы 1С.
Важно помнить: установка Отказ = Истина сообщает системе, что действие (например, запись документа) нужно отменить, но это не останавливает выполнение кода в самой процедуре. Посмотрим на типичную ошибку и правильное решение:
// НЕПРАВИЛЬНО
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
Если Не ПроверкаПройдена() Тогда
Отказ = Истина;
Сообщить("Ошибка!");
// Код ниже ВСЕ РАВНО выполнится, несмотря на Отказ = Истина
КонецЕсли;
ВыполнитьТяжелыеРасчеты();
КонецПроцедуры
// ПРАВИЛЬНО
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
Если Не ПроверкаПройдена() Тогда
Отказ = Истина;
Сообщить("Ошибка!");
Возврат; // Явно прекращаем выполнение текущего кода
КонецЕсли;
ВыполнитьТяжелыеРасчеты();
КонецПроцедуры
В обсуждениях иногда всплывает метод ЗавершитьРаботуСистемы(). Проанализируем, почему это плохой совет для нашей задачи. Во-первых, этот метод работает только на клиенте. Попытка вызвать его на сервере приведет к ошибке. Во-вторых, этот метод закрывает всё приложение 1С у пользователя. Если вы хотите просто остановить одну обработку из-за пустой переменной, закрытие всей программы будет крайне раздражающим фактором для пользователя.
Подведем итог нашему разбору. Выбор метода завершения работы зависит от ваших целей:
Помните, что грамотное управление потоком выполнения программы делает ваш код более предсказуемым, а работу пользователя с системой — комфортной.