Как правильно перегрузить свойства объектов в 1С:Управление торговлей 10.3 через COM-соединение?

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

Перенос дополнительных реквизитов и свойств номенклатуры из одной базы в другую через COM-соединение — частая задача при интеграции или синхронизации баз на платформе 1С:Предприятие 8. Однако при реализации такого механизма разработчики часто сталкиваются с ситуацией, когда свойства создаются корректно, но их значения теряют подчиненность, не привязываются к категориям или не отображаются в карточках номенклатуры приемника.

Рассмотрим подробно, почему возникают эти ошибки при переносе дополнительных реквизитов в конфигурации «Управление торговлей» редакции 10.3 и как правильно написать алгоритм переноса.

Типичные ошибки при программном переносе свойств

Разберем основные причины, по которым свойства или их значения переносятся некорректно:

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

Шаг 1. Формирование запроса к базе-источнику

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


Если КорневойКаталог.Пустая() Тогда
    Сообщить("Не выбран Корневой Каталог!");
    Возврат;
КонецЕсли;

Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|    ЗначенияСвойствОбъектов.Объект КАК Номенклатура,
|    ЗначенияСвойствОбъектов.Свойство КАК Свойство,
|    ЗначенияСвойствОбъектов.Значение КАК Значение,
|    ЗначенияСвойствОбъектов.Свойство.НазначениеСвойства КАК НазначениеСвойства
|ИЗ
|    РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
|ГДЕ
|    ЗначенияСвойствОбъектов.Объект В ИЕРАРХИИ(&ВыбКаталог)";

Запрос.УстановитьПараметр("ВыбКаталог", КорневойКаталог);
СписокСвойств = Запрос.Выполнить().Выгрузить();

Шаг 2. Корректная запись свойств и значений в базу-приемник

Рассмотрим алгоритм обхода выгруженных данных. Для каждого элемента необходимо найти объект-приемник по УИД, сопоставить само свойство (элемент ПВХ), создать или найти элемент значения свойства с указанием его владельца и записать результат в регистр сведений ЗначенияСвойствОбъектов.


Для каждого СтрНомен из СписокСвойств Цикл
    // 1. Поиск номенклатуры в приемнике по УИД
    УидВЭтойБазе = СтрНомен.Номенклатура.УникальныйИдентификатор();
    УидВоВнешнейБазе = БазаОткрыта.NewObject("УникальныйИдентификатор", Строка(УидВЭтойБазе));
    
    Справочник = БазаОткрыта.Справочники.Номенклатура;
    СправочникОбъект = Справочник.ПолучитьСсылку(УидВоВнешнейБазе).ПолучитьОбъект();
    Если СправочникОбъект = Неопределено Тогда
        Сообщить("Не нашли номенклатуру: " + СтрНомен.Номенклатура);
        Продолжить;
    КонецЕсли;

    // 2. Поиск или создание самого свойства (ПВХ СвойстваОбъектов)
    Свойство = БазаОткрыта.ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию(СокрЛП(СтрНомен.Свойство.Наименование));
    Назн = БазаОткрыта.ПланыВидовХарактеристик.НазначенияСвойствКатегорийОбъектов.НайтиПоНаименованию(СокрЛП(СтрНомен.НазначениеСвойства.Наименование));
    
    Если Назн.Наименование = "" Тогда
        Сообщить("Не нашли назначение свойства: " + СтрНомен.НазначениеСвойства.Наименование);
        Продолжить;
    КонецЕсли;

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

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

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

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

    // 4. Запись значения свойства для объекта
    МенеджерЗаписи = БазаОткрыта.РегистрыСведений.ЗначенияСвойствОбъектов.СоздатьМенеджерЗаписи();         
    МенеджерЗаписи.Объект = СправочникОбъект.Ссылка;        
    МенеджерЗаписи.Свойство = Свойство;         
    МенеджерЗаписи.Значение = НовЗнач;        
    МенеджерЗаписи.Записать();    
    
    Сообщить("Записано свойство: " + СтрНомен.Свойство.Наименование);
КонецЦикла;

Шаг 3. Привязка свойств к группам номенклатуры

Выясним причину, почему перенесенное свойство может не отображаться в диалоговом окне номенклатуры в базе-приемнике. В УТ 10.3 привязка свойства к объектам (или папкам номенклатуры) хранится отдельно в регистре сведений НазначенияСвойствОбъектов.

Чтобы свойство стало доступным для конкретной группы номенклатуры или объекта, необходимо добавить запись в этот регистр сведений:


ЗаписьНазначения = БазаОткрыта.РегистрыСведений.НазначенияСвойствОбъектов.СоздатьМенеджерЗаписи();
ЗаписьНазначения.Объект = ГруппаНоменклатурыВПриемнике; // Ссылка на папку номенклатуры или тип объектов
ЗаписьНазначения.Свойство = Свойство; // Ссылка на ПВХ СвойстваОбъектов
ЗаписьНазначения.Записать(Истина);

После заполнения этого регистра перенесенные свойства будут правильно отображаться во вкладке «Свойства» карточки номенклатуры и ее групп в базе-приемнике.

← На главную