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