logo
small logo
  • Продукты
  • Купить
  • Поддержка
  • Статьи
  • Клиентская панель Поддержка
  • Главная
  • /
  • Статьи
  • /
  • Как сделать сквозную сортировку подобных матриц на нескольких страницах в FastReport .NET
  • Как выбрать топ значений в матрице

    22 апреля 2021 г.

    Статья актуальна до версии 2022.1. В FastReport.NET есть прекрасный инструмент для вывода данных в виде сводной

    Подробнее
  • Семейство генераторов отчетов FastReport - быстрый обзор

    23 марта 2020 г.

    Отчетность – без нее невозможно вести деятельность ни в одной сфере жизнедеятельности. Бюрократия является неодолимой

    Подробнее
  • Как создать отчет из кода веб-приложения

    16 февраля 2022 г.

    Порой создание отчета может превратиться в настоящую головную боль. Например, когда вам нужно управлять содержимым

    Подробнее
  • Как распечатать несколько раз одну страницу отчета

    24 февраля 2022 г.

    Если вам нужно распечатать отдельные страницы отчета в нескольких экземплярах, то придется прибегнуть к

    Подробнее
  • Кастомизация дизайнера отчетов

    31 мая 2020 г.

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

    Подробнее

Как сделать сквозную сортировку подобных матриц на нескольких страницах в FastReport .NET

22 сентября 2021 г.

Допустим поставлена задача: отсортировать матрицу на первой странице в нужном порядке. А ещё запомнить этот порядок и применить его для сортировки подобных матриц на других страницах.

Это может понадобиться, когда у вас есть несколько страниц в отчёте, которые выводят одинаковые по заголовкам матрицы, различающиеся лишь данными. Например, первая матрица выводит количество проданных товаров, а вторая - суммы от продаж по товарам. Необходимо отсортировать по количеству или суммам, а затем, применить такой же порядок для второй матрицы. Такой кейс довольно часто встречается в аналитических отчетах.

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

Шаблон отчета

Структура таблицы:

  • country_name
  • fruit_type
  • year
  • amount
  • price
  • sum

Сортировка

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

1. Получить список стран.

2. Для каждой страны:

2.1. получить значения ячеек с видами фруктов и количеством проданных по каждому году;

2.2. отсортировать значения для нужного года;

2.3. для каждой строки записать ячейки вида фруктов и количества по всем годам согласно индексам строк в отсортированном списке.

Сортировка первой колонки - страны, и это нас удовлетворяет, а значит сортировать будем ячейки остальных колонок. Поэтому, предварительно нам нужно их запомнить, чтобы потом выстроить в их нужном порядке согласно плану сортировки. Мы выберем одну из колонок с данными за определенный год и отсортируем её по убыванию, или возрастанию. Затем воспользуемся полученным порядком индексов для сортировки всех ячеек по колонкам.

Приступим. Матрица имеет событие для модификации уже построенного объекта - ModifyResult. Создадим обработчик этого события в скрипте отчета.

 private List<List<int>> sortOrders = new List<List<int>>(); 
