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

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

Как перебрать элементы формы в 1С: практическое руководство

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

Перебор элементов формы — типичная задача при доработке конфигураций 1С: нужно массово скрыть кнопки, заблокировать поля ввода, найти конкретный элемент по части имени или собрать список всех таблиц на форме. Платформа предоставляет коллекцию элементов формы, которую можно обходить в цикле, но синтаксис зависит от типа формы: обычная форма (толстый клиент, режим совместимости) и управляемая форма используют разные объекты и разные свойства.

Ключевое различие: в обычной форме коллекция называется ЭлементыФормы, а в управляемой — Элементы. Кроме того, в управляемых формах элементы представляют собой декларативное описание интерфейса, и многие операции (например, изменение данных) выполняются через реквизиты формы, а не через сами элементы. Путаница между этими моделями — самая частая причина ошибок вида «Поле объекта не обнаружено».

Ниже разобраны оба варианта: простой обход коллекции, поиск элемента по имени и типу, рекурсивный обход с учётом групп, перебор реквизитов формы и типовые ошибки. Все примеры приведены на встроенном языке 1С и могут быть адаптированы под конкретную конфигурацию.

Отличия обычной и управляемой формы при переборе элементов

Прежде чем писать цикл, определите, с какой формой работаете. В обычной форме коллекция ЭлементыФормы содержит объекты конкретных типов: ПолеВвода, Кнопка, ТабличноеПоле и так далее. Тип элемента проверяется функцией ТипЗнч() с конкретным типом, например Тип("ТабличноеПоле").

В управляемой форме коллекция Элементы содержит объекты типа ПолеФормы, ГруппаФормы, КнопкаФормы, ТаблицаФормы. Здесь доступно свойство Вид, уточняющее назначение элемента (например, ВидПоляФормы.ПолеВвода). Родителя элемента можно получить через свойство Родитель, а вложенные элементы группы — через ПодчиненныеЭлементы.

Ещё одно важное отличие: в управляемой форме коллекция Элементы доступна только в контексте формы (в модуле формы через ЭтаФорма.Элементы или просто Элементы). Передать её на сервер вне контекста формы нельзя — это структура клиентского интерфейса, а не данные.

Простой перебор всех элементов формы

Базовый сценарий — пройтись по всем элементам верхнего уровня и выполнить с ними однотипное действие. В управляемой форме код выглядит так:

Для Каждого Элемент Из Элементы Цикл

// Пример: вывести имя и тип каждого элемента

Сообщить(Элемент.Имя + " — " + ТипЗнч(Элемент));

КонецЦикла;

В обычной форме синтаксис идентичен, меняется только имя коллекции:

Для Каждого Элемент Из ЭлементыФормы Цикл

Сообщить(Элемент.Имя);

КонецЦикла;

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

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

Для Каждого Элемент Из Элементы Цикл

Если СтрНайти(Элемент.Имя, "Служебный_") > 0 Тогда

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

КонецЕсли;

КонецЦикла;

Поиск элемента по имени без полного перебора

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

НайденныйЭлемент = Элементы.Найти("Комментарий");

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

НайденныйЭлемент.ТолькоПросмотр = Истина;

КонецЕсли;

Обращение к элементу напрямую по имени — Элементы.Комментарий — тоже работает, но если элемента с таким именем нет, возникнет ошибка выполнения. Вариант с Найти() безопаснее, когда форма может отличаться в разных режимах или дорабатывается расширением.

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

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

Фильтрация элементов по типу и виду

Частая задача — обработать только элементы определённого типа, например заблокировать все поля ввода или найти все таблицы формы. В управляемой форме проверка строится через ТипЗнч():

Для Каждого Элемент Из Элементы Цикл

Если ТипЗнч(Элемент) = Тип("ПолеФормы") Тогда

Элемент.ТолькоПросмотр = Истина;

КонецЕсли;

КонецЦикла;

Когда нужен более точный отбор, комбинируйте тип со свойством Вид. Например, чтобы отличить поле флажка от поля ввода:

Если ТипЗнч(Элемент) = Тип("ПолеФормы")

И Элемент.Вид = ВидПоляФормы.ПолеФлажка Тогда

// обработка только флажков

КонецЕсли;

Учтите, что не у всех элементов есть свойства ТолькоПросмотр, Видимость или Доступность в одинаковом наборе. Перед массовой установкой свойства убедитесь, что оно применимо к типу элемента, иначе получите ошибку «Свойство объекта не обнаружено». Безопасный шаблон — сначала фильтровать по типу, потом менять свойство.

Типичные ошибки
01
Установка свойства без проверки типа элемента — ошибка «Свойство объекта не обнаружено» на группах и декорациях
02
Перебор Элементы на серверной процедуре вне контекста формы — коллекция недоступна, код падает
03
Ожидание, что Найти() ищет по части имени — метод ищет только точное совпадение, при шаблоне нужен цикл
04
Сравнение имени элемента без учёта регистра в сложных шаблонах — имена в 1С регистронезависимы, но логика сравнения строк может ввести в заблуждение

Рекурсивный обход вложенных групп

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

Процедура ОбойтиЭлементыРекурсивно(Родитель)

Для Каждого Элемент Из Родитель.ПодчиненныеЭлементы Цикл

Сообщить(Элемент.Имя);

Если ТипЗнч(Элемент) = Тип("ГруппаФормы") Тогда

ОбойтиЭлементыРекурсивно(Элемент);

КонецЕсли;

КонецЦикла;

КонецПроцедуры;

// Вызов:

ОбойтиЭлементыРекурсивно(Элементы.ГруппаНастройки);

