Как правильно передать значение через AdditionalInfo и автоматически создать элемент в приемнике (КД 3.0)

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

При настройке обмена данными между конфигурациями 1С на платформе 8.3 (например, между 1С:ERP Управление предприятием и 1С:Бухгалтерия предприятия) по технологии EnterpriseData (Конвертация данных 3.0) разработчики часто сталкиваются с несовпадением структуры метаданных. Типичный пример: в базе-источнике (ERP) реквизит является свойством шапки документа (например, НаправлениеДеятельности), а в базе-приемнике (БП) аналогичное по смыслу значение должно записываться в строку табличной части (например, НоменклатурнаяГруппа).

Для решения таких задач стандартные правила сопоставления «свойство в свойство» не подходят. В таких случаях на помощь приходит передача данных через свойство AdditionalInfo (дополнительная информация в формате XDTO). Однако при чтении этих данных на стороне приемника возникает проблема: как правильно найти соответствующий элемент справочника в базе-приемнике и автоматически создать его, если он отсутствует? Рассмотрим подробно два способа решения этой задачи — простой программный метод и штатный архитектурный подход КД 3.0.

Зачем нужен AdditionalInfo в EnterpriseData?

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

---

Вариант 1. Программный метод (Решение «в лоб»)

Этот способ является наиболее простым в реализации и часто используется разработчиками для быстрого решения задачи. Его суть заключается в том, что мы передаем текстовое представление (наименование) нужного элемента через AdditionalInfo, а на стороне приемника перехватываем эти данные, ищем элемент по наименованию и, если поиск не дал результатов, создаем элемент программно.

Рассмотрим по шагам, как реализовать этот алгоритм.

Шаг 1. Передача данных на стороне источника (1С:ERP)

В модуле менеджера обмена источника в обработчике выгрузки документа мы помещаем наименование направления деятельности в структуру AdditionalInfo. Для этого используем метод AdditionalInfoВставить:


// Код на стороне ERP (Источник)
// Помещаем наименование направления деятельности в контейнер AdditionalInfo
AdditionalInfoВставить(ДанныеXDTO, "НаправлениеДеятельности", ДанныеИБ.НаправлениеДеятельности.Наименование);

Шаг 2. Обработка и программное создание на стороне приемника (1С:Бухгалтерия)

На стороне приемника в обработчике получения данных (например, ПриКонвертацииДанныхXDTO или в обработчике самого ПКО документа) мы выполняем чтение переданной структуры. Если элемент справочника НоменклатурныеГруппы не найден по наименованию, мы создаем его вручную с помощью метода СоздатьЭлемент().


// Код на стороне БП (Приемник)
Если ДанныеXDTO.Свойство("AdditionalInfo") И ТипЗнч(ДанныеXDTO.AdditionalInfo) = Тип("Структура") Тогда
    ДопДанные = ДанныеXDTO.AdditionalInfo;
    
    // Проверяем наличие нашего свойства в структуре
    Если ДопДанные.Свойство("НаправлениеДеятельности") Тогда
        // Выполняем поиск по наименованию в справочнике-приемнике
        НаправлениеДеятельности = Справочники.НоменклатурныеГруппы.FindByName(ДопДанные.НаправлениеДеятельности, Истина);
        
        // Если элемент не найден и переданное имя не пустое — создаем его программно
        Если НаправлениеДеятельности.IsEmpty() И ДопДанные.НаправлениеДеятельности <> "" Тогда
            НовыйОбъект = Справочники.НоменклатурныеГруппы.CreateItem();
            НовыйОбъект.Description = ДопДанные.НаправлениеДеятельности;
            
            Попытка
                НовыйОбъект.Write();
                НаправлениеДеятельности = НовыйОбъект.Ref;
            Исключение
                ЗаписьЖурналаРегистрации("ОбменДанными.ОшибкаСоздания",
                    УровеньЖурналаРегистрации.Ошибка,
                    НовыйОбъект.Metadata(),,
                    ПодробноеПредставлениеОшибки(ErrorInfo()));
            КонецПопытки;
        КонецЕсли;
        
        // Полученную ссылку "НаправлениеДеятельности" далее используем для заполнения ТЧ документа
    КонецЕсли;
КонецЕсли;

Преимущества метода: Простота реализации, понятная логика работы, отсутствие необходимости глубоко настраивать правила конвертации объектов в КД 3.0.

Недостатки метода: Этот подход нарушает базовые принципы работы Конвертации данных. Создание объектов в обход штатных механизмов КД3 приводит к тому, что для этих объектов не работают правила сопоставления, не регистрируются изменения для обратной синхронизации, а также могут возникнуть дубли элементов при повторных обменах, если наименование будет изменено пользователем.

---

Вариант 2. Штатный архитектурный подход КД 3.0 (Правильный способ)

Чтобы не нарушать ссылочную целостность и логику работы подсистемы обмена данными БСП, в Конвертации данных 3.0 предусмотрен штатный механизм работы со структурами данных и ПКО типа _ИзСтруктуры.

Выясним причину, почему это работает лучше: при таком подходе мы передаем не просто строку, а формируем полноценную структуру данных объекта, которую механизм КД3 на стороне приемника распознает и обрабатывает точно так же, как если бы это был полноценный XDTO-объект, пришедший из файла. Система сама выполнит поиск по правилам идентификации, сопоставит объект, а при его отсутствии — создаст его по правилам ПКО получения.

