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

Программист 1С v8.3 (Управляемые формы) Управленческий учет IT и автоматизация бизнеса
← На главную

При разработке отчетов без использования Системы компоновки данных (СКД) часто возникает задача: сделать некоторые параметры запроса необязательными. Например, если пользователь выбрал водителя, отчет должен показать данные только по нему, а если оставил поле пустым — вывести информацию по всем водителям. Разберем, как реализовать такую логику правильно и избежать распространенных ошибок.

Метод динамической модификации текста запроса

Первый и самый распространенный подход — это изменение текста Запрос.Текст непосредственно перед его выполнением. Если параметр не заполнен, мы просто удаляем соответствующее условие из секции ГДЕ.

Рассмотрим пример реализации:


// Предположим, у нас есть базовый текст запроса
Запрос.Текст = "ВЫБРАТЬ * ИЗ РегистрСведений.од_РаспоряженияНаДоставку КАК Распоряжения 
ГДЕ И Распоряжения.Транспорт.Водитель = &Водитель";

Если ЗначениеЗаполнено(Водитель) Тогда
    Запрос.УстановитьПараметр("Водитель", Водитель);
Иначе
    // Удаляем условие, если водитель не выбран
    Запрос.Текст = СтрЗаменить(Запрос.Текст, "И Распоряжения.Транспорт.Водитель = &Водитель", "");
КонецЕсли;

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

Использование логических условий внутри запроса

Вместо того чтобы изменять текст запроса «на лету», можно передать в Запрос пустую ссылку и обработать её логикой самого языка запросов. Это избавляет от строковых операций и делает код чище.

Разберем конструкцию ВЫБОР КОГДА:


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

Здесь, если параметр &Водитель не заполнен (передана пустая ссылка), условие всегда возвращает ИСТИНА, что фактически отключает фильтр. Это наиболее безопасный и элегантный способ.

Почему параметр «заполняется сам»?

Часто программисты сталкиваются с тем, что при повторном запуске отчета в поле ввода формы подставляется значение, выбранное ранее. Разберем, почему это происходит и как с этим бороться.

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

Как это исправить:

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

Рекомендации по написанию условий

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

Помните: Запрос в 1С реагирует на УстановитьПараметр только в том случае, если данный параметр действительно присутствует в тексте Запрос.Текст. Если вы удалили условие из текста запроса, вызов УстановитьПараметр для этого имени никак не повлияет на результат, но и ошибку не вызовет.

← На главную