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

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

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

Как перебрать все метаданные в 1С: коллекция Метаданные, циклы по справочникам, документам, регистрам, поиск объекта по имени. Готовые примеры кода на встроенном языке.

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

Объект Метаданные представляет собой корень дерева конфигурации. Из него можно обратиться к любой коллекции: Метаданные.Справочники, Метаданные.Документы, Метаданные.РегистрыСведений и так далее. Каждая коллекция поддерживает обход в цикле, поиск по имени и получение элемента по индексу.

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

Базовый перебор коллекции метаданных

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

Для Каждого Спр Из Метаданные.Справочники Цикл

Сообщить(Спр.Имя + " — " + Спр.Синоним);

КонецЦикла;

Тот же подход работает для любой коллекции: Метаданные.Документы, Метаданные.РегистрыНакопления, Метаданные.ПланыСчетов, Метаданные.Отчеты, Метаданные.Обработки. У каждого элемента коллекции доступны стандартные свойства: Имя, Синоним, Комментарий, а также специфичные — например, ДлинаКода и ДлинаНаименования у справочников.

Коллекция также поддерживает методы Количество() и Получить(Индекс), поэтому возможен и классический цикл со счётчиком. На практике «Для Каждого» удобнее и меньше подвержен ошибкам с границами индексов.

bsl
Для Каждого Док Из Метаданные.Документы Цикл
    Сообщить(Док.Имя + " | проведение: " + Док.Проведение);
КонецЦикла;

Поиск объекта метаданных по имени

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

МетаДок = Метаданные.Документы.Найти("РеализацияТоваровУслуг");

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

Сообщить("Документ не найден в конфигурации");

Иначе

Сообщить("Найден: " + МетаДок.Синоним);

КонецЕсли;

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

Перебор реквизитов, табличных частей и движений объекта

Объект метаданных сам содержит вложенные коллекции, которые тоже можно перебирать. Для справочника или документа это Реквизиты, ТабличныеЧасти, СтандартныеРеквизиты. У документа дополнительно есть Движения — список регистров, по которым он проводится.

МетаДок = Метаданные.Документы.Найти("ПриходныйОрдер");

Если МетаДок <> Неопределено Тогда

Для Каждого Реквизит Из МетаДок.Реквизиты Цикл

Сообщить(Реквизит.Имя + " : " + Строка(Реквизит.Тип));

КонецЦикла;

Для Каждого ТЧ Из МетаДок.ТабличныеЧасти Цикл

Сообщить("Табличная часть: " + ТЧ.Имя);

КонецЦикла;

КонецЕсли;

Свойство Тип реквизита возвращает объект ОписаниеТипов. Его можно анализировать дальше: метод Типы() выдаёт массив типов, что полезно при построении универсальных форм выбора или проверке составного типа.

У регистров сведений и накопления вложенные коллекции называются Измерения, Ресурсы и Реквизиты. Путать их нельзя: обращение к Реквизиты у регистра сведений вернёт только необязательные реквизиты, а измерения туда не входят.

Универсальный обход всех видов объектов конфигурации

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

ВидыОбъектов = Новый Массив;

ВидыОбъектов.Добавить("Справочники");

ВидыОбъектов.Добавить("Документы");

ВидыОбъектов.Добавить("РегистрыСведений");

ВидыОбъектов.Добавить("РегистрыНакопления");

Для Каждого Вид Из ВидыОбъектов Цикл

Коллекция = Метаданные[Вид];

Для Каждого Объект Из Коллекция Цикл

Сообщить(Вид + "." + Объект.Имя);

КонецЦикла;

КонецЦикла;

Обращение Метаданные[Вид] через строковый индекс — легальный и широко используемый приём. Он позволяет хранить перечень видов объектов в настройках обработки и не дублировать код под каждый вид.

Порядок построения универсального перебора
  1. 1
    Определите, какие виды объектов нужны: справочники, документы, регистры или всё сразу
  2. 2
    Сформируйте массив имён коллекций верхнего уровня
  3. 3
    Обойдите массив внешним циклом, получая коллекцию через Метаданные[Вид]
  4. 4
    Во внутреннем цикле обработайте каждый объект: имя, синоним, реквизиты
  5. 5
    Проверьте результат на тестовой копии базы: число объектов должно совпадать с конфигуратором

