При разработке отчетов на системе компоновки данных (СКД) часто возникает задача: предоставить пользователю возможность выбирать интервал дат на форме отчета с помощью удобного поля с типом СтандартныйПериод, но при этом сделать фильтрацию необязательной. Нередко разработчики сталкиваются с ситуацией, когда период на форме выбран, однако отчет выводит абсолютно все данные, игнорируя заданные границы. Разберем по шагам, почему это происходит и как правильно реализовать такой отбор.
Проанализируем типичную ошибку в тексте запроса СКД:
{ГДЕ
(ВТ_ИзделияКИзготовлению.СменноеЗаданиеДата МЕЖДУ &ДатаСменногоЗаданияНачало И &ДатаСменногоЗаданияОкончание) КАК ДатаСменногоЗадания}
В расширении языка запросов СКД синтаксис {ГДЕ (Условие) КАК ИмяПоля} выполняет строго определенную задачу: он объявляет пользовательское поле отбора. Это означает следующее:
ДатаСменногоЗадания на вкладке «Отбор».&ДатаСменногоЗаданияНачало и &ДатаСменногоЗаданияОкончание никак не активирует данную секцию. Поскольку отбор по псевдониму не был задействован в структуре отчета, компоновщик макета просто вырезал всю конструкцию целиком.МЕЖДУ требует одновременного наличия обеих границ. Если пользователь захочет указать только дату начала или только дату окончания, такое выражение выдаст некорректный результат либо пустую выборку.Рассмотрим классическое и самое надежное решение. Чтобы система компоновки данных самостоятельно определяла, когда нужно накладывать ограничение на дату, разделим проверку на две независимые части через фигурные скобки расширения языка запросов.
В тексте запроса СКД заменим блок отбора на следующий:
{ГДЕ
ВТ_ИзделияКИзготовлению.СменноеЗаданиеДата >= &ДатаСменногоЗаданияНачало,
ВТ_ИзделияКИзготовлению.СменноеЗаданиеДата <= &ДатаСменногоЗаданияОкончание}
Обратим внимание: условия перечисляются через запятую (или оформляются в виде двух независимых блоков {ГДЕ ...}). В синтаксисе СКД запятая в блоке {ГДЕ} выступает логическим «И», но дает компоновщику возможность исключать любое из условий, если соответствующий параметр не передан или не заполнен.
Теперь настроим параметры схемы компоновки данных на вкладке «Параметры»:
Период с типом СтандартныйПериод. Включим для него признак доступности пользователю.ДатаСменногоЗаданияНачало и ДатаСменногоЗаданияОкончание снимем флажок «Ограничение доступности» (сделаем их недоступными для прямого редактирования пользователем).
&Период.ДатаНачала
ВЫБОР КОГДА &Период.ДатаОкончания = ДАТАВРЕМЯ(1, 1, 1) ТОГДА ДАТАВРЕМЯ(1, 1, 1) ИНАЧЕ КОНЕЦПЕРИОДА(&Период.ДатаОкончания, "ДЕНЬ") КОНЕЦ
Важный нюанс: при выборе даты в типе СтандартныйПериод значение ДатаОкончания содержит время 00:00:00. Если в поле СменноеЗаданиеДата хранятся документы с произвольным временем в течение дня, применение функции КонецПериода необходимо, иначе документы за последний день периода будут исключены из отчета. Проверка на ДАТАВРЕМЯ(1, 1, 1) защищает от ситуации, когда открытая дата конца периода превращается в 01.01.0001 23:59:59, что привело бы к ошибочному отсечению всех записей.
Проанализируем альтернативный вариант, который отлично подходит для реальных таблиц (когда дата не является обязательным параметром виртуальной таблицы, например, среза последних или оборотов регистра).
В этом случае параметры запроса можно не создавать вовсе:
СменноеЗаданиеДата.Период сменного задания).В результате на пользовательской форме появится компактный элемент ввода периода, а СКД сформирует условие ГДЕ в результирующем запросе только тогда, когда пользователь заполнит значения дат.