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

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

1С: как работать с перечислением

Практическое руководство по работе с перечислениями в 1С: как обратиться к значению в коде, перебрать значения, сравнить, получить синоним и применить в запросах.

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

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

Ниже разобраны основные приёмы с примерами кода, которые работают как в обычных, так и в управляемых формах, на сервере и на клиенте (с учётом ограничений контекста).

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

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

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

Как обратиться к значению перечисления в коде

Базовый синтаксис обращения — через коллекцию менеджеров Перечисления:

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

Если Документ.Статус = Перечисления.СтатусыЗаказа.Закрыт Тогда

// логика для закрытого заказа

КонецЕсли;

Значение перечисления — это не строка. Сравнение Документ.Статус = "ВРаботе" всегда даст ложь, потому что слева объект типа «ПеречислениеСсылка», а справа строка. Это одна из самых частых ошибок начинающих разработчиков.

Если имя значения хранится в переменной (например, пришло из внешней системы), обращение выполняется через квадратные скобки:

ИмяЗначения = "ВРаботе";

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

При таком обращении с несуществующим именем будет получено значение Неопределено, поэтому результат стоит проверять перед использованием.

Как перебрать все значения перечисления

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

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

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

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

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

КонецЦикла;

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

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

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

Если Не ЗначениеЗаполнено(Документ.Статус) Тогда

// статус не указан

КонецЕсли;

Если Документ.Статус = Перечисления.СтатусыЗаказа.ПустаяСсылка() Тогда

// то же самое, явное сравнение

КонецЕсли;

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

Синоним = Строка(Документ.Статус); // "В работе"

Имя = Документ.Статус.Метаданные().ЗначенияПеречисления.Получить(

Перечисления.СтатусыЗаказа.Индекс(Документ.Статус)).Имя; // "ВРаботе"

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

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

В языке запросов к значениям перечислений обращаются через конструкцию ЗНАЧЕНИЕ():

ВЫБРАТЬ

Заказы.Ссылка

ИЗ

Документ.ЗаказПокупателя КАК Заказы

ГДЕ

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

Обратите внимание: в запросе используется единственное число — Перечисление, а не Перечисления. Альтернатива — передать значение параметром, что предпочтительнее, когда значение вычисляется в коде:

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

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

Типичные ошибки
01
Сравнение значения перечисления со строкой — результат всегда ложь, логика молча не срабатывает
02
В запросе написано Перечисление.Имя во множественном числе (Перечисления) — ошибка компиляции запроса
03
Обращение к Метаданным на тонком клиенте — падение с ошибкой о недоступности объекта
04
Переименование значения перечисления без поиска всех обращений в коде — старые ветки логики перестают работать

Изменение перечисления: что нужно знать перед правкой

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

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

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

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

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

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

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

Проверка конфигурации
Норма

Нет ошибок обращения к значениям перечисления

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

Сообщения о ненайденном значении или методе

Форма выбора значения
Норма

Все значения видны с понятными синонимами

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

Пустые строки или идентификаторы вместо названий

Отбор в отчёте по значению
Норма

Отбор находит записи с нужным значением

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

Пустой результат при заведомо существующих данных

FAQ

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

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

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

Через метод менеджера: Перечисления.ИмяПеречисления.ПустаяСсылка(). Для проверки заполненности реквизита удобнее универсальная функция ЗначениеЗаполнено() — она работает с любыми типами.

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

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

Можно ли отсортировать значения перечисления в списке выбора?

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

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

Через метаданные: Метаданные.Перечисления.ИмяПеречисления.ЗначенияПеречисления.Количество(). Это работает только на сервере, поскольку объект Метаданные недоступен на тонком клиенте.

Что произойдёт с данными, если переименовать значение перечисления?

Данные не пострадают: в базе хранится внутренний идентификатор, а не имя. Но весь код, запросы и внешние обработки, где использовано старое имя, перестанут работать. Перед переименованием выполните глобальный поиск по конфигурации и проверьте расширения.

Итог

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

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