В типовой конфигурации 1С:УПП 1.3 (Управление производственным предприятием) механизм дополнительных свойств реализован через отдельный регистр сведений ЗначенияСвойствОбъектов. Это создает определенные трудности при вводе документов "на основании": в отличие от реквизитов самого объекта, данные регистра не копируются автоматически. Основная сложность заключается в том, что в момент заполнения нового документа у него еще нет ссылки (Ref), а значит, мы не можем записать данные в регистр напрямую. Рассмотрим подробнее, как решить эту задачу правильно и элегантно.
Проанализируем ситуацию: когда пользователь нажимает кнопку "Создать на основании", срабатывает процедура ОбработкаЗаполнения в модуле объекта. В этот момент документ существует только в оперативной памяти. Регистр ЗначенияСвойствОбъектов в качестве измерения использует ссылку на объект-владелец. Поскольку ссылки еще нет, любая попытка записи в регистр выдаст ошибку или приведет к записи с пустой ссылкой.
Чтобы обойти это ограничение, мы разберем по шагам механизм двухэтапной передачи данных: от документа-основания в структуру ДополнительныеСвойства и затем — в физическую таблицу базы данных.
Это наиболее надежный и "чистый" метод. Он позволяет передать данные между разными событиями жизненного цикла объекта внутри одной транзакции.
Шаг 1. Сбор данных в ОбработкаЗаполнения
В модуле объекта (например, документа РеализацияТоваровУслуг) найдем или создадим процедуру ОбработкаЗаполнения. Здесь нам нужно прочитать свойства документа-основания и сохранить их "в карман" (в коллекцию ДополнительныеСвойства).
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
// Проверяем, что основание — это Заказ Покупателя
Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда
// Запрос к регистру для получения всех свойств заказа
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЗначенияСвойствОбъектов.Свойство,
| ЗначенияСвойствОбъектов.Значение
|ИЗ
| РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
|ГДЕ
| ЗначенияСвойствОбъектов.Объект = &Основание";
Запрос.УстановитьПараметр("Основание", ДанныеЗаполнения);
ТаблицаСвойств = Запрос.Выполнить().Выгрузить();
// Помещаем таблицу во временное хранилище объекта
ЭтотОбъект.ДополнительныеСвойства.Вставить("ТаблицаСвойствДляПереноса", ТаблицаСвойств);
КонецЕсли;
КонецПроцедуры
Шаг 2. Запись данных в событии ПриЗаписи
Теперь, когда документ записывается, у него появляется ссылка. В этот момент мы извлекаем нашу таблицу и записываем ее в регистр.
Процедура ПриЗаписи(Отказ)
Если ЭтотОбъект.ДополнительныеСвойства.Свойство("ТаблицаСвойствДляПереноса") Тогда
ТаблицаСвойств = ЭтотОбъект.ДополнительныеСвойства.ТаблицаСвойствДляПереноса;
Для Каждого СтрокаСвойство Из ТаблицаСвойств Цикл
// Создаем набор записей регистра для конкретного свойства
МенеджерЗаписи = РегистрыСведений.ЗначенияСвойствОбъектов.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Объект = ЭтотОбъект.Ссылка;
МенеджерЗаписи.Свойство = СтрокаСвойство.Свойство;
МенеджерЗаписи.Значение = СтрокаСвойство.Значение;
МенеджерЗаписи.Записать(Истина);
КонецЦикла;
// Удаляем из коллекции, чтобы не записать повторно при следующем сохранении
ЭтотОбъект.ДополнительныеСвойства.Удалить("ТаблицаСвойствДляПереноса");
КонецЕсли;
КонецПроцедуры
Если вы хотите сохранить конфигурацию на поддержке и минимизировать изменения в типовых модулях, выясним причину, по которой лучше использовать Подписки на события. Это позволит вынести логику в отдельный общий модуль.
ОбработкаЗаполнения для необходимых документов.Основание. Если это ЗаказПокупателя, считайте свойства и запишите их в Источник.ДополнительныеСвойства.ПриЗаписи. В ней извлеките данные и запишите в регистр ЗначенияСвойствОбъектов.Важный нюанс: В УПП 1.3 свойства привязаны к "Назначениям". Перед записью желательно проверить, разрешено ли выбранное свойство для типа документа Реализация. Это можно сделать через План Видов Характеристик СвойстваОбъектов, проверив состав его назначений.
Проанализируем ситуацию: всегда ли нужно физически копировать данные в базу? Если свойства реализации на 100% совпадают со свойствами заказа и не должны редактироваться отдельно, мы можем применить динамическое отображение.
В форме документа "Реализация" можно программно добавить закладку или панель, которая будет отображать свойства документа, указанного в реквизите Сделка или ДокументОснование.
Плюсы этого метода:
В УПП 1.3 существуют встроенные механизмы для работы со свойствами. Чтобы не писать запросы вручную, рекомендуем использовать функции общего модуля ПроцедурыУправленияСвойствами. Рассмотрим пример получения свойств через типовой функционал:
// Пример получения структуры свойств через типовой механизм
СтруктураСвойств = ПроцедурыУправленияСвойствами.ПолучитьСписокСвойств(ДанныеЗаполнения);
// Данная функция вернет массив или таблицу со всеми настроенными свойствами объекта
Использование типовых модулей делает ваш код более устойчивым к обновлениям системы и гарантирует соблюдение прав доступа (RLS), которые могут быть наложены на регистры сведений.
Для реализации переноса свойств в 1С:УПП 1.3 наиболее правильным считается первый вариант с использованием коллекции ДополнительныеСвойства. Он гарантирует, что данные будут записаны только в случае успешного сохранения документа и будут доступны в рамках одной транзакции. Если же вам важно сохранить "чистоту" типовой конфигурации, используйте механизм подписок на события.