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

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

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

Как обратиться к перечислению в запросе 1С: ЗНАЧЕНИЕ, сравнение, ВЫБОР, сортировка по порядку значений и типичные ошибки разработчиков.

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

Главное, что нужно понять: значение перечисления нельзя получить через точку от объекта, как это делается со ссылками на справочники. Для перечислений в языке запросов существует специальная функция ЗНАЧЕНИЕ, а для представления и порядка значений — свои приёмы. Ниже разобраны все рабочие сценарии: от простого сравнения до сортировки по порядку значений перечисления и обработки пустых ссылок.

Как перечисления хранятся и почему это важно для запроса

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

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

Базовый синтаксис: функция ЗНАЧЕНИЕ

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

Запрос = Новый Запрос;

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

"ВЫБРАТЬ

| РеализацияТоваровУслуг.Ссылка КАК Документ

|ИЗ

| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг

|ГДЕ

| РеализацияТоваровУслуг.ВидОперации = ЗНАЧЕНИЕ(Перечисление.ВидыОперацийРеализация.Товары)";

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

Сравнение и отбор по перечислению в условии ГДЕ

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

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

"ВЫБРАТЬ

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

|ИЗ

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

|ГДЕ

| Заказы.Статус В (&Статусы)";

СписокСтатусов = Новый СписокЗначений;

СписокСтатусов.Добавить(Перечисления.СтатусыЗаказов.КОтгрузке);

СписокСтатусов.Добавить(Перечисления.СтатусыЗаказов.ВРаботе);

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

Передача параметром удобна, когда набор значений определяется логикой программы, а не зашит в текст запроса. При этом в параметр можно передать и массив, и список значений — платформа корректно развернёт коллекцию в условие В. Сравнение на неравенство (<>) тоже работает, но помните про NULL: если поле может принимать NULL из-за соединения таблиц, условие «не равно» такие записи отсечёт, и их придётся обрабатывать отдельно через ЕСТЬ NULL.

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

Если просто выбрать поле типа «перечисление» в запрос, в результате будет ссылка на значение перечисления. В отчёте на СКД платформа сама покажет представление, но при программной обработке выборки вам понадобится либо само значение для сравнений, либо строка для вывода.

"ВЫБРАТЬ

| Док.Статус КАК Статус,

| ПРЕДСТАВЛЕНИЕ(Док.Статус) КАК СтатусПредставление

|ИЗ

| Документ.ЗаказКлиента КАК Док"

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

Конструкция ВЫБОР и логика по значениям перечисления

Когда по значению перечисления нужно вычислить другой показатель — например, признак срочности, коэффициент или текстовую метку, — используется конструкция ВЫБОР. Каждое значение сравнивается с ЗНАЧЕНИЕ, а ветка ИНАЧЕ страхует от непредусмотренных значений.

"ВЫБРАТЬ

| ВЫБОР

| КОГДА Док.Приоритет = ЗНАЧЕНИЕ(Перечисление.Приоритеты.Высокий)

| ТОГДА 1

| КОГДА Док.Приоритет = ЗНАЧЕНИЕ(Перечисление.Приоритеты.Средний)

| ТОГДА 2

| ИНАЧЕ 3

| КОНЕЦ КАК ПорядокСортировки

|ИЗ

| Документ.Задача КАК Док"

Ветка ИНАЧЕ обязательна в прикладном коде: если в конфигурацию позже добавят новое значение перечисления, запрос без ИНАЧЕ вернёт NULL для таких записей, и последующая группировка или сортировка поведёт себя неожиданно. Явная обработка «всего остального» делает поведение предсказуемым.

Конструкция ВЫБОР с перечислением — стандартный способ задать произвольный порядок сортировки. Сортировать результат по самому полю перечисления не всегда даёт порядок, заданный в конфигураторе: порядок зависит от внутреннего представления. Надёжнее пронумеровать значения через ВЫБОР и сортировать по числовой колонке.
ПЗ
Практическое замечание

