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