Как обратиться к программно созданному реквизиту формы в 1С

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

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

Выясним причину возникновения ошибки

Проанализируем механику работы платформы 1С. Когда реквизиты создаются в конфигураторе статически, платформа на этапе компиляции модуля формы добавляет их имена в таблицу локальных переменных. Если же реквизит создается программно с помощью метода ИзменитьРеквизиты(), локальная переменная модуля не создается.

Прямое обращение вида Сообщить(РеквизитСозданныйПрограммно); приводит к синтаксической ошибке, так как компилятор не знает о существовании такого имени в контексте модуля. Кроме того, обращение через точку (ЭтаФорма.ИмяРеквизита или ЭтотОбъект.ИмяРеквизита) оставлено для совместимости и в современных релизах платформы может блокироваться исключением для динамических реквизитов.

Основной способ: Обращение через индексатор формы

Для гарантированного получения значения программно созданного реквизита формы следует обращаться к контексту формы через квадратные скобки (индексатор). В качестве ключа передается строковое имя реквизита.

Разберем пример обращения на сервере:


// Получаем значение программного реквизита
ЗначениеРеквизита = ЭтотОбъект["РеквизитСозданныйПрограммно"];

// Выполняем необходимые действия
Сообщить(ЗначениеРеквизита);

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

Безопасное считывание с помощью структуры-зонда

Если в процессе выполнения алгоритма неизвестно заранее, существует ли реквизит на форме в данный момент (например, он мог быть еще не создан или уже удален), прямое обращение через квадратные скобки вызовет ошибку вызова свойства.

Чтобы избежать использования блока Попытка ... Исключение, применим подраздел с так называемой структурой-зондом и методом ЗаполнитьЗначенияСвойств():

  1. Создаем новую структуру, где ключом выступает имя искомого реквизита.
  2. Вызываем метод ЗаполнитьЗначенияСвойств(), где источником указываем форму (ЭтотОбъект), а в качестве списка заполняемых свойств передаем имя нашего реквизита.
  3. Если реквизит существует на форме, его значение скопируется в структуру. Если реквизита нет, ошибка не возникнет, а в структуре останется значение Неопределено.

Посмотрим на пример реализации данного подхода:


// Создаем структуру с ключом искомого реквизита
СтруктураЗонд = Новый Структура("РеквизитСозданныйПрограммно");

// Заполняем значение только для нужного реквизита (3-й параметр)
ЗаполнитьЗначенияСвойств(СтруктураЗонд, ЭтотОбъект, "РеквизитСозданныйПрограммно");

// Проверяем полученный результат
Если СтруктураЗонд.РеквизитСозданныйПрограммно <> Неопределено Тогда
    Сообщить("Значение реквизита: " + СтруктураЗонд.РеквизитСозданныйПрограммно);
КонецЕсли;

Проверка наличия реквизита и особенности контекста

Рассмотрим дополнительные нюансы работы с программными реквизитами, которые важно учитывать при разработке:

1. Проверка существования реквизита через метаданные формы
Для явной проверки наличия реквизита на форме можно использовать метод ПолучитьРеквизиты(). Он возвращает массив объектов типа РеквизитФормы. Для поиска необходимо выполнить обход массива и сравнить свойство Имя каждого элемента:


РеквизитНайден = Ложь;
МассивРеквизитов = ПолучитьРеквизиты();
Для Каждого ЭлементРеквизит Из МассивРеквизитов Цикл
    Если ЭлементРеквизит.Имя = "РеквизитСозданныйПрограммно" Тогда
        РеквизитНайден = Истина;
        Прервать;
    КонецЕсли;
КонецЦикл;

2. Ограничения внеконтекстных процедур
В процедурах и функциях с директивой &НаСервереБезКонтекста динамические реквизиты формы недоступны, так как контекст формы на сервер не передается. Если значение программного реквизита требуется обработать во внеконтекстной процедуре, передавайте его явным параметром при вызове с клиента.

3. Обращение к колонкам программных таблиц
Если программно созданный реквизит является реквизитом составного типа или колонкой динамической таблицы, обращение к нему выполняется путем указания составного пути через точку внутри квадратных скобок: ЭтотОбъект["ИмяТаблицы.ИмяКолонки"].

← На главную