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