Разработка и Конфигурация · 10 мин
Как в запросе 1С указать значение перечисления
Способы указать значение перечисления в запросе 1С: ЗНАЧЕНИЕ(), параметр запроса, ссылка через точку. Примеры кода, типичные ошибки и проверка результата.
Перечисления в 1С — это предопределённые списки значений, заданные в конфигурации: виды номенклатуры, ставки НДС, пол контрагента, типы цен и т.д. В запросе ссылку на конкретное значение перечисления нельзя указать строкой, как обычный текст — запрос просто не найдёт совпадений или выдаст ошибку исполнения.
Существует три рабочих способа передать значение перечисления в запрос: функция языка запросов ЗНАЧЕНИЕ(), параметр запроса с типом ПеречислениеСсылка и получение ссылки через менеджер перечисления во встроенном языке. Выбор зависит от того, известно ли значение на этапе написания запроса или приходит извне — из формы, отбора СКД или параметров обработки.
Ниже разобраны все три подхода с примерами кода, типичными ошибками и способами проверить, что отбор действительно сработал.
Способ 1: функция ЗНАЧЕНИЕ() в тексте запроса
Функция ЗНАЧЕНИЕ() — штатный механизм языка запросов для обращения к предопределённым данным: значениям перечислений, предопределённым элементам справочников, пустым ссылкам. Для перечислений синтаксис строится по шаблону ЗНАЧЕНИЕ(Перечисление.<ИмяПеречисления>.<ИмяЗначения>).
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Товары.Ссылка КАК Номенклатура
|ИЗ
| Справочник.Номенклатура КАК Товары
|ГДЕ
| Товары.ВидНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ВидыНоменклатуры.Товар)";
Имена перечисления и значения указываются так, как они заданы в конфигураторе — это идентификаторы метаданных, а не синонимы, которые видит пользователь. Если в конфигураторе значение называется НДС20, а синоним у него «20%», в запросе пишется именно НДС20.
Преимущество способа — отсутствие параметров и полный контроль на этапе написания запроса: конструктор запроса подскажет доступные значения, а ошибка в имени будет видна сразу. Недостаток — значение «зашито» в текст, и для другого значения придётся менять запрос или переходить на параметры.
Способ 2: передача значения через параметр запроса
Когда значение перечисления выбирает пользователь на форме или оно вычисляется в коде, его передают в запрос параметром. В тексте запроса параметр обозначается амперсандом: &СтавкаНДС.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Док.Ссылка КАК Документ
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Док
|ГДЕ
| Док.СтавкаНДС = &СтавкаНДС";
Запрос.УстановитьПараметр("СтавкаНДС", Перечисления.СтавкиНДС.НДС20);
Результат = Запрос.Выполнить();
Обратите внимание на правую часть УстановитьПараметр: используется менеджер Перечисления.<Имя>.<Значение> встроенного языка. Именно он возвращает ссылку типа ПеречислениеСсылка, которая корректно сравнится с полем в базе.
Через параметр можно передать и список значений для условия В (&СписокСтавок) — в УстановитьПараметр тогда передаётся массив или список значений, заполненный ссылками перечисления. Это удобно, когда нужно отобрать документы сразу по нескольким ставкам.
- 1Сформируйте текст запроса с условием Поле = &ИмяПараметра
- 2Получите ссылку: Перечисления.ИмяПеречисления.ИмяЗначения
- 3Вызовите Запрос.УстановитьПараметр("ИмяПараметра", Ссылка)
- 4Выполните запрос и проверьте, что выборка не пустая
Способ 3: получение ссылки во встроенном языке
Иногда значение известно только по имени в виде строки — например, при загрузке из файла или обмене, где перечисление передаётся текстом. В этом случае ссылку получают через менеджер перечисления с обращением по строковому имени.
ИмяЗначения = "НДС20";
СсылкаНаЗначение = Перечисления.СтавкиНДС[ИмяЗначения];
Запрос.УстановитьПараметр("Ставка", СсылкаНаЗначение);
Если обратиться по несуществующему имени, платформа вызовет исключение, поэтому при загрузке внешних данных стоит проверять результат: сравнивать полученное значение с Неопределено или оборачивать обращение в попытку. Безопасный вариант — перебрать метаданные перечисления и убедиться, что значение с таким именем существует.
Дополнительно полезно знать метод Перечисления.ИмяПеречисления.ПустаяСсылка() — он возвращает пустую ссылку перечисления, которая нужна для отбора незаполненных значений. В тексте запроса то же самое даёт ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.ПустаяСсылка).
Сравнение подходов и выбор под задачу
Каждый из способов решает свой класс задач, и смешивать их без необходимости не стоит. Таблица поможет быстро выбрать вариант.
| Критерий | ЗНАЧЕНИЕ() в тексте | Параметр запроса | Ссылка по строковому имени |
|---|---|---|---|
| Значение известно при разработке | Да | Да | Избыточно |
| Значение выбирает пользователь | Нет | Да | Да |
| Значение приходит строкой из обмена | Нет | Только после преобразования | Да |
| Контроль ошибок конструктором | Да | Нет | Нет |
| Отбор по списку значений (В) | Перечисление каждого через ИЛИ | Да, массивом | Да, массивом |
Сравнение вариантов
Подходит для фиксированных условий в отчётах и процедурах. Ограничение: значение нельзя поменять без изменения текста запроса.
Универсальный вариант для форм и отборов. Ограничение: нужно не забыть вызвать УстановитьПараметр до Выполнить().
Для загрузок и обменов, где значение приходит текстом. Ограничение: несуществующее имя вызывает исключение, нужна проверка.
Использование в СКД и динамических списках
В схеме компоновки данных значение перечисления указывается двумя путями. В тексте запроса набора данных работает та же функция ЗНАЧЕНИЕ(). В настройках отбора значение выбирается из выпадающего списка — СКД сама подставит ссылку нужного типа, вмешательство в код не требуется.
Если параметр отбора в СКД должен быть заполнен по умолчанию, на закладке «Параметры» в поле «Значение» также можно написать выражение ЗНАЧЕНИЕ(Перечисление.ВидыНоменклатуры.Товар) — конструктор воспримет его корректно.
В динамических списках с произвольным запросом действуют те же правила: либо ЗНАЧЕНИЕ() в тексте, либо программная установка параметра через Список.Параметры.УстановитьЗначениеПараметра("Имя", Перечисления.Имя.Значение) при создании формы.
В отчётах на СКД предпочтительнее выносить значение перечисления в параметр, а не зашивать его через ЗНАЧЕНИЕ(): так пользователь сможет менять отбор в настройках, не трогая схему.
Типичные ошибки и как их распознать
Самая частая ошибка — сравнение поля со строкой: ГДЕ СтавкаНДС = "НДС20". Запрос выполнится без ошибки, но не вернёт ни одной строки, потому что тип «строка» никогда не равен типу «ссылка на перечисление». Внешне это выглядит как «запрос не работает», хотя данные в базе есть.
Вторая ошибка — забыть вызвать УстановитьПараметр перед Выполнить(). Платформа выдаст сообщение «Параметр СтавкаНДС не установлен» — по нему сразу видно, что исправить.
Третья группа проблем — опечатки в именах метаданных: Перечисление.СтавкиНДС.НДС_20 вместо НДС20. Здесь запрос не выполнится вовсе, а консоль запросов или отладчик покажет ошибку компиляции текста. Проверяйте имена в конфигураторе, а не по синонимам в интерфейсе.
Как проверить, что отбор сработал
Базовая проверка — выполнить запрос в консоли запросов и убедиться, что выборка не пустая и содержит ожидаемые документы или элементы. Если строк нет, сначала убедитесь, что в базе вообще есть данные с этим значением: выполните тот же запрос без условия и посмотрите, какие значения реально хранятся в поле.
Для диагностики типов полезно вывести поле перечисления в результат запроса и сравнить его представление с ожидаемым. Если в поле хранится NULL (например, в соединениях), условие равенства не сработает — потребуется ЕСТЬ NULL или ЕСТЬNULL().
Как проверить результат
Поле содержит нужные значения перечисления
Поле пустое или содержит NULL — отбор не сработает
Возвращаются только строки с заданным значением
Пустая выборка при наличии данных — вероятно, сравнение со строкой
ЗНАЧЕНИЕ() подсвечивается, конструктор не ругается
Ошибка компиляции — проверьте имена метаданных
Что важно запомнить
Значение перечисления в запросе указывается через ЗНАЧЕНИЕ(Перечисление.Имя.Значение) или параметром со ссылкой из Перечисления.Имя.Значение. Сравнение со строкой не работает. Имена берутся из конфигуратора, а не из пользовательского интерфейса.
Частые вопросы
Можно ли указать значение перечисления строкой, как оно отображается пользователю?
Нет. Язык запросов сравнивает значения по типу и ссылке, а не по представлению. Условие Поле = "Товар" всегда даст ложь. Используйте ЗНАЧЕНИЕ() или параметр со ссылкой.
Как отобрать записи, где перечисление не заполнено?
Сравните поле с пустой ссылкой: ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.ПустаяСсылка) или передайте параметром Перечисления.СтавкиНДС.ПустаяСсылка(). Если поле может содержать NULL из соединения, добавьте обработку через ЕСТЬ NULL.
Как отобрать сразу по нескольким значениям перечисления?
Используйте оператор В с параметром-списком: ГДЕ Поле В (&СписокЗначений), а в УстановитьПараметр передайте массив или список значений со ссылками перечисления. Либо перечислите значения через ЗНАЧЕНИЕ() с оператором ИЛИ.
Почему запрос с ЗНАЧЕНИЕ() перестал работать после обновления конфигурации?
Скорее всего, перечисление или конкретное значение переименовали либо удалили в новой версии. Откройте конфигуратор, сверьте имя в запросе с актуальными метаданными и исправьте текст запроса.
Работает ли ЗНАЧЕНИЕ() в запросах к виртуальным таблицам регистров?
Да, функция доступна в параметрах виртуальных таблиц, в условиях отбора и в секции ГДЕ независимо от источника данных — это конструкция языка запросов, а не конкретной таблицы.
Как узнать имя значения перечисления, если виден только его синоним?
Откройте конфигуратор, найдите перечисление в дереве метаданных и посмотрите колонку «Имя» у нужного значения. Альтернатива — в толстом клиенте или через код вывести XMLСтрока(Перечисления.Имя.Значение), которая вернёт имя метаданных.