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

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

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

Почему возникают трудности с динамическим запросом?

Чаще всего разработчики пытаются собрать текст запроса вручную, используя тернарные операторы или условия Если-Тогда. Это приводит к тому, что в коде скапливаются «спагетти» из условий, где крайне сложно отследить, нужно ли ставить оператор И перед новым условием. Например, если пользователь заполнил только второе поле, но не заполнил первое, попытка добавить И в начало строки приведет к синтаксической ошибке в запросе.

Решение первое: классический прием «ГДЕ ИСТИНА»

Это самый эффективный и лаконичный способ, который позволяет навсегда забыть о проверках «является ли это условие первым». Мы используем логическую константу ИСТИНА, к которой через И «приклеиваем» любые другие условия.

Суть метода заключается в том, что при формировании текста запроса мы всегда пишем ГДЕ ИСТИНА. Даже если пользователь не выбрал ни одного фильтра, запрос будет корректным и выведет все данные. Если же отборы выбраны, мы просто дописываем их через И.

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


ТекстЗапроса = "ВЫБРАТЬ * ИЗ ... ГДЕ ИСТИНА";

Если ЗначениеЗаполнено(Студент) Тогда
    ТекстЗапроса = ТекстЗапроса + " И Студент = &Студент";
КонецЕсли;

Если ЗначениеЗаполнено(Факультет) Тогда
    ТекстЗапроса = ТекстЗапроса + " И Факультет = &Факультет";
КонецЕсли;

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

Решение второе: работа с массивом условий

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

  1. Создаем пустой массив, куда будем добавлять строки с условиями.
  2. Проверяем каждое поле формы: если оно заполнено, добавляем соответствующий фрагмент текста в массив.
  3. Если массив не пуст, преобразуем его в одну строку через оператор И.

Пример реализации такого подхода:


МассивУсловий = Новый Массив;

Если ЗначениеЗаполнено(НомерДоговора) Тогда
    МассивУсловий.Добавить("НомерДоговора = &НомерДоговора");
КонецЕсли;

Если ЗначениеЗаполнено(Группа) Тогда
    МассивУсловий.Добавить("Группа = &Группа");
КонецЕсли;

ТекстУсловий = "";
Если МассивУсловий.Количество() > 0 Тогда
    ТекстУсловий = "ГДЕ " + СтрСоединить(МассивУсловий, " И ");
КонецЕсли;

Использование Построителя запроса

Если вы работаете в старых конфигурациях или не хотите переходить на СКД, но отчет требует очень сложной логики отборов, обратите внимание на объект ПостроительЗапроса. Он специально создан для автоматической генерации запросов с динамическими условиями.

Преимущества ПостроителяЗапроса:

Советы по передаче параметров

При работе с динамическими условиями помните важную деталь: если параметр не используется (фильтр не задан), его не обязательно передавать в объект Запрос. Однако, если вы хотите использовать конструкцию вида (&Параметр = НЕОПРЕДЕЛЕНО ИЛИ Поле = &Параметр), то передача Неопределено позволит вам гибко управлять фильтрацией прямо из модуля.

Подведем итог: для большинства задач в обычных отчетах лучше всего подходит подход с ГДЕ ИСТИНА. Он максимально понятен, легко отлаживается и не требует использования тяжеловесных объектов платформы. Если же проект становится слишком масштабным, лучше сразу перенести логику в СКД, которая является стандартом для отчетов в 1С.

← На главную