Créer un tableau croisé dynamic à partir d’un DataTable

J’utilise Winforms C # pour créer une application qui doit transformer un datatable en tableau croisé dynamic. Le tableau croisé dynamic fonctionne correctement à partir d’une extrémité SQL, mais sa création à partir d’un fichier datatable semble plus difficile. Je n’arrivais pas à trouver quoi que ce soit construit dans .NET pour cela.

Remarque: je dois le faire à partir d’un côté .NET que je manipule les données avant de créer le pivot.

J’ai lu des articles qui faisaient des choses similaires, mais j’ai eu du mal à les appliquer à mon problème.

* J’ai un datatable avec les colonnes “StartDateTime”, “Tap”, et “Data”. Les dates de début doivent être regroupées et les valeurs des données moyennées (parfois plus d’une valeur de données par date de début). Le tableau est présenté ci-dessous:

entrez la description de l'image ici

Le tableau croisé dynamic devrait ressembler à l’image ci-dessous (pas de valeurs arrondies cependant). Les numéros de colonne sont les numéros de sockets distincts (un pour chaque unique).

Tableau Pivot

Comment puis-je créer ce tableau croisé dynamic à partir du datatable?

EDIT: oublié de mentionner, ces valeurs de prise ne sont pas toujours de 1-4, elles varient en nombre et en valeur.

Apprenez le tesuji de pivot de hachage:

var oDT = new DataTable; var dfq = new Dictionary; oDT.Columns.Add("StartDateTime", typeof DateTime); for (int i = 0; i < inDT.Rows.Count; i++) { var key = (DateTime)inDT.Rows[i][0]; var row = (String)inDT.Rows[i][2]; var data = (Double)inDT.Rows[i][1]; if (!oDT.Columns.Contains(row)) oDT.Columns.Add(row); if (dfq.ContainsKey(key)) { dfq[key][row] = data; } else { var oRow = oDT.NewRow(); oRow[0] = key; oRow[row] = data; dfq.Add(key, oRow); oDT.Rows.Add(oRow); } } 

Un tableau croisé dynamic comme celui-ci peut être facilement calculé à l’ aide de la bibliothèque d’agrégation gratuite NReco.PivotData :

 DataTable t; // assume it has: StartDateTime, Data, Tap var pivotData = new PivotData( new ssortingng[] {"StartDateTime","Tap"}, new AverageAggregatorFactory("Data"), new DataTableReader(t) ); var pvtTbl = new PivotTable( new [] {"StartDateTime"}, // row dimension(s) new [] {"Tap"}, // column dimension(s), pivotData); 

Les clés de ligne et de colonne sont représentées par les collections pvtTbl.RowKeys et pvtTbl.ColumnKeys; les valeurs / totaux étaient accessibles par indexeur (par exemple: pvtTbl[0,0].Value ) ou par clé de ligne + colonne (par exemple: pivotData[new Key(new DateTime(2012, 3, 30, 11, 42, 00)), new Key(4)].Value ).

Un autre petit morceau de code pour faire pivoter n’importe quelle table:

  var dataTable = new DataTable(); // your input DataTable here! var pivotedDataTable = new DataTable(); //the pivoted result var firstColumnName = "Year"; var pivotColumnName = "Codes"; pivotedDataTable.Columns.Add(firstColumnName); pivotedDataTable.Columns.AddRange( dataTable.Rows.Cast().Select(x => new DataColumn(x[pivotColumnName].ToSsortingng())).ToArray()); for (var index = 1; index < dataTable.Columns.Count; index++) { pivotedDataTable.Rows.Add( new List { dataTable.Columns[index].ColumnName }.Concat( dataTable.Rows.Cast().Select(x => x[dataTable.Columns[index].ColumnName])).ToArray()); } 

Peut-être que cela vous aidera. C’est dans vb.net.

 Public Function pivot_datatable(ByVal datatable_source As DataTable, ByVal datacolumn_rows As DataColumn(), ByVal datacolumn_columns As DataColumn, ByVal datacolumn_value As DataColumn) As DataTable Dim temp_datacolumn As DataColumn Dim current_datarow As DataRow Dim datarow_destination As DataRow = Nothing Dim current_column_name As Ssortingng = "" Dim primary_key() As DataColumn = New DataColumn() {} Dim key_columns() As Object Dim newOrdinal As Integer Dim i As Integer Dim sort_ssortingng As Ssortingng = "" Try pivot_datatable = New DataTable() For Each temp_datacolumn In datatable_source.Columns If temp_datacolumn.Ordinal <> datacolumn_columns.Ordinal AndAlso temp_datacolumn.Ordinal <> datacolumn_value.Ordinal Then array_insert(primary_key, pivot_datatable.Columns.Add(temp_datacolumn.ColumnName, temp_datacolumn.DataType)) sort_ssortingng &= temp_datacolumn.ColumnName & " ASC, " End If Next pivot_datatable.PrimaryKey = primary_key For Each current_datarow In datatable_source.Rows ' Main Process to add values to pivot table current_column_name = current_datarow(datacolumn_columns.Ordinal).ToSsortingng If Not pivot_datatable.Columns.Contains(current_column_name) Then ' Column is new temp_datacolumn = pivot_datatable.Columns.Add(current_column_name, datacolumn_value.DataType) newOrdinal = temp_datacolumn.Ordinal For i = newOrdinal - 1 To datatable_source.Columns.Count - 2 Step -1 If temp_datacolumn.ColumnName.CompareTo(pivot_datatable.Columns(i).ColumnName) < 0 Then newOrdinal = i End If Next temp_datacolumn.SetOrdinal(newOrdinal) End If key_columns = New Object() {} For Each data_column As DataColumn In datacolumn_rows array_insert(key_columns, current_datarow(data_column.Ordinal).ToString) Next data_column datarow_destination = pivot_datatable.Rows.Find(key_columns) If datarow_destination Is Nothing Then ' New Row datarow_destination = pivot_datatable.NewRow() For Each temp_datacolumn In datatable_source.Columns If temp_datacolumn.Ordinal <> datacolumn_columns.Ordinal AndAlso temp_datacolumn.Ordinal <> datacolumn_value.Ordinal Then datarow_destination(temp_datacolumn.ColumnName) = current_datarow(temp_datacolumn.ColumnName) End If Next pivot_datatable.Rows.Add(datarow_destination) End If datarow_destination(current_column_name) = current_datarow(datacolumn_value.Ordinal) Next Return sort_datatable(pivot_datatable, sort_string.Substring(0, sort_string.Length - 2)) Catch ex As Exception Return Nothing End Try End Function