Как создать собственный итог в матрице FastReport .NET

08.10.2018

Объект Матрица в FastReport .NET очень хорошо выполняет типовые задачи по отображению сводных таблиц. Но, когда задачи не стандартные нам поможет только скрипт отчета. Именно в скрипте можно реализовать почти любые требования.

Как вы знаете, матрица имеет встроенную функцию отображения итогов по полям и колонкам. Обычно, итог в сводной таблице — это сумма. Однако, как быть, если вы хотите итог с собственной формулой расчета. А если вы хотите выводить итоги выборочно, для определенных столбцов?

Чтобы сделать все это нужно отключить стандартные итоги и создать собственный столбец, в котором будет рассчитываться ваш итог. Но, если вы все-таки используете стандартные итоги, то, чтобы их значения тоже попали в пользовательский итог, нужно использовать событие матрицы AfterTotals. Оно произойдет после построения матрицы со всеми стандартными итогами, так что все данные будут в нашем распоряжении. Это событие не позволяет вам добавлять и изменять данные в матрицы, то есть использовать методы AddValue и SetValue.

Итак, рассмотрим пример.

Создаем матрицу с простейшим шаблоном:

 

Чтобы создать измерение или показатель в матрицу, нужно вставить выражение в соответствующую ячейку. Т.к. мы заполняем матрицу из кода, то нам нужны фиктивные выражения просто чтобы создать структуру. Для этого поместите любое выражение из панели «Данные» в ячейку и отчистите текст выражения, с помощью редактора выражения.

Создаем обработчик события AfterData для матрицы. В нем мы будем добавлять данные:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void Matrix1_AfterData(object sender, EventArgs e)
 {
 Matrix1.AddValue(new Object[] { "January", "Salary" }, new Object[] { "1" }, new Object[] { 1000});
 Matrix1.AddValue(new Object[] { "January", "Bonus" }, new Object[] { "1" }, new Object[] { 500});
 Matrix1.AddValue(new Object[] { "January", "Penalty" }, new Object[] { "1" }, new Object[] { 200});
 Matrix1.AddValue(new Object[] { "February", "Salary" }, new Object[] { "1" }, new Object[] { 1000});
 Matrix1.AddValue(new Object[] { "February", "Bonus" }, new Object[] { "1" }, new Object[] { 500});
 Matrix1.AddValue(new Object[] { "February", "Penalty" }, new Object[] { "1" }, new Object[] { 200});
 Matrix1.AddValue(new Object[] { "February", "Total" }, new Object[] { "1" }, new Object[] { 0});
 
 Matrix1.AddValue(new Object[] { "January", "Salary" }, new Object[] { "2" }, new Object[] { 500});
 Matrix1.AddValue(new Object[] { "January", "Bonus" }, new Object[] { "2" }, new Object[] { 300});
 Matrix1.AddValue(new Object[] { "January", "Penalty" }, new Object[] { "2" }, new Object[] { 250});
 Matrix1.AddValue(new Object[] { "February", "Salary" }, new Object[] { "2" }, new Object[] { 500});
 Matrix1.AddValue(new Object[] { "February", "Bonus" }, new Object[] { "2" }, new Object[] { 300});
 Matrix1.AddValue(new Object[] { "February", "Penalty" }, new Object[] { "2" }, new Object[] { 250});
 Matrix1.AddValue(new Object[] { "February", "Total" }, new Object[] { "2" }, new Object[] { 0});}

Здесь, мы добавляем значения для каждой ячейки матрицы. В нашем случае – это две строки данных. Обратите внимание, что мы добавили только один итог, для февраля. Пока он имеет нулевое значение, но вскоре мы рассчитаем его в событии AfterTotals.

Далее нам понадобится метод получения значения ячейки:

1
2
3
4
5
 private float GetValue(int columnIndex)
 {
 object value = Matrix1.Data.GetValue(columnIndex, rowIndex, 0);
 return new Variant(value);
 }

Все просто – передаем индекс колонки, а получаем – значение.

Также нам потребуется переменная класса – rowIndex:

private int rowIndex;

А теперь добавим метод присвоения значения ячейке:

1
2
3
4
5
private void SetValue(string complexValue, float value)
 {
 int columnIndex = Matrix1.Data.Columns.Find(complexValue.Split(';'));
 Matrix1.Data.SetValue(columnIndex, rowIndex, value);
 }

Теперь, перейдем к вычислению результата. Добавим обработчик события AfterTotals для матрицы:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private void Matrix1_AfterTotals(object sender, EventArgs e)
 {
 int[] rowIndices = Matrix1.Data.Rows.GetTerminalIndices();
 for (int i = 0; i < rowIndices.Length; i++)
 {
 rowIndex = rowIndices[i];
 
 int[] columnIndices = Matrix1.Data.Columns.GetTerminalIndices(new Object[] { "February" });
 float oplataSum = 0;
 foreach (int columnIndex in columnIndices)
 {
 oplataSum += GetValue(columnIndex);
 }
 SetValue("February;Total", oplataSum);
 }
 }

Здесь, мы получаем массив индексов строк матрицы. Затем, проходим цикл по этим индексам строк. Для каждой строки получаем массив индексов столбцов. В цикле по индексам столбцов производим нарастающую сумму. В конце присваиваем полученную сумму ячейке "February;Total".

А теперь запустим отчет:

Итог, как и предполагалось, выводится для группы February. Причем суммы от «штатного» итога тоже обработаны.

Таким образом мы можем создавать собственные итоги для нужных столбцов и строк.

.NET FastReport Script Матрица .NET FastReport Script Матрица
10 июля 2026

Как настроить Content Security Policy для отчетов FastReport .NET WEB

Узнайте, как настроить Content Security Policy для отчётов FastReport .NET WEB: обзор директив и значений CSP, изменения в архитектуре FastReport, типичные сценарии обхода и способы защиты.
22 июня 2026

Как настроить отчет с Business Objects из кода и дизайнера в FastReport .NET

В этой статье рассматривается реальный пример создания и использования шаблона отчета .frx для подключения к иерархическим бизнес-объектам в FastReport .NET.
21 апреля 2026

Использование водяных знаков в FastReport VCL

В статье подробно рассмотрели функционал добавления водяных знаков в FastReport VCL — как через визуальный интерфейс, так и программно, с помощью кода на Delphi и в скриптах отчётов.

Не является публичной офертой
© 1998-2026 ООО «Быстрые отчеты»