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.
Tabellenaufbau:
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.
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.
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.