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

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

1С: как выразить значение как перечисление в запросе

Как использовать ВЫРАЗИТЬ для приведения значения к типу перечисления в запросе 1С: синтаксис, примеры с составными типами, типичные ошибки и альтернативы.

Оператор ВЫРАЗИТЬ в языке запросов 1С приводит значение поля к указанному типу. Когда речь заходит о перечислениях, задача возникает в двух типовых ситуациях: поле имеет составной тип и его нужно «сузить» до конкретного перечисления, либо требуется сравнить значение со ссылкой перечисления, полученной не напрямую. Без явного приведения типов запрос может вернуть ошибку сравнения несовместимых типов или лишние строки.

Важно понимать ограничение сразу: ВЫРАЗИТЬ не преобразует строку «Услуга» в ссылку перечисления и не выполняет поиск по имени. Оператор лишь указывает, как интерпретировать уже хранящееся значение. Если в поле физически лежит строка, приведение к типу перечисления не сработает — для таких случаев нужны другие приёмы, описанные ниже.

Синтаксис ВЫРАЗИТЬ для перечисления

Общий вид конструкции: ВЫРАЗИТЬ(Выражение КАК Перечисление.ИмяПеречисления). Имя перечисления указывается так, как оно задано в конфигураторе, без кавычек. Результатом будет значение ссылочного типа, с которым можно сравнивать, группировать и соединять таблицы.

Типичный пример — поле составного типа, например реквизит «ВидОперации», который может хранить ссылки на разные объекты, включая перечисление:

ВЫБРАТЬ

ВЫРАЗИТЬ(Регистр.ВидПоказателя КАК Перечисление.ВидыПоказателей) КАК ВидПоказателя

ИЗ

РегистрСведений.ЗначенияПоказателей КАК Регистр

ГДЕ

ВЫРАЗИТЬ(Регистр.ВидПоказателя КАК Перечисление.ВидыПоказателей) = ЗНАЧЕНИЕ(Перечисление.ВидыПоказателей.Количество)

Если поле уже имеет единственный тип «ПеречислениеСсылка», оборачивать его в ВЫРАЗИТЬ не нужно — приведение ничего не изменит, кроме читаемости запроса. Оператор оправдан именно там, где тип неопределённый или составной.

Зачем приводить поле к перечислению

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

Вторая причина — соединение таблиц. Когда левая таблица содержит поле-«значение любого типа», а нужно присоединить данные по условию равенства конкретному значению перечисления, ВЫРАЗИТЬ делает условие соединения допустимым и позволяет оптимизатору использовать индексы.

Третья причина — группировка и итоги. Приведённое к перечислению поле можно использовать в СГРУППИРОВАТЬ ПО и получать представление значения в отчёте СКД, тогда как неопределённый тип в группировке часто приводит к пустым или нечитаемым строкам.

Составной тип поляПоле хранит ссылки разных видов

Нужно отобрать только значения конкретного перечисления

Неопределённый типПоле типа ХранилищеЗначения или произвольное

Приведение не сработает — нужен другой подход

Строка с именем значенияВ поле текст "Услуга"

ВЫРАЗИТЬ не поможет: нужна таблица перечисления или ЗНАЧЕНИЕ()

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

Частая практическая задача: во внешних данных или в текстовом поле лежит имя значения перечисления, и его нужно «превратить» в ссылку внутри запроса. ВЫРАЗИТЬ здесь бессилен — он не выполняет преобразование строки в ссылку.

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

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

ВЫБРАТЬ

Внешние.ИмяСтавки КАК ИмяСтавки,

Ставки.Ссылка КАК СтавкаСсылка

ИЗ

ВнешниеДанные КАК Внешние

ЛЕВОЕ СОЕДИНЕНИЕ Перечисление.СтавкиНДС КАК Ставки

ПО Внешние.ИмяСтавки = Ставки.Представление

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

Приведение в составных типах и NULL

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

Тот же приём работает в СКД и динамических списках, где тип поля определяется в момент выполнения. Приведение к перечислению делает доступными стандартные отборы по значениям и корректное отображение представления.

Учтите тонкость с пустыми ссылками: пустая ссылка перечисления не равна NULL. Если нужно отобрать и незаполненные значения, комбинируйте условия: ... ЕСТЬ NULL ИЛИ ... = ЗНАЧЕНИЕ(Перечисление.ВидыОпераций.ПустаяСсылка).

