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