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

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

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

Различие между типами данных на клиенте и сервере

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

Рассмотрим основные способы «превращения» коллекции формы в полноценную таблицу значений на стороне сервера.

Метод 1. Использование метода Выгрузить() в серверном контексте

Самый простой и быстрый способ получить таблицу значений из реквизита формы — это вызвать метод Выгрузить() внутри процедуры с директивой &НаСервере. Однако здесь критически важно понимать разницу между элементом интерфейса и самим реквизитом.

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

Посмотрим на правильный пример реализации:


&НаКлиенте
Процедура ОбработатьДанные(Команда)
    ПолучитьТЗНаСервере();
КонецПроцедуры

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

Метод 2. Использование функции ДанныеФормыВЗначение

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

Рассмотрим алгоритм действий:


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

Важный нюанс: использование функции ДанныеФормыВЗначение требует больше ресурсов системы, чем простой метод Выгрузить(), так как происходит полная сериализация и десериализация объекта. Используйте её только тогда, когда вам действительно нужен полный функционал ТаблицыЗначений с сохранением всех свойств.

Метод 3. Передача через массив структур (подход БСП)

В некоторых случаях (например, при передаче данных в фоновое задание или в универсальные механизмы Библиотеки Стандартных Подсистем) удобно использовать промежуточный формат — массив структур. Это позволяет передать данные «легким» способом, не перегружая контекст формы.

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


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

Или, если используется БСП на сервере:

МассивСтруктур = ОбщегоНазначения.ТаблицаЗначенийВМассив(ТаблицаСчетов.Выгрузить());

Анализ типичной ошибки: «Нельзя изменять поле, содержащее объект данных формы»

Разберем ситуацию, описанную в сообщениях форума. Ошибка «Нельзя изменять поле, содержащее объект данных формы» часто возникает в двух случаях:

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

Оптимизация передачи больших объемов данных

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

Итоги и рекомендации

Подводя итог, можно составить следующий алгоритм действий для программиста:

  1. Если нужно просто пересчитать итоги или найти строку на сервере — используйте РеквизитИмя.Выгрузить().
  2. Если нужно вызвать сложный метод объекта, связанного с таблицей (например, табличная часть документа) — используйте РеквизитФормыВЗначение("Объект").
  3. Если данные нужно передать во внешнюю функцию или фоновое задание — преобразуйте их в Массив структур.
  4. Всегда следите за именами переменных, чтобы избежать коллизий с именами реквизитов формы.

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

← На главную