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

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

Перечисления в запросах 1С: условие ГДЕ и функция ЗНАЧЕНИЕ

Как использовать перечисления в запросах 1С: оператор ГДЕ, функция ЗНАЧЕНИЕ, сравнение ссылок, получение представления. Примеры кода, ошибки и FAQ.

Перечисления в языке запросов 1С — частый источник ошибок у начинающих разработчиков. Значение перечисления нельзя сравнить со строкой или числом напрямую: платформа хранит его как ссылку на предопределённый элемент, и запрос требует специального синтаксиса. Если написать ГДЕ Статус = "Закрыт", запрос либо вернёт пустой результат, либо завершится ошибкой несоответствия типов.

Рабочий инструмент — функция ЗНАЧЕНИЕ(), которая преобразует литеральное имя значения перечисления в ссылку нужного типа. Дополнительно доступны проверка типа через ССЫЛКА, передача значения параметром, получение строкового представления и работа с пустой ссылкой. Каждый из этих приёмов имеет свои ограничения и типичные подводные камни.

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

Как платформа хранит значения перечислений

Перечисление в 1С — это прикладной объект с фиксированным списком значений, заданным в конфигураторе. В базе данных реквизит типа «ПеречислениеСсылка» хранится как ссылка, а не как текст. Именно поэтому запрос ГДЕ ВидОперации = "Продажа" не находит ни одной записи: строка и ссылка — разные типы, и сравнение всегда ложно.

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

Фильтрация через ЗНАЧЕНИЕ в условии ГДЕ

Основной способ отбора по значению перечисления — функция ЗНАЧЕНИЕ() с полным путём: имя объекта метаданных, имя перечисления, имя значения. Типичный пример для документа с реквизитом «Статус»:

ВЫБРАТЬ

Заказ.Ссылка КАК Заказ,

Заказ.Статус КАК Статус

ИЗ

Документ.ЗаказКлиента КАК Заказ

ГДЕ

Заказ.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказов.КОтгрузке)

Условие можно комбинировать с другими операторами: И, ИЛИ, НЕ. Для отбора нескольких значений удобнее использовать В (...) со списком значений через ЗНАЧЕНИЕ() либо параметр со списком значений:

ГДЕ

Заказ.Статус В (ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказов.КОтгрузке),

ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказов.Отгружен))

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

bsl
Запрос.Текст = "ВЫБРАТЬ Т.Ссылка ИЗ Документ.Реализация КАК Т ГДЕ Т.ВидОперации = ЗНАЧЕНИЕ(Перечисление.ВидыОпераций.Продажа)";

Передача значения перечисления параметром

Когда значение перечисления выбирается пользователем или вычисляется в коде, его передают параметром. В модуле значение получают через обращение к менеджеру перечисления: Перечисления.СтатусыЗаказов.КОтгрузке. Тип параметра платформа определяет автоматически.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

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

|ИЗ

| Документ.ЗаказКлиента КАК Заказ

|ГДЕ

| Заказ.Статус = &Статус";

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

Результат = Запрос.Выполнить();

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

Сравнение вариантов

ЗНАЧЕНИЕ() в тексте запроса

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

Параметр запроса

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

Список значений в параметре

Подходит для отбора по нескольким значениям через оператор В. Параметру присваивается СписокЗначений или массив со ссылками перечисления.

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

Иногда в результате запроса нужен не сам статус-ссылка, а его текст для вывода пользователю. Универсальный приём — функция ПРЕДСТАВЛЕНИЕ():

ВЫБРАТЬ

ПРЕДСТАВЛЕНИЕ(Заказ.Статус) КАК СтатусТекстом

ИЗ

Документ.ЗаказКлиента КАК Заказ

Функция возвращает синоним значения, как он задан в конфигураторе. Однако использовать ПРЕДСТАВЛЕНИЕ() в условиях ГДЕ нельзя для сравнения — это операция преобразования, и фильтровать по её результату неэффективно и ненадёжно: синоним могут изменить, и условие молча перестанет работать.

Для сортировки по логическому порядку значений перечисления (а не по алфавиту представления) применяют конструкцию ВЫБОР ... КОГДА с присвоением весов каждому значению либо просто сортируют по самому полю — платформа упорядочивает ссылки перечисления по порядку следования значений в конфигураторе.

Проверка на пустую ссылку и значения в виртуальных таблицах

Реквизит типа перечисления может быть не заполнен. В запросе это проверяется сравнением с пустой ссылкой через то же ЗНАЧЕНИЕ(), но с указанием специального значения ПустаяСсылка:

ГДЕ

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

Альтернатива — предикат ЕСТЬ NULL, но он нужен только когда пустое значение возникает из-за левого соединения, а не из-за незаполненного реквизита. Незаполненный реквизит перечисления хранит пустую ссылку, а не NULL, поэтому проверка ЕСТЬ NULL по нему ничего не найдёт — это частая причина «пропавших» документов в отчётах.

