Как эффективно передавать ссылки на документы через веб-сервис и XDTO в 1С

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

При разработке веб-сервисов в среде 1С:Предприятие одной из наиболее частых задач является передача информации об объектах (документах, справочниках) из одной информационной базы в другую. Часто возникает ситуация, когда недостаточно просто передать номер и дату документа; для последующего изменения объекта (например, редактирования комментария) необходимо иметь возможность однозначно идентифицировать его в базе-источнике. Лучшим способом для этого является передача уникального идентификатора (GUID) или ссылки.

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

Проблема получения идентификаторов в запросах

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


Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    УИД_Строкой = Строка(Выборка.Ссылка.УникальныйИдентификатор());
    // Добавление в таблицу или структуру
КонецЦикла;

Такой подход крайне неэффективен на больших объемах данных, так как обращение через точку к Ссылка.УникальныйИдентификатор() заставляет платформу выполнять дополнительные действия. Давайте разберем более быстрые способы решения этой задачи.

Способ 1: Оптимизация получения УИД через Систему компоновки данных (СКД)

Это один из самых изящных способов получить строковое представление идентификаторов без медленных циклов. Система компоновки данных работает на более низком уровне и позволяет вычислять значения быстрее. Проанализируем алгоритм действий:

  1. Создадим схему компоновки данных программно или в макете.
  2. В наборе данных запроса выберем необходимые поля, включая Ссылка.
  3. Вкладка "Вычисляемые поля": добавим поле ИдентификаторСтрокой и пропишем выражение: Строка(Ссылка.УникальныйИдентификатор()).
  4. При выполнении схемы компоновки и выгрузке результата в таблицу значений, колонка с идентификатором будет заполнена автоматически.

Посмотрим на пример программной реализации этого метода:


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

// Настройка компоновки и вывод в таблицу значений
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, Схема.НастройкиПоУмолчанию);

ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);

ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТаблицуЗначений;
ТаблицаРезультат = ПроцессорВывода.Вывести(ПроцессорКомпоновки);

Этот метод значительно сокращает время подготовки данных для веб-сервиса, особенно если нужно передать сотни или тысячи строк.

Способ 2: Использование навигационных ссылок

Если ваша задача — быстро передать ссылку, которую потом можно легко превратить обратно в объект в той же базе, воспользуемся механизмом навигационных ссылок. Навигационная ссылка — это строка формата e1cib/data/Документ.РеализацияТоваровУслуг?ref=..., которая уже содержит в себе и тип объекта, и его GUID.

Разберем преимущества этого подхода:

Пример получения ссылки для отправки:


ТекстСсылки = ПолучитьНавигационнуюСсылку(ДокументСсылка);
// Передаем ТекстСсылки как параметр веб-сервиса

Пример восстановления объекта на стороне веб-сервиса:


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

Способ 3: Правильное описание структуры в XDTO-пакете

Для более "архитектурно правильного" решения (например, если планируется интеграция не только с 1С, но и со сторонними системами) стоит описать ссылку в самом XDTO-пакете. Рассмотрим структуру, которую рекомендует использовать библиотека интеграции с 1С:Документооборотом.

Создадим тип объекта в XDTO-пакете (например, с именем ObjectID), который будет содержать два свойства:

  1. ID (тип string) — здесь будем хранить GUID.
  2. Type (тип string) — здесь будем хранить имя метаданных (например, "Документ.РеализацияТоваровУслуг").

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


ТипОбъектаXDTO = ФабрикаXDTO.Тип("http://www.my-service.ru", "ObjectID");
ОбъектИдентификатор = ФабрикаXDTO.Создать(ТипОбъектаXDTO);
ОбъектИдентификатор.ID = Строка(ДокументСсылка.УникальныйИдентификатор());
ОбъектИдентификатор.Type = ДокументСсылка.Метаданные().ПолноеИмя();

На стороне приемника (в веб-сервисе) мы восстанавливаем ссылку следующим образом:


ИмяМетаданных = ОбъектИдентификаторXDTO.Type;
Гуид = Новый УникальныйИдентификатор(ОбъектИдентификаторXDTO.ID);
Ссылка = Документы[Сред(ИмяМетаданных, 10)].ПолучитьСсылку(Гуид);
// Теперь у нас есть живая ссылка для поиска и редактирования документа

Использование стандартного OData (REST API) как альтернатива

Выясним, всегда ли нужно писать собственный веб-сервис. Если задача сводится к тому, чтобы "видеть список и редактировать пару полей", 1С предоставляет мощный встроенный механизм — OData.

При включении стандартного интерфейса OData:

Это избавляет от необходимости описывать XDTO-пакеты и писать программный код веб-сервиса вручную. Все ссылки и типы данных платформа берет на себя.

Выводы и рекомендации

Мы рассмотрели несколько подходов к решению задачи. Выбор конкретного метода зависит от ваших требований:

Помните, что передача ссылки — это только половина дела. При получении ссылки обратно в веб-сервисе всегда проверяйте её на "битость" (существование объекта в базе) перед тем, как выполнять метод ПолучитьОбъект(), чтобы избежать аварийного завершения работы сервиса.

← На главную