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

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

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

Суть проблемы: контекстные ограничения платформы

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

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

Способ 1. Использование временного хранилища

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

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

  1. На сервере создаем объект ТаблицаЗначений и заполняем его.
  2. Помещаем таблицу во временное хранилище, используя уникальный идентификатор формы.
  3. Возвращаем адрес хранилища на клиент.
  4. На клиенте сохраняем этот адрес и при необходимости передаем его в другие серверные вызовы.

Посмотрим на пример кода, реализующий этот подход:


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

&НаКлиенте
Процедура КомандаВыполнить(Команда)
    АдресДанных = ПолучитьДанныеВоВременноеХранилище();
    // Теперь переменная АдресДанных содержит строку, которую можно передавать между вызовами
КонецПроцедуры

Важно помнить, что данные во временном хранилище живут до тех пор, пока существует форма (если передан её идентификатор), либо до конца сеанса. Обратите внимание: на самом клиенте вы все равно не сможете развернуть этот адрес в таблицу, но вы сможете передать его в другую процедуру &НаСервере, где извлечете данные с помощью функции ПолучитьИзВременногоХранилища.

Способ 2. Преобразование в массив структур (универсальный способ)

Если вам нужно получить данные именно на клиенте для их обхода в цикле или отображения в диалогах, лучшим способом будет трансформация ТаблицаЗначений в Массив, состоящий из Структур. Эти типы данных являются универсальными и прекрасно передаются между сервером и клиентом. Подобные структуры часто используются при обмене данными, где для визуализации может потребоваться просмотрщик JSON в дерево значений.

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

Рассмотрим подробнее программную реализацию:


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

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

Этот метод является наиболее гибким, так как позволяет использовать данные в клиентском коде без повторных обращений к серверу. Однако стоит учитывать, что при очень больших объемах данных (десятки тысяч строк) преобразование и передача массива структур могут занять значительное время и потреблять много оперативной памяти.

Способ 3. Работа через реквизиты формы (ДанныеФормыКоллекция)

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

Выясним причину, почему это удобно: платформа берет на себя все вопросы сериализации. Для преобразования между «чистой» таблицей значений и реквизитом формы используются специальные методы: ДанныеФормыВЗначение и ЗначениеВДанныеФормы. Чтобы быстро получить описание структуры колонок для программного кода, удобно использовать средство создания кода новой таблицы значений из реквизита на форме.

Разберем по шагам процесс работы:

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

Пример использования функций преобразования:


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

Важный момент: использование ДанныеФормыВЗначение доступно только в контекстве серверного вызова формы. Если вы работаете в общем модуле, вам придется передавать данные иными способами.

Сравнительный анализ и рекомендации

Выбор метода зависит от контекста:

Рассмотрим подробнее производительность. Передача Массива структур на клиент «тяжелее», чем передача строки адреса Временного хранилища. Если ваша таблица содержит тысячи строк и сотни колонок, старайтесь минимизировать объем данных, передаваемых на клиент. Оставляйте только те колонки, которые действительно необходимы для отображения или логики интерфейса.

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

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

← На главную