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