К статье
Практический материал

Разработка и Конфигурация · 10 мин

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

Как в 1С получить имя значения перечисления из ссылки: метод через метаданные, XMLТипЗнч, запросом. Примеры кода, типичные ошибки и ответы на вопросы.

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

Ссылка на значение перечисления — это объект типа «ПеречислениеСсылка», и у него нет прямого свойства «Имя». Однако платформа предоставляет несколько рабочих способов получить имя через метаданные, функции работы с XML и запросы. Каждый способ имеет свою скорость, ограничения и область применения.

Ниже разобраны основные методы с примерами кода, указаны их ограничения, частые ошибки и критерии выбора подходящего варианта для конкретной задачи.

Что такое ссылка на перечисление и почему у неё нет свойства «Имя»

Перечисление в 1С — это прикладной объект, значения которого жестко заданы на этапе конфигурирования. Каждое значение имеет имя (идентификатор, используемый в коде), синоним (пользовательское представление) и внутреннее хранимое значение. Когда в реквизите документа или справочника хранится значение перечисления, фактически там лежит ссылка типа «ПеречислениеСсылка.ИмяПеречисления».

У объекта ссылки доступны стандартные свойства и методы: Пустая(), Метаданные(), ТипЗначения и другие. Но свойства «Имя» среди них нет, потому что имя относится к метаданным конфигурации, а не к данным информационной базы. Поэтому имя приходится извлекать обходным путем — через объект метаданных, индекс значения или механизмы сериализации.

Способ 1: получение имени через метаданные и индекс значения

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

Пример кода функции, возвращающей имя значения перечисления по ссылке:

Функция ИмяЗначенияПеречисления(СсылкаНаЗначение) Экспорт

ИмяПеречисления = СсылкаНаЗначение.Метаданные().Имя;

ИндексЗначения = Перечисления[ИмяПеречисления].Индекс(СсылкаНаЗначение);

Возврат Метаданные.Перечисления[ИмяПеречисления]

.ЗначенияПеречисления[ИндексЗначения].Имя;

КонецФункции

Функция универсальна: она принимает ссылку на любое перечисление конфигурации и возвращает строку с именем значения. Если передана пустая ссылка, метод Индекс() вернет -1, и обращение по индексу вызовет ошибку — поэтому перед вызовом стоит проверять ссылку на пустоту через ЗначениеЗаполнено() или Ссылка.Пустая().

Порядок действий
  1. 1
    Получите имя перечисления: Ссылка.Метаданные().Имя
  2. 2
    Найдите индекс значения: Перечисления[Имя].Индекс(Ссылка)
  3. 3
    Проверьте, что индекс не равен -1 (непустая ссылка)
  4. 4
    По индексу получите объект описания: Метаданные.Перечисления[Имя].ЗначенияПеречисления[Индекс]
  5. 5
    Прочитайте свойство Имя у найденного объекта

Способ 2: быстрый вариант через XMLТипЗнч

Если тип ссылки известен и нужна однострочная конструкция, можно воспользоваться сериализацией значения в XML. Функция XMLТипЗнч() возвращает описание типа, а свойство ИмяТипа содержит строку вида «EnumRef.ВидыОплат». Однако для получения имени самого значения удобнее другой прием — преобразование через ЗначениеВСтрокуВнутр или запись в XML.

Более практичный вариант — использовать сериализатор XDTO или функцию, которая при записи значения перечисления в XML автоматически подставляет его имя. В простом варианте для получения имени значения достаточно следующего кода:

Функция ИмяЗначенияЧерезXML(СсылкаНаЗначение)

Запись = Новый ЗаписьXML;

Запись.УстановитьСтроку();

СериализаторXDTO.ЗаписатьXML(Запись, СсылкаНаЗначение);

СтрокаXML = Запись.Закрыть();

// В СтрокаXML будет имя значения перечисления

Возврат СтрокаXML;

КонецФункции

Этот способ медленнее работы с метаданными и создает лишние объекты, поэтому его применяют там, где значение и так сериализуется — например, при обмене данными или формировании веб-запросов. Для массовой обработки в цикле он не рекомендуется.

Сравнение вариантов

Через метаданные и Индекс()

Быстро, универсально, работает везде. Требует проверки на пустую ссылку.

Через сериализацию XML

Удобно при обменах и интеграциях. Медленнее, избыточно для простых задач.

Через запрос (ПРЕДСТАВЛЕНИЕ)

Возвращает синоним, а не имя. Подходит только для вывода пользователю.

Жесткое сравнение значений

Если значений мало, можно сопоставить ссылки с именами через Если...Иначе. Не масштабируется.

Способ 3: получение представления запросом и его ограничения

Частая попытка новичков — получить имя перечисления запросом с функцией ПРЕДСТАВЛЕНИЕ(). Важно понимать: эта функция возвращает пользовательское представление (синоним), а не имя, заданное в конфигураторе. Если синоним отличается от имени (например, имя «НаличныйРасчет», синоним «Наличный расчет»), результат не подойдет для программной обработки и сравнения с идентификаторами.

