Почему ЗначениеВРеквизитФормы вызывает ошибку недопустимого значения параметра и как правильно установить значение реквизита?

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

При динамическом создании элементов и реквизитов на управляемой форме разработчики часто сталкиваются с ситуацией, когда попытка присвоить значение созданному реквизиту через метод ЗначениеВРеквизитФормы завершается аварийно. Платформа выдает исключение вида: Ошибка при вызове метода контекста (ЗначениеВРеквизитФормы): Недопустимое значение параметра (параметр номер '2'). При этом имя реквизита передано абсолютно точно и сам реквизит присутствует на форме. Разберем по шагам, почему возникает эта ошибка и как корректно работать со значениями реквизитов формы.

Анализ проблемы и причины возникновения ошибки

Рассмотрим типовой пример, в котором создается динамический реквизит примитивного типа Булево и поле для его отображения:


нРеквизиты = Новый Массив;
нРеквизиты.Добавить(Новый РеквизитФормы("Категория", Новый ОписаниеТипов("Булево"), , "Категория", Истина));
ИзменитьРеквизиты(нРеквизиты);

ИмяЭлемента = "КатегорияВИП";
НовыйЭлемент = Элементы.Найти(ИмяЭлемента);
Если НовыйЭлемент = Неопределено Тогда
    НовыйЭлемент = Элементы.Добавить(ИмяЭлемента, Тип("ПолеФормы"), ГруппаФормы);
    НовыйЭлемент.ПутьКДанным = "Категория";
    НовыйЭлемент.ТолькоПросмотр = Истина;
КонецЕсли;

ЗначениеВРеквизитФормы(Истина, "Категория"); // Здесь возникает ошибка

Выясним причину такого поведения платформы. Методы ЗначениеВРеквизитФормы и РеквизитФормыВЗначение имеют строго определенное назначение. Они разработаны исключительно для преобразования сложных прикладных объектов в специальные структуры данных формы и обратно. К таким объектам относятся:

  1. Объекты ссылочных типов: СправочникОбъект, ДокументОбъект, ПланВидовХарактеристикОбъект (преобразуются в ДанныеФормыСтруктураДляОбъекта);
  2. Табличные структуры: ТаблицаЗначений (преобразуется в ДанныеФормыКоллекция);
  3. Иерархические структуры: ДеревоЗначений (преобразуется в ДанныеФормыДерево).

Реквизиты простых типов (Булево, Число, Строка, Дата), а также простые ссылки не требуют никакой сериализации или специального преобразования в коллекции формы. Когда вторым параметром в метод ЗначениеВРеквизитФормы передается имя реквизита примитивного типа, платформа определяет несовместимость целевого реквизита с механизмом конвертации и сообщает об ошибке во втором параметре.

Способ 1. Прямое обращение через контекст формы (статическое имя)

Для простых типов данных управляемой формы нет необходимости вызывать специализированные методы конвертации. Любой реквизит формы доступен как свойство самого контекста формы. Если имя реквизита известно заранее, используем простое прямое присваивание:

ЭтаФорма.Категория = Истина;

Или даже короче, если код выполняется в модуле формы:

Категория = Истина;

После такого присвоения значение немедленно отобразится в связанном элементе интерфейса формы.

Способ 2. Обращение через квадратные скобки (динамическое имя)

Если мы создаем реквизиты динамически в цикле или имя реквизита хранится в переменной, прямое обращение через точку не подойдет. В 1С контекст ЭтаФорма поддерживает обращение к своим реквизитам по строковому индексу. Разберем синтаксис доступа через квадратные скобки:


ИмяРеквизита = "Категория";

// Установка значения по динамическому имени
ЭтаФорма[ИмяРеквизита] = Истина;

// Чтение значения по динамическому имени
ТекущееЗначение = ЭтаФорма[ИмяРеквизита];

Такой подход полностью решает задачу работы с динамическими реквизитами любых простых типов без генерации исключений платформы.

Особенности и правила работы с динамическими реквизитами

Рассмотрим подробнее важные нюансы, которые необходимо соблюдать при добавлении реквизитов формы в рантайме:

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