Wie man eine End-to-End-Sortierung von ähnlichen Matrizen auf mehreren Seiten in FastReport .NET durchführt

2021-09-22

Nehmen wir an, es gibt die Aufgabe, eine Matrix auf der ersten Seite in der richtigen Reihenfolge zu sortieren. Und noch diese Reihenfolge ist zu behalten und zu verwenden um ähnliche Matrizen auf anderen Seiten zu sortieren.

Dies kann notwendig sein, wenn Sie mehrere Seiten in einem Bericht haben, die die gleichen Matrixüberschriften anzeigen und sich nur durch ihre Daten unterscheiden. Die erste Matrix gibt zum Beispiel die Anzahl der verkauften Artikel an, die zweite den Umsatz je Artikel. Sie müssen nach Menge oder Betrag sortieren und dann die gleiche Reihenfolge für die zweite Matrix anwenden. Dieser Fall ist in analytischen Berichten recht häufig.

Schauen wir uns das in der praktischen Anwendung an. Nehmen wir eine völlig hypothetische Obst-Verkaufsstatistik. Es reichen jedoch nicht nur die Obstsorten aus, sondern es muss auch eine Liste der Obstimportländer erstellt werden. Die Anzahl der verkauften Artikel wird für drei Jahre angezeigt.

Berichtsvorlage

Tabellenaufbau:

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

Sortierung

Standard-Sortiermechanismen helfen uns hier nicht weiter. Daher fangen wir mit der Sortierung der Menge des verkauften Obstes für jedes Land an. Skizzieren wir eine Abfolge von Schritten:

1. Liste von Ländern.

2. Für jedes Land:

2.1. Zellenwerte mit den Obstsorten und den verkauften Mengen für jedes Jahr erhalten;

2.2. die Werte für das gewünschte Jahr sortieren;

2.3. für jede Zeile die Zellen für Obstsorte und -menge für alle Jahre entsprechend den Zeilenindex in der sortierten Liste aufschreiben.

In der ersten Spalte werden die Länder sortiert, und das passt uns, also werden wir die Zellen in den anderen Spalten sortieren. Daher müssen wir uns diese zunächst merken, um sie dann entsprechend dem Sortierplan in der gewünschten Reihenfolge anordnen zu können. Wir wählen eine der Spalten mit Daten für ein bestimmtes Jahr aus und sortieren sie in absteigender oder aufsteigender Reihenfolge. Dann verwenden wir die resultierende Indexreihenfolge, um alle Zellen nach Spalten zu sortieren.

Jetzt geht's los. Die Matrix verfügt über ein Ereignis zum Modifizieren eines bereits erstellten Objekts - ModifyResult. Erstellen Sie einen Handler für dieses Ereignis im Berichtsskript.

 private List<List<int>> sortOrders = new List<List<int>>(); 
// Liste der Sortierreihenfolge für die Aufnahme der einzelnen Obstsorten nach Ländern
 
 private void Matrix1_ModifyResult(object sender, EventArgs e)
 {
// Wörterbücher, in denen wir den Zeilenindex und den Zellenwert speichern 
 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>(); 
 // In dieser Liste werden wir eine Liste von Ländern speichern
 // Wir erhalten alle Länder aus der ersten Spalte
 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;
 
 // Wir gehen alle Spalten der Matrix durch, um die Zellen in Wörterbüchern zu speichern
 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;
 
 // Für jedes Land führen wir eine Schleife durch, um die Obstgruppen zu bestimmen und zu sortieren
 foreach (var country in countries)
 {
 total = false;
 
 sortCells.Clear(); 
 //Löschen wir die Liste zum Sortieren
 
 // Wählen wir Zellen aus den Zeilen aus, bis wir auf Total treffen, da Total nicht sortiert werden sollte
 while (!total)
 {
 if ((string)(sender as TableBase).ResultTable.GetCellData(columnTypeIndex,z).Text!="Total")
 {
 //Wählen wir Zellen für das erste Jahr aus
 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); 
 
// Wählen wir Zellen für das zweite Jahr aus
 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); 
 
 // Wählen wir Zellen für das dritte Jahr aus
 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); 
 
// Wählen wir Zellen für Obstrsorten aus 
 value = (sender as TableBase).ResultTable.GetCellData(columnTypeIndex,z).Text;
 typeCells.Add(z,value.ToString()); 
 }
 else
 {
// Schleifenausgangsbedingung
 total = true;
 } 
 z++;
 }
 
 sortCells = firstYearCells;
 // Legen wir die zu sortierende Spalte fest - in diesem Fall nach dem ersten Jahr
 
 List<int> keys = new List<int>(); 
 
