Как исправить ошибку «Несоответствие типов» при вызове ДанныеФормыВЗначение в 1С

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

При разработке управляемых форм в 1С часто возникает необходимость обработать данные табличной части на сервере, выгрузить их в таблицу значений или заполнить дополнительную вычисляемую колонку, которая добавлена только в форму и отсутствует в метаданных документа. При этом разработчики часто сталкиваются с ошибками вида «Несоответствие типов (параметр номер '1')» или «Поле объекта не обнаружено».

Проанализируем причины возникновения этих ошибок и рассмотрим правильные варианты работы с данными формы на сервере.

Причины ошибок при конвертации данных формы

Разберем две наиболее распространенные ситуации, приводящие к сбоям в коде:

  1. Передача элемента формы вместо коллекции данных. Функция ДанныеФормыВЗначение первым параметром принимает объект данных (например, Объект.Резервы с типом ДанныеФормыКоллекция), а не элемент интерфейса Элементы.Резервы (который имеет тип ТаблицаФормы). При попытке передать элемент формы возникает ошибка несоответствия типов.
  2. Использование метода РеквизитФормыВЗначение для колонок формы. Метод РеквизитФормыВЗначение("Объект") преобразует данные формы в прикладной объект метаданных (например, ДокументОбъект). Так как структура этого объекта формируется строго по метаданным конфигурации, любые колонки и реквизиты, добавленные только на форме, при таком преобразовании теряются. Дальнейшее обращение к этим колонкам вызывает ошибку «Поле объекта не обнаружено».

Вариант 1. Прямой обход коллекции данных формы (Рекомендуемый)

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

Рассмотрим пример кода на сервере:


&НаСервере
Процедура РассчитатьСреднедневнуюЗарплатуНаСервере()
    
    Для Каждого ТекСтрока Из Объект.Резервы Цикл
        ТекСтрока.СреднедневнаяЗарплата = ?(ТекСтрока.Дней = 0, 0, Окр(ТекСтрока.БазаРасчета / ТекСтрока.Дней, 2));
    КонецЦикла;
    
КонецПроцедуры

Этот способ является самым быстрым и простым, так как он не требует накладных расходов на конвертацию данных и сохраняет все пользовательские колонки формы.

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

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

Разберем реализацию этого подхода:


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

Обратите внимание: при использовании ДанныеФормыВЗначение для реквизита Объект.Резервы создается ТаблицаЗначений, в которой сохраняются как реквизиты метаданных, так и дополнительные реквизиты формы.

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

Выбирайте подход в зависимости от решаемой задачи:

  1. Для простого обхода и заполнения колонок используйте прямой цикл по Объект.ИмяТабличнойЧасти.
  2. Для работы с методами таблицы значений используйте связку ДанныеФормыВЗначение и ЗначениеВДанныеФормы, передавая в качестве параметра реквизит данных, а не элементы интерфейса.
  3. Не используйте РеквизитФормыВЗначение, если вам необходим доступ к реквизитам, созданным исключительно в контексте формы.
← На главную