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