При разработке отчетов на системе компоновки данных (СКД) часто возникает задача: сделать отчет максимально удобным для пользователя, минимизировав количество обязательных полей. Одной из классических ситуаций является работа с датами. Например, нам нужно, чтобы отчет формировался на дату, выбранную пользователем, но если она пуста — автоматически подставлялась текущая дата.
На первый взгляд задача кажется тривиальной, однако начинающие разработчики часто сталкиваются с тем, что их выражения в СКД не отрабатывают или игнорируются системой. Разберем подробно, почему так происходит и как правильно настроить логику вычисления параметров.
Проанализируем типичную попытку решения проблемы. Разработчик пишет в выражении параметра Дата следующую конструкцию:
Выбор Когда &Период Есть NULL Тогда ТекущаяДата() Иначе &Период Конец
В этом кроется первая и самая распространенная ошибка. В языке запросов и выражениях СКД тип Дата является примитивным. В отличие от ссылочных типов, он не может принимать значение NULL, если речь идет о значении параметра. Если пользователь не заполнил дату в диалоге, она принимает значение «пустой даты» — 0001-01-01 00:00:00.
Следовательно, проверка на NULL всегда будет возвращать Ложь, и система будет пытаться использовать пустую дату из начала нашей эры, что приведет к некорректным результатам в отчете.
Чтобы система корректно определила, что пользователь оставил поле пустым, нам нужно сравнивать параметр со значением пустой даты. В СКД это делается с помощью функции ДАТАВРЕМЯ(1, 1, 1). Рассмотрим исправленный вариант выражения:
Выбор
Когда &Период = ДАТАВРЕМЯ(1, 1, 1)
Тогда ТекущаяДатаСеанса()
Иначе &Период
Конец
Обратите внимание: вместо функции ТекущаяДата() мы рекомендуем использовать ТекущаяДатаСеанса(). Выясним причину: в клиент-серверном варианте работы обычная ТекущаяДата() вернет время сервера, которое может отличаться от часового пояса пользователя. Функция сеанса учитывает региональные настройки конкретного подключения, что критически важно для точности отчетов.
Даже если выражение написано верно, оно может не работать. Разберем ситуацию, когда при пустом периоде отчет все равно формируется некорректно. Причина кроется в механизме оптимизации СКД.
По умолчанию у параметров стоит режим использования Авто. Если параметр &Период не заполнен пользователем и не используется напрямую в активных частях запроса, компоновщик данных может просто «выключить» его из вычислений. Если параметр «выключен», любое выражение, ссылающееся на него, также перестает работать корректно.
Чтобы решить эту проблему, выполним следующие шаги:
&Период (тот, который заполняет пользователь).Установка этого флага гарантирует, что значение параметра (даже если оно пустое) всегда будет доступно для вычисления других параметров, таких как наша рабочая &Дата.
Часто в качестве входного параметра используется не просто Дата, а СтандартныйПериод (который включает дату начала и дату окончания). В этом случае обращение к параметру в выражении должно быть иным.
Проанализируем ситуацию: нам нужно получить дату окончания периода. Выражение будет выглядеть так:
Выбор
Когда ЗначениеЗаполнено(&СтандартныйПериод.ДатаОкончания)
Тогда &СтандартныйПериод.ДатаОкончания
Иначе КонецДня(ТекущаяДатаСеанса())
Конец
Здесь мы используем функцию ЗначениеЗаполнено(), которая отлично работает в выражениях СКД последних версий платформы 1С 8.3. Для изучения других практических вариантов работы с формулами компоновки можно использовать примеры отчетов со сложными выражениями в СКД.
Важно помнить, что СКД вычисляет параметры строго сверху вниз по списку. Если ваш вычисляемый параметр &Дата находится в списке выше, чем параметр-источник &Период, то в момент вычисления &Дата значение &Период еще не будет определено (или будет содержать значение по умолчанию).
Золотое правило: Параметр, который заполняет пользователь, всегда должен стоять в списке выше, чем параметры, которые от него зависят.
Если вы планируете использовать полученную дату в параметрах виртуальных таблиц (например, ОстаткиИОбороты), помните о «хитрости» автозаполнения. СКД иногда пытается самостоятельно управлять параметрами виртуальных таблиц, игнорируя ваши выражения.
Чтобы навязать СКД использование именно вашего вычисленного параметра, в тексте запроса следует использовать фигурные скобки:
ВЫБРАТЬ
ПродажиОстатки.Номенклатура,
ПродажиОстатки.КоличествоОстаток
ИЗ
РегистрНакопления.Продажи.Остатки({(&Дата)}, ) КАК ПродажиОстатки
Такой синтаксис указывает компоновщику, что параметр &Дата является обязательным для передачи в виртуальную таблицу именно в том виде, в котором он вычислен в схеме.
Чтобы не путать пользователя, технические параметры, которые вычисляются автоматически, лучше скрывать из пользовательских настроек:
&Дата.&Период, напротив, убедитесь, что флаг ограничения снят, чтобы пользователь мог его редактировать.Таким образом, мы создаем гибкий отчет: если пользователь хочет видеть данные на конкретное число — он его выбирает. Если же он просто открывает отчет и нажимает «Сформировать» — система автоматически подставляет актуальное время сеанса, обеспечивая получение свежих данных без лишних кликов. Для более эргономичного размещения полей ввода параметров на форме отчёта подойдёт методика стыковки элементов управляемой формы и пользовательских настроек СКД.