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

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

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

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

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

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

Ниже разобраны все три подхода с примерами кода, типичными ошибками и способами проверить, что отбор действительно сработал.

Способ 1: функция ЗНАЧЕНИЕ() в тексте запроса

Функция ЗНАЧЕНИЕ() — штатный механизм языка запросов для обращения к предопределённым данным: значениям перечислений, предопределённым элементам справочников, пустым ссылкам. Для перечислений синтаксис строится по шаблону ЗНАЧЕНИЕ(Перечисление.<ИмяПеречисления>.<ИмяЗначения>).

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

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

"ВЫБРАТЬ

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

|ИЗ

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

|ГДЕ

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

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

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

Способ 2: передача значения через параметр запроса

Когда значение перечисления выбирает пользователь на форме или оно вычисляется в коде, его передают в запрос параметром. В тексте запроса параметр обозначается амперсандом: &СтавкаНДС.

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

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

"ВЫБРАТЬ

| Док.Ссылка КАК Документ

|ИЗ

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

|ГДЕ

| Док.СтавкаНДС = &СтавкаНДС";

Запрос.УстановитьПараметр("СтавкаНДС", Перечисления.СтавкиНДС.НДС20);

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

Обратите внимание на правую часть УстановитьПараметр: используется менеджер Перечисления.<Имя>.<Значение> встроенного языка. Именно он возвращает ссылку типа ПеречислениеСсылка, которая корректно сравнится с полем в базе.

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

Порядок действий с параметром
  1. 1
    Сформируйте текст запроса с условием Поле = &ИмяПараметра
  2. 2
    Получите ссылку: Перечисления.ИмяПеречисления.ИмяЗначения
  3. 3
    Вызовите Запрос.УстановитьПараметр("ИмяПараметра", Ссылка)
  4. 4
    Выполните запрос и проверьте, что выборка не пустая

Способ 3: получение ссылки во встроенном языке

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

ИмяЗначения = "НДС20";

СсылкаНаЗначение = Перечисления.СтавкиНДС[ИмяЗначения];

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

Если обратиться по несуществующему имени, платформа вызовет исключение, поэтому при загрузке внешних данных стоит проверять результат: сравнивать полученное значение с Неопределено или оборачивать обращение в попытку. Безопасный вариант — перебрать метаданные перечисления и убедиться, что значение с таким именем существует.

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

Сравнение подходов и выбор под задачу

Каждый из способов решает свой класс задач, и смешивать их без необходимости не стоит. Таблица поможет быстро выбрать вариант.

КритерийЗНАЧЕНИЕ() в текстеПараметр запросаСсылка по строковому имени
Значение известно при разработкеДаДаИзбыточно
Значение выбирает пользовательНетДаДа
Значение приходит строкой из обменаНетТолько после преобразованияДа
Контроль ошибок конструкторомДаНетНет
Отбор по списку значений (В)Перечисление каждого через ИЛИДа, массивомДа, массивом

Сравнение вариантов

ЗНАЧЕНИЕ() в тексте запроса

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

Параметр запроса

Универсальный вариант для форм и отборов. Ограничение: нужно не забыть вызвать УстановитьПараметр до Выполнить().

Ссылка по строковому имени

Для загрузок и обменов, где значение приходит текстом. Ограничение: несуществующее имя вызывает исключение, нужна проверка.

Использование в СКД и динамических списках

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

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

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

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

Типичные ошибки и как их распознать

Самая частая ошибка — сравнение поля со строкой: ГДЕ СтавкаНДС = "НДС20". Запрос выполнится без ошибки, но не вернёт ни одной строки, потому что тип «строка» никогда не равен типу «ссылка на перечисление». Внешне это выглядит как «запрос не работает», хотя данные в базе есть.

Вторая ошибка — забыть вызвать УстановитьПараметр перед Выполнить(). Платформа выдаст сообщение «Параметр СтавкаНДС не установлен» — по нему сразу видно, что исправить.

Третья группа проблем — опечатки в именах метаданных: Перечисление.СтавкиНДС.НДС_20 вместо НДС20. Здесь запрос не выполнится вовсе, а консоль запросов или отладчик покажет ошибку компиляции текста. Проверяйте имена в конфигураторе, а не по синонимам в интерфейсе.

Типичные ошибки
01
Сравнение поля со строкой "НДС20" — запрос возвращает пустой результат без ошибки
02
Пропуск УстановитьПараметр — исключение "Параметр не установлен" при выполнении
03
Использование синонима значения вместо имени метаданных — ошибка компиляции запроса
04
Отбор по удалённому или переименованному значению после обновления конфигурации — запрос перестаёт работать

Как проверить, что отбор сработал

Базовая проверка — выполнить запрос в консоли запросов и убедиться, что выборка не пустая и содержит ожидаемые документы или элементы. Если строк нет, сначала убедитесь, что в базе вообще есть данные с этим значением: выполните тот же запрос без условия и посмотрите, какие значения реально хранятся в поле.

Для диагностики типов полезно вывести поле перечисления в результат запроса и сравнить его представление с ожидаемым. Если в поле хранится NULL (например, в соединениях), условие равенства не сработает — потребуется ЕСТЬ NULL или ЕСТЬNULL().

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

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

Выполнение запроса без условия
Норма

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

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

Поле пустое или содержит NULL — отбор не сработает

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

Возвращаются только строки с заданным значением

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

Пустая выборка при наличии данных — вероятно, сравнение со строкой

Текст запроса в консоли
Норма

ЗНАЧЕНИЕ() подсвечивается, конструктор не ругается

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

Ошибка компиляции — проверьте имена метаданных

Итог

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

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

Частые вопросы

Можно ли указать значение перечисления строкой, как оно отображается пользователю?

Нет. Язык запросов сравнивает значения по типу и ссылке, а не по представлению. Условие Поле = "Товар" всегда даст ложь. Используйте ЗНАЧЕНИЕ() или параметр со ссылкой.

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

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

Как отобрать сразу по нескольким значениям перечисления?

Используйте оператор В с параметром-списком: ГДЕ Поле В (&СписокЗначений), а в УстановитьПараметр передайте массив или список значений со ссылками перечисления. Либо перечислите значения через ЗНАЧЕНИЕ() с оператором ИЛИ.

Почему запрос с ЗНАЧЕНИЕ() перестал работать после обновления конфигурации?

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

Работает ли ЗНАЧЕНИЕ() в запросах к виртуальным таблицам регистров?

Да, функция доступна в параметрах виртуальных таблиц, в условиях отбора и в секции ГДЕ независимо от источника данных — это конструкция языка запросов, а не конкретной таблицы.

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

Откройте конфигуратор, найдите перечисление в дереве метаданных и посмотрите колонку «Имя» у нужного значения. Альтернатива — в толстом клиенте или через код вывести XMLСтрока(Перечисления.Имя.Значение), которая вернёт имя метаданных.