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

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

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

Как получить значение перечисления в 1С: обращение через менеджер, перебор значений, получение по имени и индексу, работа с перечислениями в запросах и на форме.

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

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

Материал ориентирован на разработчиков и внедренцев, работающих с конфигурациями на платформе 1С:Предприятие 8.3. Примеры кода универсальны и подходят как для типовых, так и для самописных конфигураций.

Что такое перечисление и где оно хранится

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

В базе данных значение перечисления хранится как порядковый номер (индекс) значения в списке. Это важно понимать при обменах между разными конфигурациями: если порядок значений в двух базах различается, прямое сопоставление по индексу приведёт к подмене данных. Безопасный обмен строится на именах значений.

Каждое перечисление имеет также «пустое» значение — значение по умолчанию, которое получает реквизит типа «ПеречислениеСсылка», если ему ничего не присвоили. Проверка на пустоту выполняется методом IsEmpty() в запросах или сравнением с Перечисления.ИмяПеречисления.ПустаяСсылка() в коде.

Прямое обращение к значению по имени

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

Ставка = Перечисления.СтавкиНДС.НДС20;

Статус = Перечисления.СтатусыЗаказа.ВРаботе;

Пустое = Перечисления.СтатусыЗаказа.ПустаяСсылка();

Такой код рекомендуется использовать всегда, когда имя значения известно на этапе разработки. Он читаем, быстро работает и защищён от ошибок исполнения. При сравнении значений используется обычный оператор равенства — сравнение ссылок перечислений работает корректно без дополнительных преобразований.

Обратите внимание: пустая ссылка перечисления — это не то же самое, что Неопределено. Реквизит составного типа может содержать Неопределено, и сравнение с пустой ссылкой перечисления даст ложь. Для универсальной проверки используйте функцию ЗначениеЗаполнено().

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

Когда имя значения приходит извне — из файла обмена, параметра HTTP-запроса, настройки пользователя — прямое обращение невозможно. В этом случае менеджер перечисления поддерживает обращение по строковому имени через квадратные скобки.

ИмяЗначения = "НДС20"; // получено извне

Ставка = Перечисления.СтавкиНДС[ИмяЗначения];

Если значение с таким именем не существует, обращение через скобки возвращает Неопределено, а не вызывает исключение. Это удобно для проверки: сравнив результат с Неопределено, можно понять, что входные данные некорректны, и обработать ситуацию штатно.

Альтернативный вариант — функция XMLЗначение(), которая преобразует строку в значение по её XML-представлению. Она чаще применяется при разборе данных в форматах EnterpriseData и XDTO-пакетах, где значения перечислений сериализуются по имени.

Безопасное получение значения по строке
  1. 1
    Получите строку с именем значения из внешнего источника и удалите лишние пробелы
  2. 2
    Обратитесь к менеджеру: Перечисления.ИмяПеречисления[СтрокаИмени]
  3. 3
    Проверьте результат: если он равен Неопределено — имени нет в перечислении
  4. 4
    При отсутствии значения задайте поведение по умолчанию или зафиксируйте ошибку загрузки
  5. 5
    Не присваивайте Неопределено реквизиту типа ПеречислениеСсылка без проверки

Перебор всех значений перечисления

Для построения списка выбора, заполнения таблицы сопоставления или проверки полноты данных нужно перебрать все значения перечисления. Делается это через коллекцию метаданных, а не через менеджер.

Для Каждого ЗначениеМетаданных Из Метаданные.Перечисления.СтатусыЗаказа.ЗначенияПеречисления Цикл

ИмяЗначения = ЗначениеМетаданных.Имя;

СинонимЗначения = ЗначениеМетаданных.Синоним;

СсылкаНаЗначение = Перечисления.СтатусыЗаказа[ИмяЗначения];

КонецЦикла;

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

Формирование списка значений для формы

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

Работа с перечислениями в запросах

В языке запросов значения перечислений указываются как предопределённые значения через конструкцию ЗНАЧЕНИЕ(Перечисление.ИмяПеречисления.ИмяЗначения). Это стандартный способ отбора в виртуальных таблицах и условиях.

// Фрагмент текста запроса

ГДЕ

Заказы.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказа.ВРаботе)

Если значение нужно передать динамически, его передают параметром запроса: Запрос.УстановитьПараметр("Статус", Перечисления.СтатусыЗаказа.ВРаботе), а в тексте используют &Статус. Параметризация предпочтительна, когда запрос строится программно и значение заранее неизвестно.

