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

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

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

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

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

Основной инструмент для работы с перечислениями в языке запросов — функция ЗНАЧЕНИЕ(). Она позволяет указать конкретное значение перечисления прямо в тексте запроса, не передавая его через параметр. Это удобно для отборов, сравнений и проверок в виртуальных таблицах.

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

Как устроены перечисления и почему к ним особый подход

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

Каждое значение перечисления имеет имя, заданное в конфигураторе, и синоним, который видит пользователь. Имя используется в коде и запросах, синоним — в интерфейсе. Если в конфигурации значение называется Проведен, а синоним — «Проведён успешно», то в запросе обращаются именно по имени Проведен.

Получение значения перечисления через ЗНАЧЕНИЕ()

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

ВЫБРАТЬ

РеализацияТоваровУслуг.Ссылка,

РеализацияТоваровУслуг.СуммаДокумента

ИЗ

Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг

ГДЕ

РеализацияТоваровУслуг.ВидОперации = ЗНАЧЕНИЕ(Перечисление.ВидыОперацийРеализацияТоваров.ПродажаКомиссия)

Обратите внимание: имя перечисления и имя значения пишутся без кавычек — это идентификаторы метаданных, а не строки. Конструктор запроса подставляет такие конструкции автоматически, если выбрать значение через кнопку выбора в поле условия.

Если значение перечисления нужно вернуть как поле выборки (например, константное значение для всех строк), функция тоже подходит:

ВЫБРАТЬ

ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС20) КАК СтавкаПоУмолчанию,

Товары.Номенклатура

ИЗ

Документ.ПоступлениеТоваровУслуг.Товары КАК Товары

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

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

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

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

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

"ВЫБРАТЬ

| ЗаказКлиента.Ссылка

|ИЗ

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

|ГДЕ

| ЗаказКлиента.Статус = &Статус";

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

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

Параметры удобны ещё и тем, что один и тот же текст запроса можно переиспользовать с разными значениями без изменения строки запроса. Это снижает риск ошибок при доработках и упрощает поддержку кода.

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

ГДЕ

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

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

ЗНАЧЕНИЕ() или параметр

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

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

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

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

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

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

ВЫБРАТЬ

ЗаказКлиента.Номер,

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

ИЗ

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

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

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

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

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

ГДЕ

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

Обратите внимание: пустая ссылка перечисления и NULL — разные вещи. NULL появляется только при соединениях таблиц, когда записи не нашлось. Пустая ссылка — это вполне конкретное значение, хранящееся в поле. Проверку = NULL писать нельзя вообще, только ЕСТЬ NULL.

Для составного типа поля (когда реквизит может хранить и перечисление, и другие типы) бывает нужно отобрать записи именно с перечислением. Для этого используется оператор ССЫЛКА:

ГДЕ

Регистр.ЗначениеСвойства ССЫЛКА Перечисление.ВариантыОплаты

Как добавить отбор по перечислению
  1. 1
    Откройте конструктор запроса и добавьте нужную таблицу.
  2. 2
    Перетащите поле с типом перечисления в условия (вкладка «Условия»).
  3. 3
    В правой части условия нажмите кнопку выбора и укажите конкретное значение перечисления — конструктор сам вставит ЗНАЧЕНИЕ(...).
  4. 4
    Нажмите «ОК» и выполните запрос в консоли запросов, чтобы убедиться, что записи найдены.
  5. 5
    Если записей нет — проверьте, что в базе действительно есть документы с выбранным значением, и что имя перечисления не содержит опечатки.

Перечисления в СКД и динамических списках

В системе компоновки данных значения перечислений в параметрах и отборах подставляются через настройки: пользователь выбирает значение из выпадающего списка, и СКД передаёт ссылку автоматически. В тексте запроса набора данных при этом используется обычный параметр &Статус.

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

В динамических списках с произвольным запросом ситуация аналогична. Частая задача — отбор по перечислению через отбор пользователя. Для этого в настройках динамического списка поле с перечислением должно быть доступно для отбора, а тип значения платформа определит автоматически по типу поля.

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

Проверка результата и отладка запроса

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

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

Для проверки в коде удобно выгрузить результат в таблицу значений и посмотреть её через отладчик: Выборка = Запрос.Выполнить().Выгрузить(). В таблице значений тип колонки будет виден явно — это помогает отличить ссылку от строки.

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

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

Запрос выполняется
Норма

Нет ошибок компиляции и выполнения

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

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

Количество строк
Норма

Строки найдены и соответствуют отбору

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

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

Тип поля в результате
Норма

Колонка имеет тип ПеречислениеСсылка

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

Колонка строковая — где-то применено ПРЕДСТАВЛЕНИЕ() или преобразование

Ограничения и частные случаи

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

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

Если нужно получить список всех значений перечисления (например, для заполнения таблицы на форме), запрос к самому перечислению как к таблице не поддерживается. Используйте в коде перебор коллекции: Для Каждого Значение Из Перечисления.СтатусыЗаказов Цикл ... КонецЦикла; — это делается вне запроса, средствами встроенного языка.

Итог

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

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

Частые вопросы

Можно ли в запросе получить значение перечисления по его синониму?

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

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

Либо перечислите их через ЗНАЧЕНИЕ() в операторе В, либо передайте параметр типа «Массив» или «СписокЗначений», заполненный ссылками перечисления, и используйте условие ГДЕ Поле В (&СписокСтатусов).

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

Скорее всего, значение перечисления было переименовано или удалено при обновлении. Запросы, заданные строками в коде, платформа не проверяет при сохранении модуля — ошибка проявляется только при выполнении. Найдите все обращения к перечислению глобальным поиском и исправьте имена.

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

Напрямую в языке запросов такой функции нет. Порядковый индекс можно получить только в коде через Перечисления.ИмяПеречисления.Индекс(Значение). Если нумерация нужна в отчёте, обычно используют ВЫБОР с перечислением всех значений и заданием числа вручную.

Работает ли ЗНАЧЕНИЕ() в запросах к виртуальным таблицам регистров?

Да, функцию можно использовать в параметрах виртуальных таблиц для отбора по измерениям с типом «ПеречислениеСсылка». Это даже предпочтительнее отбора в секции ГДЕ, так как отбор на уровне виртуальной таблицы выполняется раньше и эффективнее.

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

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