Как добавить новый документ в XDTO-пакет и настроить поиск объектов по наименованию при загрузке XML

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

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

В этой статье мы подробно разберем, как правильно включить новый документ в структуру XDTO и каким образом реализовать программную логику поиска объектов, если передаваемые данные не содержат ссылочных идентификаторов 1С.

Различие между форматом XDTO и логикой загрузки

Проанализируем основную ошибку, с которой сталкиваются новички: ожидание того, что XDTO-пакет сам «поймет», как искать данные в базе. Важно понимать, что XDTO (XML Data Transfer Objects) — это только описание структуры файла. Это «чертеж», который говорит системе, что за полем Номер должно идти поле Дата, и они имеют строковый и сессионный типы соответственно.

Если в файле XML указано наименование подразделения строкой, а в XDTO-пакете тип этого поля указан как ссылка на справочник, при загрузке возникнет ошибка преобразования, так как система не сможет превратить произвольный текст в UUID. Рассмотрим, как решать эту задачу правильно.

Шаг 1: Добавление документа в XDTO-пакет

Если вам необходимо добавить новый документ в пакет вручную (например, когда внешняя система на C++ не предоставляет готовую xsd схему), выполните следующие действия:

  1. Откройте нужный XDTO-пакет в конфигураторе.
  2. Создайте новый Тип объекта. Обычно его именуют по правилам платформы: DocumentObject.ИмяВашегоДокумента.
  3. Внутри типа объекта добавьте Свойства, соответствующие реквизитам документа (Номер, Дата, Проведен, ПометкаУдаления и т.д.).
  4. Важный нюанс: для реквизитов, которые являются ссылками в 1С (например, Контрагент или Склад), в свойстве XDTO-пакета лучше указать тип string (из пространства имен http://www.w3.org/2001/XMLSchema), если внешняя система передает их текстом. Если же вы укажете тип CatalogRef.Контрагенты, система будет ожидать строго формат UUID.

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

Шаг 2: Исправление ошибки «Отображение лексического значения»

Выясним причину ошибки Ошибка преобразования данных XDTO: Отображение лексического значения '' в значение типа 'ДокументСсылка...'. Она возникает, когда парсер встречает пустое значение в XML-файле для поля, которое в XDTO-пакете описано как строго типизированная ссылка.

Чтобы программа игнорировала пустые значения или корректно их обрабатывала, в свойствах элемента XDTO-пакета установите флаг Возможно пустое (Nillable). Это позволит парсеру принимать значение null без прерывания процесса загрузки.

Шаг 3: Программная реализация поиска по наименованию

Поскольку стандартная обработка ВыгрузкаЗагрузкаДанныхXML работает только с идентичными базами по UUID, для поиска по наименованию или номеру нам придется написать собственный алгоритм. Разберем пример кода, который читает XML через фабрику XDTO и ищет объект в базе.

Предположим, у нас есть документ СоглашениеОВнутреннейКооперации, и в XML передается название подразделения:


// Создаем чтение XML и связываем его с файлом
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ПутьКФайлу);

// Читаем данные в объект XDTO
ДанныеXDTO = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);

// Создаем новый документ или ищем существующий
НовыйДок = Документы.СоглашениеОВнутреннейКооперации.СоздатьДокумент();

// Прямое присвоение простых типов
НовыйДок.Дата = ДанныеXDTO.Date;
НовыйДок.Номер = ДанныеXDTO.Number;

// Логика поиска ссылки по наименованию (в XML пришла строка)
НаименованиеПодразделения = ДанныеXDTO.SubdivisionName;
СсылкаПодразделение = Справочники.Подразделения.НайтиПоНаименованию(НаименованиеПодразделения);

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

НовыйДок.Записать();
ЧтениеXML.Закрыть();

Шаг 4: Поиск документа по номеру и дате

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

Проанализируем, как это реализовать:


// Поиск существующего документа по номеру и дате
ДокСсылка = Документы.СоглашениеОВнутреннейКооперации.НайтиПоНомеру(ДанныеXDTO.Number, ДанныеXDTO.Date);

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

// Далее заполняем реквизиты объекта...
ОбъектДокумент.Записать();

Использование атрибутов для идентификации

Если внешняя система (на C++ или ином языке) генерирует свой собственный уникальный ID, рекомендуется добавить его в XDTO-пакет как Атрибут (Attribute), а не как элемент. В 1С создайте соответствующий дополнительный реквизит у документа и индексируйте его. Это позволит выполнять поиск мгновенно через НайтиПоРеквизиту().

Рассмотрим пример поиска по внешнему ID:


ВнешнийID = ДанныеXDTO.ExternalID; // Значение атрибута из XML
ДокСсылка = Документы.СоглашениеОВнутреннейКооперации.НайтиПоРеквизиту("ВнешнийИдентификаторСистемы", ВнешнийID);

Если Не ДокСсылка.Пустая() Тогда
    // Работаем с найденным объектом
КонецЕсли;

Резюме

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

  1. В XDTO-пакете описываем только структуру. Для гибкости поиска (по названию) используем строковые типы string.
  2. Для загрузки данных используем объект ФабрикаXDTO, который превращает XML в удобный объект.
  3. Логику сопоставления объектов (поиск по наименованию, поиск по дате и номеру) пишем вручную, используя стандартные методы поиска 1С (НайтиПоНаименованию, НайтиПоРеквизиту).
  4. При возникновении ошибок преобразования проверяем соответствие типов и возможность использования пустых значений (Nillable).

Такой подход делает интеграцию надежной и позволяет обрабатывать данные из систем, которые «ничего не знают» о внутреннем устройстве и ссылочной целостности 1С.

← На главную