Метод построения нарастающих итогов в таблице и диаграмме.
Одна из самых сложных проблем в СКД -создание ресурсов вида “нарастающие” итоги.
1.Типичным решением этой проблемы является левое соединение таблицы с самой собой. В группировки включается период исходной таблицы по которому строится итог с накоплением. В условие соединения входит выражение вида Исх.ПериодДень >= Соед.ПериодДень. Собственно итоговое поле в запросе вычисляется агрегатной функцией СУММА(Соед.Ресурс) в присоединенной таблице по полю ресурса.
Этот подход хорош для специализиированных отчетов в которых зараннее известно какое поле периода будет использовано в группировке.
В универсальных отчетах (например по регистру накоплений с настройкой Авто в периоде виртуальной таблицы) , в которых заранее неизвестно, группировку по какому периоду будет выполнять пользователь – этот подход становится малоприемлем. Кроме того – этот подход приводит к дополнительным накладным расходам на выполнение более сложного запроса.
2. Другим широко применяемым подходом является использование функции СКД “ВычислитьВыражение” в вычислимых полях.
Например настраивается вычислимое поле “КоличествоНарастающий” : ВычислитьВыражение(“Сумма(Количество)”, , , “Первая”, “Текущая”)
Вычислимое поле настраивается ресурсом. Для правильного расчета в группировках и итогах в выражении ресурса должна быть использована функция Максимум()
Максимум(КоличествоНарастающий)
Этот подход прекрасно работает в таблицах по любым вертикально расположенным группировкам, но совершенно не работает в диаграммах. Диаграммы почему то совершенно не хотят вычислять функцию “ВычислитьВыражение”.Вместо значений с накоплением в диаграмме отображаются значения без накопления.
В горизонтально расположенных группировках таблиц – нарастающий итог тоже не рассчитывается… но это еще предмет будущего изучения.
Решении которое предлагаю ниже – отталкивается от второго подхода. Нарастающие итоги создаются созданием ресурса на основе вычисляемого поля с функцие СКД “ВыполнитьВыражение”. Единственное дополнительное условие которое вводится – ограничение на имя “накопительного” ресурса – в нем должно быть в любом регистре подстрока “нараст”. Зачем это нужно – увидите далее.
Теперь надо чтобы при выборе такого ресурса в диагрумму значения считались с накоплением. Идея проста – накапливать значение для каждого ресурса в момент когда выводится точка диаграммы и подменять значение в диаграмме на “накопленное”.
Для этого используется обработчик события “ПередВыводомЭлементРезультата” в модуле объекта отчета.
Процедура ПередВыводомЭлементРезультата(МакетКомпоновки, ПроцессорКомпоновки, ЭлементРезультата) Экспорт
Макеты = ЭлементРезультата.Макеты;
Для Каждого Мак из Макеты Цикл
Если ТипЗнч(Мак.Макет) = Тип(“МакетРесурсаДиаграммыОбластиКомпоновкиДанных”) Тогда
СтруктМакета = Новый Структура(“Макет,Поле,ИмяПараметраПоля,ИмяПараметраВыражения,ЗначениеРесурса”);
ФлДобавлятьМакет = Ложь;
Для Каждого Пар из Мак.Параметры Цикл
Если ТипЗнч(Пар) = Тип(“ПараметрОбластиРасшифровкаКомпоновкиДанных”) Тогда
Для Каждого Выр Из Пар.ВыраженияПолей Цикл
СтруктМакета.Поле = Выр.Поле;
НаимПоляНР = Нрег(Выр.Поле);
Если СтрЧислоВхождений(НаимПоляНР,”нараст”) > 0 Тогда
ФлДобавлятьМакет = Истина;
КонецЕсли;
КонецЦикла;
СтруктМакета.ИмяПараметраПоля = Пар.Имя;
КонецЕсли;
Если ТипЗнч(Пар) = Тип(“ПараметрОбластиВыражениеКомпоновкиДанных”) Тогда
СтруктМакета.ИмяПараметраВыражения =Пар.Имя;
КонецЕсли;
КонецЦикла;
СтруктМакета.ЗначениеРесурса = 0;
СтруктМакета.Макет = Мак.Имя;
Если ФлДобавлятьМакет Тогда
МассивМакетов.Добавить(СтруктМакета);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если ( ЭлементРезультата.Макет <> “”) И ( ЭлементРезультата.ТипЭлемента = ТипЭлементаРезультатаКомпоновкиДанных.НачалоИКонец ) Тогда
Для Каждого СМ из МассивМакетов Цикл
Если СМ.Макет = ЭлементРезультата.Макет Тогда
ПарВыражения = Неопределено;
Для Каждого Пар из ЭлементРезультата.ЗначенияПараметров Цикл
Если Пар.Имя = СМ.ИмяПараметраВыражения Тогда
ПарВыражения = Пар;
Прервать;
КонецЕсли;
КонецЦикла;
Если ПарВыражения <> Неопределено Тогда
СМ.ЗначениеРесурса = СМ.ЗначениеРесурса + ?( ПарВыражения.Значение = null,0,ПарВыражения.Значение);
ПарВЫражения.Значение = СМ.ЗначениеРесурса;
КонецЕсли;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
В обработчике “ПередВыводомОтчета” создаем массив макетов.
Процедура ПередВыводомОтчета(МакетКомпоновки, ПроцессорКомпоновки) Экспорт
МассивМакетов = Новый Массив;
КонецПроцедуры
Переменная МассивМакетов должна быть переменной модуля.
Обратите внимание- по названию ресурса программа сама теперь знает надо ли в диаграмме выводить нарастающий итог.
Вот и все.
Спасибо большое за статью. Очень интересно. Самому на практике пока хватало вывода нарастающих итогов в таблице. Справлялся через ВычислитВыражение
В план-фактном анализе, если плановые данные равномерно разбиты на дни, особый интерес представляет наложение линейно возрастающего (по дням) графика плана и нарастающиего графика выполнения плана (факта). На этой же диаграмме уместно видеть график отклонений. Картина динамики получается совершенно наглядная.