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

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

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

Как представить перечисление строкой в запросе 1С: ВЫБОР КОГДА, ПРЕДСТАВЛЕНИЕ, соединение со строковой таблицей. Примеры кода, типичные ошибки и ограничения.

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

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

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

Почему ВЫРАЗИТЬ не работает с перечислениями

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

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

Способ 1: ВЫБОР КОГДА — надёжное преобразование в строку

Самый контролируемый способ — конструкция ВЫБОР, где каждому значению перечисления сопоставляется строковый литерал. Запрос полностью определяет результат, не зависит от настроек представления и одинаково работает в обычных запросах, СКД и динамических списках.

ВЫБРАТЬ

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

ВЫБОР

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

ТОГДА "Новый"

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

ТОГДА "В работе"

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

ТОГДА "Завершён"

ИНАЧЕ "Не задан"

КОНЕЦ КАК СтатусСтрокой

ИЗ

Документ.ЗаказПокупателя КАК Заказ

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

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

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

Способ 2: функция ПРЕДСТАВЛЕНИЕ

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

ВЫБРАТЬ

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

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

ИЗ

Документ.ЗаказПокупателя КАК Заказ

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

Применяйте ПРЕДСТАВЛЕНИЕ там, где строка нужна только для отображения пользователю: колонка отчёта, расшифровка, выгрузка «как на экране». Для логики сравнений, соединений и обмена данными этот способ не подходит.

Способ 3: соединение с таблицей соответствий

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

ВЫБРАТЬ

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

"NEW" КАК КодСтрокой

ПОМЕСТИТЬ СоответствиеСтатусов

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ

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

"DONE"

;

ВЫБРАТЬ

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

СоответствиеСтатусов.КодСтрокой КАК СтатусСтрокой

ИЗ

Документ.ЗаказПокупателя КАК Заказ

ЛЕВОЕ СОЕДИНЕНИЕ СоответствиеСтатусов КАК СоответствиеСтатусов

ПО Заказ.Статус = СоответствиеСтатусов.Статус

Используйте левое соединение и проверяйте ЕСТЬNULL по строковому полю: если для какого-то значения перечисления соответствие не заведено, строка будет NULL. Такой подход удобен, когда соответствий много или они меняются пользователями, но требует дисциплины заполнения таблицы соответствий.

Выбор способа под задачу

Единого «правильного» варианта нет — выбор зависит от того, где используется строка и кто управляет её содержимым.

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

ВЫБОР КОГДА

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

ПРЕДСТАВЛЕНИЕ()

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

Таблица соответствий

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

Для СКД предпочтителен ВЫБОР: он корректно участвует в группировках, отборах и ресурсах, а вычисляемые поля на его основе ведут себя предсказуемо. ПРЕДСТАВЛЕНИЕ в СКД тоже работает, но отбор по такому полю пользователь сможет строить только по строке, что неудобно и хрупко.

Маршрут решения

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

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

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

Большинство проблем при преобразовании перечислений в строку связаны не с синтаксисом, а с неполным учётом значений и контекста выполнения запроса.

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

Отдельная ловушка — пустая ссылка перечисления. В ВЫБОР она не равна ни одному из значений, поэтому попадает в ИНАЧЕ; в соединении с таблицей соответствий даёт NULL. Если пустое значение осмысленно (например, «статус не установлен»), обработайте его явно отдельной веткой или ЕСТЬNULL(..., "Не указан").

Проверка результата

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

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

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

Значения строкового поля в результате
Норма

Все строки заполнены осмысленно, нет NULL и пустых строк без причины

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

NULL, пустые строки или «ИНАЧЕ»-значение у большой доли записей

Полнота охвата значений перечисления
Норма

Каждое значение из конфигуратора имеет свою ветку или строку в соответствии

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

Новые значения после обновления конфигурации попадают в ветку по умолчанию

Группировка и сортировка по строковому полю
Норма

Группы формируются ожидаемо, порядок соответствует логике отчёта

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

Появляются отдельные группы с NULL или дубли из-за разных регистров символов

Работа отбора
Норма

Отбор по значению перечисления выполнен через ЗНАЧЕНИЕ(...), а не по строке

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

Отбор сравнивает ПРЕДСТАВЛЕНИЕ со строкой и зависит от синонимов

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

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

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

Напрямую в языке запросов — нет. Функция ПРЕДСТАВЛЕНИЕ возвращает синоним, а не имя. Если нужно именно имя значения, сопоставьте его вручную через ВЫБОР КОГДА либо получите в коде встроенного языка через метаданные: Метаданные.Перечисления.ИмяПеречисления.ЗначенияПеречисления.

Работает ли ВЫБОР КОГДА с перечислениями в СКД?

Да, конструкция ВЫБОР полностью поддерживается в запросах наборов данных СКД. Поле, построенное на ВЫБОР, можно использовать в группировках, ресурсах и отборах. Для отборов предпочтительнее оставить рядом исходное поле перечисления, чтобы пользователь выбирал значение из списка, а не вводил строку.

Почему ПРЕДСТАВЛЕНИЕ возвращает пустую строку для некоторых записей?

Чаще всего поле содержит пустую ссылку перечисления или NULL после соединения таблиц. Проверьте источник поля и оберните результат в ЕСТЬNULL либо обработайте пустую ссылку через ВЫБОР отдельной веткой.

Можно ли сравнить перечисление со строкой напрямую в условии ГДЕ?

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

Что быстрее: ВЫБОР или соединение с таблицей соответствий?

На типовых объёмах разница незаметна. ВЫБОР выполняется без дополнительного соединения и обычно чуть проще для оптимизатора; соединение оправдано, когда соответствия хранятся в данных и ими управляют пользователи. Выбирайте по удобству поддержки, а не по производительности.

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

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

Итог

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

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