Пример запроса, возвращающего представление:

ВЫБРАТЬ

ПРЕДСТАВЛЕНИЕ(РеализацияТоваров.ВидОплаты) КАК ВидОплаты

ИЗ

Документ.РеализацияТоваровУслуг КАК РеализацияТоваров

Запросный подход оправдан, когда нужно вывести данные пользователю в отчете или печатной форме. Для логики обмена, сопоставления с внешними системами и условий в коде используйте способ через метаданные — только он гарантированно возвращает программный идентификатор.

Проверка результата и обработка крайних случаев

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

Обработайте три крайних случая. Первый — пустая ссылка: Перечисления[Имя].Индекс(ПустаяСсылка) вернет -1, и без проверки код упадет с ошибкой. Второй — значение перечисления, удаленное из конфигурации, но оставшееся в данных: индекс может выйти за границы коллекции ЗначенияПеречисления. Третий — переданное значение другого типа: проверяйте тип через ТипЗнч() перед обращением к менеджеру перечисления.

Контрольные точки

Как проверить результат

Сравнение с конфигуратором
Норма

Имя совпадает с именем значения в дереве конфигурации

Тревожный признак

Имя отличается или содержит пробелы — получено представление, а не имя

Пустая ссылка
Норма

Функция возвращает пустую строку или заданное значение по умолчанию

Тревожный признак

Ошибка «Индекс находится за границами массива»

Тип параметра
Норма

Передана ссылка на перечисление, ТипЗнч дает ПеречислениеСсылка.*

Тревожный признак

Передано строковое представление или значение другого типа

Типичные ошибки при получении имени перечисления

Опыт показывает, что большинство проблем при этой задаче связано не с самим методом, а с неверными предположениями о данных. Разберем распространенные ошибки и их последствия.

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

Типичные ошибки
01
Использование ПРЕДСТАВЛЕНИЕ() или Строка(Ссылка) вместо имени — возвращается синоним, логика сравнения ломается при его изменении
02
Отсутствие проверки на пустую ссылку — ошибка «индекс за границами» при Индекс() = -1
03
Вызов функции с метаданными на тонком клиенте — недоступность контекста сервера, ошибка выполнения
04
Сравнение имени с учетом регистра при интеграции с внешней системой — несовпадение значений из-за разного регистра букв
05
Получение имени в цикле через сериализацию XML — заметное замедление при больших объемах данных

Где размещать функцию и как вызывать из разных контекстов

Оптимальное место для универсальной функции получения имени — общий серверный модуль с признаками «Сервер» и «Вызов сервера». Тогда её можно вызывать и из серверного кода, и с клиента. Если модуль не экспортный, функция будет доступна только внутри него.

Пример вызова из кода формы или модуля объекта:

ИмяЗначения = ОбщегоНазначенияСервер.ИмяЗначенияПеречисления(Объект.ВидОплаты);

// Результат: "НаличныйРасчет"

Если конфигурация построена на БСП (Библиотека стандартных подсистем), проверьте наличие готовых функций в общих модулях — в типовых решениях часто уже есть аналогичные механизмы работы с перечислениями, и дублировать их не нужно. Использование штатных функций упрощает обновление конфигурации.

FAQ: частые вопросы

Чем имя перечисления отличается от представления?

Имя — это идентификатор значения, заданный в конфигураторе и используемый в коде (например, «НаличныйРасчет»). Представление (синоним) — строка для пользователя («Наличный расчет»). Функция Строка(Ссылка) и запросная ПРЕДСТАВЛЕНИЕ() возвращают синоним, а имя получают только через метаданные или сериализацию.

Почему возникает ошибка «Индекс находится за границами массива»?

Эта ошибка возникает, когда метод Индекс() вернул -1 — то есть передана пустая ссылка. Перед обращением к коллекции ЗначенияПеречисления проверяйте ссылку через Ссылка.Пустая() или сравнивайте индекс с -1.

Можно ли получить имя перечисления на тонком клиенте?

Напрямую работа с Метаданными на тонком клиенте ограничена. Правильный подход — вынести функцию в общий серверный модуль с признаком «Вызов сервера» и вызывать её с клиента как серверную процедуру.

Как получить имя, если известен тип перечисления заранее?

Код упрощается: не нужно получать имя перечисления через Метаданные().Имя, а сразу пишется Перечисления.ВидыОплат.Индекс(Ссылка) и далее Метаданные.Перечисления.ВидыОплат.ЗначенияПеречисления[Индекс].Имя.

Что быстрее: метаданные или запрос?

Работа через метаданные и Индекс() выполняется в памяти без обращения к СУБД, поэтому быстрее запроса. Запрос оправдан только когда данные и так выбираются из базы и нужно представление для вывода.

Итог

Что важно запомнить

Имя значения перечисления получают через метаданные: Перечисления[Имя].Индекс(Ссылка) дает индекс, по которому из Метаданные.Перечисления[Имя].ЗначенияПеречисления берется свойство Имя. Всегда проверяйте ссылку на пустоту, не путайте имя с представлением и размещайте функцию в серверном общем модуле.