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

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

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

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

1. Где располагается код заполнения документа

Проанализируем архитектуру вызовов платформы 1С. Когда пользователь нажимает кнопку Создать на основании, платформа инициализирует создание нового объекта-приемника и вызывает специальное событие в модуле объекта создаваемого документа (документа-приемника, а не документа-источника).

Для создания обработчика выполним следующие шаги:

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

2. Назначение параметров процедуры ОбработкаЗаполнения

Рассмотрим структуру типовой процедуры модуля объекта:


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

Выясним назначение ключевых параметров:

  1. ДанныеЗаполнения — содержит ссылку на объект, из которого была вызвана команда ввода на основании (документ-источник), либо структуру переданных параметров при программном вызове. Название этой переменной менять в заголовке процедуры не требуется, так как в нее могут передаваться различные типы документов-оснований.
  2. СтандартнаяОбработка — булевый флаг. Если установить его в значение Ложь, платформа отключит стандартные системные механизмы заполнения (например, автозаполнение по структуре подчиненности или базовые системные механизмы конфигурации).

3. Проверка типа источника и перенос реквизитов

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

Посмотрим на пример заполнения реквизитов шапки:


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

4. Быстрое копирование одноименных реквизитов и табличных частей

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


// Заполняем все совпадающие по имени свойства шапки
ЗаполнитьЗначенияСвойств(ЭтотОбъект, ДанныеЗаполнения);

// Несовпадающие реквизиты дозаполняем явным присвоением
ЭтотОбъект.Груз = ДанныеЗаполнения.ГрузЕТСНГ;

Для переноса строк табличной части с идентичной структурой колонок применим метод выгрузки и загрузки:


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

5. Фиксация связи документов в структуре подчиненности

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

ЭтотОбъект.ДокументОснование = ДанныеЗаполнения;

6. Разделение логики объекта и экранных форм

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

Если на форме документа размещены динамические элементы, расчетные панели или встроенные отчеты, их нельзя формировать внутри ОбработкаЗаполнения:

  1. Расчетные данные формы инициализируются в модуле формы документа в процедуре ПриСозданииНаСервере с анализом переданных параметров.
  2. Печатные формы и отчеты выносятся в отдельные объекты конфигурации (обработки, отчеты) либо формируются через модуль менеджера документа при вызове команд печати.

7. Программный ввод на основании

Если требуется создать и заполнить документ программно без открытия пользовательского интерфейса, используется метод объекта Заполнить(), который передает управление в процедуру ОбработкаЗаполнения:


НовыйДокумент = Документы.ОтправлениеФ.СоздатьДокумент();
НовыйДокумент.Заполнить(СсылкаНаПеревозкуТК);
НовыйДокумент.Записать(РежимЗаписиДокумента.Запись);
← На главную