Порядок действий при составном типе
  1. 1
    Определите фактический тип поля в конфигураторе: составной, единственный или строковый
  2. 2
    Если тип составной — оберните поле в ВЫРАЗИТЬ(Поле КАК Перечисление.ИмяПеречисления)
  3. 3
    Добавьте условие отбора через ЗНАЧЕНИЕ() или параметр с типом перечисления
  4. 4
    Проверьте результат на тестовых данных, включая строки со значениями других типов
  5. 5
    Убедитесь, что пустые и NULL-значения обрабатываются так, как задумано

Типичные ошибки и как их избежать

Самая распространённая ошибка — попытка написать ВЫРАЗИТЬ("Услуга" КАК Перечисление.ВидыНоменклатуры) и ожидать ссылку. Запрос либо упадёт с ошибкой, либо вернёт NULL: строковый литерал нельзя привести к ссылочному типу. Строку в ссылку преобразует только код на встроенном языке или соединение с таблицей перечисления.

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

Третья ошибка — приведение типа в условии соединения без необходимости, когда оба поля уже имеют одинаковый тип перечисления. Лишний ВЫРАЗИТЬ не вредит логике, но затрудняет чтение и иногда мешает оптимизатору. Применяйте его осознанно.

Типичные ошибки
01
Приведение строки к перечислению через ВЫРАЗИТЬ — результат NULL вместо ссылки; используйте ЗНАЧЕНИЕ() или соединение с таблицей перечисления
02
Сравнение поля составного типа со значением перечисления без приведения — ошибка несовместимых типов или пустой результат
03
Игнорирование различия NULL и пустой ссылки — в выборку не попадают незаполненные строки
04
Опечатка в имени значения внутри ЗНАЧЕНИЕ() — запрос падает только при выполнении, а не при написании

Альтернативы ВЫРАЗИТЬ

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

Для отбора по списку значений удобнее параметр-список: Поле В (&СписокЗначений), где параметр имеет тип «СписокЗначений» с элементами перечисления. Это читаемее, чем цепочка ИЛИ с ВЫРАЗИТЬ.

Если тип значения определяется в коде динамически, приведение можно выполнить до запроса: получить ссылку через Перечисления.ИмяПеречисления[ИмяЗначения] и передать её параметром. Такой подход безопаснее при работе с данными из внешних источников — недопустимое имя вызовет понятную ошибку в коде, а не молчаливый NULL в запросе.

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

ВЫРАЗИТЬ(Поле КАК Перечисление...)

Подходит для составных типов, где ссылка уже хранится; не преобразует строки

ЗНАЧЕНИЕ(Перечисление...Значение)

Лучший вариант, когда имя значения известно заранее; работает как константа

Соединение с таблицей перечисления

Для динамических строковых имён из внешних данных; медленнее, зависит от представления

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

Ссылка вычисляется в коде и передаётся готовой; максимальный контроль и скорость

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

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

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

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

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

Тип колонки результата
Норма

Отображаются представления значений перечисления

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

Пустые ячейки или NULL во всех строках

Отбор по значению
Норма

В выборку попадают только строки с нужным значением

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

Строки с другими типами или пустым результатом при заведомо существующих данных

Производительность
Норма

Запрос выполняется за приемлемое время на рабочем объёме

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

Резкое замедление при соединении по строковому представлению

Полезная привычка — в запросах с составными типами всегда приводить поле к конкретному типу в секции ВЫБРАТЬ, даже если отбор не нужен. Это упрощает дальнейшую настройку отчёта в СКД: поля с определённым типом получают корректные отборы, формат и представление автоматически.
ПЗ
Практическое замечание

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

Можно ли через ВЫРАЗИТЬ преобразовать строку в значение перечисления?

Нет. ВЫРАЗИТЬ не выполняет поиск ссылки по строке — он только указывает, как трактовать уже хранящееся значение. Для строк используйте ЗНАЧЕНИЕ() при известном имени, соединение с таблицей перечисления по представлению или преобразование в коде через Перечисления.ИмяПеречисления[ИмяЗначения].

Что вернёт ВЫРАЗИТЬ, если в поле лежит значение другого типа?

NULL, без ошибки. Это поведение удобно использовать для фильтрации: условие ЕСТЬ НЕ NULL после приведения отберёт только строки, где физически хранится ссылка нужного перечисления.

Нужно ли приводить поле, если оно уже имеет тип перечисления?

Нет. Если тип поля единственный и совпадает с нужным перечислением, ВЫРАЗИТЬ ничего не изменит. Оператор имеет смысл только для составных и неопределённых типов.

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

Пустая ссылка — это реальное значение типа перечисления, NULL — отсутствие значения. Они не равны друг другу, поэтому для отбора незаполненных полей нужно проверять оба варианта через ИЛИ.

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

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

Итог

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

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