Как сконвертировать обычный реквизит справочника в значение ПВХ (дополнительный реквизит БСП) в 1С:Конвертация данных 2.1?

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

При интеграции систем на платформе 1С разработчики часто сталкиваются с задачей перехода от жесткой структуры метаданных к гибкой. Типичный пример: в старой базе-источнике свойство объекта (например, «Цвет») хранилось как обычный реквизит с типом ПеречислениеСсылка. В современной базе-приемнике (например, 1С:Документооборот, 1С:ERP или 1С:Управление торговлей, построенных на БСП) этот реквизит должен стать частью механизма дополнительных реквизитов и сведений.

Сложность заключается в том, что в БСП дополнительные реквизиты хранятся в табличной части ДополнительныеРеквизиты, где строками являются пары: Свойство (тип ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения) и Значение (тип СправочникСсылка.ЗначенияСвойствОбъектов, который жестко подчинен ПВХ). Стандартным сопоставлением «реквизит в реквизит» в 1С:Конвертация данных 2.1 (КД 2.1) эту задачу решить невозможно. В этой статье мы подробно разберем два надежных сценария реализации этой логики.

Проанализируем оба подхода, их преимущества и пошаговую настройку.

---

Способ 1. Передача значения через параметры и обработка в Приемнике (Рекомендуемый)

Этот способ является наиболее гибким и простым в отладке. Мы не пытаемся сопоставить сложные структуры в XML-правилах. Вместо этого мы передаем текстовое представление значения во временный параметр объекта, а на стороне базы-приемника программно находим (или создаем) нужное свойство и значение, после чего записываем их в табличную часть.

Рассмотрим пошагово, как это настроить в КД 2.1.

Шаг 1. Настройка ПКС в базе-источнике

  1. Откроем ПКО (Правило конвертации объекта) для нашего справочника-источника.
  2. В таблице «Правила конвертации свойств» (ПКС) добавим новую строку.
  3. Поля Источник и Приемник оставим пустыми.
  4. В колонке «Имя параметра» укажем понятное имя, например: ЦветПараметр.
  5. Установим флаг «Передать данные в параметр».
  6. В обработчике события Перед выгрузкой этого ПКС напишем код, который превратит наше перечисление в строку для передачи:

Если ЗначениеЗаполнено(Источник.Цвет) Тогда
    Значение = Строка(Источник.Цвет);
Иначе
    Отказ = Истина; // Если цвет не заполнен, параметр передавать не нужно
КонецЕсли;

Шаг 2. Написание алгоритма обработки в базе-приемнике

Теперь перейдем к ПКО нашего справочника и откроем обработчик события После загрузки. Этот обработчик выполняется на стороне приемника, когда объект уже прочитан из XML, его реквизиты заполнены в памяти, но сам объект еще не записан в базу данных.

Пропишем следующий алгоритм поиска ПВХ, создания значения и заполнения табличной части:


