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

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

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

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

Почему вид операции не виден в ОбработкаЗаполнения при стандартном открытии формы

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

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

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

Чтобы обойти это ограничение, рассмотрим два основных подхода: программную передачу структуры через параметр ЗначенияЗаполнения и использование механизма БСП.

Способ 1. Программная команда с передачей структуры через «ЗначенияЗаполнения»

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

Разберем по шагам реализацию данного варианта.

Шаг 1. Создание команд ввода на основании

В документе-основании создадим отдельные команды (или одну команду с меню/выбором действия), например, «Создать документ (товары)» и «Создать документ (услуги)». В модуле команды вызываем открытие формы нового документа с заполнением специальной структуры:


&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)

    // ПараметрКоманды содержит ссылку на текущий исходный документ
    ПараметрыЗаполнения = Новый Структура;
    ПараметрыЗаполнения.Вставить("ДокументОснование", ПараметрКоманды);
    ПараметрыЗаполнения.Вставить("ВидОперации", ПредопределенноеЗначение("Перечисление.ВидыОпераций.Услуги"));

    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("ЗначенияЗаполнения", ПараметрыЗаполнения);

    ОткрытьФорму("Документ.Документ2.ФормаОбъекта", ПараметрыФормы, ПараметрыВыполненияКоманды.Источник, ПараметрыВыполненияКоманды.Уникальность, ПараметрыВыполненияКоманды.Окно);

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

Шаг 2. Обработка структуры в модуле создаваемого объекта

В модуле объекта создаваемого документа переопределим процедуру ОбработкаЗаполнения. Теперь параметром ДанныеЗаполнения может быть как обычная ссылка (при типовом заполнении), так и наша структура:


Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)

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

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

Процедура ЗаполнитьПоДокументуОснованию(СсылкаОснование)

    Если ЭтотОбъект.ВидОперации = Перечисления.ВидыОпераций.Услуги Тогда
        // Заполнение табличной части услуг
    Иначе
        // Заполнение табличной части товаров
    КонецЕсли;

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

Важная деталь: если параметр СтандартнаяОбработка в процедуре ОбработкаЗаполнения останется равным Истина, платформа самостоятельно сопоставит ключи структуры ДанныеЗаполнения с именами реквизитов документа и автоматически заполнит реквизит ВидОперации, если их наименования и типы совпадают.

Способ 2. Использование подключаемых команд Библиотеки стандартных подсистем (БСП)

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

Посмотрим на алгоритм настройки через модуль менеджера создаваемого документа:

  1. Открываем модуль менеджера подчиненного документа (куда вводятся данные).
  2. Находим или добавляем экспортную процедуру ДобавитьКомандыСозданияНаОсновании.
  3. Регистрируем нужные варианты команд с заполнением дополнительных параметров:

Процедура ДобавитьКомандыСозданияНаОсновании(КомандыСозданияНаОсновании, ПараметрыИсправления) Экспорт

    Команда = КомандыСозданияНаОсновании.Добавить();
    Команда.Идентификатор = "СоздатьДокумент2Услуги";
    Команда.Представление = НСтр("ru = 'Документ2 (услуги)'");
    Команда.Порядок = 10;
    
    // Передаем вид операции в структуру дополнительных параметров
    ДополнительныеПараметры = Новый Структура;
    ДополнительныеПараметры.Вставить("ВидОперации", Перечисления.ВидыОпераций.Услуги);
    Команда.ДополнительныеПараметры = ДополнительныеПараметры;

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

Подсистема БСП при формировании команды автоматически упакует ДополнительныеПараметры и передаст их в процедуру ОбработкаЗаполнения модуля объекта в составе структуры ДанныеЗаполнения, что позволит обработать операцию аналогично первому способу.

Контроль корректности и отказ от заполнения

В процессе заполнения может выясниться, что выбранный вид операции не подходит под текущее состояние документа-основания (например, в исходном документе нет услуг, а выбран вид операции «Услуги»).

Обратите внимание: у системного обработчика ОбработкаЗаполнения отсутствует стандартный параметр Отказ. Для прерывания процесса создания документа и информирования пользователя по стандартам разработки 1С используется генерация исключения:


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

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

← На главную