Как загрузить данные из XML через XDTO без GUID и организовать поиск по номеру и дате

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

В практике интеграции 1С с внешними системами (например, написанными на C++, Python или Java) часто возникает ситуация, когда внешняя программа не владеет внутренними идентификаторами (GUID) объектов 1С. При попытке использовать стандартный механизм СериализаторXDTO.ПрочитатьXML() система выдает ошибку, так как ожидает строгое соответствие метаданным, включая уникальный идентификатор ссылки. В этой статье мы подробно разберем, как обойти это ограничение, правильно настроить поиск по номеру и дате и какие инструменты платформы «1С:Предприятие 8» лучше всего подходят для этой задачи.

Анализ проблемы: почему Сериализатор XDTO выдает ошибку

Разберем ситуацию: вы добавили новый документ в конфигурацию и создали пакет XDTO. При попытке прочитать XML-файл, в котором отсутствует поле Ref (ссылка), метод СериализаторXDTO.ПрочитатьXML(ЧтениеXML) прерывает работу. Это происходит потому, что СериализаторXDTO — это высокоуровневый инструмент. Его главная задача — максимально быстро и жестко восстановить объект 1С из XML-представления. Если в метаданных документа указано, что он является ссылочным типом, сериализатор обязан найти GUID, чтобы сопоставить его с записью в базе данных.

Важный нюанс: даже если вы укажете пустой GUID, сериализатор попытается найти объект с таким идентификатором. Если не найдет — создаст пустую ссылку, но не выполнит поиск по вашим полям (номеру и дате), так как он "не знает" бизнес-логики вашего приложения.

Решение 1: Использование «нулевого» GUID для обхода проверки формата

Проанализируем самый простой способ, который позволяет «обмануть» парсер 1С, если структура файла жестко завязана на стандартный пакет XDTO. Если внешняя система не может предоставить реальный идентификатор, она может передавать так называемый нулевой идентификатор (пустой GUID).

Пример заполнения поля в XML-файле:

<Ref>00000000-0000-0000-0000-000000000000</Ref>

Это позволит методу ПрочитатьXML не выдавать ошибку несоответствия формата. Однако помните, что это лишь техническая уловка. После чтения таким способом вам все равно придется программно искать документ, так как 1С просто создаст объект с пустыми ссылками.

Решение 2: Переход на Фабрику XDTO для гибкой загрузки

Рассмотрим более профессиональный и надежный подход. Вместо использования СериализаторXDTO, мы воспользуемся ФабрикаXDTO. Разберем ключевое различие: Фабрика создает промежуточный ОбъектXDTO, который является моделью данных в памяти и не привязан к конкретным записям в базе данных. Это дает нам полную свободу действий.

Выполним загрузку по шагам:

  1. Прочитаем XML-файл в ОбъектXDTO.
  2. Извлечем из него номер и дату.
  3. Выполним поиск документа в базе данных стандартными методами 1С.
  4. Если документ найден — обновим его, если нет — создадим новый.

Посмотрим на пример кода, реализующий эту логику:


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

// 2. Чтение в объект XDTO (используем Фабрику вместо Сериализатора)
ДанныеXDTO = ФабрикаXDTO.ПрочитатьXML(Чтение);

// 3. Извлечение ключевых полей для поиска
НомерДок = ДанныеXDTO.Number; // Имена свойств зависят от вашего пакета XDTO
ДатаДок = ДанныеXDTO.Date;

// 4. Поиск документа в базе
СсылкаНаДок = Документы.ПриходныйКассовыйОрдер.НайтиПоНомеру(НомерДок, ДатаДок);

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

// 5. Заполнение остальных реквизитов
НовыйОбъект.Контрагент = Справочники.Контрагенты.НайтиПоНаименованию(ДанныеXDTO.CounterpartyName);
// ... заполнение остальных полей ...

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

Решение 3: Настройка атрибутов поиска через ID и IDREF

Выясним причину, по которой некоторые разработчики пытаются использовать атрибуты id в XML. В стандарте XDTO существуют типы ID и IDREF. Они предназначены для организации внутренних ссылок внутри одного XML-документа. Например, если у вас в одном файле передается список сотрудников и список подразделений, вы можете один раз описать подразделение с id="Dep01", а у каждого сотрудника указать parent="Dep01".

Важно: Платформа 1С не использует эти атрибуты для автоматического поиска в SQL-таблицах. Любая логика сопоставления id из файла с ссылками в базе должна быть написана вами вручную на языке 1С.

Решение 4: Использование технологии Конвертация данных 3.0

Проанализируем ситуацию, когда проект обмена данными масштабный. Если вам нужно постоянно синхронизировать множество объектов без GUID, рекомендуется использовать «Конвертацию данных 3.0» (КД 3). В этой технологии обмен строится на основе формата EnterpriseData (который также является XDTO-пакетом).

В КД 3 механизм поиска реализован декларативно. В правилах обработки данных (ПОД) вы можете указать "Ключевые свойства". При загрузке система сама выполнит следующий алгоритм:

Этот подход избавляет от необходимости писать громоздкие конструкции НайтиПоНомеру для каждого типа документа.

Советы по проектированию пакетов XDTO для поиска

Рассмотрим несколько рекомендаций по созданию пакетов XDTO в Конфигураторе, чтобы упростить процесс загрузки:

  1. Не используйте автосоздание пакета по метаданным: Если вы создаете пакет на основе реального документа 1С, платформа добавит туда служебные поля (вроде Ref, DeletionMark), которые могут быть лишними при обмене с внешними системами.
  2. Создавайте собственные типы: Опишите тип объекта в XDTO-пакете вручную. Укажите свойства Number (тип string) и Date (тип dateTime) как обязательные (minOccurs = 1).
  3. Атрибуты vs Элементы: Для полей поиска (Номер, Дата) удобнее использовать элементы, а для метаданных (версия схемы, идентификатор системы-отправителя) — атрибуты.

Подведем итог: если вы столкнулись с невозможностью передачи GUID, откажитесь от СериализаторXDTO в пользу ФабрикаXDTO. Это позволит вам реализовать любую логику поиска и сопоставления объектов, делая вашу систему интеграции гибкой и устойчивой к ошибкам формата данных.

← На главную