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