Пустая ссылка и незаполненное перечисление

Поле типа «перечисление» может быть не заполнено — тогда оно содержит пустую ссылку. Проверка на пустое значение делается через тот же ЗНАЧЕНИЕ, но с указанием специального значения ПустаяСсылка.

"ГДЕ

| Док.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказов.ПустаяСсылка)"

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

Перечисление в параметрах виртуальных таблиц и СКД

Виртуальные таблицы регистров принимают параметры отбора, и перечисления там передаются так же — через параметр с типом «перечисление». Важно, чтобы тип параметра совпадал с типом измерения или реквизита, иначе отбор молча не сработает.

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

Типичные ошибки
01
Сравнение поля-перечисления со строкой: условие Док.Статус = "Новый" никогда не выполнится, потому что сравниваются разные типы данных
02
Использование синонима вместо имени значения в ЗНАЧЕНИЕ: запрос не компилируется, если синоним отличается от имени в конфигураторе
03
Отсутствие ветки ИНАЧЕ в ВЫБОР: при добавлении нового значения перечисления в конфигурацию запрос начинает возвращать NULL
04
Игнорирование пустых ссылок: записи с незаполненным перечислением выпадают из отборов и искажают итоги отчётов

Проверка результата и отладка запроса

После написания запроса проверьте три вещи. Во-первых, что условие по перечислению реально отбирает записи: выполните запрос в консоли запросов на тестовой базе и сравните количество строк с ожидаемым. Во-вторых, что в выборке нет неожиданных NULL — они появляются при соединениях и неполных ВЫБОР. В-третьих, что представления выводятся на нужном языке, если конфигурация многоязычная.

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

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

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

Количество строк в выборке
Норма

Совпадает с числом документов с нужным статусом в списке документов

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

Выборка пустая или содержит лишние записи

Значения поля перечисления в результате
Норма

Только ожидаемые значения, без NULL без причины

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

Появляются NULL или неожиданные значения

Текст запроса после изменения конфигурации
Норма

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

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

Ошибка «Поле не найдено» при открытии отчёта

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

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

Нет, типы не совпадают, и условие не сработает. Если у вас есть строковое название значения, сначала преобразуйте его в значение перечисления во встроенном языке (например, через Перечисления.ИмяПеречисления[ИмяЗначения]) и передайте в запрос параметром.

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

Прямой сортировки по порядку конфигуратора в языке запросов нет. Стандартный приём — пронумеровать значения конструкцией ВЫБОР в нужном порядке и добавить УПОРЯДОЧИТЬ ПО этой числовой колонке.

Что вернёт ЗНАЧЕНИЕ, если значение удалили из конфигурации?

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

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

Сформируйте список значений или массив во встроенном языке, передайте его параметром и используйте оператор В (&Параметр). Платформа автоматически развернёт коллекцию в набор условий.

Чем отличается пустая ссылка перечисления от NULL?

Пустая ссылка — это штатное незаполненное значение поля, она существует в самой таблице. NULL появляется только в результате соединений, когда записи в присоединяемой таблице не нашлось. Проверяются они по-разному: пустая ссылка — через ЗНАЧЕНИЕ(...ПустаяСсылка), NULL — через ЕСТЬ NULL.

Работает ли ЗНАЧЕНИЕ с перечислениями в СКД?

Да, в тексте запроса схемы компоновки функция ЗНАЧЕНИЕ работает так же. Для пользовательских отборов лучше добавить параметр с типом ссылки на перечисление, чтобы в настройках отчёта был выпадающий список значений.

Итог

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

Значение перечисления в запросе задаётся через ЗНАЧЕНИЕ(Перечисление.Имя.Значение) по имени из конфигуратора, а не по синониму. Строковые сравнения не работают, пустые ссылки и NULL обрабатываются отдельно, а для сортировки и логики по значениям используйте конструкцию ВЫБОР с обязательной веткой ИНАЧЕ.