Разработка и Конфигурация · 10 мин
Как в 1С получить объект метаданных по имени
Как в 1С получить объект метаданных по имени: НайтиПоПолномуИмени, обращение через коллекцию, проверка результата, типичные ошибки и примеры кода.
Объект метаданных в 1С — это описание элемента конфигурации: справочника, документа, регистра, отчёта и так далее. Получить такой объект по имени требуется при универсальных обработках, обменах данными, динамическом построении запросов и формировании отчётов, когда тип объекта заранее неизвестен.
Встроенный язык предоставляет несколько способов: прямое обращение через коллекции свойства Метаданные, поиск методом НайтиПоПолномуИмени() и обратная операция — получение метаданных от уже существующего объекта через Метаданные(). Выбор зависит от того, что известно на входе: короткое имя, полное имя вида «Справочник.Номенклатура» или ссылка на объект базы.
Критически важно помнить: все методы поиска возвращают Неопределено, если объект не найден. Обращение к свойствам такого результата без проверки — самая частая причина ошибок «Поле объекта не обнаружено» в универсальных алгоритмах.
Обращение через коллекции свойства Метаданные
Самый прямой способ — обратиться к нужной коллекции глобального свойства Метаданные и найти объект методом Найти() по короткому имени. Коллекции соответствуют видам объектов: Справочники, Документы, РегистрыСведений, Перечисления, Отчеты, Обработки и другие.
ОбъектМД = Метаданные.Справочники.Найти("Номенклатура");
Если ОбъектМД = Неопределено Тогда
Сообщить("Справочник с таким именем не найден");
Иначе
Сообщить("Представление: " + ОбъектМД.Представление());
КонецЕсли;
Если имя объекта гарантированно существует в конфигурации (например, оно зашито в код и не меняется), допустимо прямое обращение через точку: Метаданные.Документы.РеализацияТоваровУслуг. Но при любом внешнем источнике имени — параметре функции, настройке пользователя, файле обмена — используйте Найти() с проверкой результата.
Универсальный поиск через НайтиПоПолномуИмени
Когда вид объекта заранее неизвестен, используется метод Метаданные.НайтиПоПолномуИмени(). Он принимает строку в формате «Вид.Имя», например «Документ.ПоступлениеТоваров» или «РегистрСведений.КурсыВалют». Это основной инструмент для универсальных обработок, где тип и имя приходят одной строкой — из настроек, XML-файлов или параметров обмена.
Функция ПолучитьМетаданные(ПолноеИмя) Экспорт
ОбъектМД = Метаданные.НайтиПоПолномуИмени(ПолноеИмя);
Если ОбъектМД = Неопределено Тогда
ВызватьИсключение "Метаданные не найдены: " + ПолноеИмя;
КонецЕсли;
Возврат ОбъектМД;
КонецФункции
Метод поддерживает и более глубокие пути: «Справочник.Номенклатура.Реквизит.Артикул» вернёт метаданные конкретного реквизита, а «Справочник.Номенклатура.ТабличнаяЧасть.Товары» — метаданные табличной части. Это удобно для проверки наличия реквизита до обращения к нему в запросе или коде.
Учтите, что полное имя строится по имени вида в единственном числе: «Справочник», «Документ», «РегистрНакопления», а не «Справочники» или «Документы». Ошибка в виде — типичная причина, почему поиск возвращает Неопределено при корректном коротком имени.
Получение метаданных от существующего объекта или ссылки
Обратная задача — узнать метаданные объекта, который уже есть в руках у разработчика. У любой ссылки, объекта данных и даже записи регистра есть метод Метаданные(), возвращающий соответствующий объект описания метаданных.
МД = СсылкаНаДокумент.Метаданные();
Сообщить(МД.Имя); // "РеализацияТоваровУслуг"
Сообщить(МД.ПолноеИмя()); // "Документ.РеализацияТоваровУслуг"
Для значений, у которых метода Метаданные() нет (например, у строки типа), используется Метаданные.НайтиПоТипу(ТипЗнч(Значение)). Этот метод принимает тип и возвращает объект метаданных, которому соответствует данный тип, либо Неопределено для примитивных типов вроде «Строка» или «Число».
Сравнение способов поиска
Подходит, когда вид объекта известен заранее; быстрый и читаемый, но требует отдельной ветки кода для каждого вида
Универсальный вариант для строк вида "Вид.Имя"; единственный способ, когда тип неизвестен на этапе написания кода
Когда объект уже существует; не требует знания имени вообще
Когда известен только тип значения; не работает для примитивных типов
Проверка результата и безопасная работа
Правило без исключений: любой поиск метаданных по строковому имени должен завершаться проверкой на Неопределено. Это особенно важно в коде, который выполняется в разных конфигурациях или после обновлений — объект мог быть переименован или удалён при доработке.
После проверки полезно убедиться, что найденный объект относится к ожидаемому виду. Для этого сравнивают результат МД.ПолноеИмя() с шаблоном или используют функцию вида:
Если Метаданные.Справочники.Содержит(ОбъектМД) Тогда
// работаем как со справочником
КонецЕсли;
Как проверить результат
Объект метаданных, свойства Имя и ПолноеИмя() доступны
Неопределено — имя или вид указаны неверно
Совпадает с шаблоном "Вид.Имя" в единственном числе
Лишние пробелы, множественное число, кириллица в имени вида
Метаданные.Документы.Содержит(ОбъектМД) = Истина
Объект найден, но это другой вид метаданных
Практический сценарий: динамическое построение запроса
Частая задача — сформировать текст запроса по имени объекта, полученному из настроек. Здесь метаданные нужны, чтобы корректно определить имя таблицы и проверить наличие нужных реквизитов до компоновки текста запроса.
- 1Получите полное имя объекта из настройки и очистите его: СокрЛП(ПолноеИмя)
- 2Найдите метаданные: Метаданные.НайтиПоПолномуИмени(ПолноеИмя)
- 3Проверьте результат на Неопределено и при отсутствии объекта выдайте понятное сообщение
- 4Проверьте наличие нужного реквизита: ОбъектМД.Реквизиты.Найти("Организация")
- 5Сформируйте текст запроса, подставив ОбъектМД.ПолноеИмя() как имя таблицы
- 6Выполните запрос и обработайте результат
ОбъектМД = Метаданные.НайтиПоПолномуИмени(ПолноеИмя);
Если ОбъектМД = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ТекстЗапроса = "ВЫБРАТЬ Ссылка ИЗ " + ОбъектМД.ПолноеИмя();
Если ОбъектМД.Реквизиты.Найти("Организация") <> Неопределено Тогда
ТекстЗапроса = ТекстЗапроса + " ГДЕ Организация = &Организация";
КонецЕсли;
Такой подход делает обработку устойчивой к различиям между объектами: запрос к документу без реквизита «Организация» не упадёт с ошибкой, а просто вернёт все записи.
Ограничения и нюансы платформы
Поиск метаданных выполняется быстро и не обращается к базе данных — это работа со структурой конфигурации в памяти. Поэтому такие вызовы можно использовать в циклах без опасений за производительность, хотя кэширование результата в переменной всё равно остаётся хорошей практикой.
На веб-клиенте и тонком клиенте доступ к метаданным есть только в серверном коде: свойство Метаданные недоступно в клиентском контексте. Универсальные функции поиска следует размещать в серверных общих модулях и вызывать с клиента через серверные вызовы.
Ещё один нюанс — объекты, входящие в состав подсистем с префиксом удаления или помеченные на удаление в конфигураторе, физически отсутствуют в метаданных после обновления конфигурации базы данных. Код, ссылавшийся на них по имени, начнёт получать Неопределено — это штатная ситуация, которую проверка результата корректно обрабатывает.
В универсальных обработках удобно один раз построить соответствие "полное имя → объект метаданных" для всех поддерживаемых объектов и дальше работать с ним. Это упрощает отладку: все допустимые имена видны в одном месте, а ошибки ввода отсекаются до выполнения основной логики.
FAQ
Что вернёт НайтиПоПолномуИмени, если объекта нет в конфигурации?
Метод вернёт значение Неопределено без генерации исключения. Исключение возникнет только при синтаксически некорректной строке полного имени. Поэтому проверка результата обязательна в любом сценарии.
Можно ли найти метаданные по синониму объекта?
Штатного метода поиска по синониму нет. Синоним — это представление для пользователя, оно может быть задано на нескольких языках и не является идентификатором. Если нужен поиск по представлению, придётся перебирать коллекцию метаданных в цикле и сравнивать свойство Синоним (или Представление()).
Как получить метаданные реквизита объекта?
Двумя способами: через коллекцию реквизитов найденного объекта — ОбъектМД.Реквизиты.Найти("ИмяРеквизита"), либо сразу по полному пути — Метаданные.НайтиПоПолномуИмени("Справочник.Номенклатура.Реквизит.Артикул"). Оба варианта возвращают Неопределено при отсутствии реквизита.
Работает ли поиск метаданных на тонком клиенте?
Свойство Метаданные доступно только на сервере. В клиентском модуле нужно вызывать серверную функцию из общего модуля с признаками «Сервер» и «Вызов сервера», которая выполнит поиск и вернёт, например, имя и представление объекта простыми типами.
Чем НайтиПоТипу отличается от НайтиПоПолномуИмени?
НайтиПоТипу принимает тип значения (например, Тип("ДокументСсылка.РеализацияТоваровУслуг")) и возвращает метаданные соответствующего объекта. НайтиПоПолномуИмени работает со строкой. Первый метод удобен, когда есть значение неизвестного вида, второй — когда есть только текстовое имя из настроек или файла.
Что важно запомнить
Для известного вида объекта используйте Метаданные.<Вид>.Найти(Имя), для универсального поиска — Метаданные.НайтиПоПолномуИмени("Вид.Имя") с единственным числом в имени вида. Любой результат проверяйте на Неопределено, а строки из внешних источников очищайте и валидируйте до подстановки в запросы.