Метод построения нарастающих итогов в таблице и диаграмме.

Одна из самых сложных проблем в СКД  -создание ресурсов вида “нарастающие” итоги.

1.Типичным решением этой проблемы  является левое соединение  таблицы с самой собой. В группировки включается период исходной таблицы по которому строится итог с накоплением. В условие соединения входит выражение вида  Исх.ПериодДень >= Соед.ПериодДень. Собственно итоговое поле в запросе вычисляется агрегатной функцией СУММА(Соед.Ресурс)  в присоединенной таблице по полю ресурса.

Этот подход хорош для специализиированных отчетов в которых зараннее известно какое поле периода будет использовано в группировке.

В универсальных отчетах (например по регистру накоплений с настройкой Авто в периоде виртуальной таблицы) ,  в которых заранее неизвестно,  группировку по какому периоду будет выполнять пользователь – этот подход становится малоприемлем. Кроме того – этот подход приводит к дополнительным накладным расходам на выполнение более сложного запроса.

2. Другим широко применяемым подходом является использование функции СКД “ВычислитьВыражение”   в вычислимых полях.

Например настраивается  вычислимое поле “КоличествоНарастающий” : ВычислитьВыражение(“Сумма(Количество)”, , , “Первая”, “Текущая”)

Вычислимое поле настраивается ресурсом. Для правильного расчета в группировках и итогах в выражении ресурса должна быть использована функция Максимум()

Максимум(КоличествоНарастающий)

Этот подход прекрасно работает в таблицах по любым вертикально расположенным группировкам, но совершенно не работает в диаграммах. Диаграммы почему то совершенно не хотят вычислять функцию “ВычислитьВыражение”.Вместо значений с накоплением в диаграмме отображаются значения без накопления.

В горизонтально расположенных группировках таблиц – нарастающий итог тоже не рассчитывается… но это еще предмет будущего изучения.

Решении которое предлагаю ниже – отталкивается от второго подхода. Нарастающие итоги создаются созданием ресурса на основе вычисляемого поля с функцие СКД “ВыполнитьВыражение”. Единственное дополнительное условие которое вводится – ограничение на имя “накопительного” ресурса  – в нем должно быть в любом регистре подстрока “нараст”. Зачем это нужно – увидите далее.

Теперь надо чтобы при выборе такого ресурса в диагрумму значения считались с накоплением. Идея проста – накапливать значение для каждого  ресурса в момент когда выводится точка диаграммы и подменять значение в диаграмме на  “накопленное”.

Для этого используется обработчик события “ПередВыводомЭлементРезультата” в модуле объекта отчета.
Процедура ПередВыводомЭлементРезультата(МакетКомпоновки, ПроцессорКомпоновки, ЭлементРезультата) Экспорт

Макеты = ЭлементРезультата.Макеты;

Для Каждого Мак из Макеты Цикл
Если ТипЗнч(Мак.Макет) = Тип(“МакетРесурсаДиаграммыОбластиКомпоновкиДанных”) Тогда

СтруктМакета = Новый Структура(“Макет,Поле,ИмяПараметраПоля,ИмяПараметраВыражения,ЗначениеРесурса”);
ФлДобавлятьМакет = Ложь;
Для Каждого Пар из Мак.Параметры   Цикл
Если ТипЗнч(Пар)  = Тип(“ПараметрОбластиРасшифровкаКомпоновкиДанных”) Тогда

Для Каждого Выр Из Пар.ВыраженияПолей Цикл
СтруктМакета.Поле = Выр.Поле;

НаимПоляНР =  Нрег(Выр.Поле);
Если СтрЧислоВхождений(НаимПоляНР,”нараст”) > 0 Тогда
ФлДобавлятьМакет = Истина;
КонецЕсли;
КонецЦикла;
СтруктМакета.ИмяПараметраПоля = Пар.Имя;
КонецЕсли;

Если ТипЗнч(Пар) = Тип(“ПараметрОбластиВыражениеКомпоновкиДанных”) Тогда
СтруктМакета.ИмяПараметраВыражения =Пар.Имя;
КонецЕсли;

КонецЦикла;
СтруктМакета.ЗначениеРесурса = 0;
СтруктМакета.Макет  =  Мак.Имя;
Если ФлДобавлятьМакет Тогда
МассивМакетов.Добавить(СтруктМакета);
КонецЕсли;
КонецЕсли;
КонецЦикла;

Если ( ЭлементРезультата.Макет <> “”)  И  ( ЭлементРезультата.ТипЭлемента = ТипЭлементаРезультатаКомпоновкиДанных.НачалоИКонец ) Тогда
Для Каждого СМ из МассивМакетов Цикл
Если СМ.Макет =  ЭлементРезультата.Макет  Тогда
ПарВыражения = Неопределено;
Для Каждого Пар из  ЭлементРезультата.ЗначенияПараметров Цикл
Если Пар.Имя = СМ.ИмяПараметраВыражения Тогда
ПарВыражения = Пар;
Прервать;
КонецЕсли;
КонецЦикла;
Если ПарВыражения <> Неопределено Тогда
СМ.ЗначениеРесурса =  СМ.ЗначениеРесурса + ?( ПарВыражения.Значение = null,0,ПарВыражения.Значение);
ПарВЫражения.Значение = СМ.ЗначениеРесурса;
КонецЕсли;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;

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

В  обработчике “ПередВыводомОтчета”  создаем массив макетов.

Процедура ПередВыводомОтчета(МакетКомпоновки, ПроцессорКомпоновки) Экспорт
МассивМакетов = Новый Массив;

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

 

Переменная МассивМакетов должна быть переменной модуля.

Обратите внимание- по названию ресурса программа сама теперь знает надо ли в диаграмме выводить нарастающий итог.

Вот и все.

 

Подписаться
Уведомить о
guest
2 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
also
10 лет назад

Спасибо большое за статью. Очень интересно. Самому на практике пока хватало вывода нарастающих итогов в таблице. Справлялся через ВычислитВыражение