Как получить программное имя элемента перечисления в 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке в среде 1С:Предприятие часто возникает задача программного получения имени элемента перечисления (его идентификатора), заданного в конфигураторе. Важно не путать это с синонимом, который предназначен для отображения пользователю и может меняться. Программное имя используется для жестких привязок в коде, при интеграциях или в сложных запросах. Рассмотрим несколько эффективных способов решения этой задачи, разберем их плюсы, минусы и особенности работы на клиенте и сервере.

Проблема использования стандартных методов

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

Способ 1. Использование функции XMLСтрока

Разберем самый быстрый и лаконичный способ, который часто называют «лайфхаком». Функция XMLСтрока() предназначена для сериализации данных в формат XML. Согласно внутренним механизмам платформы, при преобразовании ссылки перечисления в строку XML, 1С записывает именно его имя (идентификатор), а не синоним.

Проанализируем пример кода:


Для каждого ЭлтПеречисления Из Перечисления.СтавкиНДС Цикл
    ИмяЭлемента = XMLСтрока(ЭлтПеречисления);
    Сообщить("Имя элемента: " + ИмяЭлемента);
КонецЦикла;

Преимущества метода:

  1. Высокая скорость работы: это простое преобразование типа, которое не требует обращения к тяжелому дереву метаданных.
  2. Работа на клиенте: метод доступен в тонком и толстом клиенте без необходимости вызова серверного контекста, что критически важно для производительности интерфейса.
  3. Лаконичность: всего одна функция решает задачу.

Способ 2. Обращение к метаданным по индексу

Если нам необходимо получить имя элемента, работая напрямую со структурой конфигурации, или если мы уже перебираем коллекцию значений метаданных, можно воспользоваться обращением по индексу. Каждое значение перечисления имеет свой порядковый номер (индекс), который совпадает в коллекции ссылок и в коллекции метаданных.

Рассмотрим, как это реализовать по шагам:


// Получаем коллекцию метаданных значений конкретного перечисления
ЗначенияМетаданных = Метаданные.Перечисления.DX_ЧеклистПроверки.ЗначенияПеречисления;

// Перебираем элементы через цикл по количеству
Для к = 0 По Перечисления.DX_ЧеклистПроверки.Количество() - 1 Цикл
    // Получаем ссылку на элемент для каких-то действий
    СсылкаНаЭлемент = Перечисления.DX_ЧеклистПроверки[к];
    
    // Получаем имя этого элемента из метаданных по тому же индексу
    ИмяЭлемента = ЗначенияМетаданных.Получить(к).Имя;
    
    Сообщить("Элемент: " + СсылкаНаЭлемент + " имеет имя: " + ИмяЭлемента);
КонецЦикла;

Этот метод считается более «прозрачным» с точки зрения архитектуры метаданных 1С, так как он не полагается на побочные эффекты сериализации XML.

Способ 3. Метод Метаданные.НайтиПоОбъекту()

Выясним, как получить имя, если у нас есть только ссылка на элемент и мы находимся на стороне сервера. Платформа предоставляет универсальный метод Метаданные.НайтиПоОбъекту(), который работает для большинства ссылочных типов, включая перечисления.

Посмотрим на пример функции:


&НаСервере
Функция ПолучитьИмяЗначенияПеречисления(СсылкаНаЭлемент)
    // Находим объект метаданных конкретного значения
    ОбъектМетаданных = Метаданные.НайтиПоОбъекту(СсылкаНаЭлемент);
    
    // Возвращаем программное имя
    Возврат ОбъектМетаданных.Имя;
КонецФункции

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

Способ 4. Использование метода Индекс() для ссылки

Если у вас есть ссылка на элемент, и вы хотите получить его имя через метаданные, не используя поиск по объекту, можно вычислить индекс ссылки внутри её типа. Это более надежный способ получения имени через метаданные, если вы уже находитесь в контексте конкретного перечисления.

Проанализируем ситуацию:


СсылкаНаЭлемент = Перечисления.СостоянияЗаказов.Выполнен;

// 1. Получаем индекс элемента в перечислении
ПорядковыйИндекс = Перечисления.СостоянияЗаказов.Индекс(СсылкаНаЭлемент);

// 2. Обращаемся к метаданным по этому индексу
ИмяЭлемента = Метаданные.Перечисления.СостоянияЗаказов.ЗначенияПеречисления[ПорядковыйИндекс].Имя;

Сравнение методов и рекомендации

Выбор метода зависит от контекста выполнения кода и требований к производительности:

  1. Для клиентского кода: Используйте только XMLСтрока(). Это единственный способ получить имя без серверного вызова и лишних задержек.
  2. Для разовых операций на сервере: Подойдет Метаданные.НайтиПоОбъекту(). Это чисто и понятно другим разработчикам.
  3. Для массовой обработки данных в циклах: Рекомендуется либо XMLСтрока(), либо предварительная выгрузка имен во временную таблицу или структуру (Соответствие), где ключом будет ссылка, а значением — имя.

Помните: Никогда не используйте функцию Строка(ЭлементПеречисления) для получения программного имени. Она возвращает синоним, и если бухгалтер решит переименовать «НДС 20%» в «Основная ставка НДС» в конфигураторе через синоним, ваш код, завязанный на строковое представление, перестанет работать.

Таким образом, мы разобрали все основные способы получения идентификатора элемента. Наиболее универсальным и рекомендуемым для большинства задач остается метод XMLСтрока() благодаря своей скорости и доступности на всех слоях приложения.

← На главную