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