Как передать Таблицу Значений с сервера на клиент и обратно в управляемом приложении 1С

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

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

Почему Таблица Значений не работает на клиенте

Проанализируем ситуацию: в тонком и веб-клиенте тип ТаблицаЗначений отсутствует в целях безопасности и производительности. Этот объект предназначен для тяжелых операций с данными на стороне сервера (сортировка, индексация, свертка). Для отображения данных пользователю или их временного хранения на форме используются специальные типы — ДанныеФормыКоллекция, ДанныеФормыСтруктура и другие. Поэтому, если нам нужно передать данные "транзитом", мы вынуждены их конвертировать в универсальные коллекции, которые "умеют" пересекать границу между сервером и клиентом.

Вариант 1: Конвертация в массив структур

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

Рассмотрим пример кода для преобразования на сервере:


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

Теперь выясним, как собрать таблицу обратно на сервере, когда массив вернулся с клиента. Важно помнить, что при создании новой таблицы нужно заранее определить колонки, иначе метод ЗаполнитьЗначенияСвойств не сработает корректно.


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

Вариант 2: Использование механизмов БСП

Если вы работаете в современной конфигурации (например, УТ 11, ERP 2 или БП 3.0), нет необходимости писать велосипеды. В составе Библиотеки стандартных подсистем (БСП) уже есть готовые инструменты. Посмотрим на функции общего модуля ОбщегоНазначения:

  1. ОбщегоНазначения.ТаблицаЗначенийВМассив(ТЗ) — быстро преобразует вашу таблицу в массив структур.
  2. ОбщегоНазначения.МассивВТаблицуЗначений(Массив) — выполняет обратную операцию.

Использование этих функций — признак хорошего тона в современной разработке, так как они оптимизированы и учитывают многие нюансы платформы.

Вариант 3: Работа через реквизиты формы

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

  1. Создаем на форме реквизит с типом ТаблицаЗначений (в редакторе формы это будет выглядеть как группа колонок).
  2. На сервере используем встроенные методы преобразования:

&НаСервере
Процедура ЗагрузитьДанныеНаФорму(ТЗ)
    // ТЗ - это наша исходная ТаблицаЗначений
    // Объект.ДанныеТаблицы - это реквизит формы типа ДанныеФормыКоллекция
    ЗначениеВДанныеФормы(ТЗ, Объект.ДанныеТаблицы);
КонецПроцедуры

Для обратного получения таблицы на сервере используем:


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

Вариант 4: Временное хранилище

Когда таблица содержит десятки тысяч строк, передача её в виде массива структур может привести к "зависанию" интерфейса из-за огромного объема передаваемого XML-трафика. В таких случаях проанализируем возможность использования временного хранилища.

Схема работы будет следующей:

  1. На сервере помещаем ТаблицаЗначений во временное хранилище: Адрес = ПоместитьВоВременноеХранилище(ТЗ, УникальныйИдентификатор);
  2. Передаем на клиент только строковую переменную Адрес.
  3. Когда на клиенте нужно выполнить действие с этими данными, мы снова вызываем сервер, передаем Адрес и извлекаем таблицу: ТЗ = ПолучитьИзВременногоХранилища(Адрес);

Важный нюанс: на самом клиенте вы все равно не сможете превратить адрес обратно в таблицу, это можно сделать только на сервере.

Типичная архитектурная ошибка

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

Почему так делать нельзя: каждый вызов серверной функции с клиента — это сетевой пакет. Если в файле 1000 строк, вы сделаете 1000 микро-запросов к серверу. Это крайне медленно.

Как правильно: передайте на сервер путь к файлу (или сам файл в хранилище), прочитайте его и создайте все 1000 элементов в одном серверном вызове. На клиент верните только краткий отчет о результате операции. Это сократит время работы обработки в разы.

Подведем итоги

Для эффективной работы с данными между клиентом и сервером придерживайтесь следующих правил:

Помните, что ТаблицаЗначений — это мощный инструмент, но его использование требует понимания клиент-серверной архитектуры 1С.

← На главную