Как преобразовать перечисление в строку в запросе 1С?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При разработке отчетов и обработок в платформе 1С:Предприятие часто возникает задача получить строковое имя или синоним значения перечисления непосредственно в запросе. Однако разработчики сталкиваются с тем, что стандартные конструкции не позволяют работать с полученным результатом как с полноценной строкой.

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

Почему функции ПРЕДСТАВЛЕНИЕ и ВЫРАЗИТЬ не работают как ожидается

Выясним причину поведения платформы при вызове стандартных функций:

  1. Функции ПРЕДСТАВЛЕНИЕ() и ПРЕДСТАВЛЕНИЕССЫЛКИ() не вычисляются средствами СУБД на уровне базы данных. Платформа 1С подставляет строковое представление объекта уже после выполнения запроса, на этапе формирования выборки результата. По этой причине поля с представлением нельзя использовать в секциях ГДЕ, ПО, СГРУППИРОВАТЬ ПО, УПОРЯДОЧИТЬ ПО, а также передавать их в строковые функции (например, ПОДСТРОКА или оператор ПОДОБНО).
  2. Конструкция приведения типов ВЫРАЗИТЬ(ПРЕДСТАВЛЕНИЕ(Поле) КАК СТРОКА(100)) вызывает синтаксическую ошибку, так как результат работы функции представления имеет специальный внутренний служебный тип, не подлежащий прямому приведению к примитивным типам данных СУБД.

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

Способ 1. Передача таблицы значений перечисления через временную таблицу

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

Разберем по шагам реализацию этого механизма:

  1. Создаем функцию, которая считывает метаданные нужного перечисления и заполняет объект ТаблицаЗначений.
  2. Помещаем полученную таблицу во временную таблицу внутри пакета запросов.
  3. Выполняем ЛЕВОЕ СОЕДИНЕНИЕ основной таблицы данных с временной таблицей по ссылке перечисления.

Посмотрим на пример программного кода вспомогательной функции:


Функция ТаблицаИменПеречисления(ИмяПеречисления)
    
    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Значение", Новый ОписаниеТипов("ПеречислениеСсылка." + ИмяПеречисления));
    Таблица.Колонки.Добавить("Имя", ОбщегоНазначения.ПолучитьОписаниеТиповСтроки(100));
    
    Для Каждого ЗнПереч Из Метаданные.Перечисления[ИмяПеречисления].ЗначенияПеречисления Цикл
        НовСтр = Таблица.Добавить();
        НовСтр.Значение = Перечисления[ИмяПеречисления][ЗнПереч.Имя];
        НовСтр.Имя = ЗнПереч.Имя;
    КонецЦикла;
    
    Возврат Таблица;
    
КонецФункции

Теперь рассмотрим, как использовать подготовленную таблицу в тексте основного запроса:


Процедура ВыполнитьЗапросСИменамиПеречислений()
    
    ПеречНДС = ТаблицаИменПеречисления("СтавкиНДС");
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |    Таб.Имя КАК Имя,
        |    Таб.Значение КАК Значение
        |ПОМЕСТИТЬ ТабПеречНДС
        |ИЗ
        |    &ПеречНДС КАК Таб
        |;
        |
        |////////////////////////////////////////////////////////////////////////////////
        |ВЫБРАТЬ
        |    Номенклатура.Ссылка КАК Ссылка,
        |    Номенклатура.СтавкаНДС КАК СтавкаНДС,
        |    ЕСТЬNULL(ТабПеречНДС.Имя, """") КАК ИмяПереч,
        |    Номенклатура.Код КАК Код
        |ИЗ
        |    Справочник.Номенклатура КАК Номенклатура
        |    ЛЕВОЕ СОЕДИНЕНИЕ ТабПеречНДС КАК ТабПеречНДС
        |        ПО Номенклатура.СтавкаНДС = ТабПеречНДС.Значение";
        
    Запрос.УстановитьПараметр("ПеречНДС", ПеречНДС);
    
    Выборка = Запрос.Выполнить().Выбрать();
    Пока Выборка.Следующий() Цикл
        Сообщить(Выборка.Код + " - " + Выборка.ИмяПереч);
    КонецЦикла;
    
КонецПроцедуры

Преимущество данного способа заключается в том, что поле ТабПеречНДС.Имя становится полноценным строковым полем на уровне СУБД. К нему можно применять любые строковые операторы и условия.

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

Если перечисление содержит фиксированное и небольшое количество значений, либо текст запроса генерируется динамически, можно использовать явное сопоставление через конструкцию ВЫБОР КОГДА ... ТОГДА ....

Проанализируем пример такого фрагмента в запросе:


ВЫБРАТЬ
    Номенклатура.Ссылка,
    ВЫБОР
        КОГДА Номенклатура.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС20) ТОГДА "НДС20"
        КОГДА Номенклатура.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС10) ТОГДА "НДС10"
        КОГДА Номенклатура.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.БезНДС) ТОГДА "БезНДС"
        ИНАЧЕ ""
    КОНЕЦ КАК ИмяСтавкиСтрокой
ИЗ
    Справочник.Номенклатура КАК Номенклатура

При большом количестве элементов конструкцию ВЫБОР можно быстро сформировать программно в цикле по коллекции Метаданные.Перечисления[ИмяПеречисления].ЗначенияПеречисления и встроить полученную подстроку в текст запроса перед его выполнением.

Способ 3. Программная постобработка и XMLСтрока

Если строковое представление не требуется непосредственно для фильтрации или группировки внутри СУБД, а нужно лишь для последующего вывода или интеграции, эффективнее получить строковые идентификаторы во встроенном языке 1С после выполнения запроса.

Для этого применяются встроенные методы платформы:

  1. Метод XMLСтрока(ЗначениеПеречисления) — возвращает точное имя идентификатора перечисления на латинице/кириллице без пробелов (например, "НДС20").
  2. Метод Строка(ЗначениеПеречисления) — возвращает пользовательский синоним перечисления (например, "20%").

Пример программной обработки выборки:


Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    ИмяИдентификатора = XMLСтрока(Выборка.СтавкаНДС);
    ПользовательскийСиноним = Строка(Выборка.СтавкаНДС);
    Сообщить(ИмяИдентификатора + " | " + ПользовательскийСиноним);
КонецЦикла;

Преобразование перечислений в Системе компоновки данных (СКД)

Если отчет разрабатывается на базе СКД, задача решается без усложнения текста запроса:

  1. На вкладке Вычисляемые поля схемы компоновки данных можно объявить новое поле и задать выражение Строка(СтавкаНДС).
  2. Над полученным полем СКД позволяет выполнять любые операции конкатенации строк, условия отбора, а также вызывать экспортные функции общих модулей конфигурации.
← На главную