Как программно получить список реквизитов объекта или формы в 1С 8.3

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Разграничение понятий: Реквизиты объекта vs Реквизиты формы

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

Рассмотрим по шагам основные способы получения этой информации.

Способ 1. Получение реквизитов объекта через Метаданные (Сервер)

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

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


// Функция возвращает список имен реквизитов конкретного справочника
&НаСервере
Функция ПолучитьСписокРеквизитовМетаданных(ИмяСправочника)
    Список = Новый СписокЗначений;
    
    // Получаем объект метаданных
    ОбъектМетаданных = Метаданные.Справочники[ИмяСправочника];
    
    // Перебираем коллекцию Реквизиты
    Для Каждого ТекРеквизит Из ОбъектМетаданных.Реквизиты Цикл
        Список.Добавить(ТекРеквизит.Имя, ТекРеквизит.Синоним);
    КонецЦикла;
    
    Возврат Список;
КонецФункции

Важно помнить, что у объектов 1С, помимо созданных нами реквизитов, есть так называемые Стандартные реквизиты (Код, Наименование, Ссылка, ПометкаУдаления и т.д.). Проводя анализ структуры метаданных, если вы хотите получить абсолютно все поля, их нужно обходить отдельно:


Для Каждого СтандартныйРеквизит Из ОбъектМетаданных.СтандартныеРеквизиты Цикл
    Список.Добавить(СтандартныйРеквизит.Имя);
КонецЦикла;

Способ 2. Использование метода ПолучитьРеквизиты() управляемой формы

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

Разберем, как отфильтровать только те поля, которые относятся к основному объекту формы:


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

Каждый элемент массива содержит полезные свойства: Имя, ТипЗначения, Путь. Это позволяет не только получить список имен, но и понять, какие данные в них хранятся.

Способ 3. Преобразование данных формы в значение (Тяжелый метод)

Иногда разработчики используют конструкцию РеквизитФормыВЗначение("Объект"). Это переносит данные из структуры формы в полноценный прикладной объект на сервере. После этого можно обратиться к методу Метаданные() этого объекта.

Рассмотрим пример:


&НаСервере
Процедура ПолучитьЧерезПреобразование()
    // Конвертируем данные формы в объект справочника/документа
    ОбъектБД = РеквизитФормыВЗначение("Объект");
    
    // Получаем метаданные
    Для Каждого Реквизит Из ОбъектБД.Метаданные().Реквизиты Цикл
        // Работаем с реквизитами
    КонецЦикла;
КонецПроцедуры

Внимание: Этот метод считается ресурсоемким. Платформа вынуждена создавать в памяти сервера тяжелый объект, инициализировать его и заполнять данными. Проанализируем ситуацию: если вам нужно просто получить имена полей, лучше использовать Метаданные.НайтиПоТипу(ТипЗнч(Объект)), что работает значительно быстрее.

Способ 4. Работа с табличными частями

Часто под «списком реквизитов» подразумевают вообще весь состав данных. Однако Табличные части не входят в коллекцию Реквизиты. Если ваша задача — получить полную структуру данных, необходимо отдельно обходить коллекцию табличных частей и реквизиты каждой из них.

Выясним, как это реализовать:


// Обход табличных частей на сервере
Для Каждого ТЧ Из ОбъектМетаданных.ТабличныеЧасти Цикл
    Сообщить("Табличная часть: " + ТЧ.Имя);
    Для Каждого РеквизитТЧ Из ТЧ.Реквизиты Цикл
        Сообщить(" - Реквизит ТЧ: " + РеквизитТЧ.Имя);
    КонецЦикла;
КонецЦикла;

Способ 5. Оптимизация и использование БСП

Если в вашей конфигурации установлена Библиотека Стандартных Подсистем (БСП), задача упрощается. В общем модуле ОбщегоНазначения существуют функции, позволяющие получить структуру реквизитов объекта по ссылке или типу без лишних циклов.

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

Нюансы работы с ДанныеФормыСтруктура на клиенте

На клиенте объект Объект (тип ДанныеФормыСтруктура) ведет себя не как обычная структура. Вы не можете выполнить цикл Для Каждого по нему, чтобы получить ключи. Если вам критично получить список доступных полей на клиенте без серверного вызова, существует «хитрый» способ через сериализацию:

  1. Преобразовать Объект в XDTO или JSON.
  2. Распарсить полученную строку, чтобы извлечь имена свойств.

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

Резюме

Подведем итоги нашего анализа:

Используя эти подходы, мы можем создавать гибкие и универсальные алгоритмы, которые будут корректно работать в любых прикладных решениях на базе 1С.

← На главную