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

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

Как выбрать перечисление в 1С: запросы, код и проверка значений

Как выбрать перечисление в 1С: в запросе, в коде, через ЗначениеПеречисления и ПеречислениеМенеджер. Примеры, сравнение способов, типичные ошибки и ответы на вопросы.

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

Ключевой принцип: значение перечисления — это не строка. Сравнение СтавкаНДС = "НДС20" не сработает, потому что строка никогда не равна значению перечисления. Нужно обращаться к значению через специальные конструкции: ЗНАЧЕНИЕ(...) в запросе или Перечисления.ИмяПеречисления.ИмяЗначения в коде. Ниже разобраны все рабочие способы с примерами и проверкой результата.

Выбор перечисления в запросе через ЗНАЧЕНИЕ()

В языке запросов 1С прямое обращение к значению перечисления выполняется оператором ЗНАЧЕНИЕ с полным путём: имя перечисления из конфигуратора и имя значения. Пример для отбора номенклатуры по виду:

ВЫБРАТЬ

Номенклатура.Ссылка КАК Товар

ИЗ

Справочник.Номенклатура КАК Номенклатура

ГДЕ

Номенклатура.ВидНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ВидыНоменклатуры.Товар)

Имена внутри ЗНАЧЕНИЕ() — это имена объектов метаданных, а не синонимы, которые видит пользователь. Если в конфигураторе значение называется НДС20, а пользователю показывается «20%», в запросе пишется именно НДС20. Ошибка в имени приводит к сообщению «Неверное имя предопределенного значения» при выполнении запроса.

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

Выбор через параметр запроса

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

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

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

"ВЫБРАТЬ

| Сотрудники.Ссылка

|ИЗ

| Справочник.Сотрудники КАК Сотрудники

|ГДЕ

| Сотрудники.Пол = &Пол";

Запрос.УстановитьПараметр("Пол", Перечисления.ПолФизическогоЛица.Мужской);

Результат = Запрос.Выполнить().Выбрать();

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

Частный случай — отбор по нескольким значениям перечисления. Здесь используют оператор В со списком значений или массивом, переданным параметром. Условие ГДЕ Ставка В (&СписокСтавок) корректно отработает, если в параметр передать массив из значений перечисления.

Обращение к перечислению в коде

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

Типовая проверка значения реквизита выглядит так:

Если Документ.Статус = Перечисления.СтатусыДокументов.Проведен Тогда

// действия для проведённого документа

КонецЕсли;

Когда имя перечисления или значения известно только в виде строки (например, при загрузке из файла или из настроек), используют индексное обращение: Перечисления["ВидыНоменклатуры"]["Товар"]. Этот способ универсальнее, но медленнее и не контролируется компилятором: опечатка в строке проявится только в момент выполнения.

Сравнение способов обращения

Перечисления.Имя.Значение

Быстрый и контролируется при проверке модуля. Подходит, когда имена известны на этапе разработки.

Перечисления[ИмяСтрокой][ЗначениеСтрокой]

Для универсальных механизмов обмена и настроек. Ошибки имени выявляются только в рантайме.

Менеджер перечисления

Перечисления.Имя.ПустаяСсылка() и работа со списком значений. Нужен для проверок на пустое значение и перебора всех значений.

Работа через менеджер перечисления

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

  • Перечисления.СтатусыДокументов.ПустаяСсылка() — получение пустого значения для сравнения или инициализации реквизита;
  • перебор всех значений перечисления через метаданные: Метаданные.Перечисления.СтатусыДокументов.ЗначенияПеречисления — когда нужно заполнить список выбора на форме или проверить допустимость строки;
  • проверка принадлежности значения типу: ТипЗнч(Значение) = Тип("ПеречислениеСсылка.СтатусыДокументов").

Проверка на пустое значение — отдельная тема. Конструкция Если НЕ ЗначениеЗаполнено(Реквизит) работает и для перечислений, но в запросах сравнение с пустой ссылкой пишется явно: ГДЕ Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыДокументов.ПустаяСсылка). Сравнение с NULL здесь не подходит — пустая ссылка перечисления и NULL в запросе различаются, особенно в левых соединениях.

Как выбрать перечисление в запросе: порядок действий
  1. 1
    Откройте конфигуратор и найдите перечисление в дереве метаданных, запомните точное имя объекта и имена значений
  2. 2
    Напишите запрос с условием ГДЕ Реквизит = ЗНАЧЕНИЕ(Перечисление.ИмяПеречисления.ИмяЗначения) либо с параметром
  3. 3
    Если значение приходит извне — передайте его через УстановитьПараметр, а не подстановкой в текст
  4. 4
    Выполните запрос в консоли запросов и убедитесь, что отбор вернул ожидаемые строки
  5. 5
    Проверьте граничные случаи: пустое значение реквизита и NULL от соединения таблиц

Отбор по перечислению в динамических списках и СКД

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

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

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

Типичные ошибки
01
Сравнение значения перечисления со строкой: условие Реквизит = "НДС20" всегда ложно, отбор возвращает пустой результат
02
Использование синонима вместо имени значения в ЗНАЧЕНИЕ() — ошибка выполнения запроса о неверном имени
03
Сравнение пустой ссылки перечисления с NULL в запросе — строки с пустым значением теряются
04
Подстановка имени значения строкой прямо в текст запроса вместо параметра — риск ошибок и сложность сопровождения
05
Переименование значения перечисления в конфигураторе без поиска всех обращений — запросы и код начинают падать после обновления

Проверка результата и границы безопасной работы

Проверить корректность выбора перечисления можно до запуска в рабочей базе. Консоль запросов в режиме предприятия покажет, возвращает ли условие строки, а отладчик позволит убедиться, что в параметр попало значение нужного типа — в табло значений тип отображается как «ПеречислениеСсылка.Имя», а не «Строка».

Изменения, связанные с перечислениями, безопасны, пока речь идёт о чтении данных. Риск появляется при двух операциях: переименовании или удалении значения перечисления в конфигураторе и массовой замене значений в реквизитах объектов обработкой. Удаление значения, на которое ссылаются записи базы, приведёт к «битым» ссылкам вида «<Объект не найден>» в этих реквизитах. Перед такими изменениями делайте резервную копию и проверяйте ссылки через поиск ссылок на объект.

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

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

Тип значения в параметре запроса
Норма

ПеречислениеСсылка.ИмяПеречисления

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

Строка — отбор не сработает

Результат запроса в консоли
Норма

Возвращаются строки с нужным значением реквизита

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

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

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

Используется ЗНАЧЕНИЕ(...ПустаяСсылка)

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

Сравнение с NULL — строки теряются

Частые вопросы о выборе перечислений в 1С

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

Нет, такое сравнение всегда ложно. Если на входе строка, её нужно сначала преобразовать в значение перечисления в коде через Перечисления[Имя][Значение] и передать в запрос параметром.

Как выбрать все документы, где перечисление не заполнено?

Используйте условие ГДЕ Реквизит = ЗНАЧЕНИЕ(Перечисление.ИмяПеречисления.ПустаяСсылка). Учтите, что если реквизит участвует в левом соединении, для отсутствующих записей значение будет NULL, и его нужно обрабатывать отдельно через ЕСТЬ NULL.

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

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

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

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

Чем отличается ЗНАЧЕНИЕ() от параметра запроса?

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

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

Используйте сравнение типа: ТипЗнч(Переменная) = Тип("ПеречислениеСсылка.ИмяПеречисления"). Это надёжнее, чем проверка представления значения строкой.

Итог

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

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