Как получить объект метаданных по имени или представлению в 1С

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

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

Постановка задачи и начальные условия

Рассмотрим ситуацию: на управляемой форме создана обработка, где в реквизит типа СписокЗначений (назовем его СписРегСвед) при открытии формы загружаются все доступные в конфигурации регистры сведений. Логика заполнения выглядит следующим образом:


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

Проблема возникает на следующем этапе: когда пользователь нажимает кнопку «Обработать», нам нужно по выбранному значению из списка (строке с именем) получить доступ к самому объекту метаданных для программной работы с ним.

Метод 1: Прямое обращение к коллекции метаданных

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


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

Этот метод является предпочтительным, так как он работает максимально быстро и требует минимум кода. Важно помнить, что Метаданные.РегистрыСведений — это системная коллекция, доступная на сервере.

Метод 2: Использование функции НайтиПоПолномуИмени

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

Ошибка: Попытка обращения во множественном числе, например, "РегистрыСведений.ИмяРегистра".

Правильное решение: Для поиска объекта через этот метод необходимо указывать тип объекта в единственном числе. Проанализируем правильный синтаксис:


// Правильно: Тип объекта в единственном числе
ПолноеИмя = "РегистрСведений." + ИмяРегистра; 
ОбъектМетаданных = Метаданные.НайтиПоПолномуИмени(ПолноеИмя);

// Примеры для других типов метаданных:
// "Справочник.Номенклатура"
// "Документ.РеализацияТоваровУслуг"
// "РегистрНакопления.Продажи"

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

Различие между Объектом метаданных и Менеджером

Важно не путать объект метаданных и менеджер объекта. Проанализируем ситуацию подробнее:

  1. Объект метаданных (полученный через Метаданные.РегистрыСведений[...]) нужен для того, чтобы узнать структуру: какие у регистра есть измерения, ресурсы, какой у них тип данных или длина строки.
  2. Менеджер объекта нужен для совершения действий: чтения записей, создания наборов записей или вызова экспортных процедур модуля менеджера.

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


ИмяРегистра = "ЦеныНоменклатуры";
// Обращаемся к менеджеру регистра для создания набора записей
Набор = РегистрыСведений[ИмяРегистра].СоздатьНаборЗаписей();

Рекомендации по безопасности и производительности

Рассмотрим несколько важных моментов, которые помогут сделать ваш код более надежным:

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


ОбъектМетаданных = Метаданные.РегистрыСведений.Найти(ИмяРегистра);
Если ОбъектМетаданных = Неопределено Тогда
    Сообщить("Ошибка: Регистр с именем " + ИмяРегистра + " не найден в конфигурации!");
    Возврат;
КонецЕсли;

Оптимизация в циклах: Обращение к объекту Метаданные на сервере — операция относительно «тяжелая». Если вы планируете обрабатывать тысячи строк, лучше один раз получить необходимые свойства объектов в таблицу значений или соответствие (Соответствие), а затем работать уже с этой структурой в оперативной памяти.

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


ИмяРегистра = "ВашРегистр";
ТипКлюча = Тип("РегистрСведенийКлючЗаписи." + ИмяРегистра);

Таким образом, мы выяснили, что для получения объекта метаданных по представлению или имени лучше всего использовать прямой доступ к коллекции Метаданные.РегистрыСведений[Имя], предварительно сохранив именно техническое Имя объекта в СписокЗначений. Это исключает путаницу с синонимами и гарантирует корректную работу кода.

← На главную