Отдельный приём — получение представления значения перечисления прямо в запросе через функцию ПРЕДСТАВЛЕНИЕ(). Это избавляет от необходимости постобработки результата при выводе в отчёт, хотя для дальнейших сравнений в коде лучше работать с самим значением, а не со строкой.

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

Сравнение значений перечислений выполняется оператором равенства. Для проверки вхождения в группу допустимых значений удобны два подхода: перечисление вариантов через ИЛИ либо проверка через массив и метод Найти(). При трёх и более вариантах массив читается лучше.

Допустимые = Новый Массив;

Допустимые.Добавить(Перечисления.СтатусыЗаказа.ВРаботе);

Допустимые.Добавить(Перечисления.СтатусыЗаказа.Отгружен);

Если Допустимые.Найти(ТекущийСтатус) <> Неопределено Тогда

// статус допустим

КонецЕсли;

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

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

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

Обращение по строковому имени
Норма

Возвращено значение типа ПеречислениеСсылка

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

Возвращено Неопределено — имени нет в конфигурации

Сравнение значений
Норма

Равенство срабатывает для одинаковых значений

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

Сравниваются строки-представления вместо значений

Перебор через метаданные
Норма

Количество итераций равно числу значений в конфигураторе

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

Цикл пустой — проверьте имя перечисления

Типичные ошибки и ограничения

Наиболее распространённая ошибка — обращение к значению по синониму вместо имени. Синоним «НДС 20%» и имя «НДС20» — разные вещи, и обращение Перечисления.СтавкиНДС["НДС 20%"] вернёт Неопределено. При загрузке данных извне всегда сопоставляйте внешние представления с именами значений через явную таблицу соответствия.

Вторая группа ошибок связана с расширениями конфигурации. Перечисления, добавленные расширением, доступны в коде только если расширение подключено; при его отключении обращение к такому значению вызовет исключение. Код, зависящий от расширяемых объектов, стоит защищать проверками через метаданные.

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

Типичные ошибки
01
Обращение по синониму вместо имени — результат Неопределено и пропущенные данные
02
Сравнение значения перечисления со строкой — условие никогда не выполняется
03
Использование индексов при обмене между разными конфигурациями — подмена значений
04
Присвоение Неопределено реквизиту без проверки — неочевидные пустые данные в отчётах
05
Обращение к метаданным в клиентском контексте тонкого клиента — ошибка исполнения

Когда перечисление не подходит

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

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

Перечисление или справочник

Перечисление

Фиксированный набор значений, меняется только разработчиком; быстрый доступ из кода, контроль на этапе компиляции модуля

Справочник

Пользователь может добавлять элементы, есть дополнительные реквизиты; доступ к значениям только через поиск или предопределённые элементы

Итог

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

Прямое обращение Перечисления.Имя.Значение — основной способ; по строке используйте менеджер с квадратными скобками и проверку на Неопределено; перебор всех значений идёт через метаданные; в запросах применяйте ЗНАЧЕНИЕ() или параметры. Всегда работайте с именами значений, а не синонимами и индексами.

Частые вопросы

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

Надёжного прямого способа нет: синонимы могут дублироваться и меняться. Практичный вариант — перебрать коллекцию Метаданные.Перечисления.Имя.ЗначенияПеречисления, сравнивая свойство Синоним, и по найденному имени получить значение через менеджер. Для регулярных загрузок лучше построить таблицу соответствия внешних названий и имён значений.

Чем отличается пустая ссылка перечисления от Неопределено?

Пустая ссылка — это легитимное значение типа ПеречислениеСсылка, означающее «значение не выбрано». Неопределено — отсутствие значения как такового, оно встречается в реквизитах составного типа и как результат неудачного обращения по строковому имени. Сравнение пустой ссылки с Неопределено даёт ложь, поэтому для универсальной проверки используйте ЗначениеЗаполнено().

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

Используйте функцию XMLСтрока(): она вернёт имя значения, например «НДС20». Функция Строка() для этой цели не подходит — она возвращает представление (синоним), которое может содержать пробелы и не совпадать с именем.

Можно ли обратиться к перечислению, не зная его имени заранее?

Да. Сначала получите объект метаданных по строке: Метаданные.Перечисления.Найти(ИмяПеречисления). Затем через менеджер Перечисления[ИмяПеречисления][ИмяЗначения] получите значение. Оба обращения по строке могут вернуть Неопределено, поэтому каждый шаг нужно проверять.

Почему обращение Перечисления.Имя[Строка] возвращает Неопределено?

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

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

Передайте в запрос массив или список значений параметром и используйте условие В (&СписокСтатусов). Это лаконичнее, чем перечисление через ИЛИ, и позволяет менять набор значений без правки текста запроса.