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