При интеграции 1С с внешними системами через Web-сервисы (SOAP) или HTTP-запросы, разработчики часто сталкиваются с объектами СписокXDTO. Хотя платформа позволяет обходить эти списки циклом, работать с ними напрямую в интерфейсе или использовать их в запросах невозможно. Стандартная задача — преобразовать полученные данные в привычную ТаблицуЗначений. Рассмотрим, как сделать это максимально эффективно, универсально и с учетом нюансов динамической структуры XML. Для построения комплексных интеграций и автоматического приведения XML/JSON к универсальным коллекциям 1С можно использовать готовый инструмент для стандартизации и конвертации данных.
Если мы заранее не знаем структуру ответа API (имена полей могут меняться или их слишком много для ручного описания), нам поможет механизм перебора свойств XDTO-объекта. Проанализируем базовый алгоритм, который позволяет динамически формировать колонки таблицы значений.
Основная идея заключается в том, чтобы прочитать свойства первого элемента списка, создать соответствующие колонки в ТаблицаЗначений, а затем в цикле заполнить строки данными. Разберем программную реализацию этой задачи:
Функция XDTOВТаблицуЗначений(XDTOСписок)
ТаблицаЗначений = Новый ТаблицаЗначений;
// Проверяем, что список не пуст
Если XDTOСписок.Количество() > 0 Тогда
// Получаем первый элемент для определения структуры колонок
ПервыйЭлемент = XDTOСписок[0];
// Создание колонок на основе свойств объекта XDTO
Для каждого Свойство Из ПервыйЭлемент.Свойства() Цикл
ТаблицаЗначений.Колонки.Добавить(Свойство.Имя);
КонецЦикла;
// Заполнение таблицы данными
Для каждого ЭлементСписка Из XDTOСписок Цикл
НоваяСтрока = ТаблицаЗначений.Добавить();
Для каждого Колонка Из ТаблицаЗначений.Колонки Цикл
НоваяСтрока[Колонка.Имя] = ЭлементСписка[Колонка.Имя];
КонецЦикла;
КонецЦикла;
КонецЕсли;
Возврат ТаблицаЗначений;
КонецФункции
Важный нюанс: В языке 1С индексация СписокXDTO начинается с нуля. В примере кода выше мы обращаемся к XDTOСписок[0]. Если структура ваших объектов в списке может различаться (например, в первом элементе отсутствует необязательное поле, а во втором оно есть), этот метод может пропустить важные колонки.
Для повышения производительности, особенно на больших объемах данных, мы можем отказаться от вложенного цикла перебора колонок. Платформа 1С предоставляет встроенную функцию ЗаполнитьЗначенияСвойств, которая умеет сопоставлять имена свойств ОбъектXDTO с именами колонок ТаблицаЗначений.
Проанализируем обновленный цикл заполнения:
Для каждого ЭлементСписка Из XDTOСписок Цикл
НоваяСтрока = ТаблицаЗначений.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, ЭлементСписка);
КонецЦикла;
Использование ЗаполнитьЗначенияСвойств не только сокращает объем кода, но и работает значительно быстрее на списках, содержащих тысячи элементов. Это происходит за счет оптимизации внутреннего механизма платформы по поиску соответствий имен.
Выясним причину, по которой первый способ может подвести. В XML-схемах (XSD) свойства могут быть помечены как необязательные. Если в первом объекте списка значение свойства пустое, метод Свойства() может просто не вернуть это свойство в коллекции. В результате в таблице значений не появится соответствующая колонка.
Чтобы сделать код по-настоящему универсальным, вместо анализа данных первого объекта (экземпляра), мы должны обратиться к его типу (метаданным). Посмотрим на пример реализации:
// Вместо ПервыйЭлемент.Свойства() используем описание типа
ТипОбъекта = XDTOСписок.Тип().Элемент; // Получаем тип элементов в списке
Для каждого Свойство Из ТипОбъекта.Свойства Цикл
ТаблицаЗначений.Колонки.Добавить(Свойство.Имя);
КонецЦикла;
Такой подход гарантирует, что в ТаблицаЗначений будут созданы абсолютно все колонки, предусмотренные схемой API, даже если в конкретном ответе часть данных отсутствует.
Одной из проблем прямого копирования из XDTO в ТЗ является потеря типов. Например, даты могут остаться строками, а числа — специфическими типами XDTO. Если схема XDTO известна конфигурации (загружена как XDTO-пакет), мы можем использовать СериализаторXDTO.
Метод СериализаторXDTO.ПрочитатьXDTO() преобразует объект XDTO в прикладной объект 1С (например, в Структура или Соответствие), автоматически конвертируя типы данных. Рассмотрим, как это применить:
Для каждого ЭлементСписка Из XDTOСписок Цикл
// Превращаем XDTO в обычную структуру 1С с типизированными данными
ДанныеСтроки = СериализаторXDTO.ПрочитатьXDTO(ЭлементСписка);
НоваяСтрока = ТаблицаЗначений.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, ДанныеСтроки);
КонецЦикла;
Обратите внимание: Этот метод наиболее эффективен, если в вашей системе подключена соответствующая веб-ссылка или импортирован XSD-пакет. Для упрощения этой задачи можно использовать обработку для автоматического формирования XSD-файла.
Если вам нужно получить таблицу значений максимально быстро, не заботясь о ручном создании каждой колонки, можно воспользоваться комбинацией сериализации в JSON и ПостроительЗапроса. Этот метод автоматически соберет все уникальные поля из всех элементов списка.
СписокXDTO в строку JSON.Массив структур.ПостроительЗапроса для выгрузки массива в таблицу.Проанализируем пример кода:
// 1. Преобразование в массив структур через промежуточный JSON
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
СериализаторXDTO.ЗаписатьJSON(ЗаписьJSON, XDTOСписок);
СтрокаJSON = ЗаписьJSON.Закрыть();
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(СтрокаJSON);
МассивДанных = ПрочитатьJSON(ЧтениеJSON);
// 2. Быстрая выгрузка в ТЗ с автосозданием колонок
Построитель = Новый ПостроительЗапроса;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(МассивДанных);
ТЗ = Построитель.Результат.Выгрузить();
Этот способ является самым коротким с точки зрения написания кода, но стоит помнить, что двойная конвертация (XDTO -> JSON -> Массив) может потреблять значительный объем оперативной памяти при обработке сотен тысяч записей.
Подведем итог и определим, какой метод лучше использовать в различных ситуациях:
ЗаполнитьЗначенияСвойств (Способ 2).Тип().Свойства (Способ 3).СериализаторXDTO (Способ 4).ПостроительЗапроса (Способ 5).При реализации любого из этих решений не забывайте обрабатывать вложенные объекты. Если свойство элемента списка само является объектом, стандартная таблица значений запишет в ячейку ссылку на ОбъектXDTO. В таких случаях потребуется рекурсивная обработка или приведение вложенных объектов к строковому представлению.