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

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

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

Почему возникает ошибка передачи данных?

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

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

Способ 1: Использование Массива Структур

Самый простой и понятный метод для передачи небольших объемов данных — это конвертация таблицы в массив структур. Тип Массив и тип Структура доступны и на клиенте, и на сервере, и они отлично сериализуются (передаются между контекстами).

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

Рассмотрим пример серверного кода, который подготавливает данные:


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

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


&НаКлиенте
Процедура ОбработатьДанные()
    
    // Вызываем серверную функцию
    МассивДанных = ПолучитьДанныеНаСервере();
    
    // Перебираем полученный массив
    Для Каждого ЭлементМассива Из МассивДанных Цикл
        // Обращаемся к свойствам структуры
        Сообщить("Товар: " + Строка(ЭлементМассива.Номенклатура) + 
                 ", Кол-во: " + ЭлементМассива.Количество);
    КонецЦикла;
    
КонецПроцедуры

Преимущества метода: Простота реализации и наглядность кода.
Недостатки: При очень большом количестве строк (десятки тысяч) конвертация в структуры и их передача может занять время и создать нагрузку на трафик.

Способ 2: Использование Временного Хранилища

Если нам необходимо передать большой объем данных или мы хотим сохранить структуру таблицы для дальнейшей обработки (например, передать её из одной формы в другую), лучше воспользоваться механизмом ВременноеХранилище. Этот механизм позволяет поместить данные в специальную область памяти на сервере и получить строковый адрес, который можно легко передать на клиент.

Давайте разберем алгоритм действий:

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

Посмотрим на реализацию этого подхода. Сначала серверная часть:


&НаСервере
Функция ПоместитьТаблицуВХранилище()
    
    ТЗ = ПолучитьТаблицуИзЗапроса();
    
    // Помещаем ТЗ во временное хранилище. 
    // УникальныйИдентификатор формы передаем, чтобы данные жили, пока жива форма.
    АдресВХранилище = ПоместитьВоВременноеХранилище(ТЗ, УникальныйИдентификатор);
    
    Возврат АдресВХранилище;
    
КонецФункции

Теперь клиентская часть. Обратите внимание: мы получаем только строку адреса. Сама таблица на клиент не "приезжает". Этот способ идеален, если таблица нужна нам позже для другого серверного вызова (например, для печати или проведения).


&НаКлиенте
Процедура ВыполнитьДействие()
    
    АдресТЗ = ПоместитьТаблицуВХранилище();
    
    // Теперь мы можем передать этот адрес в другую процедуру
    // или открыть другую форму, передав адрес в параметры
    ПараметрыФормы = Новый Структура("АдресДанных", АдресТЗ);
    ОткрытьФорму("ОбщаяФорма.ФормаОбработкиДанных", ПараметрыФормы);
    
КонецПроцедуры

Способ 3: Сериализация XDTO (Дополнительный вариант)

Существует еще один метод, который полезно знать — использование СериализаторXDTO. Он позволяет превратить сложные объекты (включая таблицу значений) в XML-строку, которую можно передать на клиент. Однако на клиенте мы получим именно строку XML, а не готовую коллекцию, поэтому этот метод используется реже, в основном для интеграций.

Проанализируем пример кода для общего развития:


&НаСервере
Функция СериализоватьТЗ()
    
    ТЗ = Новый ТаблицаЗначений;
    // ... заполнение ТЗ ...
    
    ЗаписьXML = Новый ЗаписьXML;
    ЗаписьXML.УстановитьСтроку();
    
    СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ТЗ);
    
    Возврат ЗаписьXML.Закрыть(); // Возвращает строку XML
    
КонецФункции

Рекомендации по выбору метода

Давайте подведем итог и определим, когда и какой метод лучше использовать:

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

← На главную