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




(0) Может оформить стоит?
(1) Да, код лучше бы разукрасить, а решение интересное
(0) вариант 3 — использовать 2 скд. В первой вычисляете наарастающие итоги ч/з вычислитьВыражение, программно ее выполнять в ТЗ, а пртом как источник данных ее пихать во вторую СКД которая будет проcто выводить данные в диаграмму
Вариант 4. — Использование самой компоновки данных — ВычислитьВыражение(«Сумма(Значение)», «МояГруппировка» , , «Первая», «Текущая»). Можно использовать начиная с версии платформы 8.2.14.
Вариант 5 — послать на фиг СКД, и сделать обычный отчет. Религия не позволяет ? Какая пользователю разница, СКД внутри, или нет? Это же надо так жутко извращаться для выполнения простых вещей.
К стати, мне приходилось использовать и другой вариант — функции общего модуля и модуля менеджера отчета, когда стояла задача вычисления среднеквадратического отклонения. К тому же в данном варианте можно решать более сложные задачи.
А так можно использовать источник данных — объектную модель.
(5) bulpi,
Если отчет должен гибко настравиться, послать СКД не просто.
(5) bulpi,
Еще одна причина делать на СКД — ненавижу рисовать макеты для отчетов.
За последние пол-года не сделал ни одного отчета без СКД.
Пользователи воспринимают отчеты на СКД как выполненные более профессионально.
Широко использую программное управление компоновкой и внешние источники данных.
Постоянно пользуюсь «шаблоном универсального отчета СКД» от 1С.
Отличное работающее решение. Еще бы такое же для таблицы СКД.
Для СуммаДок не Максимум(КоличествоНарастающий), а Сумма(СуммаДок)