При разработке отчетов на Системе Компоновки Данных (СКД) мы часто сталкиваемся с требованием установить период по умолчанию. Классическая задача: пользователь открывает отчет, и период автоматически устанавливается как "с начала текущего года по текущую дату".
Казалось бы, задача тривиальная, но новички и даже опытные программисты часто спотыкаются о нюансы работы объекта СтандартныйПериод, приоритеты настроек и пользовательский кэш. В этой статье мы подробно разберем, как правильно реализовать эту логику, рассмотрим несколько способов решения и проанализируем типичные ошибки.
Прежде чем писать код, давайте разберемся, с чем мы работаем. В параметрах СКД часто используется тип значения СтандартныйПериод. Это не просто две даты (начала и окончания). Это сложный объект платформы, который имеет свойство Вариант.
Вариант определяет логику заполнения дат. Например, "Этот месяц", "Прошлый год", "С начала этого года". Если мы хотим, чтобы отчет всегда открывался с периодом "С начала года", правильнее всего оперировать именно вариантом, а не пытаться вручную вычислять и подставлять конкретные даты (например, '01.01.2024').
Самый элегантный и "чистый" способ, который не требует написания кода в модуле формы или объекта, — использование механизма выражений непосредственно в схеме компоновки данных. Это позволяет использовать встроенные механизмы платформы. Давайте рассмотрим алгоритм действий:
НачалоПериода и КонецПериода, либо единый параметр Период типа СтандартныйПериод.НачалоПериода в колонке Выражение пропишите формулу.
Для установки начала года используйте следующую конструкцию языка выражений СКД:
НачалоПериода(ТекущаяДата(), "Год")
Как это работает: При инициализации настроек СКД вычислит это выражение и подставит результат в качестве значения по умолчанию. Это идеальный вариант для установки дефолтных значений.
Если у вас используется единый параметр Период (тип СтандартныйПериод), то задать ему значение через выражение сложнее, так как выражение возвращает конкретную дату, а не объект СтандартныйПериод. В этом случае лучше использовать связь параметров, о которой мы поговорим ниже.
Если логика выбора периода сложная (например, зависит от роли пользователя или других условий), нам придется прибегнуть к программированию. Здесь важно помнить, что мы работаем с вариантами периода.
Рассмотрим пример кода, который можно разместить в модуле формы отчета (например, в событии ПриЗагрузкеПользовательскихНастроекНаСервере или при создании на сервере, если настройки еще не загружены).
Нам нужно найти параметр настроек и установить ему правильное значение.
// Получаем доступ к пользовательским настройкам
ПользовательскиеНастройки = Отчет.КомпоновщикНастроек.ПользовательскиеНастройки;
// Ищем параметр "Период" по имени в основных настройках, чтобы получить его ID
// (Важно: в пользовательских настройках поиск идет по ID, а не по имени)
ИдентификаторПараметра = Неопределено;
Для Каждого ЭлементНастройки Из Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы Цикл
Если Строка(ЭлементНастройки.Параметр) = "Период" Тогда
ИдентификаторПараметра = ЭлементНастройки.ИдентификаторПользовательскойНастройки;
Прервать;
КонецЕсли;
КонецЦикла;
Если ИдентификаторПараметра <> Неопределено Тогда
// Находим элемент в пользовательских настройках
ЗначениеПараметра = ПользовательскиеНастройки.Элементы.Найти(ИдентификаторПараметра);
Если ЗначениеПараметра <> Неопределено Тогда
// Создаем новый стандартный период
НовыйПериод = Новый СтандартныйПериод;
// Устанавливаем вариант "С начала этого года"
НовыйПериод.Вариант = ВариантСтандартногоПериода.СНачалаЭтогоГода;
// Присваиваем значение параметру
ЗначениеПараметра.Значение = НовыйПериод;
ЗначениеПараметра.Использование = Истина;
КонецЕсли;
КонецЕсли;
Использование ВариантСтандартногоПериода.СНачалаЭтогоГода предпочтительнее ручного расчета дат, так как в интерфейсе пользователя отобразится понятное название периода, а не сухие цифры.
Часто в запросе используются параметры &НачалоПериода и &КонецПериода (тип Дата), а пользователю на форму хочется вывести один красивый элемент управления СтандартныйПериод.
Давайте разберем, как это настроить корректно:
Период, укажите тип СтандартныйПериод.НачалоПериода и КонецПериода установите ограничение доступности (галочки "Ограничение доступности"), чтобы пользователь их не видел.&Период.ДатаНачала&Период.ДатаОкончания
Теперь, установив значение параметра Период в вариант "С начала этого года" (любым из способов выше), система автоматически разложит его на даты и передаст в запрос.
Очень часто разработчики пишут правильный код или настраивают схему, но при запуске отчета видят старый период. Давайте проанализируем основные причины.
В теме обсуждения был приведен пример кода, который не будет работать:
// НЕПРАВИЛЬНО
НастройкиОтчета = КомпоновщикНастроек.ПолучитьНастройки();
ПараметрДатаНачала = НастройкиОтчета.ПараметрыДанных.НайтиЗначениеПараметра(...);
ПараметрДатаНачала.Значение = НачалоГода(ТекущаяДата());
Причина: Метод ПолучитьНастройки() возвращает копию настроек для компоновки результата. Изменение этой копии никак не влияет на настройки, отображаемые на форме, и не сохраняется в компоновщике для следующего формирования. Работать нужно напрямую с коллекциями КомпоновщикНастроек.Настройки или КомпоновщикНастроек.ПользовательскиеНастройки.
Это самая распространенная причина, по которой изменения "не применяются".
Ситуация: Вы добавили выражение НачалоПериода(ТекущаяДата(), "Год") в конфигураторе. Запускаете отчет в Предприятии, а там всё равно стоит прошлая дата или пустой период.
Причина: 1С автоматически сохраняет настройки отчета для каждого пользователя. Если вы ранее открывали этот отчет и меняли период, платформа запомнила ваш выбор. При следующем открытии сохраненная пользовательская настройка имеет приоритет над настройкой из конфигуратора (схемы).
Решение:
После этого ваши изменения, сделанные в конфигураторе, вступят в силу. Для программного сброса можно использовать метод:
КомпоновщикНастроек.ЗагрузитьНастройки(СхемаКомпоновкиДанных.НастройкиПоУмолчанию);
Но будьте осторожны: это сбросит все личные настройки пользователя (отборы, группировки).
Некоторые пытаются менять параметры в событии модуля объекта ПриКомпоновкеРезультата.
Это сработает технически (отчет сформируется за нужный период), но визуально пользователь этого не увидит. На форме останутся старые даты, а отчет покажет данные за новые. Это вводит пользователей в заблуждение. Изменять настройки для интерактивной работы нужно в модуле формы.
Для решения задачи установки периода "С начала года":
НачалоПериода(ТекущаяДата(), "Год") в схеме компоновки данных. Не забыть сбросить пользовательские настройки для проверки.СтандартныйПериод и связать его с датами запроса через выражения &Период.ДатаНачала.Вариант = ВариантСтандартногоПериода.СНачалаЭтогоГода, работая с коллекцией ПользовательскиеНастройки, а не с копией настроек.