Разработка и Конфигурация · 8 мин
1С: как обратиться к реквизиту формы по имени
Как в 1С обратиться к реквизиту формы по имени: ЭтаФорма[ИмяРеквизита], Элементы.Найти, универсальный код для управляемых и обычных форм.
Обращение к реквизиту формы по имени — типичная задача при разработке универсальных обработок, когда имя реквизита заранее неизвестно и вычисляется в коде: например, при обходе однотипных полей «Показатель1», «Показатель2» и так далее. В управляемых формах 1С:Предприятия 8.3 прямой доступ через точку не работает с переменной, поэтому используется обращение по строковому имени через квадратные скобки.
Основной приём — конструкция ЭтаФорма[ИмяРеквизита], где ИмяРеквизита — строковая переменная. Для элементов формы (полей ввода, таблиц) используется метод Элементы.Найти(ИмяЭлемента). Эти два подхода покрывают практически все сценарии динамического доступа к данным формы.
Чем реквизит формы отличается от элемента формы
Реквизит формы — это данные, хранящиеся в форме: строки, числа, ссылки, таблицы значений. Элемент формы — это визуальный объект на экране: поле ввода, надпись, кнопка, табличное поле, которое отображает реквизит или часть его данных. Один элемент связан с реквизитом через свойство «ПутьКДанным», но это разные объекты с разными способами доступа.
Путаница между ними — самая частая причина ошибок. Если нужно прочитать или изменить значение, которое ввёл пользователь, обращайтесь к реквизиту. Если нужно скрыть поле, изменить заголовок или доступность — обращайтесь к элементу. Обращение к элементу вместо реквизита вернёт объект поля ввода, а не значение, и попытка сложить его с числом вызовет ошибку.
Обращение к реквизиту через ЭтаФорма[ИмяРеквизита]
В управляемой форме реквизиты доступны как свойства объекта формы, и платформа позволяет обращаться к ним по строковому имени через квадратные скобки. Это работает и на клиенте, и на сервере в контексте формы:
ИмяРеквизита = "Показатель" + Формат(НомерПоказателя, "ЧГ=");
ЗначениеПоказателя = ЭтаФорма[ИмяРеквизита];
ЭтаФорма[ИмяРеквизита] = ЗначениеПоказателя * 2;
Такой код удобен для циклической обработки однотипных реквизитов: заполнения таблиц показателей, сброса группы полей, копирования значений между наборами реквизитов. Вместо десятков однотипных строк присваивания пишется один цикл.
Для Сч = 1 По 5 Цикл
ЭтаФорма["Показатель" + Сч] = 0;
КонецЦикла;Если реквизит с указанным именем не существует, платформа выдаст ошибку «Поле объекта не обнаружено». Поэтому имя либо формируется по строгому шаблону, либо перед обращением проверяется существование реквизита.
Обращение к элементу формы через Элементы.Найти
Для управления видимостью, доступностью, заголовком поля используется коллекция Элементы формы. Метод Найти() возвращает элемент по имени или Неопределено, если элемент не найден — это удобно для безопасного кода:
ЭлементПоле = Элементы.Найти("Показатель" + НомерПоказателя);
Если ЭлементПоле <> Неопределено Тогда
ЭлементПоле.Видимость = Ложь;
КонецЕсли;
Обратите внимание: имя элемента и имя связанного с ним реквизита могут совпадать, но это не гарантируется. При создании поля в конфигураторе платформа обычно называет элемент так же, как реквизит, однако разработчик мог переименовать элемент. Проверяйте фактические имена в редакторе формы.
Как проверить существование реквизита перед обращением
Универсальный способ — получить список реквизитов формы методом ПолучитьРеквизиты() и проверить наличие нужного имени. Метод доступен только в серверном контексте формы:
Функция РеквизитСуществует(ИмяРеквизита)
Для Каждого Реквизит Из ПолучитьРеквизиты() Цикл
Если Реквизит.Имя = ИмяРеквизита Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецФункции
На клиенте ПолучитьРеквизиты() недоступен. Если проверка нужна на клиенте, используйте попытку обращения в конструкции Попытка...Исключение или переносите логику в серверную процедуру. Впрочем, в большинстве случаев имена реквизитов известны из структуры формы, и проверка нужна только в универсальных механизмах.
- 1Определите, что нужно: значение (реквизит) или оформление (элемент)
- 2Для значения используйте ЭтаФорма[ИмяРеквизита] со строковой переменной
- 3Для элемента используйте Элементы.Найти(Имя) и проверку на Неопределено
- 4Если имя вычисляется динамически, убедитесь, что реквизит существует
- 5Протестируйте код на клиенте и на сервере отдельно
Особенности для обычных форм и реквизитов объекта
В обычных формах (режим совместимости, старые конфигурации) прямое обращение ЭтаФорма[ИмяРеквизита] тоже работает для реквизитов формы, а для элементов используется коллекция ЭлементыФормы с методом Найти(). Синтаксис похож, но коллекции разные, и код не переносится между типами форм без корректировки.
Отдельный случай — реквизиты самого объекта (документа, справочника), а не формы. В управляемой форме объекта они доступны через основной реквизит, обычно называемый «Объект»: Объект[ИмяРеквизита] или ЭтаФорма.Объект[ИмяРеквизита]. Для произвольных объектов вне формы работает обращение через квадратные скобки у любого объекта данных: ДокументОбъект["Сумма"].
Сравнение способов
Реквизит формы в управляемой форме. Работает на клиенте и сервере, ошибка при отсутствии реквизита
Элемент управляемой формы. Возвращает Неопределено при отсутствии — безопасно
Реквизит объекта данных (документа, справочника), а не формы
Элемент в обычной форме, только для старых конфигураций
Типичные ошибки и ограничения
Первая ошибка — попытка обратиться к реквизиту через Элементы.Найти() и прочитать у него значение. У поля ввода нет свойства со значением данных формы; значение хранится в реквизите, на который элемент ссылается. Вторая ошибка — использование ПолучитьРеквизиты() в клиентской процедуре: платформа выдаст ошибку вызова метода в данном контексте.
Третья распространённая проблема — обращение к реквизиту табличной части объекта через ЭтаФорма[Имя]. Табличные части объекта доступны через Объект.ИмяТабличнойЧасти, а текущие данные строки на клиенте — через Элементы.ИмяТаблицы.ТекущиеДанные. Динамически имя подставляется так же: Объект[ИмяТабличнойЧасти].
Ещё одно ограничение: динамическое обращение по имени затрудняет поиск ссылок на реквизит при рефакторинге. Конфигуратор не найдёт такие обращения при переименовании реквизита, поэтому строковые имена стоит формировать по документированному шаблону и покрывать код тестами.
Частые вопросы
Как обратиться к реквизиту формы, если его имя хранится в переменной?
Используйте квадратные скобки: ЭтаФорма[ИмяПеременной]. Переменная должна содержать строку с точным именем реквизита с учётом регистра, принятого в конфигурации.
Работает ли ЭтаФорма[Имя] на клиенте в управляемой форме?
Да, обращение к реквизиту формы по строковому имени работает и в клиентских, и в серверных процедурах формы. Ограничение касается только метода ПолучитьРеквизиты(), доступного лишь на сервере.
Как безопасно обратиться к элементу, которого может не быть?
Используйте Элементы.Найти(Имя) и проверяйте результат на Неопределено перед обращением к свойствам. Прямое обращение Элементы.Имя к несуществующему элементу вызовет ошибку.
Чем отличается доступ к реквизиту формы и к реквизиту объекта?
Реквизит формы — собственные данные формы, доступ через ЭтаФорма[Имя]. Реквизит объекта (документа, справочника) — данные основного реквизита формы, доступ через Объект[Имя]. При записи объекта сохраняются только его реквизиты, реквизиты формы теряются при закрытии.
Можно ли перебрать все реквизиты формы в цикле?
Да, на сервере: Для Каждого Реквизит Из ПолучитьРеквизиты() Цикл — у каждого элемента есть свойства Имя, ТипЗначения, Путь. На клиенте такой перебор недоступен, при необходимости передавайте список имён с сервера.
Как обратиться к колонке таблицы значений — реквизита формы — по имени?
Сначала получите таблицу: Таблица = ЭтаФорма[ИмяТаблицы], затем у строки обращайтесь к колонке по имени: СтрокаТаблицы[ИмяКолонки]. Квадратные скобки работают и для строк таблиц значений.
Что важно запомнить
Значение реквизита формы по имени читается через ЭтаФорма[ИмяРеквизита], элемент управления ищется через Элементы.Найти(Имя) с проверкой на Неопределено. Реквизиты объекта доступны через Объект[Имя]. Проверка существования реквизита — только на сервере через ПолучитьРеквизиты().