Как передать таблицу значений с сервера на клиент и избежать ошибки отображения типов?

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

При разработке в среде управляемого приложения разработчики нередко сталкиваются с ситуацией, когда данные, сформированные на сервере в виде таблицы значений, требуется проанализировать или отобразить на стороне тонкого клиента. Попытка передать объект ТаблицаЗначений напрямую или через вызов функции ПолучитьИзВременногоХранилища() на клиенте завершается системной ошибкой XDTO: «Отсутствует отображение для типа ValueTable».

Разберем природу этого ограничения и рассмотрим практические способы решения задачи: от конвертации данных в сериализуемые структуры до быстрой визуализации без включенной серверной отладки.

Выясним причину ошибки

Проанализируем контекст выполнения кода. Метод ПоместитьВоВременноеХранилище() на сервере отрабатывает корректно, поскольку объект ТаблицаЗначений поддерживается серверным контекстом. Однако сбой происходит именно в тот момент, когда на клиенте вызывается метод:


&НаКлиенте
Процедура Тест(Команда)
    АдресХранилища = ТестНаСервере();
    ТЗССервера = ПолучитьИзВременногоХранилища(АдресХранилища);
КонецПроцедуры

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

Способ 1. Преобразование таблицы значений в массив структур

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

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


&НаСервере
Функция ПолучитьДанныеТаблицы()
    // Создаем или получаем исходную таблицу значений
    ТЗ = Новый ТаблицаЗначений;
    ТЗ.Колонки.Добавить("Код");
    ТЗ.Колонки.Добавить("Наименование");
    
    // Заполняем данными
    НоваяСтрока = ТЗ.Добавить();
    НоваяСтрока.Код = "001";
    НоваяСтрока.Наименование = "Товар 1";
    
    // Преобразуем таблицу в массив структур
    МассивРезультат = ОбщегоНазначения.ТаблицаЗначенийВМассив(ТЗ);
    Возврат МассивРезультат;
КонецФункции

Если в вашей конфигурации нет библиотеки БСП, выполним аналогичное преобразование вручную:


&НаСервере
Функция ПреобразоватьТЗВМассив(ТаблицаИсточника)
    Массив = Новый Массив;
    Колонки = ТаблицаИсточника.Колонки;
    
    Для Каждого СтрокаТЗ Из ТаблицаИсточника Цикл
        СтруктураСтроки = Новый Структура;
        Для Каждого Колонка Из Колонки Цикл
            СтруктураСтроки.Вставить(Колонка.Имя, СтрокаТЗ[Колонка.Имя]);
        КонецЦикла;
        Массив.Добавить(СтруктураСтроки);
    КонецЦикла;
    
    Возврат Массив;
КонецФункции

На стороне клиента результат работы такой функции успешно считывается в виде стандартного массива:


&НаКлиенте
Процедура ОбработатьДанные(Команда)
    ДанныеВВидеМассива = ПолучитьДанныеТаблицы();
    Для Каждого Элемент Из ДанныеВВидеМассива Цикл
        Сообщить(Элемент.Наименование);
    КонецЦикла;
КонецПроцедуры

Способ 2. Использование реквизита формы (ДанныеФормыКоллекция)

Если данные таблицы необходимо отобразить пользователю на форме или использовать в элементах формы, правильнее связать таблицу значений с реквизитом управляемой формы. На клиенте такой реквизит будет доступен как тип ДанныеФормыКоллекция.

Разберем по шагам порядок работы:

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

Посмотрим на пример серверной процедуры:


&НаСервере
Процедура ЗаполнитьРеквизитФормы(ТЗДанные)
    // Преобразуем объект ТаблицаЗначений в данные формы
    ЗначениеВРеквизитФормы(ТЗДанные, "ТаблицаДанных");
КонецПроцедуры

Если в дальнейшем потребуется обратное преобразование на сервере для сложных манипуляций (поиск, группировка, сортировка), используем обратный метод: ТЗ = РеквизитФормыВЗначение("ТаблицаДанных");.

Способ 3. Экспресс-просмотр таблицы значений через ПостроительОтчета

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

Для этого воспользуемся возможностями объекта ПостроительОтчета. Он умеет формировать ТабличныйДокумент напрямую из таблицы значений, а табличный документ, в отличие от таблицы значений, полностью доступен на тонком клиенте.

Рассмотрим реализацию:


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

&НаКлиенте
Процедура ПросмотретьТЗ(Команда)
    // Вызываем серверную функцию и сразу открываем окно с результатом
    ТабДок = ПолучитьТабличныйДокументССервера();
    ТабДок.Показать("Анализ данных таблицы");
КонецПроцедуры

Данный подход позволяет за несколько строк кода открыть отдельное окно с форматированной таблицей, содержащей все имена колонок и строки вычисленной таблицы значений.

Способ 4. Включение серверной отладки для штатного анализа

Если анализ данных необходим в процессе разработки, лучшим решением остается включение штатного механизма отладки на сервере 1С:Предприятия.

Разберем параметры запуска службы:

  1. Для стандартного отладчика по протоколу TCP служба сервера ragent должна запускаться с ключом -debug. В операционной системе Windows этот флаг прописывается в системном реестре в параметре ImagePath соответствующей службы.
  2. При использовании HTTP-отладки (появившейся в версии 8.3.7) режим отладки настраивается в файле конфигурации отладки сервера.
  3. После перезапуска службы сервера в конфигураторе открываем меню «Отладка» -> «Подключение...» и проверяем автоматическое подключение к фоновым заданиям и сеансам сервера.

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

← На главную