// Проверяем наличие переданного параметра
Если ПараметрыОбъекта <> Неопределено И ПараметрыОбъекта.Свойство("ЦветПараметр") Тогда
    ИмяЦвета = СокрЛП(ПараметрыОбъекта.ЦветПараметр);
    
    Если ЗначениеЗаполнено(ИмяЦвета) Тогда
        
        // 1. Ищем элемент ПВХ "Цвет" по наименованию
        СвойствоПВХ = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Цвет");
        
        Если ЗначениеЗаполнено(СвойствоПВХ) Тогда
            
            // 2. Ищем значение в подчиненном справочнике "ЗначенияСвойствОбъектов" с учетом владельца
            ЗначениеЦвета = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию(ИмяЦвета, Истина, , СвойствоПВХ);
            
            // Если такого цвета в базе еще нет — создаем его программно
            Если НЕ ЗначениеЗаполнено(ЗначениеЦвета) Тогда
                НовоеЗначение = Справочники.ЗначенияСвойствОбъектов.СоздатьЭлемент();
                НовоеЗначение.Владелец = СвойствоПВХ; // Обязательно привязываем к нашему ПВХ
                НовоеЗначение.Наименование = ИмяЦвета;
                
                Попытка
                    НовоеЗначение.Записать();
                    ЗначениеЦвета = НовоеЗначение.Ссылка;
                Исключение
                    ЗаписьЖурналаРегистрации("КонвертацияДанных", УровеньЖурналаРегистрации.Ошибка, , , 
                        "Не удалось создать значение свойства: " + ИмяЦвета + ". Ошибка: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
                КонецПопытки;
            КонецЕсли;
            
            // 3. Заполняем табличную часть "ДополнительныеРеквизиты" в объекте приемника
            Если ЗначениеЗаполнено(ЗначениеЦвета) Тогда
                // Проверяем, нет ли уже в табличной части строки с этим свойством, чтобы избежать дублирования
                Отбор = Новый Структура("Свойство", СвойствоПВХ);
                НайденныеСтроки = Объект.ДополнительныеРеквизиты.НайтиСтроки(Отбор);
                
                Если НайденныеСтроки.Количество() > 0 Тогда
                    // Перезаписываем значение в существующей строке
                    НайденныеСтроки[0].Значение = ЗначениеЦвета;
                Иначе
                    // Добавляем новую строку
                    НоваяСтрока = Объект.ДополнительныеРеквизиты.Добавить();
                    НоваяСтрока.Свойство = СвойствоПВХ;
                    НоваяСтрока.Значение = ЗначениеЦвета;
                КонецЕсли;
            КонецЕсли;
            
        КонецЕсли;
    КонецЕсли;
КонецЕсли;

Преимущества метода: Высокая скорость работы, полный контроль над процессом поиска и создания элементов через встроенный язык 1С, отсутствие необходимости создавать сложные вложенные правила конвертации.

---

Способ 2. Использование ПКГС и виртуальной коллекции (Без кода в Приемнике)

Если по регламенту разработки вам запрещено использовать сложные обработчики «После загрузки» на стороне приемника (например, загрузка выполняется в закрытом контуре, где транзакции должны быть максимально «чистыми»), мы можем решить задачу стандартными средствами XML-маппинга КД 2.1.

Для этого мы сымитируем наличие табличной части на стороне источника с помощью виртуальной коллекции.

Шаг 1. Создание ПКГС (Правила конвертации группы свойств)

  1. В ПКО вашего справочника добавьте новую группу свойств (ПКГС).
  2. Поле Источник оставьте пустым.
  3. В поле Приемник выберите табличную часть ДополнительныеРеквизиты.
  4. Откройте обработчик события Перед обработкой этого ПКГС. Здесь мы программно сформируем таблицу значений, которую КД воспримет как реальную табличную часть источника:

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

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

Шаг 2. Настройка ПКС внутри ПКГС

Внутри созданной группы свойств добавьте два правила конвертации свойств (ПКС):

  1. Для свойства (Свойство):
    • Источник: Свойство.
    • Приемник: Свойство.
    • Правило (ПКО): Выберите ПКО для плана видов характеристик ДополнительныеРеквизитыИСведения (в настройках этого ПКО должен быть указан поиск по наименованию).
  2. Для значения (Значение):
    • Источник: Значение.
    • Приемник: Значение.
    • Правило (ПКО): Создайте специальное ПКО, например, ПеречислениеЦвета_В_ЗначенияСвойствОбъектов.

Выясним причину, почему для значения требуется особое ПКО. Поскольку справочник ЗначенияСвойствОбъектов подчинен плану видов характеристик, при создании его элементов XML-пакет должен содержать информацию о владельце. Настроим ПКО ПеречислениеЦвета_В_ЗначенияСвойствОбъектов следующим образом:

Значение = "Цвет"; // Имя владельца для поиска по наименованию ---

Важные технические нюансы работы с механизмами БСП

Независимо от выбранного способа, необходимо учитывать особенности архитектуры Библиотеки стандартных подсистем:

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

Мы подробно разобрали два отличных инструмента для решения этой интеграционной задачи. Для большинства проектов оптимальным решением будет Способ 1, так как он обеспечивает простоту чтения кода, легкость отладки стандартными средствами и быстродействие при загрузке больших объемов данных.

← На главную