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

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

Как в 1С перебрать реквизиты формы

Как в 1С перебрать реквизиты формы: ПолучитьРеквизиты(), РеквизитФормыВЗначение, ИзменитьРеквизиты. Примеры кода, типичные ошибки и проверка результата.

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

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

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

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

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

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

Отдельный случай — основной реквизит формы (обычно Объект у форм документов и справочников). Его реквизиты — это реквизиты прикладного объекта, и их структуру правильнее получать из метаданных, а не из формы.

Базовый перебор через ПолучитьРеквизиты()

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

&НаСервере

Процедура ПоказатьРеквизитыНаСервере()

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

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

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

КонецЦикла;

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

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

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

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

// обработка значения

КонецЦикла;

Учтите: метод вернёт и служебные реквизиты, которые платформа добавляет автоматически (например, параметры динамических списков, реквизиты расширений форм). Если нужны только «свои» реквизиты, фильтруйте по имени или по типу.

Порядок действий
  1. 1
    Откройте модуль формы и определите контекст: клиент или сервер
  2. 2
    Вызовите ПолучитьРеквизиты() и сохраните массив в переменную
  3. 3
    Организуйте цикл Для Каждого по массиву реквизитов
  4. 4
    Внутри цикла читайте значение через ЭтаФорма[Реквизит.Имя]
  5. 5
    Отфильтруйте служебные реквизиты по имени или типу, если они мешают
  6. 6
    Проверьте результат в отладчике: точка останова внутри цикла и просмотр Реквизит.Имя

Перебор вложенных реквизитов и реквизитов объекта

Параметр пути в ПолучитьРеквизиты

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

У объекта РеквизитФормы свойство Путь показывает родителя, а Имя — локальное имя. Полный путь к данным складывается как Путь + "." + Имя (для верхнего уровня путь пустой).

Перебор реквизитов прикладного объекта

Если цель — перебрать именно реквизиты документа (включая те, что не выведены на форму), надёжнее работать через метаданные после преобразования данных формы в объект:

&НаСервере

Процедура ПеребратьРеквизитыОбъекта()

ОбъектДанных = РеквизитФормыВЗначение("Объект");

МетаданныеОбъекта = ОбъектДанных.Метаданные();

Для Каждого Реквизит Из МетаданныеОбъекта.Реквизиты Цикл

Значение = ОбъектДанных[Реквизит.Имя];

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

КонецЦикла;

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

Такой способ доступен только на сервере и создаёт копию данных формы. Изменения в ОбъектДанных не попадут обратно на форму, пока не выполнить ЗначениеВРеквизитФормы(ОбъектДанных, "Объект").

Динамическое создание и перебор реквизитов через ИзменитьРеквизиты

Когда реквизиты добавляются программно — например, по настройкам пользователя — используется метод ИзменитьРеквизиты(Добавляемые, Удаляемые). Он принимает массивы объектов Новый РеквизитФормы(Имя, ОписаниеТипов, Путь, Заголовок, СохраняемыеДанные). После изменения состава перебор выполняется тем же ПолучитьРеквизиты() — новые реквизиты появятся в массиве автоматически.

Типовой сценарий — формирование набора реквизитов по произвольной таблице колонок:

&НаСервере

Процедура ДобавитьРеквизитыПоКолонкам()

Добавляемые = Новый Массив;

Для Каждого Колонка Из ТаблицаКолонок Цикл

Добавляемые.Добавить(Новый РеквизитФормы(Колонка.Имя,

Колонка.ТипЗначения, "", Колонка.Заголовок));

КонецЦикла;

ИзменитьРеквизиты(Добавляемые);

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

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

bsl
Функция РеквизитСуществует(ИмяРеквизита)
    Для Каждого Реквизит Из ПолучитьРеквизиты() Цикл
        Если Реквизит.Имя = ИмяРеквизита Тогда
            Возврат Истина;
        КонецЕсли;
    КонецЦикла;
    Возврат Ложь;
КонецФункции

Практические сценарии использования

Очистка всех реквизитов формы

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

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

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

Продолжить;

КонецЕсли;

ЭтаФорма[Реквизит.Имя] = Неопределено;

КонецЦикла;

Проверка заполненности

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

Копирование значений между формами

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

Сравнение вариантов

ПолучитьРеквизиты()

Подходит для обхода реквизитов самой формы. Работает на клиенте и сервере, но возвращает также служебные реквизиты.

Метаданные объекта

Подходит, когда нужны реквизиты прикладного объекта, включая не выведенные на форму. Требует сервера и РеквизитФормыВЗначение.

Перебор Элементы формы

Подходит для управления видимостью и доступностью полей. Значения так не получить — только пути к данным.

Типичные ошибки и как их избежать

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

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

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

Проверка результата и отладка

Проверить корректность перебора проще всего в отладчике: поставьте точку останова внутри цикла и добавьте в табло выражения Реквизит.Имя, Реквизит.ТипЗначения и ЭтаФорма[Реквизит.Имя]. Нормальный признак — каждая итерация соответствует ожидаемому реквизиту, значение читается без исключений.

Для быстрой диагностики без отладчика выведите состав реквизитов через Сообщить() и сравните со списком в редакторе формы (панель «Реквизиты» в конфигураторе). Расхождение состава — признак того, что часть реквизитов добавлена программно или относится к расширениям формы.

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

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

Состав массива ПолучитьРеквизиты()
Норма

Содержит все реквизиты из редактора формы плюс служебные

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

Отсутствуют ожидаемые реквизиты — возможно, они подчинены пути, вызовите ПолучитьРеквизиты("Объект")

Чтение значения ЭтаФорма[Реквизит.Имя]
Норма

Значение читается без исключения на каждой итерации

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

Ошибка обращения — проверьте контекст выполнения и тип реквизита

ИзменитьРеквизиты
Норма

После вызова новые реквизиты видны в ПолучитьРеквизиты()

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

Исключение о дублировании — реквизит с таким именем уже существует

Итог

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

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

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

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

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

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

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

Почему ПолучитьРеквизиты() возвращает реквизиты, которых нет в редакторе формы?

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

Как изменить значение реквизита, зная только его имя в переменной?

Используйте обращение через квадратные скобки: ЭтаФорма[ИмяРеквизита] = НовоеЗначение. Перед записью полезно проверить существование реквизита перебором ПолучитьРеквизиты() и убедиться, что тип присваиваемого значения соответствует ТипЗначения реквизита, иначе получите ошибку преобразования.

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

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