При проектировании интеграций между различными конфигурациями 1С мы часто сталкиваемся с ситуацией, когда архитектура данных в базах-участниках обмена существенно различается. Одной из самых сложных задач является реализация обмена по принципу «один ко многим». Рассмотрим классический сценарий: в базе-источнике (например, самописной конфигурации) разработчик объединил функционал нескольких документов в один, разместив данные в разных табличных частях. В базе-приемнике (например, типовой ERP или УТ) для этих целей предусмотрено несколько самостоятельных документов.
Проанализируем ситуацию: стандартные механизмы 1С:Конвертация данных (как версии 2.1, так и 3.0) по умолчанию ориентированы на синхронизацию объектов «один к одному». Основная трудность здесь заключается не столько в переносе полей, сколько в идентификации. Нам необходимо понять, как заставить механизмы БСП (Библиотеки стандартных подсистем) корректно сопоставлять один объект источника с несколькими объектами приемника и не «перетирать» связи в регистре сведений Соответствия объектов информационных баз.
В КД 2.1 решение задачи «один ко многим» строится на использовании событийных обработчиков в правилах выгрузки данных (ПВД) и правилах конвертации объектов (ПКО). Разберем по шагам, как это реализовать.
Основным инструментом для нас станет метод ВыгрузитьПоПравилу. Вместо того чтобы полагаться на стандартную выборку объектов, мы опишем алгоритм выгрузки вручную в ПВД. Проанализируем пример логики в обработчике «Перед выгрузкой данных» для правила выгрузки:
// Пример в ПВД
Для Каждого СтрокаТЧ Из Объект.ТабличнаяЧасть1 Цикл
// Формируем структуру данных для первого типа документа-приемника
ПараметрыВыгрузки = Новый Структура;
ПараметрыВыгрузки.Вставить("Дата", Объект.Дата);
ПараметрыВыгрузки.Вставить("Организация", Объект.Организация);
ПараметрыВыгрузки.Вставить("Номенклатура", СтрокаТЧ.Номенклатура);
// Вызываем выгрузку по конкретному ПКО
ВыгрузитьПоПравилу(Объект, , ПараметрыВыгрузки, , "ДокументПриемник_Тип1");
КонецЦикла;
Для Каждого СтрокаТЧ Из Объект.ТабличнаяЧасть2 Цикл
// Аналогично для второго типа документа
ВыгрузитьПоПравилу(Объект, , , , "ДокументПриемник_Тип2");
КонецЦикла;
Важный нюанс идентификации: Если мы просто вызовем ВыгрузитьПоПравилу несколько раз для одного и того же объекта-источника, приемник может запутаться, так как УИД (уникальный идентификатор) источника будет везде одинаковым. Чтобы избежать этого, рассмотрим способы разделения поиска:
ПередВыгрузкой ПКО можно программно изменить идентификатор, передаваемый в файл обмена, на основе GUID источника и префикса, специфичного для конкретной части данных.В КД3 ситуация сложнее, так как обмен идет через формат Enterprise Data (XDTO), и механизм БСП жестко завязан на регистр Публичные идентификаторы объектов. Выясним, как обойти ограничение «одна ссылка — один идентификатор».
Разберем процесс работы менеджера обмена. Когда мы выгружаем объект, система вызывает метод ВыгрузитьОбъект. Чтобы реализовать «один ко многим», нам нужно переопределить логику в модуле менеджера обмена (обычно это делается в обработчике ПриОтправкеДанных).
Использование синтетических идентификаторов (GUID): Каждому целевому объекту в приемнике нужен свой уникальный ключ в формате XML. Мы можем генерировать его программно. Посмотрим на логику:
Проанализируем пример формирования синтетического GUID:
// Пример логики формирования ключа
ИдентификаторИсточника = Строка(Объект.Ссылка.УникальныйИдентификатор());
КлючСвязи = "Часть_1_"; // Префикс для первой части
НовыйGUID = ПолучитьGUIDИзСтроки(КлючСвязи + ИдентификаторИсточника);
Такой подход гарантирует, что механизм БСП в базе-приемнике создаст N записей в регистре сведений, сопоставляя один объект источника (через разные строковые идентификаторы в XML) с разными ссылками в приемнике.
Выясним причину, по которой стандартный обмен может давать сбои. Регистр соответствий БСП хранит связь между ссылкой текущей базы и строковым идентификатором другой базы. Если мы пытаемся записать несколько соответствий для одной ссылки, стандартная процедура ОбменДаннымиСервер.УстановитьСоответствие может перезаписать предыдущую запись, если не указаны дополнительные измерения.
Как направить БСП в нужное русло:
Чтобы успешно реализовать схему «один ко многим», необходимо обеспечить уникальность Идентификатора объекта обмена (входящего GUID из XML). Поскольку в регистре БСП идентификатор из другой базы является частью уникального ключа (измерения), система позволит хранить несколько записей для одной локальной ссылки источника, если у них будут разные внешние GUID.
Рассмотрим еще один надежный способ, который часто применяется в сложных проектах. Если логика расщепления данных слишком громоздкая для написания в правилах обмена, можно использовать «Технический документ».
ПриЗаписи для этого технического документа.Этот метод значительно упрощает отладку, так как вы всегда видите, какие данные пришли из источника в первозданном виде, и можете легко локализовать ошибку в коде «расклейки» данных внутри базы-приемника.
Подведем итог: реализация обмена «один ко многим» требует отхода от автоматической генерации правил. Основной секрет успеха кроется в управлении уникальностью идентификаторов. Используйте синтетические GUID или модифицированные ключевые поля поиска, чтобы механизмы БСП могли однозначно идентифицировать каждую часть «разваленного» документа.