Рассмотрим подробнее по шагам, как настроить этот процесс.

Шаг 1. Формирование структуры на стороне источника (ERP)

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


// Код на стороне ERP (Источник)
СтруктураДанныхНГ = Новый Структура;
// Передаем наименование и любые другие реквизиты (например, Код, Родитель и др.)
СтруктураДанныхНГ.Вставить("Наименование", ДанныеИБ.НаправлениеДеятельности.Наименование);

// Передаем структуру в выгрузку, указав ПКО, которое умеет конвертировать ее в объект формата
СтруктураПКО = Новый Структура("Значение, ИмяПКО", СтруктураДанныхНГ, "Справочник_НоменклатурныеГруппы_ИзСтруктуры");
AdditionalInfoВставить(ДанныеXDTO, "НаправлениеДеятельности", СтруктураПКО);

Шаг 2. Чтение данных через БСП на стороне приемника (БП)

На стороне приемника в обработчике мы отказываемся от прямого использования метода СоздатьЭлемент(). Вместо этого мы вызываем штатную функцию библиотеки стандартных подсистем (БСП) — ОбменДаннымиXDTOСервер.СтруктураОбъектаXDTOВДанныеИБ(). Эта функция принимает параметры, сопоставляет данные с базой и возвращает ссылку на найденный или вновь созданный элемент. Для быстрого изучения программного интерфейса и методов подсистем можно использовать справочник по методам БСП с примерами кода.


// Код на стороне БП (Приемник)
Если ДанныеXDTO.Свойство("AdditionalInfo") И ТипЗнч(ДанныеXDTO.AdditionalInfo) = Тип("Структура") Тогда
    ДопДанные = ДанныеXDTO.AdditionalInfo;
    
    Если ДопДанные.Свойство("НаправлениеДеятельности") Тогда
        // Подготавливаем структуру поиска для ПКО получения
        СтруктураПоиска = Новый Структура;
        СтруктураПоиска.Вставить("Наименование", ДопДанные.НаправлениеДеятельности);
        
        // Получаем ПКО получения для Номенклатурных групп
        ПКО_НГ = ОбменДаннымиXDTOСервер.ПКОПоИмени(КомпонентыОбмена, "Справочник_НоменклатурныеГруппы_Получение");
        
        // Вызываем штатный метод БСП для поиска или создания объекта
        РезультатКонвертации = ОбменДаннымиXDTOСервер.СтруктураОбъектаXDTOВДанныеИБ(
            КомпонентыОбмена, 
            СтруктураПоиска, 
            ПКО_НГ, 
            "ПолучитьСсылку"
        );
        
        Если РезультатКонвертации <> Неопределено Тогда
            НоменклатурнаяГруппаСсылка = РезультатКонвертации.Ссылка;
            // Успешно получили ссылку, записываем ее в ТЧ документа
        КонецЕсли;
    КонецЕсли;
КонецЕсли;

---

Критически важный нюанс КД 3.0: Защита от удаления временных объектов

Проанализируем ситуацию, с которой сталкиваются многие разработчики при использовании метода СтруктураОбъектаXDTOВДанныеИБ. Часто объект успешно создается в процессе загрузки, но после завершения сеанса обмена внезапно «исчезает» из базы данных (ссылки на него в документах превращаются в битые «<Объект не найден>»).

В чем причина такого поведения системы?

В КД 3.0 реализован строгий механизм контроля ссылочной целостности. Когда мы создаем объект «на лету» по ссылке (используя действие "ПолучитьСсылку"), система помечает его как временный и записывает в служебную таблицу ТаблицаОбъектовСозданныхПоСсылкам. Если до конца файла обмена этот объект так и не встретится в качестве полноценного («корневого») элемента XML-пакета, КД 3.0 посчитает его «мусорным» и автоматически удалит перед завершением транзакции загрузки методом УдалитьВременныеОбъектыСозданныеПоСсылкам.

Как решить эту проблему?

Чтобы система не удаляла созданный из структуры элемент, необходимо выполнить тонкую настройку правил конвертации в базе КД 3.0:

  1. Откройте конфигурацию «Конвертация данных, редакция 3.0».
  2. Перейдите к правилам конвертации объектов (ПКО) для вашей целевой сущности (в нашем случае это Справочник_НоменклатурныеГруппы_Получение).
  3. Найдите свойство Разрешить создавать объект из структуры (в некоторых версиях интерфейса оно может называться Разрешить создание по ссылке или находиться в дополнительных настройках ПКО).
  4. Установите для этого флага значение Истина.

Данная настройка сообщает платформе, что информации, переданной в структуре, абсолютно достаточно для создания полноценного, легитимного элемента справочника, и его не нужно помещать в список временных объектов на удаление.

---

Резюме

Мы рассмотрели два подхода к передаче данных через AdditionalInfo в Конвертации данных 3.0. Программный метод хорош своей быстротой и автономией (код пишется непосредственно в модулях конфигураций без перевыгрузки правил обмена), но он обходит механизмы контроля данных. Архитектурный метод КД 3.0 с использованием правил ИзСтруктуры и функций БСП является более сложным в настройке, однако гарантирует корректную регистрацию объектов, отсутствие дублей и стабильность обмена в долгосрочной перспективе.

← На главную