При разработке отчетов в системе компоновки данных (СКД) часто возникает необходимость использовать текущую дату. Это может потребоваться для фильтрации данных (например, выборка активных заказов на сегодня), для вычислений в ресурсах или просто для вывода информации в заголовке отчета. Важно понимать, что в самом языке запросов 1С функции ТекущаяДата() не существует — запрос выполняется на стороне СУБД, которая «не знает» о функциях встроенного языка 1С. В этом легко убедиться, используя консоль запросов — для этого пригодится универсальная консоль запросов и СКД для разработчиков. Однако СКД предоставляет богатый инструментарий для обхода этого ограничения. Разберем все доступные способы подробно.
Самый простой и эффективный способ получить текущую дату в запросе — это использование вкладки Параметры в схеме компоновки данных. Рассмотрим, как это настроить по шагам:
&ТекДата).ТекущаяДата() или ТекущаяДатаСеанса().Важный нюанс: проанализируем разницу между этими функциями. Функция ТекущаяДата() возвращает время сервера, на котором выполняется код. Если сервер находится в Москве, а пользователь — в Петропавловске-Камчатском, время может значительно отличаться. Поэтому в большинстве случаев правильнее использовать ТекущаяДатаСеанса(), которая учитывает часовой пояс текущего пользователя.
Разберем ситуацию с пользовательскими настройками. Если мы укажем выражение для параметра, но при этом включим его в пользовательские настройки, может возникнуть конфликт. Проанализируем поведение системы: если параметр включен в пользовательские настройки, но в схеме заполнено поле Выражение, то значение из выражения будет иметь приоритет, а выбор пользователя может игнорироваться. Чтобы избежать ошибок, для таких параметров в колонке Использование лучше устанавливать значение Авто.
Иногда требуется более сложная логика получения даты — например, с учетом графиков работ или специфических смещений. В этом случае мы можем вызвать экспортную функцию из общего модуля прямо в выражении параметра СКД. Посмотрим на пример реализации.
Сначала создадим функцию в общем модуле (модуль должен иметь флаг Сервер и Вызов сервера):
Функция ПолучитьНачалоРабочегоДня() Экспорт
// Здесь может быть сложная логика
Возврат НачалоДня(ТекущаяДатаСеанса());
КонецФункции
Затем в параметрах СКД в колонке Выражение укажем:
ИмяОбщегоМодуля.ПолучитьНачалоРабочегоДня()
Этот метод позволяет гибко управлять данными, не перегружая саму схему компоновки сложными конструкциями.
Часто перед нами стоит задача: "Подставить текущую дату по умолчанию, но дать пользователю возможность ее изменить". Если мы просто пропишем выражение в параметрах, пользователь не сможет переопределить дату вручную на форме отчета. В такой ситуации нам поможет программная установка значения в модуле отчета. Разберем, как это сделать в событии ПриКомпоновкеРезультата.
Рассмотрим пример кода в модуле отчета:
Процедура ПриКомпоновкеРезультата(ДанныеРасшифровки, СтандартнаяОбработка)
// Получаем текущие настройки компоновщика
ПараметрТекДата = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("ТекДата");
// Проверяем, заполнено ли значение пользователем
Если ПараметрТекДата <> Неопределено И НЕ ПараметрТекДата.Использование Тогда
ПараметрТекДата.Значение = ТекущаяДатаСеанса();
ПараметрТекДата.Использование = Истина;
КонецЕсли;
КонецПроцедуры
Этот подход решает проблему, описанную многими разработчиками: мы обеспечиваем актуальность данных "из коробки", сохраняя при этом гибкость отчета для конечного пользователя.
Если текущая дата нужна нам не для фильтрации в ГДЕ, а для вывода в колонке или для расчетов (например, вычисление срока просрочки в днях), мы можем использовать Вычисляемые поля. В СКД функции встроенного языка доступны там напрямую.
Выясним, как рассчитать количество дней с момента отгрузки до текущего момента. В списке вычисляемых полей добавим новое поле и в колонке Выражение напишем:
РазностьДат(ДатаОтгрузки, ТекущаяДатаСеанса(), "ДЕНЬ")
Это поле можно будет использовать как обычный ресурс или детальное поле отчета.
В типовых конфигурациях для задания временных рамок часто используется тип СтандартныйПериод. Мы можем инициализировать его текущим днем или месяцем через выражение. Посмотрим на синтаксис:
Новый СтандартныйПериод(НачалоДня(ТекущаяДатаСеанса()), КонецДня(ТекущаяДатаСеанса()))
Если прописать это в выражении параметра с типом СтандартныйПериод, отчет при открытии всегда будет предлагать данные за "Сегодня".
Проанализируем ситуацию, когда в запросе нужно проверить дату на заполненность или сравнить ее с текущей, если она не задана. В запросе СКД удобно использовать конструкцию ВЫБОР КОГДА совместно с параметрами:
ГДЕ ВЫБОР
КОГДА &УказыватьДату = ЛОЖЬ ТОГДА ИСТИНА
ИНАЧЕ ДатаДокумента <= &ТекДата
КОНЕЦ
Либо, если мы хотим подставить текущую дату прямо внутри запроса в случае пустого значения поля:
ЕСТЬNULL(Таблица.ДатаЗавершения, &ТекДата)
Здесь &ТекДата — это предварительно подготовленный параметр с выражением ТекущаяДатаСеанса().
Для улучшения визуального восприятия отчета полезно выводить дату формирования прямо в заголовке. Выясним, как это сделать средствами СКД без программирования. В настройках отчета перейдем в Другие настройки -> Заголовок. Там можно использовать шаблоны. Однако более надежный способ — использование параметров в тексте заголовка.
В области настроек (Layout) можно создать текстовое поле и указать в нем выражение:
"Отчет сформирован по состоянию на: " + Формат(&ТекДата, "ДФ=dd.MM.yyyy")
Подведем итог: для большинства задач достаточно указать ТекущаяДатаСеанса() в выражении параметра на закладке "Параметры". Если же логика требует ручной корректировки пользователем, следует перенести установку значения в модуль отчета в процедуру ПриКомпоновкеРезультата. Использование функций общих модулей оправдано только при наличии сложной бизнес-логики расчета даты.