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

Программист 1С v8.3 (Обычные формы) 1С:Комплексная автоматизация IT и автоматизация бизнеса
← На главную

При реализации бизнес-логики в 1С часто возникает задача запретить создание подчиненного документа (например, «Реализация товаров и услуг») на основании документа-источника (например, «Заказ покупателя»), если в исходном документе не заполнены обязательные реквизиты. Однако стандартное поведение платформы при попытке прервать операцию в обработчике заполнения нередко приводит к открытию пустой формы нового документа.

Разберем причины такого поведения платформы 1С и рассмотрим корректные способы отмены создания и открытия документа на основании.

Почему оператор «Возврат» в ОбработкаЗаполнения открывает пустой документ

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

  1. В оперативной памяти создается новый объект документа.
  2. Вызывается процедура ОбработкаЗаполнения(Основание) в модуле объекта создаваемого документа.
  3. После выполнения процедуры платформа открывает основную форму созданного объекта для интерактивного редактирования.

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

Рассмотрим несколько способов корректной отмены создания документа.

Способ 1. Проверка в событии формы «ПередОткрытием»

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

Посмотрим на пример реализации в обычном приложении (КА 1.1 / УПП 1.3):


Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
    
    // Проверяем, что форма открывается для нового документа с переданным основанием
    Если ЭтоНовый() И ЗначениеЗаполнено(ПараметрОснование) Тогда
        
        Если НЕ ЗначениеЗаполнено(ПараметрОснование.ДатаОтгрузки) Тогда
            Предупреждение("Нельзя создать реализацию: в заказе не заполнена дата отгрузки!");
            Отказ = Истина;
            Возврат;
        КонецЕсли;
        
    КонецЕсли;

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

Разберем особенности этого подхода:

  1. Уничтожение объекта: Если процедура ОбработкаЗаполнения уже заполнила реквизиты в памяти, но в ПередОткрытием установлен флаг Отказ = Истина, объект не записывается в базу данных и уничтожается из оперативной памяти без следов в информационной базе.
  2. Оповещение пользователя: В обычном приложении метод Предупреждение() является модальным и гарантирует, что пользователь увидит причину отмены операции. Использование метода Сообщить() в связке с Отказ = Истина может привести к тому, что окно сообщений останется незамеченным.
  3. Ограничение: Данная проверка срабатывает только при интерактивной работе пользователя через форму. Если документ создается программно (например, фоновым заданием или внешней обработкой без открытия формы), код события ПередОткрытием выполнен не будет.

Способ 2. Вызов исключения в «ОбработкаЗаполнения»

Если требуется гарантированно запретить создание объекта как интерактивно, так и программно непосредственно на этапе заполнения, можно использовать аварийное прерывание выполнения кода через вызов исключения.

Посмотрим на пример реализации в модуле объекта:


Процедура ОбработкаЗаполнения(Основание)
    
    Если ТипЗнч(Основание) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда
        
        Если НЕ ЗначениеЗаполнено(Основание.ДатаОтгрузки) Тогда
            ВызватьИсключение "Невозможно создать документ: в заказе-основании не указана дата отгрузки.";
        КонецЕсли;
        
        // Алгоритм заполнения реквизитов документа
        // ...
        
    КонецЕсли;

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

Особенности использования исключений:

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

Способ 3. Проверка в документе-источнике перед созданием

Наиболее удобным с точки зрения пользовательского интерфейса является перенос проверки на сторону документа-основания (в форму «Заказа покупателя»). В этом случае создание нового объекта даже не инициализируется, если условия не соблюдены.

Разберем по шагам, как это реализовать:

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

Посмотрим на пример кода в модуле формы документа-источника:


Процедура ДействияФормыСоздатьРеализацию(Кнопка)
    
    // Проверяем заполненность обязательных данных в текущем документе
    Если НЕ ЗначениеЗаполнено(ЭтотОбъект.ДатаОтгрузки) Тогда
        Предупреждение("Перед созданием реализации необходимо заполнить дату отгрузки в текущем заказе!");
        Возврат;
    КонецЕсли;
    
    // Инициализируем создание нового документа на основании
    ПараметрыФормы = Новый Структура("Основание", ЭтотОбъект.Ссылка);
    ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаОбъекта", ПараметрыФормы);

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

Способ 4. Комплексный контроль на уровне «ПередЗаписью»

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


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    Если ЗначениеЗаполнено(Сделка) И ТипЗнч(Сделка) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда
        Если НЕ ЗначениеЗаполнено(Сделка.ДатаОтгрузки) Тогда
            Отказ = Истина;
            Сообщить("Запись отменена: в заказе " + Строка(Сделка) + " не указана дата отгрузки!", СтатусСообщения.Важное);
        КонецЕсли;
    КонецЕсли;

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

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

← На главную