// Wenn wir eine vollständige Sortierliste für alle Länder haben, dann ist die erste Seite des Berichts erstellt und wir können diese Liste für die zweite Seite verwenden. Hier wird die End-to-End-Sortierung vorgenommen.
 if ( sortOrders.Count == countries.Count )
 {
 keys = sortOrders.ElementAt(countryOrder);
 }
 else 
 keys = sortCells.OrderByDescending(i=>i.Value).Select(key => key.Key).ToList(); 
// Sortieren wir den Array in absteigender Reihenfolge mit Hilfe der Linq-Bibliothek
 
 int k = 0;
// Schleife durch alle Elemente der sortierten Liste
 foreach(var key in keys)
 {
// Ordnen wir die Zellwerte für alle Spalten in Sortierreihenfolge an
 (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)); 
// Speichern wir die Sortierreihenfolge für das aktuelle Land
 
 // Es ist wichtig folgendes zu löschen
 firstYearCells.Clear();
 secondYearCells.Clear();
 thirdYearCells.Clear();
 typeCells.Clear();
 countryOrder++; 
// Weiter zum nächsten Land
 }
}
}

Kopieren wir nun die Berichtsseite mit der Matrix, aber anstelle des Feldes amount wird die Summe sum angezeigt.

Wählen wir in den Ereignissen der Matrix den Handler aus, den wir für ModifyResult erstellt haben.

Erstellen Sie ein ModifyResult - Matrixereignis

Wenn wir den Bericht ausführen, werden wir feststellen, dass die Reihenfolge der Obstsorten auf den beiden Seiten gleich ist. Dies bedeutet, dass die auf der ersten Seite vorgenommene Sortierung auch auf die zweite Seite angewendet wird.

Vergleich der  Sortierreihenfolge der Matrizen auf den verschiedenen Seiten des Berichts

So können wir mit dem Berichts-Skript die Daten in den Matrizen nach Belieben manipulieren. Und das Wichtigste ist, dass wir die gleiche Sortierreihenfolge auf verschiedenen Seiten des Berichts anwenden können.

9. November 2023

Bericht in C# in FastReport Cloud erstellen

In diesem Artikel zeigen wir Ihnen anhand eines Beispiels, wie Sie mit FastReport Cloud SDK Berichte erstellen und in ein beliebiges Format exportieren können.
4. Oktober 2023

Erstellen einer Bericht aus einer ASP.NET Core Anwendung mit FastReport.Core.Skia

Wir erklären Ihnen, wie Sie mit FastReport einen Bericht unter Windows und Linux erstellen.Kern.Skia und ein privater NuGet-Server.
25. September 2023

Erstellen von Preisschildern mit Produktzusammensetzungen in FastReport VCL

Ab Version 2023.3 wurde der FastReport VCL-Berichts-Engine ein weiteres leistungsfähiges Werkzeug hinzugefügt – das Reduzieren von Text im Textobjekt.
Fast Reports
  • 800-985-8986 (Englisch, die USA)
  • +4930568373928 (Deutsch)
  • +55 19 98147-8148 (Portugiesisch)
  • info@fast-report.com
  • 66 Canal Center Plaza, Ste 505, Alexandria, VA 22314

© 1998-2024 Fast Reports Inc.