Как вывести содержимое СписокXDTO на форму в 1С

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

При интеграции 1С с внешними информационными системами через Web-сервисы или при разборе XML/JSON-документов разработчики часто сталкиваются с объектами модели XDTO (XML Data Transfer Objects). Одним из таких объектов является СписокXDTO. Это специализированная коллекция, предназначенная для представления списочных данных XML-схемы.

Рано или поздно возникает прикладная задача: быстро и наглядно вывести содержимое полученного списка на форму для анализа пользователем или выполнения интерактивных действий. Попытка напрямую привязать СписокXDTO к элементу формы (например, к табличному полю в обычном приложении или к динамическому списку/таблице в управляемом приложении) приводит к неудаче. Система просто не понимает этот тип данных в контексте интерфейса. В этой статье мы подробно разберем, почему возникает эта проблема, и рассмотрим несколько эффективных способов вывода данных из СписокXDTO на форму.

Выясняем причину: почему не работает прямой вывод и ЗаполнитьЗначенияСвойств

Давайте проанализируем, почему стандартные и привычные механизмы 1С пасуют перед XDTO. Первое, что пробуют сделать разработчики, — это связать элемент управления формы с типом СписокЗначений и напрямую присвоить ему СписокXDTO. Но СписокXDTO — это не коллекция простых значений 1С, а сложная иерархическая структура метаданных. Он хранит в себе элементы типа ОбъектXDTO или ЗначениеXDTO, которые не сопоставляются напрямую с типами платформы.

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

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

Чтобы решить эту проблему, нам потребуется преобразовать данные XDTO в понятные для интерфейса платформы структуры. Разберем три основных практических метода решения этой задачи.

Способ 1: Универсальное динамическое создание Таблицы Значений

Рассмотрим самый надежный способ, который не требует жесткого кодирования структуры данных. Мы напишем универсальную функцию, которая сама проанализирует структуру первого элемента в СписокXDTO, динамически создаст необходимые колонки в ТаблицаЗначений без привязки к конкретным типам, а затем перенесет все данные.

Посмотрим на пример реализации такой функции:


Функция СписокXDTOВТаблицуЗначений(СписокXDTO) Export
    
    Таблица = Новый ТаблицаЗначений;
    
    Если СписокXDTO.Количество() = 0 Тогда
        Возврат Таблица;
    КонецЕсли;
    
    // 1. Динамически определяем структуру колонок по первому элементу
    ПервыйЭлемент = СписокXDTO.Получить(0); 
    
    Если ТипЗнч(ПервыйЭлемент) = Тип("ОбъектXDTO") Тогда
        Для Каждого Свойство Из ПервыйЭлемент.Свойства() Цикл
            // Создаем колонку без явного указания типа, чтобы избежать конфликтов приведения типов
            Таблица.Колонки.Добавить(Свойство.Имя);
        КонецЦикла;
    Иначе
        // Если в списке находятся простые значения, создаем одну универсальную колонку
        Таблица.Колонки.Добавить("Значение");
    КонецЕсли;
    
    // 2. Заполняем созданную таблицу данными
    Для Каждого Элемент Из СписокXDTO Цикл
        НоваяСтрока = Таблица.Добавить();
        
        Если ТипЗнч(Элемент) = Тип("ОбъектXDTO") Тогда
            Для Каждого Колонка Из Таблица.Колонки Цикл
                ИмяСвойства = Колонка.Имя;
                ЗначениеСвойства = Элемент[ИмяСвойства];
                
                // Обрабатываем возможные вложенные структуры XDTO
                Если ТипЗнч(ЗначениеСвойства) = Тип("ОбъектXDTO") Тогда
                    НоваяСтрока[ИмяСвойства] = "[Объект XDTO]";
                ИначеЕсли ТипЗнч(ЗначениеСвойства) = Тип("СписокXDTO") Тогда
                    НоваяСтрока[ИмяСвойства] = "[Список XDTO]";
                Иначе
                    // Для простых типов записываем значение напрямую
                    НоваяСтрока[ИмяСвойства] = ЗначениеСвойства;
                КонецЕсли;
            КонецЦикла;
        Иначе
            // Для списка простых значений (ЗначениеXDTO)
            НоваяСтрока.Значение = Элемент;
        КонецЕсли;
    КонецЦикла;
    
    Возврат Таблица;
    
КонецФункции

