Как программно рассчитать и установить параметры отчета СКД на основании другого параметра?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке отчетов на базе Системы Компоновки Данных (СКД) часто возникает задача: пользователь выбирает на форме один ключевой параметр (например, дату формирования отчета), а другие параметры (начало и конец предыдущего периода, даты сравнения) должны рассчитаться и подставиться автоматически. Разберем типичную ситуацию, с которой сталкиваются разработчики, выясним причину ошибки и рассмотрим правильные способы решения задачи.

Проанализируем классическую ошибку. Разработчик пытается перехватить формирование отчета в обработчике ПриКомпоновкеРезультата модуля объекта отчета и вручную прописать значения параметров:


Процецедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)     

    ПараметрДатаОтчета = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("КонецПериод"));
    
    Параметр = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("Дата1"));
    Параметр.Значение   = НачалоМесяца(ДобавитьМесяц(ПараметрДатаОтчета.Значение, -2));
    Параметр.Использование = Истина;   
    
    Параметр1 = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("Дата2"));
    Параметр1.Значение   = КонецМесяца(ДобавитьМесяц(ПараметрДатаОтчета.Значение, -2));
    Параметр1.Использование = Истина;

КонецПроцедуры

Несмотря на написанный код, отчет формируется так, будто в параметр подставляется пустая дата (или начало отчета времен). Посмотрим, почему это происходит.

Причины некорректной работы программной установки параметров

Архитектура СКД подразумевает разделение настроек на несколько слоев. Исходный код из примера обращается к свойству КомпоновщикНастроек.Настройки. Это базовые настройки схемы (те, что заданы в конфигураторе). Когда пользователь вносит изменения в интерфейсе (выбирает дату в шапке отчета), эти данные помещаются в КомпоновщикНастроек.ПользовательскиеНастройки.

При стандартной генерации отчета (если включена СтандартнаяОбработка = Истина) платформа накладывает пользовательские настройки поверх базовых. В результате:

  1. Читая значение из базовых настроек, мы получаем пустоту, а не то, что ввел пользователь.
  2. Даже если мы запишем вычисленные даты в базовые настройки, платформа при выводе перекроет их пользовательскими (в которых эти зависимые даты, как правило, не заполнены или сброшены).

Рассмотрим правильные подходы к решению этой задачи.

Способ 1: Декларативный расчет параметров (Рекомендуемый)

Лучший подход — отказаться от написания кода в модуле объекта и перенести логику непосредственно в саму схему СКД. Это избавит от множества проблем, включая сюрпризы при фоновом выполнении или рассылке отчетов, где форма отчета не создается.

Откроем схему компоновки данных, перейдем на вкладку Параметры. Для зависимых параметров Дата1 и Дата2 в колонке Выражение напишем формулы на встроенном языке СКД:


// Для параметра Дата1 (начало месяца, сдвинутое на -2 месяца)
НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(&КонецПериод, "МЕСЯЦ", -2), "МЕСЯЦ")

// Для параметра Дата2 (конец месяца, сдвинутое на -2 месяца)
КОНЕЦПЕРИОДА(ДОБАВИТЬКДАТЕ(&КонецПериод, "МЕСЯЦ", -2), "МЕСЯЦ")

Также можно вызывать экспортные функции из общих серверных модулей прямо в поле выражения. Например, МойОбщийМодуль.РассчитатьСложнуюДату(&КонецПериод). Это позволяет реализовать сколь угодно сложную логику вычисления.

Способ 2: Использование методов БСП

Если конфигурация построена на Библиотеке Стандартных Подсистем (БСП) и значения действительно нужно установить программно (например, на основе сложного запроса к базе данных), воспользуемся готовыми методами. Они корректно работают со всеми слоями настроек компоновщика.

В процедуре ПриКомпоновкеРезультата вызовем процедуру БСП:


КомпоновкаДанныхКлиентСервер.УстановитьПараметр(КомпоновщикНастроек, "Дата1", ВычисленнаяДата1);
КомпоновкаДанныхКлиентСервер.УстановитьПараметр(КомпоновщикНастроек, "Дата2", ВычисленнаяДата2);

Способ 3: Полная программная компоновка отчета

Если БСП в конфигурации нет, а программное вмешательство необходимо, нам придется перехватить весь процесс генерации отчета, отключив стандартную обработку.

Разберем по шагам, как это сделать правильно:

  1. Отключаем типовой механизм платформы: СтандартнаяОбработка = Ложь;
  2. Получаем итоговые настройки, которые объединяют базовую схему и то, что ввел пользователь в форме: Настройки = КомпоновщикНастроек.ПолучитьНастройки();
  3. Находим нужные параметры внутри полученной переменной Настройки и устанавливаем им вычисленные значения.
  4. Инициализируем КомпоновщикМакетаКомпоновкиДанных, передаем туда саму схему и наши модифицированные Настройки.
  5. Полученный макет передаем в ПроцессорКомпоновкиДанных.
  6. Выводим результат в ДокументРезультат с помощью ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент.

Важное ограничение данного метода: визуальные значения параметров на форме отчета после формирования не обновятся. Пользователь будет видеть старые (пустые) даты отбора, хотя данные выведутся за правильный вычисленный период. Поэтому первый способ (использование выражений СКД) всегда остается наиболее предпочтительным с точки зрения архитектуры платформы 1С.

← На главную