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

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

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

Выясним причину: почему не работает конструкция с МЕЖДУ и псевдонимом

Проанализируем типичную ошибку в тексте запроса СКД:


{ГДЕ
    (ВТ_ИзделияКИзготовлению.СменноеЗаданиеДата МЕЖДУ &ДатаСменногоЗаданияНачало И &ДатаСменногоЗаданияОкончание) КАК ДатаСменногоЗадания}

В расширении языка запросов СКД синтаксис {ГДЕ (Условие) КАК ИмяПоля} выполняет строго определенную задачу: он объявляет пользовательское поле отбора. Это означает следующее:

  1. Такое условие попадает в результирующий SQL-запрос только тогда, когда пользователь или разработчик явно включит отбор по полю ДатаСменногоЗадания на вкладке «Отбор».
  2. Наличие значений в параметрах &ДатаСменногоЗаданияНачало и &ДатаСменногоЗаданияОкончание никак не активирует данную секцию. Поскольку отбор по псевдониму не был задействован в структуре отчета, компоновщик макета просто вырезал всю конструкцию целиком.
  3. Оператор МЕЖДУ требует одновременного наличия обеих границ. Если пользователь захочет указать только дату начала или только дату окончания, такое выражение выдаст некорректный результат либо пустую выборку.

Способ 1. Раздельные условия на границы периода (рекомендуемый)

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

В тексте запроса СКД заменим блок отбора на следующий:


{ГДЕ 
    ВТ_ИзделияКИзготовлению.СменноеЗаданиеДата >= &ДатаСменногоЗаданияНачало,
    ВТ_ИзделияКИзготовлению.СменноеЗаданиеДата <= &ДатаСменногоЗаданияОкончание}

Обратим внимание: условия перечисляются через запятую (или оформляются в виде двух независимых блоков {ГДЕ ...}). В синтаксисе СКД запятая в блоке {ГДЕ} выступает логическим «И», но дает компоновщику возможность исключать любое из условий, если соответствующий параметр не передан или не заполнен.

Теперь настроим параметры схемы компоновки данных на вкладке «Параметры»:

  1. Создадим основной параметр Период с типом СтандартныйПериод. Включим для него признак доступности пользователю.
  2. Для параметров ДатаСменногоЗаданияНачало и ДатаСменногоЗаданияОкончание снимем флажок «Ограничение доступности» (сделаем их недоступными для прямого редактирования пользователем).
  3. В колонке «Выражение» для параметра начала периода напишем: &Период.ДатаНачала
  4. В колонке «Выражение» для параметра окончания периода настроим захват конца дня с корректной обработкой незаполненной даты:
    
    ВЫБОР КОГДА &Период.ДатаОкончания = ДАТАВРЕМЯ(1, 1, 1) ТОГДА ДАТАВРЕМЯ(1, 1, 1) ИНАЧЕ КОНЕЦПЕРИОДА(&Период.ДатаОкончания, "ДЕНЬ") КОНЕЦ
    

Важный нюанс: при выборе даты в типе СтандартныйПериод значение ДатаОкончания содержит время 00:00:00. Если в поле СменноеЗаданиеДата хранятся документы с произвольным временем в течение дня, применение функции КонецПериода необходимо, иначе документы за последний день периода будут исключены из отчета. Проверка на ДАТАВРЕМЯ(1, 1, 1) защищает от ситуации, когда открытая дата конца периода превращается в 01.01.0001 23:59:59, что привело бы к ошибочному отсечению всех записей.

Способ 2. Использование штатного механизма отборов СКД без параметров

Проанализируем альтернативный вариант, который отлично подходит для реальных таблиц (когда дата не является обязательным параметром виртуальной таблицы, например, среза последних или оборотов регистра).

В этом случае параметры запроса можно не создавать вовсе:

  1. Полностью удалим условия на даты в фигурных скобках из текста запроса.
  2. Перейдем на вкладку «Настройки» в схеме компоновки данных.
  3. На вкладке «Отбор» добавим поле СменноеЗаданиеДата.
  4. Установим вид сравнения «В интервале (включая границы)».
  5. Нажмем правой кнопкой мыши по добавленному отбору и выберем «Свойства элемента пользовательских настроек». Отметим флаг «Включать в пользовательские настройки» и зададим понятный заголовок (например, Период сменного задания).

В результате на пользовательской форме появится компактный элемент ввода периода, а СКД сформирует условие ГДЕ в результирующем запросе только тогда, когда пользователь заполнит значения дат.

← На главную