При использовании стандартной сериализации в 1С разработчики часто сталкиваются с ситуацией, когда метод ЗаписатьXML(ЗаписьXML, Объект) выгружает ссылочные реквизиты (например, договоры контрагентов, склады, номенклатуру) исключительно в виде их типа и уникального идентификатора (UUID). Разберем причины такого поведения платформы и рассмотрим практические способы выгрузки объектов с полным набором вложенных реквизитов.
Метод ЗаписатьXML использует стандартный СериализаторXDTO и встроенную системную модель типов 1С. В реляционной базе данных ссылки являются независимыми сущностями. Если бы платформа при выгрузке ссылки автоматически начинала каскадно («глубоко») сериализовать объект, на который она указывает, это приводило бы к выгрузке почти всей информационной базы и неконтролируемым зацикливаниям (когда объект А ссылается на объект Б, а объект Б — на объект А).
Поэтому стандартный механизм 1С сериализует саму ссылку компактно: через уникальный идентификатор. Чтобы передать полные данные связанных объектов, требуется применить один из специализированных инструментов или написать собственный алгоритм обхода.
Если задача заключается в переносе данных между одинаковыми или однотипными конфигурациями, разработка собственного кода часто оказывается избыточной. Проанализируем возможности типового инструмента:
Выгрузка и загрузка данных XML.epf автоматически определяет состав выгружаемых объектов.Когда требуется переносить данные между разными структурами баз (например, сопоставлять контрагентов не по УИД, а по ИНН/КПП, а договоры по номеру и дате), оптимальным решением является инструмент «1С:Конвертация данных»:
ИНН или Код.Если обмен строится по строгому формату со сторонней системой или веб-сервисом, наиболее архитектурно правильным подходом является использование XDTO:
Договор объявляется не как простая строка с УИД, а как сложный тип со всеми требуемыми реквизитами (Номер, Дата, ВидДоговора).
ТипКонтрагента = ФабрикаXDTO.Тип("http://mycompany.ru/exchange", "Контрагент");
ТипДоговора = ФабрикаXDTO.Тип("http://mycompany.ru/exchange", "Договор");
ОбъектXDTOКонтрагент = ФабрикаXDTO.Создать(ТипКонтрагента);
ОбъектXDTOКонтрагент.Наименование = КонтрагентСсылка.Наименование;
ОбъектXDTOКонтрагент.ИНН = КонтрагентСсылка.ИНН;
Если ЗначениеЗаполнено(КонтрагентСсылка.ОсновнойДоговор) Тогда
ОбъектXDTОДоговор = ФабрикаXDTO.Создать(ТипДоговора);
ОбъектXDTОДоговор.Номер = КонтрагентСсылка.ОсновнойДоговор.Номер;
ОбъектXDTОДоговор.Дата = КонтрагентСсылка.ОсновнойДоговор.Дата;
ОбъектXDTOКонтрагент.ОсновнойДоговор = ОбъектXDTОДоговор;
КонецЕсли;
ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, ОбъектXDTOКонтрагент);
Для простых сценариев или небольших интеграций можно формировать XML напрямую, управляя узлами и атрибутами документа:
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл("C:\Exchange\data.xml", "UTF-8");
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьXML.ЗаписатьНачалоЭлемента("Контрагент");
ЗаписьXML.ЗаписатьАтрибут("УИД", Строка(КонтрагентОбъект.Ссылка.УникальныйИдентификатор()));
ЗаписьXML.ЗаписатьЭлемент("Наименование", КонтрагентОбъект.Наименование);
ЗаписьXML.ЗаписатьЭлемент("ИНН", КонтрагентОбъект.ИНН);
Если ЗначениеЗаполнено(КонтрагентОбъект.ОсновнойДоговорКонтрагента) Тогда
ДоговорОбъект = КонтрагентОбъект.ОсновнойДоговорКонтрагента;
ЗаписьXML.ЗаписатьНачалоЭлемента("ОсновнойДоговор");
ЗаписьXML.ЗаписатьЭлемент("Номер", ДоговорОбъект.Номер);
ЗаписьXML.ЗаписатьЭлемент("Дата", Формат(ДоговорОбъект.Дата, "ДФ=yyyy-MM-dd"));
ЗаписьXML.ЗаписатьЭлемент("Наименование", ДоговорОбъект.Наименование);
ЗаписьXML.ЗаписатьКонецЭлемента(); // ОсновнойДоговор
КонецЕсли;
ЗаписьXML.ЗаписатьКонецЭлемента(); // Контрагент
ЗаписьXML.Закрыть();
Если формат XML не является жестким требованием принимающей стороны, удобным решением будет сборка данных в универсальные коллекции с последующей сериализацией в JSON:
ДанныеКонтрагента = Новый Структура;
ДанныеКонтрагента.Вставить("Наименование", КонтрагентОбъект.Наименование);
ДанныеКонтрагента.Вставить("ИНН", КонтрагентОбъект.ИНН);
Если ЗначениеЗаполнено(КонтрагентОбъект.ОсновнойДоговорКонтрагента) Тогда
Договор = КонтрагентОбъект.ОсновнойДоговорКонтрагента;
ДанныеДоговора = Новый Структура;
ДанныеДоговора.Вставить("Номер", Договор.Номер);
ДанныеДоговора.Вставить("Дата", Договор.Дата);
ДанныеКонтрагента.Вставить("Договор", ДанныеДоговора);
КонецЕсли;
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьФайл("C:\Exchange\data.json");
ЗаписатьJSON(ЗаписьJSON, ДанныеКонтрагента);
ЗаписьJSON.Закрыть();
Резюме: Функция ЗаписатьXML не предназначена для автоматического раскрытия ссылок. Для выгрузки связанных реквизитов следует использовать специализированные конфигурации обмена (Конвертация данных), готовые механизмы EnterpriseData, XDTO-пакеты либо осуществлять последовательный обход реквизитов вручную через методы ЗаписьXML.