Как реализовать необязательный параметр в запросе 1С и почему игнорируются фигурные скобки?

Программист 1С v8.3 (Обычные формы)
← На главную

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

Почему условие в фигурных скобках {} не работает в обычном запросе?

Проанализируем типичную ошибку начинающих разработчиков. Использование фигурных скобок {ГДЕ ...} — это синтаксис, предназначенный исключительно для Системы компоновки данных (СКД) или Построителя отчета. Когда мы пишем обычный объект Запрос и устанавливаем его текст через Запрос.Текст = "...", платформа воспринимает всё содержимое внутри фигурных скобок как комментарий и просто игнорирует его при выполнении на уровне СУБД.

Для того чтобы эти условия заработали, запрос должен быть обработан специальным механизмом, который «развернет» эти скобки в реальное условие ГДЕ. Если же вы используете Запрос.Выполнить(), вам нужно применять другие подходы.

Способ 1. Универсальное условие с использованием конструкции ВЫБОР

Разберем самый простой вариант, который не требует динамического изменения текста запроса. Мы можем прописать логику проверки параметра прямо в секции ГДЕ. Идея заключается в том, что условие должно возвращать Истина либо при совпадении значений, либо если параметр не заполнен.

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


Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|	КонтрагентыМенеджеры.Ссылка КАК Контрагент,
|	КонтрагентыМенеджеры.МенеджерПокупателя
|ИЗ
|	Справочник.Контрагенты.МенеджерыПокупателя КАК КонтрагентыМенеджеры
|ГДЕ
|	ВЫБОР 
|		КОГДА &Менеджер = ЗНАЧЕНИЕ(Справочник.Пользователи.ПустаяСсылка) ТОГДА ИСТИНА
|		ИНАЧЕ КонтрагентыМенеджеры.МенеджерПокупателя = &Менеджер
|	КОНЕЦ";

Запрос.УстановитьПараметр("Менеджер", Менеджер);
РезультатЗапроса = Запрос.Выполнить().Выгрузить();

Важный нюанс: этот метод отлично подходит для небольших таблиц. Однако стоит помнить, что использование сложных логических условий в ГДЕ может помешать СУБД эффективно использовать индексы, что приведет к замедлению работы на огромных объемах данных.

Также обратите внимание на типы данных. Если параметр &Менеджер имеет составной тип, проверка на ПустаяСсылка конкретного справочника может не сработать. В таких случаях надежнее передавать Неопределено и проверять на него.

Способ 2. Динамическое формирование текста запроса

Проанализируем ситуацию, когда нам важна максимальная производительность. Чтобы СУБД построила оптимальный план выполнения, в тексте запроса не должно быть лишних условий. Мы будем добавлять условие ГДЕ только тогда, когда параметр действительно заполнен.

Посмотрим, как это реализовать на практике:


ТекстУсловия = "";
Если ЗначениеЗаполнено(Менеджер) Тогда
    ТекстУсловия = "ГДЕ КонтрагентыМенеджеры.МенеджерПокупателя = &Менеджер";
КонецЕсли;

Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|	КонтрагентыМенеджеры.Ссылка,
|	КонтрагентыМенеджеры.МенеджерПокупателя
|ИЗ
|	Справочник.Контрагенты.МенеджерыПокупателя КАК КонтрагентыМенеджеры
|" + ТекстУсловия;

Если ЗначениеЗаполнено(Менеджер) Тогда
    Запрос.УстановитьПараметр("Менеджер", Менеджер);
КонецЕсли;

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

Способ 3. Использование Построителя отчета (для обычных форм)

Если ваша задача подразумевает, что завтра условий может стать больше (по организации, по региону, по группе контрагентов), лучше сразу задействовать ПостроительОтчета. Этот объект умеет самостоятельно обрабатывать те самые фигурные скобки {}, которые игнорирует обычный запрос.

Выясним, как правильно настроить такой механизм. Для начала подготовим текст запроса с конструкциями построителя:


ТекстЗапроса = 
"ВЫБРАТЬ
|	КонтрагентыМенеджеры.Ссылка,
|	КонтрагентыМенеджеры.МенеджерПокупателя
|ИЗ
|	Справочник.Контрагенты.МенеджерыПокупателя КАК КонтрагентыМенеджеры
|{ГДЕ
|	КонтрагентыМенеджеры.МенеджерПокупателя.* КАК Менджер}";

Построитель = Новый ПостроительОтчета(ТекстЗапроса);
// Если параметр Менеджер на форме заполнен, добавляем его в отбор построителя
Если ЗначениеЗаполнено(Менеджер) Тогда
    НовыйОтбор = Построитель.Отбор.Добавить("Менджер");
    НовыйОтбор.Значение = Менеджер;
    НовыйОтбор.Использование = Истина;
КонецЕсли;

// Построитель сам сформирует правильный текст запроса с учетом отборов
Построитель.Выполнить();
Результат = Построитель.Результат.Выгрузить();

Использование построителя позволяет пользователю интерактивно добавлять любые отборы, если вывести ПостроительОтчета.Отбор на форму в виде табличного поля. Это гораздо мощнее и гибче, чем прописывание каждого условия вручную в коде.

Важные рекомендации по работе с табличными частями

Разберем еще один критический момент. В исходном вопросе данные выбираются из табличной части Справочник.Контрагенты.МенеджерыПокупателя.

  1. Дублирование записей: Если у одного контрагента в списке указано три менеджера, и вы не наложили фильтр, то этот контрагент появится в результате трижды. Чтобы избежать этого, всегда используйте ключевое слово РАЗЛИЧНЫЕ или группировку по ссылке контрагента.
  2. Индексация: По умолчанию реквизиты табличных частей не индексируются. Если вы планируете часто искать контрагентов по менеджеру в этой таблице, обязательно зайдите в конфигуратор и установите свойство «Индексировать» для реквизита МенеджерПокупателя в табличной части справочника. Это критически важно для быстродействия.
  3. Работа с пустой ссылкой: Помните, что ЗНАЧЕНИЕ(Справочник.Имя.ПустаяСсылка) работает только для конкретных типов. Если вы работаете с составным типом, используйте проверку на НЕОПРЕДЕЛЕНО или проверяйте заполненность параметра в коде перед запуском запроса.

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

← На главную