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

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

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

Как в 1С получить объект метаданных по имени: НайтиПоПолномуИмени, обращение через коллекцию, проверка результата, типичные ошибки и примеры кода.

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

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

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

Обращение через коллекции свойства Метаданные

Самый прямой способ — обратиться к нужной коллекции глобального свойства Метаданные и найти объект методом Найти() по короткому имени. Коллекции соответствуют видам объектов: Справочники, Документы, РегистрыСведений, Перечисления, Отчеты, Обработки и другие.

ОбъектМД = Метаданные.Справочники.Найти("Номенклатура");

Если ОбъектМД = Неопределено Тогда

Сообщить("Справочник с таким именем не найден");

Иначе

Сообщить("Представление: " + ОбъектМД.Представление());

КонецЕсли;

Если имя объекта гарантированно существует в конфигурации (например, оно зашито в код и не меняется), допустимо прямое обращение через точку: Метаданные.Документы.РеализацияТоваровУслуг. Но при любом внешнем источнике имени — параметре функции, настройке пользователя, файле обмена — используйте Найти() с проверкой результата.

Универсальный поиск через НайтиПоПолномуИмени

Когда вид объекта заранее неизвестен, используется метод Метаданные.НайтиПоПолномуИмени(). Он принимает строку в формате «Вид.Имя», например «Документ.ПоступлениеТоваров» или «РегистрСведений.КурсыВалют». Это основной инструмент для универсальных обработок, где тип и имя приходят одной строкой — из настроек, XML-файлов или параметров обмена.

Функция ПолучитьМетаданные(ПолноеИмя) Экспорт

ОбъектМД = Метаданные.НайтиПоПолномуИмени(ПолноеИмя);

Если ОбъектМД = Неопределено Тогда

ВызватьИсключение "Метаданные не найдены: " + ПолноеИмя;

КонецЕсли;

Возврат ОбъектМД;

КонецФункции

Метод поддерживает и более глубокие пути: «Справочник.Номенклатура.Реквизит.Артикул» вернёт метаданные конкретного реквизита, а «Справочник.Номенклатура.ТабличнаяЧасть.Товары» — метаданные табличной части. Это удобно для проверки наличия реквизита до обращения к нему в запросе или коде.

Учтите, что полное имя строится по имени вида в единственном числе: «Справочник», «Документ», «РегистрНакопления», а не «Справочники» или «Документы». Ошибка в виде — типичная причина, почему поиск возвращает Неопределено при корректном коротком имени.

Типичные ошибки
01
Использование множественного числа в полном имени: "Справочники.Номенклатура" вместо "Справочник.Номенклатура" — поиск вернёт Неопределено
02
Обращение к свойствам результата без проверки на Неопределено — ошибка выполнения при отсутствии объекта
03
Поиск по синониму вместо имени: синоним может быть на любом языке и не подходит для идентификации
04
Игнорирование лишних пробелов в строке имени, полученной из внешнего источника

Получение метаданных от существующего объекта или ссылки

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

МД = СсылкаНаДокумент.Метаданные();

Сообщить(МД.Имя); // "РеализацияТоваровУслуг"

Сообщить(МД.ПолноеИмя()); // "Документ.РеализацияТоваровУслуг"

Для значений, у которых метода Метаданные() нет (например, у строки типа), используется Метаданные.НайтиПоТипу(ТипЗнч(Значение)). Этот метод принимает тип и возвращает объект метаданных, которому соответствует данный тип, либо Неопределено для примитивных типов вроде «Строка» или «Число».

Сравнение способов поиска

Метаданные.Справочники.Найти()

Подходит, когда вид объекта известен заранее; быстрый и читаемый, но требует отдельной ветки кода для каждого вида

Метаданные.НайтиПоПолномуИмени()

Универсальный вариант для строк вида "Вид.Имя"; единственный способ, когда тип неизвестен на этапе написания кода

Ссылка.Метаданные()

Когда объект уже существует; не требует знания имени вообще

Метаданные.НайтиПоТипу()

Когда известен только тип значения; не работает для примитивных типов

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

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

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

Если Метаданные.Справочники.Содержит(ОбъектМД) Тогда

// работаем как со справочником

КонецЕсли;

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

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

Результат поиска
Норма

Объект метаданных, свойства Имя и ПолноеИмя() доступны

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

Неопределено — имя или вид указаны неверно

Полное имя
Норма

Совпадает с шаблоном "Вид.Имя" в единственном числе

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

