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