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