При разработке в среде 1С:Предприятие часто возникает задача программного получения имени элемента перечисления (его идентификатора), заданного в конфигураторе. Важно не путать это с синонимом, который предназначен для отображения пользователю и может меняться. Программное имя используется для жестких привязок в коде, при интеграциях или в сложных запросах. Рассмотрим несколько эффективных способов решения этой задачи, разберем их плюсы, минусы и особенности работы на клиенте и сервере.
Когда мы работаем с перечислением в цикле Для каждого, мы получаем ссылку на элемент перечисления. Попытка вызвать метод Метаданные().Имя непосредственно у переменной цикла приведет к тому, что система вернет имя самого объекта метаданных (самого перечисления), а не конкретного выбранного значения. Это происходит потому, что метод Метаданные() для ссылочного типа возвращает объект описания типа всего перечисления в целом. Нам же нужно «спуститься» на уровень ниже — к конкретному значению.
Разберем самый быстрый и лаконичный способ, который часто называют «лайфхаком». Функция XMLСтрока() предназначена для сериализации данных в формат XML. Согласно внутренним механизмам платформы, при преобразовании ссылки перечисления в строку XML, 1С записывает именно его имя (идентификатор), а не синоним.
Проанализируем пример кода:
Для каждого ЭлтПеречисления Из Перечисления.СтавкиНДС Цикл
ИмяЭлемента = XMLСтрока(ЭлтПеречисления);
Сообщить("Имя элемента: " + ИмяЭлемента);
КонецЦикла;
Преимущества метода:
Если нам необходимо получить имя элемента, работая напрямую со структурой конфигурации, или если мы уже перебираем коллекцию значений метаданных, можно воспользоваться обращением по индексу. Каждое значение перечисления имеет свой порядковый номер (индекс), который совпадает в коллекции ссылок и в коллекции метаданных.
Рассмотрим, как это реализовать по шагам:
// Получаем коллекцию метаданных значений конкретного перечисления
ЗначенияМетаданных = Метаданные.Перечисления.DX_ЧеклистПроверки.ЗначенияПеречисления;
// Перебираем элементы через цикл по количеству
Для к = 0 По Перечисления.DX_ЧеклистПроверки.Количество() - 1 Цикл
// Получаем ссылку на элемент для каких-то действий
СсылкаНаЭлемент = Перечисления.DX_ЧеклистПроверки[к];
// Получаем имя этого элемента из метаданных по тому же индексу
ИмяЭлемента = ЗначенияМетаданных.Получить(к).Имя;
Сообщить("Элемент: " + СсылкаНаЭлемент + " имеет имя: " + ИмяЭлемента);
КонецЦикла;
Этот метод считается более «прозрачным» с точки зрения архитектуры метаданных 1С, так как он не полагается на побочные эффекты сериализации XML.
Выясним, как получить имя, если у нас есть только ссылка на элемент и мы находимся на стороне сервера. Платформа предоставляет универсальный метод Метаданные.НайтиПоОбъекту(), который работает для большинства ссылочных типов, включая перечисления.
Посмотрим на пример функции:
&НаСервере
Функция ПолучитьИмяЗначенияПеречисления(СсылкаНаЭлемент)
// Находим объект метаданных конкретного значения
ОбъектМетаданных = Метаданные.НайтиПоОбъекту(СсылкаНаЭлемент);
// Возвращаем программное имя
Возврат ОбъектМетаданных.Имя;
КонецФункции
Важное замечание: данный метод работает исключительно на стороне сервера. При вызове его в цикле по большому количеству элементов может наблюдаться снижение производительности, так как поиск по дереву метаданных — операция ресурсоемкая.
Если у вас есть ссылка на элемент, и вы хотите получить его имя через метаданные, не используя поиск по объекту, можно вычислить индекс ссылки внутри её типа. Это более надежный способ получения имени через метаданные, если вы уже находитесь в контексте конкретного перечисления.
Проанализируем ситуацию:
СсылкаНаЭлемент = Перечисления.СостоянияЗаказов.Выполнен;
// 1. Получаем индекс элемента в перечислении
ПорядковыйИндекс = Перечисления.СостоянияЗаказов.Индекс(СсылкаНаЭлемент);
// 2. Обращаемся к метаданным по этому индексу
ИмяЭлемента = Метаданные.Перечисления.СостоянияЗаказов.ЗначенияПеречисления[ПорядковыйИндекс].Имя;
Выбор метода зависит от контекста выполнения кода и требований к производительности:
XMLСтрока(). Это единственный способ получить имя без серверного вызова и лишних задержек.Метаданные.НайтиПоОбъекту(). Это чисто и понятно другим разработчикам.XMLСтрока(), либо предварительная выгрузка имен во временную таблицу или структуру (Соответствие), где ключом будет ссылка, а значением — имя.Помните: Никогда не используйте функцию Строка(ЭлементПеречисления) для получения программного имени. Она возвращает синоним, и если бухгалтер решит переименовать «НДС 20%» в «Основная ставка НДС» в конфигураторе через синоним, ваш код, завязанный на строковое представление, перестанет работать.
Таким образом, мы разобрали все основные способы получения идентификатора элемента. Наиболее универсальным и рекомендуемым для большинства задач остается метод XMLСтрока() благодаря своей скорости и доступности на всех слоях приложения.