Как передать таблицу значений с клиента на сервер в 1С: разбираем рабочие методы

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

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

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

Почему возникает ошибка?

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

Для решения этой задачи мы должны использовать механизмы, поддерживаемые платформой для обмена данными: Временное хранилище или Сериализуемые коллекции (например, Массив Структур).

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

Это наиболее универсальный и рекомендуемый метод, особенно если таблица содержит большое количество строк. Рассмотрим этот процесс по шагам.

Алгоритм действий следующий:

  1. На клиенте или в контексте формы мы помещаем данные во временное хранилище.
  2. Получаем адрес этого хранилища (строка).
  3. Передаем адрес строкой в серверную процедуру.
  4. На сервере получаем данные из хранилища по адресу.

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


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

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

Важный нюанс: Обратите внимание на второй параметр метода ПоместитьВоВременноеХранилище. Мы передаем УникальныйИдентификатор формы. Это связывает данные с жизнью формы. Если передать туда Новый УникальныйИдентификатор, данные удалятся сразу после возврата управления с сервера на клиент.

Способ 2: Массив Структур (для небольших данных)

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

Разберем этот метод подробнее. Он работает, потому что и Массив, и Структура доступны и на клиенте, и на сервере, и легко сериализуются платформой (XDTO).


&НаКлиенте
Процедура ОтправитьСписокНаСервер(Команда)
    
    МассивДанных = Новый Массив;
    
    // Заполняем массив структурами
    // Это имитация строк таблицы
    Строка1 = Новый Структура("Номенклатура, Количество", "Товар 1", 10);
    Строка2 = Новый Структура("Номенклатура, Количество", "Товар 2", 5);
    
    МассивДанных.Добавить(Строка1);
    МассивДанных.Добавить(Строка2);
    
    // Спокойно передаем массив в параметре
    ОбработатьМассивНаСервере(МассивДанных);
    
КонецПроцедуры

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

КонецПроцедуры

Преимущества и недостатки:

Преобразование ДанныеФормыКоллекция в ТаблицуЗначений

Часто возникает вопрос: а как быть, если данные уже есть на форме в виде табличной части (ТЧ)? Рассмотрим метод РеквизитФормыВЗначение.

Если мы находимся в серверной процедуре с контекстом (&НаСервере), платформа сама передает данные формы на сервер. Нам нужно лишь конвертировать их в прикладной объект.


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

Резюме

Подведем итог нашему анализу проблемы передачи данных:

  1. Для передачи произвольных таблиц используйте связку ПоместитьВоВременноеХранилище (клиент) и ПолучитьИзВременногоХранилища (сервер).
  2. Для простых списков данных используйте Массив из объектов типа Структура.
  3. Для работы с табличными частями текущей формы используйте методы конвертации реквизитов формы (РеквизитФормыВЗначение).

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

← На главную