При разработке универсальных инструментов, таких как консоли запросов, редакторы реквизитов или системы миграции данных, программисты часто сталкиваются с необходимостью получить не только значения реквизитов, но и полный перечень их свойств. В отладчике мы видим дерево свойств: Имя, Синоним, Тип, Подсказка, Индексировать и многие другие. Однако платформа 1С не предоставляет прямого метода вроде "ПолучитьСписокСвойств()".
В этой статье мы разберем несколько эффективных способов, как "вытащить" эти данные программно, не прибегая к ручному перебору всех возможных имен из синтакс-помощника.
Самый простой, но ограниченный метод — это перебор коллекции метаданных объекта. Мы можем получить доступ к реквизитам, табличным частям и стандартным реквизитам. Проанализируем базовый цикл обхода:
// Получаем объект метаданных (например, справочника)
МетаданныеОбъекта = Метаданные.Справочники.Номенклатура;
// Обходим основные реквизиты
Для Каждого МетаданныеРеквизит Из МетаданныеОбъекта.Реквизиты Цикл
// Мы можем обращаться к свойствам, если знаем их имена
ИмяРеквизита = МетаданныеРеквизит.Имя;
СинонимРеквизита = МетаданныеРеквизит.Синоним;
ТипРеквизита = МетаданныеРеквизит.Тип;
// Но как узнать, какие еще свойства доступны у этого объекта?
КонецЦикла;
Проблема этого подхода в том, что для каждого типа метаданных (Справочник, Документ, Регистр) набор доступных свойств разный. Чтобы сделать код по-настоящему универсальным, нам нужно получить именно список ключей.
Если наша задача ограничена получением состава полей и их базовых типов, мы можем воспользоваться объектом СхемаЗапроса. Этот метод позволяет увидеть объект так, как его "видит" СУБД, включая стандартные реквизиты.
Рассмотрим пример построения схемы для динамического анализа:
ТекстЗапроса = "ВЫБРАТЬ * ИЗ Справочник.Номенклатура";
СхемаЗапроса = Новый СхемаЗапроса;
СхемаЗапроса.УстановитьТекстЗапроса(ТекстЗапроса);
// Обращаемся к первой (и единственной) выборке в пакете
Для каждого Колонка Из СхемаЗапроса.ПакетЗапросов[0].Колонки Цикл
// Здесь мы получаем псевдоним (имя поля в БД) и его тип
Сообщить("Поле: " + Колонка.Псевдоним + ", Тип: " + Колонка.ТипЗначения);
КонецЦикла;
Этот способ хорош для получения состава полей, но он не даст нам специфических свойств метаданных, таких как ФорматРедактирования или АвтоОтметкаНезаполненного.
Проанализируем наиболее продвинутый и мощный способ. Объекты метаданных в 1С поддерживают сериализацию в XDTO. При сериализации платформа превращает объект метаданных в структуру данных, где каждое свойство становится отдельным элементом. Мы можем прочитать описание типа этого XDTO-объекта и получить все доступные имена свойств.
Разберем реализацию этого метода по шагам:
// Функция возвращает массив имен свойств для любого объекта метаданных
Функция ПолучитьСписокСвойствМетаданных(ОбъектМетаданных) Экспорт
СписокСвойств = Новый Массив;
Попытка
// Используем глобальный объект СериализаторXDTO
ОбъектXDTO = СериализаторXDTO.ЗаписатьXDTO(ОбъектМетаданных);
ТипXDTO = ОбъектXDTO.Тип();
// Перебираем все свойства типа XDTO
Для каждого СвойствоXDTO Из ТипXDTO.Свойства Цикл
СписокСвойств.Добавить(СвойствоXDTO.Имя);
КонецЦикла;
Исключение
// Некоторые объекты могут не поддерживать прямую сериализацию
Возврат Неопределено;
КонецПопытки;
Возврат СписокСвойств;
КонецФункции
// Пример использования:
РеквизитМетаданных = Метаданные.Справочники.Номенклатура.Реквизиты.Артикул;
Свойства = ПолучитьСписокСвойствМетаданных(РеквизитМетаданных);
Для Каждого ИмяСвойства Из Свойства Цикл
Сообщить("У реквизита есть свойство: " + ИмяСвойства);
КонецЦикла;
Важное замечание: Этот метод позволяет получить даже те свойства, которые добавлены в новых версиях платформы, так как описание типа XDTO формируется динамически на основе текущего состояния метаданных.
Если по каким-то причинам работа с XDTO неудобна, можно использовать промежуточную выгрузку в XML. Принцип похож: мы записываем объект метаданных в поток XML и анализируем имена тегов.
Посмотрим на пример реализации через ЗаписьXML и ЧтениеXML:
Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку();
СериализаторXDTO.ЗаписатьXML(Запись, ОбъектМетаданных);
ТекстXML = Запись.Закрыть();
// Теперь читаем XML и собираем имена узлов первого уровня
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(ТекстXML);
Пока Чтение.Прочитать() Цикл
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
// Имя тега соответствует имени свойства
Сообщить("Обнаружено свойство: " + Чтение.Имя);
КонецЕсли;
КонецЦикла;
Этот метод позволяет получить текстовый перечень всех установленных свойств. Стоит учитывать, что свойства с пустыми значениями могут не попасть в XML-выгрузку в зависимости от настроек сериализации.
Если у вас уже есть список предполагаемых имен свойств (например, эталонный массив для конкретной версии платформы), вы можете проверять их наличие у конкретного объекта метаданных с помощью метода Свойство(). Это помогает избежать ошибок выполнения при обращении к несуществующим ключам.
Проанализируем ситуацию: у справочника есть свойство Иерархический, а у документа его нет. Чтобы не писать бесконечные проверки Если ЭтоСправочник Тогда, используем универсальный подход:
// Проверяем наличие свойства по имени
ЗначениеСвойства = Неопределено;
Если ОбъектМетаданных.Свойство("Иерархический", ЗначениеСвойства) Тогда
// Если свойство существует, в переменную ЗначениеСвойства запишется его результат
Сообщить("Свойство 'Иерархический' существует и равно: " + ЗначениеСвойства);
КонецЕсли;
При получении свойств через XDTO или XML важно помнить, что значения могут быть не только простыми строками или числами. Выясним, с какими типами придется работать:
Булево (Индексировать), Строка (Подсказка).ИспользованиеОбщегоРеквизита.Тип вернет объект ОписаниеТипов, который сам требует дальнейшего разбора.Для корректного отображения этих данных в интерфейсе вашей обработки рекомендуется использовать функцию Строка(ЗначениеСвойства) или анализировать тип полученного значения через ТипЗнч().
Мы рассмотрели различные подходы к получению свойств метаданных. Подведем итоги:
Свойство().Используя эти инструменты, вы сможете создавать гибкие и универсальные механизмы для работы с конфигурацией 1С "на лету", не тратя время на изучение синтакс-помощника для каждого нового реквизита.