К статье
Практический материал

Разработка и Конфигурация · 8 мин

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

Как в 1С обратиться к реквизиту формы по имени: ЭтаФорма[ИмяРеквизита], Элементы.Найти, универсальный код для управляемых и обычных форм.

Обращение к реквизиту формы по имени — типичная задача при разработке универсальных обработок, когда имя реквизита заранее неизвестно и вычисляется в коде: например, при обходе однотипных полей «Показатель1», «Показатель2» и так далее. В управляемых формах 1С:Предприятия 8.3 прямой доступ через точку не работает с переменной, поэтому используется обращение по строковому имени через квадратные скобки.

Основной приём — конструкция ЭтаФорма[ИмяРеквизита], где ИмяРеквизита — строковая переменная. Для элементов формы (полей ввода, таблиц) используется метод Элементы.Найти(ИмяЭлемента). Эти два подхода покрывают практически все сценарии динамического доступа к данным формы.

Чем реквизит формы отличается от элемента формы

Реквизит формы — это данные, хранящиеся в форме: строки, числа, ссылки, таблицы значений. Элемент формы — это визуальный объект на экране: поле ввода, надпись, кнопка, табличное поле, которое отображает реквизит или часть его данных. Один элемент связан с реквизитом через свойство «ПутьКДанным», но это разные объекты с разными способами доступа.

Путаница между ними — самая частая причина ошибок. Если нужно прочитать или изменить значение, которое ввёл пользователь, обращайтесь к реквизиту. Если нужно скрыть поле, изменить заголовок или доступность — обращайтесь к элементу. Обращение к элементу вместо реквизита вернёт объект поля ввода, а не значение, и попытка сложить его с числом вызовет ошибку.

Обращение к реквизиту через ЭтаФорма[ИмяРеквизита]

В управляемой форме реквизиты доступны как свойства объекта формы, и платформа позволяет обращаться к ним по строковому имени через квадратные скобки. Это работает и на клиенте, и на сервере в контексте формы:

ИмяРеквизита = "Показатель" + Формат(НомерПоказателя, "ЧГ=");

ЗначениеПоказателя = ЭтаФорма[ИмяРеквизита];

ЭтаФорма[ИмяРеквизита] = ЗначениеПоказателя * 2;

Такой код удобен для циклической обработки однотипных реквизитов: заполнения таблиц показателей, сброса группы полей, копирования значений между наборами реквизитов. Вместо десятков однотипных строк присваивания пишется один цикл.

bsl
Для Сч = 1 По 5 Цикл
    ЭтаФорма["Показатель" + Сч] = 0;
КонецЦикла;

Если реквизит с указанным именем не существует, платформа выдаст ошибку «Поле объекта не обнаружено». Поэтому имя либо формируется по строгому шаблону, либо перед обращением проверяется существование реквизита.

Обращение к элементу формы через Элементы.Найти

Для управления видимостью, доступностью, заголовком поля используется коллекция Элементы формы. Метод Найти() возвращает элемент по имени или Неопределено, если элемент не найден — это удобно для безопасного кода:

ЭлементПоле = Элементы.Найти("Показатель" + НомерПоказателя);

Если ЭлементПоле <> Неопределено Тогда

ЭлементПоле.Видимость = Ложь;

КонецЕсли;

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

Как проверить существование реквизита перед обращением

Универсальный способ — получить список реквизитов формы методом ПолучитьРеквизиты() и проверить наличие нужного имени. Метод доступен только в серверном контексте формы:

Функция РеквизитСуществует(ИмяРеквизита)

Для Каждого Реквизит Из ПолучитьРеквизиты() Цикл

Если Реквизит.Имя = ИмяРеквизита Тогда

Возврат Истина;

КонецЕсли;

КонецЦикла;

Возврат Ложь;

КонецФункции

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

Порядок действий
  1. 1
    Определите, что нужно: значение (реквизит) или оформление (элемент)
  2. 2
    Для значения используйте ЭтаФорма[ИмяРеквизита] со строковой переменной
  3. 3
    Для элемента используйте Элементы.Найти(Имя) и проверку на Неопределено
  4. 4
    Если имя вычисляется динамически, убедитесь, что реквизит существует
  5. 5
    Протестируйте код на клиенте и на сервере отдельно

Особенности для обычных форм и реквизитов объекта

В обычных формах (режим совместимости, старые конфигурации) прямое обращение ЭтаФорма[ИмяРеквизита] тоже работает для реквизитов формы, а для элементов используется коллекция ЭлементыФормы с методом Найти(). Синтаксис похож, но коллекции разные, и код не переносится между типами форм без корректировки.

