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