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

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

При работе с запросами в системе «1С:Предприятие 8» часто возникает задача вывода данных из реквизитов, имеющих тип Перечисление. Начинающие разработчики нередко сталкиваются с дилеммой: выводить ли ссылку на значение, текстовое представление или программный идентификатор. Ситуация осложняется, когда перечисление содержит десятки значений, и логика их обработки должна быть гибкой.

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

Вариант 1: Вывод ссылки на значение перечисления

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

Рассмотрим пример кода:


ВЫБРАТЬ
    СправочникНоменклатура.Ссылка КАК Товар,
    СправочникНоменклатура.Статус КАК Статус
ИЗ
    Справочник.Номенклатура КАК СправочникНоменклатура

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

Вариант 2: Получение текстового представления (Синонима)

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

Давайте проанализируем, как это работает:


ВЫБРАТЬ
    СправочникНоменклатура.Ссылка КАК Товар,
    ПРЕДСТАВЛЕНИЕ(СправочникНоменклатура.Статус) КАК СтатусТекстом
ИЗ
    Справочник.Номенклатура КАК СправочникНоменклатура

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

Вариант 3: Использование конструкции ВЫБОР КОГДА (для получения имен)

Иногда требуется получить не синоним, а именно программное имя (идентификатор) значения перечисления (например, Оплачено, НеОплачено). Способ, предложенный автором вопроса, является рабочим, но имеет свои нюансы.

Рассмотрим пример такой конструкции:


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

Анализ ситуации: Если значений 15 и более, такой код становится громоздким и трудночитаемым («хардкод»). При добавлении нового значения в перечисление вам придется вручную вносить правки во все подобные запросы. Мы рекомендуем использовать этот метод только в исключительных случаях, когда нужно жестко задать строковое значение для ограниченного набора элементов.

Вариант 4: Масштабируемый метод через временную таблицу

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

Выполним следующие шаги:

  1. Создадим таблицу значений в коде 1С, заполнив ее ссылками на перечисления и их именами.
  2. Передадим эту таблицу в запрос как параметр.
  3. В запросе поместим ее во временную таблицу и соединим с основными данными.

Посмотрим на пример реализации:


// В коде 1С:
ТЗ_Имена = Новый ТаблицаЗначений;
ТЗ_Имена.Колонки.Добавить("СсылкаПеречисления");
ТЗ_Имена.Колонки.Добавить("ИмяЗначения", Новый ОписаниеТипов("Строка",,,, Новый КвалификаторыСтроки(100)));

Для Каждого ЗначениеИзМетаданных Из Метаданные.Перечисления.СтатусыЗаказов.ЗначенияПеречисления Цикл
    НоваяСтрока = ТЗ_Имена.Добавить();
    Имя = ЗначениеИзМетаданных.Имя;
    НоваяСтрока.СсылкаПеречисления = Перечисления.СтатусыЗаказов[Имя];
    НоваяСтрока.ИмяЗначения = Имя;
КонецЦикла;

Запрос.УстановитьПараметр("ТаблицаИмен", ТЗ_Имена);

Теперь проанализируем текст самого запроса:


ВЫБРАТЬ
    ВТ_Имена.СсылкаПеречисления КАК СсылкаПеречисления,
    ВТ_Имена.ИмяЗначения КАК ИмяЗначения
ПОМЕСТИТЬ ВТ_Соответствия
ИЗ
    &ТаблицаИмен КАК ВТ_Имена
;

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

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

Дополнительные возможности: Функция ПОРЯДОК()

Выясним еще одну интересную деталь. Если вам нужно вывести не текст, а порядковый номер значения (индекс), как оно задано в дереве метаданных, используйте функцию ПОРЯДОК(). Это крайне полезно для правильной сортировки данных в отчетах.

Пример использования:


ВЫБРАТЬ
    Статус,
    ПОРЯДОК(Статус) КАК ПорядковыйНомер
ИЗ
    Справочник.Договоры
УПОРЯДОЧИТЬ ПО
    ПорядковыйНомер

Подведем итоги

Выбор метода зависит от конечной цели:

Использование правильного подхода не только упростит поддержку вашего кода, но и обеспечит стабильную работу системы при развитии конфигурации.

← На главную