В процессе разработки на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с необходимостью передать данные из таблицы значений, находящейся на сервере, в клиентские процедуры. Прямая передача объекта ТаблицаЗначений или его строк (СтрокаТаблицыЗначений) невозможна, так как эти типы не являются сериализуемыми и не могут существовать вне серверного контекста. В этой статье мы подробно разберем, как правильно упаковать данные нескольких колонок в массив, чтобы они стали доступны на стороне клиента.
Давайте проанализируем ситуацию: когда мы пытаемся передать МояТЗ или результат метода ПолучитьВыделенныеСтроки() в клиентскую процедуру (например, в механизм ПодключаемыеКомандыКлиент.ВыполнитьКоманду), платформа выдает ошибку "Недопустимый тип!". Это происходит потому, что тип СтрокаТаблицыЗначений — это не просто набор данных, а ссылка на область памяти в объекте таблицы на сервере. Клиентское приложение «не знает», как работать с этой структурой напрямую. Чтобы решить проблему, нам нужно преобразовать данные в универсальные коллекции, такие как Массив, Структура или Соответствие.
Наиболее правильным и читаемым способом является создание массива, каждый элемент которого представляет собой структуру. Ключами структуры будут выступать имена колонок. Это позволяет обращаться к данным по имени, а не по индексу, что значительно упрощает дальнейшую поддержку кода.
Разберем по шагам, как реализовать этот метод:
Посмотрим на пример кода:
МойМассив = Новый Массив;
Для каждого СтрокаТЗ Из МояТЗ Цикл
// Формируем структуру с данными текущей строки
ДанныеСтроки = Новый Структура("Колонка1, Колонка2", СтрокаТЗ.Колонка1, СтрокаТЗ.Колонка2);
// Добавляем заполненную структуру в итоговый массив
МойМассив.Добавить(ДанныеСтроки);
КонецЦикла;
Возврат МойМассив;
В этом примере Колонка1 и Колонка2 — это имена ваших реальных колонок в ТЗ. После такой обработки МойМассив можно смело передавать на клиент. На стороне клиента вы сможете обращаться к данным так: ЭлементМассива.Колонка1.
Если по какой-то причине вы не хотите использовать структуры (например, требуется экстремальная экономия памяти при передаче огромных объемов данных), можно использовать вложенные массивы. В этом случае каждый элемент основного массива сам будет являться массивом из двух (или более) элементов.
Проанализируем пример реализации:
МойМассив = Новый Массив;
Для каждого СтрокаТЗ Из МояТЗ Цикл
ВложенныйМассив = Новый Массив;
ВложенныйМассив.Добавить(СтрокаТЗ.Колонка1);
ВложенныйМассив.Добавить(СтрокаТЗ.Колонка2);
МойМассив.Добавить(ВложенныйМассив);
КонецЦикла;
Важный нюанс: при таком подходе на клиенте вам придется обращаться к данным по индексам: Строка[0] для первой колонки и Строка[1] для второй. Это менее удобно и может привести к ошибкам, если порядок добавления колонок изменится.
Если ваша конфигурация построена на базе Библиотеки стандартных подсистем (БСП), вам не обязательно писать циклы вручную. В модуле ОбщегоНазначения часто присутствует функция, которая делает всю работу за вас. Она оптимизирована и работает быстрее ручного перебора.
Рассмотрим использование функции ТаблицаЗначенийВМассив():
// Пример вызова функции БСП
МассивРезультат = ОбщегоНазначения.ТаблицаЗначенийВМассив(МояТЗ);
// Если нужно только определенные колонки, можно предварительно выгрузить их в новую ТЗ
МояТЗ_Краткая = МояТЗ.Скопировать(, "Колонка1, Колонка2");
МассивРезультат = ОбщегоНазначения.ТаблицаЗначенийВМассив(МояТЗ_Краткая);
Иногда объем данных в таблице настолько велик, что передача массива через параметры процедуры вызывает заметные задержки в работе интерфейса ("подтормаживание" при пересылке трафика). В этом случае выясним причину и применим лучший архитектурный подход — Временное хранилище.
Вместо передачи самого массива, мы помещаем его в хранилище на сервере и передаем на клиент только уникальный адрес (строку):
// На сервере
АдресДанных = ПоместитьВоВременноеХранилище(МойМассив, УникальныйИдентификатор);
Возврат АдресДанных;
// На клиенте
// Передаем только адрес (строку) в процедуру
ПодключаемыеКомандыКлиент.ВыполнитьКоманду(ЭтотОбъект, Команда, Элементы.Список, АдресДанных);
Этот метод позволяет избежать десериализации больших объемов данных на стороне клиента до тех пор, пока они действительно не понадобятся.
Мы выяснили, что основная проблема автора заключалась в попытке передать «сырые» серверные объекты на сторону клиента. Использование конструкции Новый Структура внутри цикла позволяет упаковать любое количество колонок в один элемент массива. Главное правило: всегда преобразуйте типы ТаблицаЗначений и СтрокаТаблицыЗначений в Массив или Структуру перед возвратом данных с сервера на клиент.