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