Рекурсия удобна, когда действие должно применяться к поддереву формы: скрыть целый раздел, собрать все поля внутри страницы, построить карту иерархии для отладки. Если нужно обработать всю форму целиком без привязки к иерархии, простой плоский цикл по Элементы проще и быстрее.

Глубина вложенности групп в типовых формах невелика, поэтому риск переполнения стека при рекурсии практически отсутствует. Тем не менее не вызывайте рекурсивный обход в обработчиках, срабатывающих на каждое изменение формы, — это заметно нагружает клиентское приложение.

Сравнение подходов

Плоский цикл по Элементы

Подходит для обработки всех элементов формы без учёта иерархии; простой и быстрый, но не даёт информации о вложенности

Метод Найти()

Оптимален при известном точном имени; не работает с шаблонами и частичными совпадениями

Рекурсия по ПодчиненныеЭлементы

Нужна для обработки отдельной ветки формы; требует аккуратности и чуть больше кода

Перебор реквизитов формы и связь с элементами

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

МассивРеквизитов = ЭтаФорма.ПолучитьРеквизиты();

Для Каждого Реквизит Из МассивРеквизитов Цикл

Сообщить(Реквизит.Имя + " : " + Реквизит.ТипЗначения);

КонецЦикла;

Метод ПолучитьРеквизиты() принимает необязательный параметр — путь к родительскому реквизиту. Без параметра возвращаются реквизиты верхнего уровня; если передать имя реквизита-объекта (например, "Объект" в форме документа), получите его реквизиты, то есть фактически реквизиты самого документа.

Связь между реквизитом и элементом не обязательна: реквизит может существовать без элемента на форме, а элемент (надпись, декорация, кнопка) — без реквизита. У полей формы связь задаётся свойством ПутьКДанным. Поэтому перебор элементов и перебор реквизитов решают разные задачи: первый — про интерфейс, второй — про данные.

Перебор строк табличной части и динамического списка на форме

Отдельный частный случай — перебор не самих элементов, а данных, которые элементы отображают. Для табличной части объекта перебираются строки коллекции, а не элементы:

Для Каждого Строка Из Объект.Товары Цикл

Строка.Цена = Строка.Цена * 1.1;

КонецЦикла;

Если на форме размещён динамический список, перебирать его строки напрямую нельзя — список формируется запросом и подгружает данные порциями. Чтобы получить данные, нужно работать с запросом списка (через схему компоновки) или использовать методы получения данных. Попытка «перебрать элементы таблицы формы, чтобы прочитать строки» — типичная ошибка: элемент ТаблицаФормы даёт доступ только к текущей строке и выделенным строкам, а не ко всем данным списка.

Для обычной таблицы значений, выведенной на форму как реквизит, перебор выполняется по коллекции реквизита: Для Каждого Строка Из ИмяТаблицы Цикл. Элемент формы здесь служит только визуальным представлением.

Контрольные точки

Как проверить результат

Откройте форму в режиме предприятия после изменений
Норма

Все целевые элементы изменили состояние (скрыты, заблокированы) как задумано

Тревожный признак

Часть элементов не изменилась — вероятно, они вложены в группу, которую цикл не охватил, или фильтр по имени не сработал

Журнал регистрации и окно сообщений
Норма

Нет ошибок «Свойство объекта не обнаружено» и «Поле объекта не обнаружено»

Тревожный признак

Есть ошибки — значит, код обратился к свойству, несовместимому с типом элемента, или к несуществующему элементу

Поведение при повторном открытии формы
Норма

Логика срабатывает стабильно при каждом открытии

Тревожный признак

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

Где размещать код перебора и ограничения

Код перебора элементов размещается в модуле формы. Типичные события: ПриСозданииНаСервере (первичная настройка видимости и доступности), ПриОткрытии (клиентские корректировки), обработчики изменения ключевых реквизитов. Для управляемых форм помните о директивах компиляции: &НаСервере, &НаКлиенте — коллекция Элементы доступна в обоих контекстах формы, но вызов серверных процедур с клиента требует явного объявления.

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

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

Итог

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

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

Часто задаваемые вопросы

Как перебрать элементы формы в управляемом приложении 1С?

Используйте цикл «Для Каждого Элемент Из Элементы Цикл» в модуле формы. Коллекция Элементы содержит все элементы, включая вложенные в группы. Для фильтрации проверяйте тип через ТипЗнч(Элемент) и свойство Вид.

Чем отличается Элементы от ЭлементыФормы?

ЭлементыФормы — коллекция обычной формы (режим обычного приложения), содержит объекты типа ПолеВвода, Кнопка, ТабличноеПоле. Элементы — коллекция управляемой формы с объектами ПолеФормы, ГруппаФормы, КнопкаФормы, ТаблицаФормы. Синтаксис перебора одинаковый, отличаются типы и наборы свойств элементов.

Как найти элемент формы, если известна только часть имени?

Метод Найти() ищет только точное совпадение, поэтому переберите коллекцию циклом и проверяйте имена функцией СтрНайти(Элемент.Имя, "ЧастьИмени") > 0. Совпавшие элементы складывайте в массив, а обрабатывайте после завершения цикла.

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

Да, в модуле управляемой формы коллекция Элементы доступна и в серверных процедурах контекста формы. Но передать её как параметр в общий модуль или на другой объект нельзя — коллекция существует только внутри формы.

Почему возникает ошибка «Свойство объекта не обнаружено» при переборе?

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

Как перебрать строки таблицы на форме, а не сами элементы?

Перебирайте коллекцию данных реквизита, а не элемент формы: Для Каждого Строка Из Объект.Товары Цикл. Элемент ТаблицаФормы даёт доступ только к текущей и выделенным строкам, а динамический список вообще не позволяет перебрать строки напрямую — нужен запрос.