Разработка и Конфигурация · 10 мин
Как в 1С получить имя перечисления из ссылки
Как в 1С получить имя значения перечисления из ссылки: метод через метаданные, XMLТипЗнч, запросом. Примеры кода, типичные ошибки и ответы на вопросы.
При разработке на платформе 1С часто возникает задача: по ссылке на значение перечисления получить его имя так, как оно задано в конфигураторе (например, «НаличныйРасчет» вместо представления «Наличный расчет»). Это нужно для обменов данными, сериализации, логирования, сравнения значений в коде и формирования внешних файлов, где требуется именно программный идентификатор, а не пользовательское представление.
Ссылка на значение перечисления — это объект типа «ПеречислениеСсылка», и у него нет прямого свойства «Имя». Однако платформа предоставляет несколько рабочих способов получить имя через метаданные, функции работы с XML и запросы. Каждый способ имеет свою скорость, ограничения и область применения.
Ниже разобраны основные методы с примерами кода, указаны их ограничения, частые ошибки и критерии выбора подходящего варианта для конкретной задачи.
Что такое ссылка на перечисление и почему у неё нет свойства «Имя»
Перечисление в 1С — это прикладной объект, значения которого жестко заданы на этапе конфигурирования. Каждое значение имеет имя (идентификатор, используемый в коде), синоним (пользовательское представление) и внутреннее хранимое значение. Когда в реквизите документа или справочника хранится значение перечисления, фактически там лежит ссылка типа «ПеречислениеСсылка.ИмяПеречисления».
У объекта ссылки доступны стандартные свойства и методы: Пустая(), Метаданные(), ТипЗначения и другие. Но свойства «Имя» среди них нет, потому что имя относится к метаданным конфигурации, а не к данным информационной базы. Поэтому имя приходится извлекать обходным путем — через объект метаданных, индекс значения или механизмы сериализации.
Способ 1: получение имени через метаданные и индекс значения
Классический и наиболее корректный способ — определить индекс значения перечисления через менеджер перечисления, а затем по индексу найти объект описания в метаданных и прочитать его имя. Этот метод работает на сервере и на толстом клиенте, не требует запросов к базе и выполняется быстро.
Пример кода функции, возвращающей имя значения перечисления по ссылке:
Функция ИмяЗначенияПеречисления(СсылкаНаЗначение) Экспорт
ИмяПеречисления = СсылкаНаЗначение.Метаданные().Имя;
ИндексЗначения = Перечисления[ИмяПеречисления].Индекс(СсылкаНаЗначение);
Возврат Метаданные.Перечисления[ИмяПеречисления]
.ЗначенияПеречисления[ИндексЗначения].Имя;
КонецФункции
Функция универсальна: она принимает ссылку на любое перечисление конфигурации и возвращает строку с именем значения. Если передана пустая ссылка, метод Индекс() вернет -1, и обращение по индексу вызовет ошибку — поэтому перед вызовом стоит проверять ссылку на пустоту через ЗначениеЗаполнено() или Ссылка.Пустая().
- 1Получите имя перечисления: Ссылка.Метаданные().Имя
- 2Найдите индекс значения: Перечисления[Имя].Индекс(Ссылка)
- 3Проверьте, что индекс не равен -1 (непустая ссылка)
- 4По индексу получите объект описания: Метаданные.Перечисления[Имя].ЗначенияПеречисления[Индекс]
- 5Прочитайте свойство Имя у найденного объекта
Способ 2: быстрый вариант через XMLТипЗнч
Если тип ссылки известен и нужна однострочная конструкция, можно воспользоваться сериализацией значения в XML. Функция XMLТипЗнч() возвращает описание типа, а свойство ИмяТипа содержит строку вида «EnumRef.ВидыОплат». Однако для получения имени самого значения удобнее другой прием — преобразование через ЗначениеВСтрокуВнутр или запись в XML.
Более практичный вариант — использовать сериализатор XDTO или функцию, которая при записи значения перечисления в XML автоматически подставляет его имя. В простом варианте для получения имени значения достаточно следующего кода:
Функция ИмяЗначенияЧерезXML(СсылкаНаЗначение)
Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку();
СериализаторXDTO.ЗаписатьXML(Запись, СсылкаНаЗначение);
СтрокаXML = Запись.Закрыть();
// В СтрокаXML будет имя значения перечисления
Возврат СтрокаXML;
КонецФункции
Этот способ медленнее работы с метаданными и создает лишние объекты, поэтому его применяют там, где значение и так сериализуется — например, при обмене данными или формировании веб-запросов. Для массовой обработки в цикле он не рекомендуется.
Сравнение вариантов
Быстро, универсально, работает везде. Требует проверки на пустую ссылку.
Удобно при обменах и интеграциях. Медленнее, избыточно для простых задач.
Возвращает синоним, а не имя. Подходит только для вывода пользователю.
Если значений мало, можно сопоставить ссылки с именами через Если...Иначе. Не масштабируется.
Способ 3: получение представления запросом и его ограничения
Частая попытка новичков — получить имя перечисления запросом с функцией ПРЕДСТАВЛЕНИЕ(). Важно понимать: эта функция возвращает пользовательское представление (синоним), а не имя, заданное в конфигураторе. Если синоним отличается от имени (например, имя «НаличныйРасчет», синоним «Наличный расчет»), результат не подойдет для программной обработки и сравнения с идентификаторами.
Пример запроса, возвращающего представление:
ВЫБРАТЬ
ПРЕДСТАВЛЕНИЕ(РеализацияТоваров.ВидОплаты) КАК ВидОплаты
ИЗ
Документ.РеализацияТоваровУслуг КАК РеализацияТоваров
Запросный подход оправдан, когда нужно вывести данные пользователю в отчете или печатной форме. Для логики обмена, сопоставления с внешними системами и условий в коде используйте способ через метаданные — только он гарантированно возвращает программный идентификатор.
Проверка результата и обработка крайних случаев
После получения имени стоит убедиться, что результат соответствует ожиданиям. Простейшая проверка — вывести имя в сообщение или журнал и сравнить с тем, что видно в конфигураторе в свойствах значения перечисления. Имя должно совпадать посимвольно, включая регистр (хотя встроенный язык нечувствителен к регистру, внешние системы могут быть чувствительны).
Обработайте три крайних случая. Первый — пустая ссылка: Перечисления[Имя].Индекс(ПустаяСсылка) вернет -1, и без проверки код упадет с ошибкой. Второй — значение перечисления, удаленное из конфигурации, но оставшееся в данных: индекс может выйти за границы коллекции ЗначенияПеречисления. Третий — переданное значение другого типа: проверяйте тип через ТипЗнч() перед обращением к менеджеру перечисления.
Как проверить результат
Имя совпадает с именем значения в дереве конфигурации
Имя отличается или содержит пробелы — получено представление, а не имя
Функция возвращает пустую строку или заданное значение по умолчанию
Ошибка «Индекс находится за границами массива»
Передана ссылка на перечисление, ТипЗнч дает ПеречислениеСсылка.*
Передано строковое представление или значение другого типа
Типичные ошибки при получении имени перечисления
Опыт показывает, что большинство проблем при этой задаче связано не с самим методом, а с неверными предположениями о данных. Разберем распространенные ошибки и их последствия.
Первая группа ошибок — путаница между именем, синонимом и представлением. Вторая — отсутствие защиты от некорректных входных данных. Третья — попытка получить имя на тонком клиенте там, где доступ к метаданным ограничен: обращение к Метаданные на клиенте в управляемом приложении возможно не везде, поэтому такие функции размещают в серверных общих модулях.
Где размещать функцию и как вызывать из разных контекстов
Оптимальное место для универсальной функции получения имени — общий серверный модуль с признаками «Сервер» и «Вызов сервера». Тогда её можно вызывать и из серверного кода, и с клиента. Если модуль не экспортный, функция будет доступна только внутри него.
Пример вызова из кода формы или модуля объекта:
ИмяЗначения = ОбщегоНазначенияСервер.ИмяЗначенияПеречисления(Объект.ВидОплаты);
// Результат: "НаличныйРасчет"
Если конфигурация построена на БСП (Библиотека стандартных подсистем), проверьте наличие готовых функций в общих модулях — в типовых решениях часто уже есть аналогичные механизмы работы с перечислениями, и дублировать их не нужно. Использование штатных функций упрощает обновление конфигурации.
FAQ: частые вопросы
Чем имя перечисления отличается от представления?
Имя — это идентификатор значения, заданный в конфигураторе и используемый в коде (например, «НаличныйРасчет»). Представление (синоним) — строка для пользователя («Наличный расчет»). Функция Строка(Ссылка) и запросная ПРЕДСТАВЛЕНИЕ() возвращают синоним, а имя получают только через метаданные или сериализацию.
Почему возникает ошибка «Индекс находится за границами массива»?
Эта ошибка возникает, когда метод Индекс() вернул -1 — то есть передана пустая ссылка. Перед обращением к коллекции ЗначенияПеречисления проверяйте ссылку через Ссылка.Пустая() или сравнивайте индекс с -1.
Можно ли получить имя перечисления на тонком клиенте?
Напрямую работа с Метаданными на тонком клиенте ограничена. Правильный подход — вынести функцию в общий серверный модуль с признаком «Вызов сервера» и вызывать её с клиента как серверную процедуру.
Как получить имя, если известен тип перечисления заранее?
Код упрощается: не нужно получать имя перечисления через Метаданные().Имя, а сразу пишется Перечисления.ВидыОплат.Индекс(Ссылка) и далее Метаданные.Перечисления.ВидыОплат.ЗначенияПеречисления[Индекс].Имя.
Что быстрее: метаданные или запрос?
Работа через метаданные и Индекс() выполняется в памяти без обращения к СУБД, поэтому быстрее запроса. Запрос оправдан только когда данные и так выбираются из базы и нужно представление для вывода.
Что важно запомнить
Имя значения перечисления получают через метаданные: Перечисления[Имя].Индекс(Ссылка) дает индекс, по которому из Метаданные.Перечисления[Имя].ЗначенияПеречисления берется свойство Имя. Всегда проверяйте ссылку на пустоту, не путайте имя с представлением и размещайте функцию в серверном общем модуле.