Получение метаданных из объекта данных и обратная задача

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

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

ИмяВида = МетаОбъект.Имя; // "РеализацияТоваровУслуг"

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

Метод ПолноеИмя() возвращает строку вида «Документ.РеализацияТоваровУслуг», которую затем можно использовать в Метаданные.НайтиПоПолномуИмени() или передавать между базами при обмене. Это удобный формат для логирования и универсальных механизмов.

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

Способы найти объект метаданных

Метаданные.Документы.Найти(Имя)

Подходит, когда вид объекта известен заранее. Быстрый поиск внутри одной коллекции.

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

Подходит, когда вид и имя приходят одной строкой, например из настроек обмена. Требует строгого формата «Вид.Имя».

Полный перебор коллекций

Подходит для поиска по части имени или по синониму, когда точное имя неизвестно. Медленнее, но гибче.

Перебор состава подсистем, ролей и прав

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

Для проверки прав текущего пользователя на конкретный объект удобнее функция ПравоДоступа("Чтение", МетаОбъект) — она принимает объект метаданных вторым параметром. Так можно построить список документов, доступных пользователю, пройдясь по коллекции и отфильтровав недоступные.

Типичные ошибки и ограничения

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

Вторая ошибка — сравнение типов через строку. Вместо разбора строки Строка(Реквизит.Тип) надёжнее использовать Реквизит.Тип.СодержитТип(Тип("ДокументСсылка.РеализацияТоваровУслуг")). Строковое представление типа зависит от локализации и формата вывода.

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

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

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

Количество найденных объектов
Норма

Совпадает с числом объектов в дереве конфигуратора

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

Меньше — вероятно, перебрана не та коллекция или объект в подсистеме отфильтрован

Результат Найти()
Норма

Возвращён объект, доступны Имя и Синоним

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

Неопределено — имя указано с ошибкой или объект отсутствует

ПолноеИмя() объекта
Норма

Строка вида «Вид.Имя» без лишних пробелов

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

Пустая строка или ошибка — объект метаданных не получен

Частые вопросы

Можно ли перебрать метаданные на тонком клиенте?

Нет, работа с объектом Метаданные доступна на сервере и в толстом клиенте. В управляемом приложении размещайте такой код в серверных процедурах общих модулей и возвращайте на клиент только готовый результат — например, массив имён или таблицу значений.

Как узнать, к какому виду относится объект метаданных?

Получите полное имя через ПолноеИмя() и возьмите часть до первой точки — это вид объекта. Либо проверяйте принадлежность через Метаданные.Справочники.Содержит(Объект) и аналогичные методы других коллекций.

Как перебрать только объекты, входящие в конкретную подсистему?

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

Почему НайтиПоПолномуИмени возвращает Неопределено?

Чаще всего нарушен формат строки: нужен строго вид «Вид.Имя» без пробелов, с точным регистронезависимым именем объекта. Также проверьте, что объект существует в текущей конфигурации — при обмене между разными конфигурациями имена могут не совпадать.

Можно ли через метаданные получить данные объекта, например записи регистра?

Нет. Метаданные описывают только структуру. Для чтения данных используйте запросы или менеджеры объектов (Справочники.Номенклатура, РегистрыСведений.ЦеныНоменклатуры), которые можно получить динамически по имени из метаданных.

Как перебрать стандартные реквизиты объекта?

У объекта метаданных есть коллекция СтандартныеРеквизиты: для документа это Номер, Дата, Проведен и другие. Обходится она так же, как обычные Реквизиты, в цикле «Для Каждого».

Итог

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

Все метаданные доступны через глобальное свойство Метаданные: коллекции обходятся циклом «Для Каждого», поиск выполняется методами Найти() и НайтиПоПолномуИмени() с обязательной проверкой на Неопределено. Универсальный обход строится через массив имён коллекций и обращение Метаданные[Вид]. Код работы с метаданными выполняйте на сервере и проверяйте результат на копии базы.