Отдельный случай — реквизиты самого объекта (документа, справочника), а не формы. В управляемой форме объекта они доступны через основной реквизит, обычно называемый «Объект»: Объект[ИмяРеквизита] или ЭтаФорма.Объект[ИмяРеквизита]. Для произвольных объектов вне формы работает обращение через квадратные скобки у любого объекта данных: ДокументОбъект["Сумма"].

Сравнение способов

ЭтаФорма[Имя]

Реквизит формы в управляемой форме. Работает на клиенте и сервере, ошибка при отсутствии реквизита

Элементы.Найти(Имя)

Элемент управляемой формы. Возвращает Неопределено при отсутствии — безопасно

Объект[Имя]

Реквизит объекта данных (документа, справочника), а не формы

ЭлементыФормы.Найти(Имя)

Элемент в обычной форме, только для старых конфигураций

Типичные ошибки и ограничения

Первая ошибка — попытка обратиться к реквизиту через Элементы.Найти() и прочитать у него значение. У поля ввода нет свойства со значением данных формы; значение хранится в реквизите, на который элемент ссылается. Вторая ошибка — использование ПолучитьРеквизиты() в клиентской процедуре: платформа выдаст ошибку вызова метода в данном контексте.

Третья распространённая проблема — обращение к реквизиту табличной части объекта через ЭтаФорма[Имя]. Табличные части объекта доступны через Объект.ИмяТабличнойЧасти, а текущие данные строки на клиенте — через Элементы.ИмяТаблицы.ТекущиеДанные. Динамически имя подставляется так же: Объект[ИмяТабличнойЧасти].

Типичные ошибки
01
Чтение значения через Элементы.Найти() вместо ЭтаФорма[Имя] — возвращается поле, а не значение
02
Вызов ПолучитьРеквизиты() на клиенте — метод доступен только на сервере
03
Отсутствие проверки результата Элементы.Найти() — ошибка при обращении к свойствам Неопределено
04
Путаница имён элемента и реквизита, если разработчик переименовал элемент
05
Обращение к табличной части объекта через ЭтаФорма вместо Объект[Имя]

Ещё одно ограничение: динамическое обращение по имени затрудняет поиск ссылок на реквизит при рефакторинге. Конфигуратор не найдёт такие обращения при переименовании реквизита, поэтому строковые имена стоит формировать по документированному шаблону и покрывать код тестами.

Частые вопросы

Как обратиться к реквизиту формы, если его имя хранится в переменной?

Используйте квадратные скобки: ЭтаФорма[ИмяПеременной]. Переменная должна содержать строку с точным именем реквизита с учётом регистра, принятого в конфигурации.

Работает ли ЭтаФорма[Имя] на клиенте в управляемой форме?

Да, обращение к реквизиту формы по строковому имени работает и в клиентских, и в серверных процедурах формы. Ограничение касается только метода ПолучитьРеквизиты(), доступного лишь на сервере.

Как безопасно обратиться к элементу, которого может не быть?

Используйте Элементы.Найти(Имя) и проверяйте результат на Неопределено перед обращением к свойствам. Прямое обращение Элементы.Имя к несуществующему элементу вызовет ошибку.

Чем отличается доступ к реквизиту формы и к реквизиту объекта?

Реквизит формы — собственные данные формы, доступ через ЭтаФорма[Имя]. Реквизит объекта (документа, справочника) — данные основного реквизита формы, доступ через Объект[Имя]. При записи объекта сохраняются только его реквизиты, реквизиты формы теряются при закрытии.

Можно ли перебрать все реквизиты формы в цикле?

Да, на сервере: Для Каждого Реквизит Из ПолучитьРеквизиты() Цикл — у каждого элемента есть свойства Имя, ТипЗначения, Путь. На клиенте такой перебор недоступен, при необходимости передавайте список имён с сервера.

Как обратиться к колонке таблицы значений — реквизита формы — по имени?

Сначала получите таблицу: Таблица = ЭтаФорма[ИмяТаблицы], затем у строки обращайтесь к колонке по имени: СтрокаТаблицы[ИмяКолонки]. Квадратные скобки работают и для строк таблиц значений.

Итог

Что важно запомнить

Значение реквизита формы по имени читается через ЭтаФорма[ИмяРеквизита], элемент управления ищется через Элементы.Найти(Имя) с проверкой на Неопределено. Реквизиты объекта доступны через Объект[Имя]. Проверка существования реквизита — только на сервере через ПолучитьРеквизиты().