В параметрах виртуальных таблиц (например, РегистрНакопления.Товары.Обороты) отбор по перечислению задаётся тем же выражением ЗНАЧЕНИЕ() в параметре условия. Всегда накладывайте отбор именно в параметрах виртуальной таблицы, а не в секции ГДЕ после неё — это существенно сокращает объём обрабатываемых данных.

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

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

Запрос с ЗНАЧЕНИЕ() выполняется без ошибок
Норма

Конструктор запроса подсвечивает значение как корректное, выборка содержит ожидаемые документы

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

Ошибка «Поле не найдено» или «Неверные параметры в операции сравнения» — проверьте имя перечисления и значения

Отбор по незаполненному статусу
Норма

Находятся документы, где реквизит пустой

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

Пустой результат при проверке ЕСТЬ NULL — замените на сравнение с ПустаяСсылка

Представление в отчёте
Норма

Выводится синоним значения из конфигуратора

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

Выводится пусто — реквизит не заполнен, добавьте обработку пустой ссылки

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

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

Ограничение функции ЗНАЧЕНИЕ(): она принимает только литеральный путь, нельзя подставить имя значения через параметр. Если имя значения должно вычисляться динамически, получайте ссылку в коде через Перечисления[ИмяПеречисления][ИмяЗначения] и передавайте параметром.

Ещё одно ограничение касается плана обмена и составных типов: если реквизит имеет составной тип (перечисление плюс справочник), сравнение с ЗНАЧЕНИЕ() работает, но для ускорения выборки полезно дополнительно проверять тип через ВЫРАЗИТЬ(... КАК Перечисление.Имя) или условие ССЫЛКА.

Типичные ошибки
01
Сравнение со строкой: ГДЕ Статус = "Закрыт" — условие всегда ложно, запрос возвращает пустую выборку без ошибки
02
Проверка незаполненного реквизита через ЕСТЬ NULL — пустая ссылка перечисления не является NULL, документы теряются
03
Имя значения в кавычках внутри ЗНАЧЕНИЕ() — синтаксическая ошибка при выполнении
04
Использование синонима вместо имени значения — ошибка или пустой результат, если синоним отличается от имени
05
Фильтрация по ПРЕДСТАВЛЕНИЮ() — условие ломается при изменении синонима и не использует индексы
Маршрут решения

Как выбрать действие

Условие отбора фиксировано и не меняетсяИспользуйте ЗНАЧЕНИЕ(Перечисление.Имя.Значение) прямо в тексте запроса
Значение выбирает пользователь или вычисляется в кодеПолучите ссылку в модуле и передайте параметром запроса
Нужно отобрать по нескольким значениямПередайте параметр со списком значений и используйте оператор В (&Список)
Нужен текст статуса для выводаДобавьте поле ПРЕДСТАВЛЕНИЕ(Реквизит), но фильтруйте по ссылке
Нужно найти документы без статусаСравните реквизит с ЗНАЧЕНИЕ(Перечисление.Имя.ПустаяСсылка)

FAQ

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

Нет. Типы «Строка» и «ПеречислениеСсылка» несовместимы для сравнения: условие либо вернёт пустой результат, либо вызовет ошибку. Преобразуйте имя значения в ссылку через ЗНАЧЕНИЕ() или передайте ссылку параметром.

Что указывать в ЗНАЧЕНИЕ() — имя или синоним значения?

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

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

Сравните реквизит с пустой ссылкой: ГДЕ Реквизит = ЗНАЧЕНИЕ(Перечисление.ИмяПеречисления.ПустаяСсылка). Проверка ЕСТЬ NULL здесь не подходит, потому что незаполненный реквизит хранит пустую ссылку, а не NULL.

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

Сформируйте в коде массив или СписокЗначений со ссылками перечисления, передайте его параметром и используйте оператор В: ГДЕ Статус В (&Статусы). Платформа сама развернёт список в условие.

Почему запрос с ЗНАЧЕНИЕ() выдаёт ошибку «Поле не найдено»?

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

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

Достаточно указать УПОРЯДОЧИТЬ ПО по самому полю-перечислению: платформа сортирует ссылки по порядку следования значений в метаданных. Сортировка по ПРЕДСТАВЛЕНИЮ() даст алфавитный порядок синонимов, что обычно не совпадает с логикой процесса.

Итог

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

Перечисления в запросах 1С сравниваются только как ссылки: через ЗНАЧЕНИЕ(Перечисление.Имя.Значение) или параметр. Строковое сравнение не работает, пустое значение — это ПустаяСсылка, а не NULL, а ПРЕДСТАВЛЕНИЕ() применяется только для вывода, но не для отбора.