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