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

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

1С: перечисление как строка в запросе — все рабочие способы

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

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

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

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

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

В языке запросов 1С значение перечисления — это ссылка на предопределённый элемент особого объекта метаданных. Когда вы помещаете поле типа «ПеречислениеСсылка» в список выборки, запрос возвращает именно ссылку. Если такой результат передать в СКД или выгрузить как есть, представление подставится автоматически, но в самом тексте запроса строкового значения не существует.

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

Ещё одна особенность: у перечисления есть два «строковых» облика — синоним (то, что видит пользователь, например «Проведён») и имя значения, заданное в конфигураторе (например «Проведен» без пробелов и в заданном регистре). Эти строки могут различаться, и для разных задач нужны разные из них: для выгрузки пользователю — синоним, для обмена с внешними системами — чаще имя значения.

Способ 1: функция ПРЕДСТАВЛЕНИЕ в запросе

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

ВЫБРАТЬ

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

ИЗ

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

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

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

Способ 2: соединение с таблицей перечисления

Перечисление доступно в запросе как полноценная таблица с именем вида Перечисление.ИмяПеречисления. У неё есть служебные поля: Ссылка, Порядок и другие. Это позволяет соединить основную таблицу с таблицей перечисления и взять нужные данные оттуда.

ВЫБРАТЬ

Заказы.Номер,

Статусы.Ссылка КАК СтатусСсылка,

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

ИЗ

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

ЛЕВОЕ СОЕДИНЕНИЕ Перечисление.СтатусыЗаказов КАК Статусы

ПО Заказы.Статус = Статусы.Ссылка

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

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

Способ 3: обработка результата в коде

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

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

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

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

КонецЦикла;

Для получения имени значения, заданного в конфигураторе, используется работа с метаданными:

ИмяЗначения = XMLСтрока(Выборка.Статус);

// или через метаданные:

МетаданныеПеречисления = Выборка.Статус.Метаданные();

ИндексЗначения = Перечисления[МетаданныеПеречисления.Имя].Индекс(Выборка.Статус);

ИмяЗначения = МетаданныеПеречисления.ЗначенияПеречисления[ИндексЗначения].Имя;

Функция XMLСтрока — самый короткий путь получить имя значения: она возвращает именно идентификатор из конфигуратора, который удобно передавать в обмены данными и веб-сервисы. Обратное преобразование выполняется через XMLЗначение с указанием типа.

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

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

Быстро и без кода, возвращает синоним. Ограничение: поведение зависит от версии платформы, имени значения не даёт.

Соединение с таблицей перечисления

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

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

Надёжно, всегда возвращает синоним. Ограничение: требует постобработки выборки, не работает внутри СКД без вычисляемых полей.

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

Возвращает имя значения для обменов и интеграций. Ограничение: только в коде, не в тексте запроса.

Сравнение перечисления со строкой в условии запроса

Обратная задача встречается так же часто: на вход приходит строка (например, из параметра обмена), и нужно отобрать документы с этим значением перечисления. Прямое сравнение «ссылка = строка» в запросе невозможно — типы несовместимы, и запрос либо упадёт с ошибкой, либо молча ничего не найдёт.

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

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

Запрос.УстановитьПараметр("Статус", ЗначениеСтатуса);

Запрос.Текст =

"ВЫБРАТЬ

| Заказы.Ссылка

|ИЗ

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

|ГДЕ

| Заказы.Статус = &Статус";

Обращение Перечисления.ИмяПеречисления[Строка] работает по имени значения из конфигуратора, а не по синониму. Если строка пришла от пользователя в виде синонима («Новый» вместо «New»), сначала найдите значение перебором коллекции ЗначенияПеречисления с сравнением по синониму или представлению.

Типичные ошибки и как их проверить

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

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

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

Типичные ошибки
01
Сравнение перечисления со строкой в условии ГДЕ — запрос падает или возвращает пустой результат; решение: преобразовать строку в значение перечисления до запроса
02
Ожидание имени значения от функции ПРЕДСТАВЛЕНИЕ — она возвращает синоним; для имени используйте XMLСтрока в коде
03
Поиск значения по синониму через Перечисления.Имя[Строка] — обращение по индексу работает по имени, а не по синониму; для синонима нужен перебор коллекции значений
04
Сравнение с пустой строкой вместо ЗНАЧЕНИЕ(...ПустаяСсылка) — условие никогда не выполняется

Проверка результата и выбор подхода

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

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

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

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

Заполненность строковой колонки
Норма

Для всех строк с заполненным перечислением колонка содержит текст

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

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

Соответствие текста ожиданиям
Норма

В отчёте — синоним, в обмене — имя значения из конфигуратора

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

В выгрузке для внешней системы виден пользовательский синоним вместо имени

Отбор по строковому параметру
Норма

Документы отбираются по значению, преобразованному в ссылку перечисления

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

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

Часто задаваемые вопросы

Можно ли получить строку перечисления прямо в СКД без кода?

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

Чем имя значения перечисления отличается от синонима?

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

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

Переберите коллекцию Метаданные.Перечисления.ИмяПеречисления.ЗначенияПеречисления и сравните свойство Синоним каждого элемента с искомой строкой. Найденный индекс преобразуйте в значение через Перечисления.ИмяПеречисления.Получить(Индекс).

Почему сравнение перечисления с пустой строкой не работает?

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

Что быстрее: ПРЕДСТАВЛЕНИЕ в запросе или Строка() в коде?

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

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

Да. Соедините основную таблицу с таблицей Перечисление.ИмяПеречисления по ссылке и добавьте в упорядочивание поле Порядок этой таблицы. Записи выстроятся в том порядке, в котором значения перечисления заданы в конфигураторе, а не по алфавиту синонимов.

Итог

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

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