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

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

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

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

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

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

Почему перечисление нельзя просто привести к строке

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

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

Способ 1. Функция ПРЕДСТАВЛЕНИЕ

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

ВЫБРАТЬ

Док.Ссылка КАК Документ,

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

ИЗ

Документ.РеализацияТоваровУслуг КАК Док

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

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

Способ 2. Конструкция ВЫБОР с явными значениями

Когда нужен полный контроль над итоговым текстом — например, для выгрузки во внешнюю систему, где ожидаются коды «NEW», «PAID», «SHIPPED», — используйте ВЫБОР с перечислением всех значений:

ВЫБРАТЬ

ВЫБОР

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

ТОГДА "NEW"

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

ТОГДА "PAID"

ИНАЧЕ "OTHER"

КОНЕЦ КАК СтатусКод

ИЗ

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

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

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

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

Способ 3. Преобразование после выполнения запроса

Часто рациональнее не тянуть строку в запросе, а получить ссылку перечисления и преобразовать её в коде при обходе выборки. Это быстрее по производительности и гибче:

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

СтатусСтрокой = Строка(Выборка.Статус); // синоним значения

СтатусКод = XMLСтрока(Выборка.Статус); // имя значения в метаданных

НоваяСтрока = ТаблицаРезультата.Добавить();

НоваяСтрока.СтатусТекст = СтатусСтрокой;

НоваяСтрока.СтатусКод = СтатусКод;

КонецЦикла;

Разница между двумя вариантами принципиальна. Строка() возвращает синоним — текст на языке пользователя, который может меняться при доработке конфигурации. XMLСтрока() возвращает имя значения перечисления из метаданных («Новый», «Оплачен»), которое стабильно, пока разработчик не переименует значение в конфигураторе. Для обменов между системами XMLСтрока предпочтительнее.

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

Сравнение способов

ПРЕДСТАВЛЕНИЕ в запросе

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

ВЫБОР с явными значениями

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

Строка() / XMLСтрока() в коде

Максимальная гибкость и скорость запроса. Минус: строка появляется только после запроса, не подходит для СКД и консоли

Перечисление как строка в СКД и динамических списках

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

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

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

Обратная задача: получить перечисление из строки

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

ЗначениеСтатуса = Перечисления.СтатусыЗаказа[СтрокаИзФайла];

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

Для Каждого Значение Из Метаданные.Перечисления.СтатусыЗаказа.ЗначенияПеречисления Цикл

Если Значение.Синоним = СтрокаИзФайла Тогда

НайденноеЗначение = Перечисления.СтатусыЗаказа[Значение.Имя];

Прервать;

КонецЕсли;

КонецЦикла;

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

Порядок выбора решения
  1. 1
    Определите, где нужна строка: внутри запроса, в СКД или в коде
  2. 2
    Для отчёта или выгрузки «как видит пользователь» — используйте ПРЕДСТАВЛЕНИЕ
  3. 3
    Для обмена с внешней системой с фиксированными кодами — ВЫБОР или XMLСтрока() в коде
  4. 4
    Оставьте ссылочное поле для отборов и группировок, строку — только для вывода
  5. 5
    Проверьте результат на записи с каждым значением перечисления, включая пустую ссылку

Проверка результата и граничные случаи

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

Отдельно проверьте пустую ссылку перечисления: ПРЕДСТАВЛЕНИЕ вернёт пустую строку, а ВЫБОР без обработки этого случая отдаст значение из ветки ИНАЧЕ или NULL. Если пустое значение для вас осмысленно (например, «статус не задан»), добавьте явную ветку КОГДА Поле = ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказа.ПустаяСсылка).

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

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

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

Тип поля в результате запроса
Норма

Строка ожидаемой длины, доступны строковые функции

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

Осталась ссылка на перечисление — преобразование не сработало

Новые значения перечисления
Норма

Каждое значение даёт осмысленный текст

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

Часть значений попадает в ИНАЧЕ или даёт NULL

Пустая ссылка
Норма

Обработана явно: пустая строка или маркер

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

NULL ломает последующую конкатенацию строк

Скорость запроса
Норма

Время выполнения сопоставимо с вариантом без представления

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

Запрос замедлился в разы — уберите ПРЕДСТАВЛЕНИЕ из условий и соединений

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

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

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

Что вернёт ПРЕДСТАВЛЕНИЕ для пустой ссылки перечисления?

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

Чем XMLСтрока лучше Строка() для обмена данными?

XMLСтрока возвращает имя значения из метаданных, которое меняется только при явном переименовании разработчиком. Синоним, который даёт Строка(), может меняться при доработках интерфейса и зависит от языка, что делает его ненадёжным ключом для интеграций.

Работает ли ПРЕДСТАВЛЕНИЕ в виртуальных таблицах и итогах?

Да, функция применима к полям виртуальных таблиц регистров. Но учитывайте, что она выполняется уже после вычисления итогов, и в больших отчётах по регистрам её применение к измерениям может ощутимо замедлить формирование.

Как получить строку перечисления в параметре запроса?

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

Почему консоль запросов не ругается на ВЫРАЗИТЬ к строке, а запрос падает?

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

Итог

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

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