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