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