//Список порядков сортировки для каждого забора видов фруктов по странам
 
 private void Matrix1_ModifyResult(object sender, EventArgs e)
 {
//Словари в которых мы будем хранить индекс строки и значение ячейки
 Dictionary<int, double> firstYearCells = new Dictionary<int, double>();
 Dictionary<int, double> secondYearCells = new Dictionary<int, double>();
 Dictionary<int, double> thirdYearCells = new Dictionary<int, double>();
 Dictionary<int, string> typeCells = new Dictionary<int, string>();
 Dictionary<int, double> sortCells = new Dictionary<int, double>();
 
//bool prevYearSortNeeded = false;
 
 var total = false;
 var z = 1;
 var val2 = 0.0;
 var val3 = 0.0;
 
 List<string> countries = new List<string>(); 
 //В этом списке будем хранить список стран
 //Получаем все страны из первой колонки 
 for (int j=2; j<(sender as TableBase).ResultTable.RowCount-1; j++)
 { 
 try
 {
 var val = (sender as TableBase).ResultTable.GetCellData(0,j).Value.ToString();
 if (val.Length > 0) countries.Add(val);
 }
 catch (Exception)
 {}
 }
 
 int columnFirstYearIndex=0;
 int columnSecondYearIndex=0;
 int columnThirdYearIndex=0;
 int columnTypeIndex=0;
 
 //Проходим по всем колонкам матрицы чтобы сохранить ячейки в словари
 for (int t=0; t < (sender as TableBase).ResultTable.ColumnCount; t++)
 {
 
 if ((sender as TableBase).ResultTable.GetCellData(t,0).Text.Contains("2017"))
 {
 columnFirstYearIndex=t;
 }
 if ((sender as TableBase).ResultTable.GetCellData(t,0).Text.Contains("2018"))
 { 
 columnSecondYearIndex=t;
 }
 if ((sender as TableBase).ResultTable.GetCellData(t,0).Text.Contains("2019"))
 { 
 columnThirdYearIndex=t;
 }
 if ((sender as TableBase).ResultTable.GetCellData(t,0).Text.Contains("Fruit"))
 {
 columnTypeIndex=t;
 }
 }
 
 int countryOrder =0;
 
 //Для каждой страны прогоняем цикл, чтобы определить группы фруктов и отсортировать их
 foreach (var country in countries)
 {
 total = false;
 
 sortCells.Clear(); 
 //Очищаем список для сортировки
 
 //Выбираем ячейки из строк пока не встретим Total. Так как Total не должен сортироваться 
 while (!total)
 {
 if ((string)(sender as TableBase).ResultTable.GetCellData(columnTypeIndex,z).Text!="Total")
 {
 //Выбираем ячейки для первого года
 var value = (sender as TableBase).ResultTable.GetCellData(columnFirstYearIndex,z).Value;
 if (value!=null)
 {
 Double.TryParse(value.ToString(),out val3);
 firstYearCells.Add(z,val3);
 }
 else
 firstYearCells.Add(z, 0.0); 
 
//Выбираем ячейки для второго года 
 value = (sender as TableBase).ResultTable.GetCellData(columnSecondYearIndex,z).Value;
 if (value!=null)
 {
 Double.TryParse(value.ToString(),out val3);
 secondYearCells.Add(z,val3);
 }
 else
 secondYearCells.Add(z, 0.0); 
 
 //Выбираем ячейки для третьего года 
 value = (sender as TableBase).ResultTable.GetCellData(columnThirdYearIndex,z).Value;
 if (value!=null)
 {
 Double.TryParse(value.ToString(),out val3);
 thirdYearCells.Add(z,val3);
 }
 else
 thirdYearCells.Add(z, 0.0); 
 
//Выбираем ячейки для типов фруктов 
 value = (sender as TableBase).ResultTable.GetCellData(columnTypeIndex,z).Text;
 typeCells.Add(z,value.ToString()); 
 }
 else
 {
//Условие выхода из цикла
 total = true;
 } 
 z++;
 }
 
 sortCells = firstYearCells;
 //Задаем колонку для сортировки - в данном случае по первому году
 
 List<int> keys = new List<int>(); 
 
//Если имеем заполненный список сортировок для всех стран - значит первая страница отчета построена и можно использовать этот список на второй странице. Именно здесь обеспечивается сквозная сортировка.
 if ( sortOrders.Count == countries.Count )
 {
 keys = sortOrders.ElementAt(countryOrder);
 }
 else 
 keys = sortCells.OrderByDescending(i=>i.Value).Select(key => key.Key).ToList(); 
//Сортируем массив по убыванию используя библиотеку Linq
 
 int k = 0;
//Проходим цикл по всем элементам отсортированного списка
 foreach(var key in keys)
 {
//Выстраиваем значения ячеек для всех колонок в порядке сортировки
 (sender as TableBase).ResultTable.GetCellData(columnFirstYearIndex, firstYearCells.Keys.ElementAt(k)).Text = firstYearCells[key].ToString();
 (sender as TableBase).ResultTable.GetCellData(columnSecondYearIndex, secondYearCells.Keys.ElementAt(k)).Text = secondYearCells[key].ToString();
 (sender as TableBase).ResultTable.GetCellData(columnThirdYearIndex, thirdYearCells.Keys.ElementAt(k)).Text = thirdYearCells[key].ToString();
 (sender as TableBase).ResultTable.GetCellData(columnTypeIndex, typeCells.Keys.ElementAt(k)).Text = typeCells[key].ToString();
 k++; 
 } 
 if (keys.Count>0) sortOrders.Add(new List<int>(keys)); 
//Сохраняем порядок сортировки для текущей страны 
 
 //Важно почистить
 firstYearCells.Clear();
 secondYearCells.Clear();
 thirdYearCells.Clear();
 typeCells.Clear();
 countryOrder++; 
//Переходим к следующей стране
 }
}
}

Теперь копируем страницу отчета с матрицей, но вместо поля amount будем выводить sum.

А в событиях матрицы выберем созданный нами обработчик для ModifyResult.

Создаем событие матрицы ModifyResult

В результате запуска отчета мы увидим, что порядок видов фруктов на двух страницах совпадает. А это означает, что сортировка, полученная на первой странице применена и на второй.

Сравниваем порядок сортировки матриц на разных страницах отчета

Таким образом, мы с помощью скрипта отчета можем манипулировать данными в матрицах как нам угодно. А самое главное - применять один порядок сортировки на разных страницах отчета.

О продукте Скачать Купить
avatar
Dmitriy Fedyashov
Технический писатель
Fast Reports Team: Dmitriy Fedyashov - Technical Writer at Fast Reports
.NET FastReport Report Filtering Matrix

Добавить комментарий
logo
  • +7(800)551-75-80
  • info@fastreport.ru
  • Ростов-на-Дону, Россия, 344082, ул.Обороны 24, офис 311
  • Купить
  • Загрузить
  • Документация
  • Отзывы
  • Как деинсталировать
  • Онлайн поддержка
  • FAQ
  • Видео уроки
  • Форум
  • Статьи
  • Наши Новости
  • Пресса о нас
  • Реселлеры
  • ВУЗам
  • Карьера
  • Контакты

© 1998-2022 ООО «Фаст Репортс»

  • Согласие с обработкой персональных данных
  • Не является публичной офертой