Лишние пробелы, множественное число, кириллица в имени вида

Принадлежность к виду
Норма

Метаданные.Документы.Содержит(ОбъектМД) = Истина

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

Объект найден, но это другой вид метаданных

Практический сценарий: динамическое построение запроса

Частая задача — сформировать текст запроса по имени объекта, полученному из настроек. Здесь метаданные нужны, чтобы корректно определить имя таблицы и проверить наличие нужных реквизитов до компоновки текста запроса.

Порядок действий
  1. 1
    Получите полное имя объекта из настройки и очистите его: СокрЛП(ПолноеИмя)
  2. 2
    Найдите метаданные: Метаданные.НайтиПоПолномуИмени(ПолноеИмя)
  3. 3
    Проверьте результат на Неопределено и при отсутствии объекта выдайте понятное сообщение
  4. 4
    Проверьте наличие нужного реквизита: ОбъектМД.Реквизиты.Найти("Организация")
  5. 5
    Сформируйте текст запроса, подставив ОбъектМД.ПолноеИмя() как имя таблицы
  6. 6
    Выполните запрос и обработайте результат
ОбъектМД = Метаданные.НайтиПоПолномуИмени(ПолноеИмя);

Если ОбъектМД = Неопределено Тогда

Возврат Неопределено;

КонецЕсли;

ТекстЗапроса = "ВЫБРАТЬ Ссылка ИЗ " + ОбъектМД.ПолноеИмя();

Если ОбъектМД.Реквизиты.Найти("Организация") <> Неопределено Тогда

ТекстЗапроса = ТекстЗапроса + " ГДЕ Организация = &Организация";

КонецЕсли;

Такой подход делает обработку устойчивой к различиям между объектами: запрос к документу без реквизита «Организация» не упадёт с ошибкой, а просто вернёт все записи.

Ограничения и нюансы платформы

Поиск метаданных выполняется быстро и не обращается к базе данных — это работа со структурой конфигурации в памяти. Поэтому такие вызовы можно использовать в циклах без опасений за производительность, хотя кэширование результата в переменной всё равно остаётся хорошей практикой.

На веб-клиенте и тонком клиенте доступ к метаданным есть только в серверном коде: свойство Метаданные недоступно в клиентском контексте. Универсальные функции поиска следует размещать в серверных общих модулях и вызывать с клиента через серверные вызовы.

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

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

FAQ

Что вернёт НайтиПоПолномуИмени, если объекта нет в конфигурации?

Метод вернёт значение Неопределено без генерации исключения. Исключение возникнет только при синтаксически некорректной строке полного имени. Поэтому проверка результата обязательна в любом сценарии.

Можно ли найти метаданные по синониму объекта?

Штатного метода поиска по синониму нет. Синоним — это представление для пользователя, оно может быть задано на нескольких языках и не является идентификатором. Если нужен поиск по представлению, придётся перебирать коллекцию метаданных в цикле и сравнивать свойство Синоним (или Представление()).

Как получить метаданные реквизита объекта?

Двумя способами: через коллекцию реквизитов найденного объекта — ОбъектМД.Реквизиты.Найти("ИмяРеквизита"), либо сразу по полному пути — Метаданные.НайтиПоПолномуИмени("Справочник.Номенклатура.Реквизит.Артикул"). Оба варианта возвращают Неопределено при отсутствии реквизита.

Работает ли поиск метаданных на тонком клиенте?

Свойство Метаданные доступно только на сервере. В клиентском модуле нужно вызывать серверную функцию из общего модуля с признаками «Сервер» и «Вызов сервера», которая выполнит поиск и вернёт, например, имя и представление объекта простыми типами.

Чем НайтиПоТипу отличается от НайтиПоПолномуИмени?

НайтиПоТипу принимает тип значения (например, Тип("ДокументСсылка.РеализацияТоваровУслуг")) и возвращает метаданные соответствующего объекта. НайтиПоПолномуИмени работает со строкой. Первый метод удобен, когда есть значение неизвестного вида, второй — когда есть только текстовое имя из настроек или файла.

Итог

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

Для известного вида объекта используйте Метаданные.<Вид>.Найти(Имя), для универсального поиска — Метаданные.НайтиПоПолномуИмени("Вид.Имя") с единственным числом в имени вида. Любой результат проверяйте на Неопределено, а строки из внешних источников очищайте и валидируйте до подстановки в запросы.