В процессе разработки и настройки отчетов на базе Системы компоновки данных (СКД) в 1С:Предприятие 8.3 часто возникает потребность в специфических периодах, которых нет в стандартном списке платформы. Например, пользователям могут потребоваться варианты «Последние два дня», «Последние два месяца» или «Предыдущая смена». Стандартный системный перечень («Сегодня», «Вчера», «Этот месяц» и т.д.) жестко прошит в платформе, и расширить его напрямую невозможно. Однако существуют эффективные обходные пути.
В этой статье мы подробно разберем, как реализовать поддержку произвольных периодов так, чтобы они корректно работали как при ручном формировании отчета, так и в автоматических рассылках отчетов, где критически важно автоматическое смещение дат.
Тип данных СтандартныйПериод является системным перечислением. Его визуальный список в интерфейсе формируется ядром платформы 1С. Разработчик не может программно добавить в этот объект новые элементы. Если пользователь выбирает «Произвольный период» и фиксирует даты, то при использовании в рассылках эти даты останутся статичными. Например, если указать 01.10.2023–02.10.2023, то и через месяц рассылка придет с данными за эти же числа. Наша задача — заставить систему вычислять даты динамически относительно ТекущаяДата.
Проанализируем самый «чистый» способ, который не требует написания сложного кода и работает на уровне настроек самой схемы компоновки данных. Мы можем использовать язык выражений СКД для динамического расчета дат.
Разберем по шагам, как настроить период «Последние 2 дня»:
НачалоПериода и КонецПериода.НачалоПериода пропишем формулу:
ДобавитьКДате(НачалоПериода(ТекущаяДатаСеанса(), "День"), "День", -1)
КонецПериода укажем:
КонецПериода(ТекущаяДатаСеанса(), "День")
Важный нюанс: использование функции ТекущаяДатаСеанса() вместо обычной ТекущаяДата() позволяет корректно учитывать часовой пояс пользователя, если сервер находится в другом регионе. Это критично для крупных распределенных систем.
Если мы хотим предоставить пользователю возможность выбирать в интерфейсе (в том числе в настройках рассылки) конкретный именованный вариант, рассмотрим следующий алгоритм:
Создадим новый параметр, например, ВариантПериода с типом Строка. В списке доступных значений для этого параметра добавим: «ДваДня», «ТриДня», «Произвольный».
Теперь в параметре НачалоПериода в поле выражения используем конструкцию ВЫБОР КОГДА:
ВЫБОР
КОГДА &ВариантПериода = "ДваДня"
ТОГДА ДобавитьКДате(НачалоПериода(ТекущаяДатаСеанса(), "День"), "День", -1)
КОГДА &ВариантПериода = "ТриДня"
ТОГДА ДобавитьКДате(НачалоПериода(ТекущаяДатаСеанса(), "День"), "День", -2)
ИНАЧЕ &НачалоПериода
КОНЕЦ
Этот подход позволяет пользователю в настройках рассылки просто выбрать понятную строку из списка, а система сама вычислит актуальные даты на момент формирования письма.
Выясним, как управлять периодом программно, если логика расчета слишком сложна для выражений СКД. Для этого используется обработчик события ПриКомпоновкеРезультата в модуле отчета. Рассмотрим пример кода, который перехватывает настройки перед формированием:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
// Получаем доступ к параметрам данных
ПараметрыКД = КомпоновщикНастроек.Настройки.ПараметрыДанных;
// Попробуем найти пользовательскую настройку для нашего параметра
ПараметрВариант = ПараметрыКД.Элементы.Найти("ОтборПоПериоду");
Если ПараметрВариант <> Неопределено И ПараметрВариант.Использование Тогда
Если ПараметрВариант.Значение = "ПоследниеДваДня" Тогда
// Отключаем стандартные выражения, если они были заданы в схеме
// Устанавливаем значения напрямую
ПараметрыКД.УстановитьЗначениеПараметра("НачалоПериода", НачалоДня(ДобавитьКДате(ТекущаяДата(), "День", -1)));
ПараметрыКД.УстановитьЗначениеПараметра("КонецПериода", КонецДня(ТекущаяДата()));
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Обратите внимание на объект КомпоновщикНастроек.ПользовательскиеНастройки. Если параметр выведен в пользовательские настройки (что обычно и происходит в рассылках), изменять нужно именно элементы в коллекции ПользовательскиеНастройки, так как они имеют приоритет над основными настройками компоновщика.
Проанализируем ситуацию с рассылками в типовых конфигурациях (УТ 11, ERP, КА). Рассылка отчетов базируется на механизмах Библиотеки стандартных подсистем (БСП). Когда вы создаете рассылку, система копирует текущий Вариант отчета. При необходимости можно использовать готовое решение для расширения периодических параметров в рассылке отчетов БСП.
Чтобы ваш кастомный период заработал в рассылке:
Если вы используете Решение 1 (выражения в СКД), убедитесь, что в пользовательских настройках самого отчета (в форме отчета) флажок использования для дат снят или они не редактируются пользователем вручную. Иначе зафиксированные пользователем даты перекроют динамическое выражение из схемы.
Разберем ситуацию, когда разработчик не видит тип СтандартнаяДатаНачала в списке доступных типов параметров. Этот тип появляется в СКД только в определенных условиях:
Дата (без галочки составного типа).СтандартныйПериод, а затем платформа позволит использовать уточняющие типы для отдельных дат.Использование СтандартнаяДатаНачала удобно тем, что оно предоставляет пользователю системный выпадающий список (Начало этого дня, начало прошлого месяца и т.д.), но оно все равно не решает задачу добавления новых пунктов (например, «2 месяца назад»), поэтому использование выражений (Решение 1) остается наиболее гибким вариантом.
Мы рассмотрели несколько подходов к расширению функционала периодов в 1С. Для большинства задач использование выражений СКД является оптимальным: оно не требует изменения программного кода, легко переносится между базами и безупречно работает в механизмах автоматических рассылок. Если же требуется сложная бизнес-логика или интеграция с внешними данными, следует использовать программную установку параметров в модуле отчета через событие ПриКомпоновкеРезультата.