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

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

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

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

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

Решение 1: Использование массива структур (Рекомендуемый способ)

Наиболее правильным и читаемым способом является создание массива, каждый элемент которого представляет собой структуру. Ключами структуры будут выступать имена колонок. Это позволяет обращаться к данным по имени, а не по индексу, что значительно упрощает дальнейшую поддержку кода.

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

  1. Создадим новый пустой массив.
  2. Запустим цикл по строкам исходной таблицы значений.
  3. Внутри цикла для каждой строки создадим новую структуру, куда поместим значения нужных нам колонок.
  4. Добавим структуру в массив.

Посмотрим на пример кода:


МойМассив = Новый Массив;
Для каждого СтрокаТЗ Из МояТЗ Цикл
    // Формируем структуру с данными текущей строки
    ДанныеСтроки = Новый Структура("Колонка1, Колонка2", СтрокаТЗ.Колонка1, СтрокаТЗ.Колонка2);
    // Добавляем заполненную структуру в итоговый массив
    МойМассив.Добавить(ДанныеСтроки);
КонецЦикла;
Возврат МойМассив;

В этом примере Колонка1 и Колонка2 — это имена ваших реальных колонок в ТЗ. После такой обработки МойМассив можно смело передавать на клиент. На стороне клиента вы сможете обращаться к данным так: ЭлементМассива.Колонка1.

Решение 2: Использование массива массивов

Если по какой-то причине вы не хотите использовать структуры (например, требуется экстремальная экономия памяти при передаче огромных объемов данных), можно использовать вложенные массивы. В этом случае каждый элемент основного массива сам будет являться массивом из двух (или более) элементов.

Проанализируем пример реализации:


МойМассив = Новый Массив;
Для каждого СтрокаТЗ Из МояТЗ Цикл
    ВложенныйМассив = Новый Массив;
    ВложенныйМассив.Добавить(СтрокаТЗ.Колонка1);
    ВложенныйМассив.Добавить(СтрокаТЗ.Колонка2);
    
    МойМассив.Добавить(ВложенныйМассив);
КонецЦикла;

Важный нюанс: при таком подходе на клиенте вам придется обращаться к данным по индексам: Строка[0] для первой колонки и Строка[1] для второй. Это менее удобно и может привести к ошибкам, если порядок добавления колонок изменится.

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

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

Рассмотрим использование функции ТаблицаЗначенийВМассив():


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

Оптимизация передачи через Временное хранилище

Иногда объем данных в таблице настолько велик, что передача массива через параметры процедуры вызывает заметные задержки в работе интерфейса ("подтормаживание" при пересылке трафика). В этом случае выясним причину и применим лучший архитектурный подход — Временное хранилище.

Вместо передачи самого массива, мы помещаем его в хранилище на сервере и передаем на клиент только уникальный адрес (строку):


// На сервере
АдресДанных = ПоместитьВоВременноеХранилище(МойМассив, УникальныйИдентификатор);
Возврат АдресДанных;

// На клиенте
// Передаем только адрес (строку) в процедуру
ПодключаемыеКомандыКлиент.ВыполнитьКоманду(ЭтотОбъект, Команда, Элементы.Список, АдресДанных);

Этот метод позволяет избежать десериализации больших объемов данных на стороне клиента до тех пор, пока они действительно не понадобятся.

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

Мы выяснили, что основная проблема автора заключалась в попытке передать «сырые» серверные объекты на сторону клиента. Использование конструкции Новый Структура внутри цикла позволяет упаковать любое количество колонок в один элемент массива. Главное правило: всегда преобразуйте типы ТаблицаЗначений и СтрокаТаблицыЗначений в Массив или Структуру перед возвратом данных с сервера на клиент.

← На главную