Проанализируем этот код. Мы создаем колонки таблицы значений динамически, основываясь на свойствах объекта XDTO. Обратите внимание, что мы не передаем второй параметр в метод Таблица.Колонки.Добавить(). Это позволяет колонке принимать значения абсолютно любого типа, включая другие объекты и списки. Если в процессе обхода мы натыкаемся на вложенную структуру, мы заменяем ее текстовым представлением, предотвращая падение платформы или некорректное преобразование типов.

Способ 2: Сериализация через JSON

Если структура вашего XDTO сложная, многоуровневая и содержит сильные вложенности, ручной обход может показаться громоздким. В современных версиях платформы 1С (начиная с 8.3) есть изящный обходной путь — использование JSON-сериализации.

Платформа умеет автоматически трансформировать сложные структуры XDTO в JSON-строку, а встроенные механизмы чтения JSON с легкостью превращают эту строку во взаимно вложенные стандартные коллекции 1С: Массив и Структура. С ними работать в коде интерфейса в разы проще.

Разберем по шагам, как реализовать этот алгоритм:


// Предположим, у нас есть ИсходныйОбъектXDTO, содержащий наш СписокXDTO

// Шаг 1: Записываем объект XDTO в строку JSON
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();

// Сериализуем объект с помощью встроенной фабрики XDTO
ФабрикаXDTO.ЗаписатьJSON(ЗаписьJSON, ИсходныйОбъектXDTO); 
СтрокаJSON = ЗаписьJSON.Закрыть();

// Шаг 2: Читаем полученную строку обратно в коллекции 1С
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(СтрокаJSON);

// На выходе получаем Массив Структур, полностью повторяющий структуру XDTO
ДанныеФормы = ПрочитатьJSON(ЧтениеJSON); 
ЧтениеJSON.Закрыть();

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

Способ 3: Использование встроенных функций БСП

Если вы ведете разработку в типовой конфигурации 1С, созданной на базе Библиотеки Стандартных Подсистем (БСП), вам не нужно изобретать велосипед и писать собственные конвертеры. В БСП уже встроены высокоэффективные оптимизированные механизмы для работы со схемами XDTO.

В частности, вы можете воспользоваться общим модулем ОбменДаннымиXDTOСервер. Функция ОбъектXDTOВСтруктуру() берет на себя всю рутину по рекурсивному разбору элементов XDTO:


// Пример использования готового функционала БСП
СтруктураДанных = ОбменДаннымиXDTOСервер.ОбъектXDTOВСтруктуру(ВашОбъектXDTO);

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

Как правильно вывести полученную Таблицу Значений на Обычную форму

После того как мы успешно преобразовали СписокXDTO в стандартную ТаблицаЗначений одним из приведенных выше способов, нам необходимо отобразить ее пользователю. Рассмотрим, как правильно сделать это в обычном приложении (неуправляемые формы), так как именно там чаще всего возникают сложности с динамическим обновлением элементов.

Для вывода нам понадобится элемент управления Табличное поле. Выполним следующие шаги:

  1. Добавим на форму элемент управления Табличное поле (например, дадим ему имя ТабличноеПолеДанных).
  2. В свойствах этого табличного поля тип значения оставим пустым либо укажем как ТаблицаЗначений (но ни в коем случае не СписокЗначений!).
  3. В коде формы применим специальную последовательность вызова методов, чтобы колонки на экране перестраивались динамически под структуру пришедшего XDTO.

Рассмотрим пример программного вывода на форму:


// 1. Получаем подготовленную таблицу значений из нашего списка XDTO
ТаблицаДляВывода = СписокXDTOВТаблицуЗначений(ПолученныйСписокXDTO);

// 2. Связываем полученную таблицу значений с интерфейсным элементом формы
ЭлементыФормы.ТабличноеПолеДанных.Значение = ТаблицаДляВывода;

// 3. Самый важный шаг: заставляем элемент формы перестроить визуальные колонки
ЭлементыФормы.ТабличноеПолеДанных.СоздатьКолонки();

Обратите особое внимание на метод СоздатьКолонки(). Если его не вызвать, то табличное поле на форме останется пустым, даже если в свойстве Значение находится заполненная таблица. Этот метод анализирует структуру колонок переданной таблицы значений и автоматически создает соответствующие им визуальные столбцы на форме. Пользователь мгновенно увидит все данные на экране.

После этого вы сможете полноценно работать с интерактивными свойствами таблицы. Например, перехватив событие Выбор или ПриАктивизацииСтроки у табличного поля, вы легко сможете получить значение текущей строки (например, уникальный идентификатор GUID) и выполнить по нему любые дальнейшие действия в системе.

← На главную