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