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