我有以下将普通数据表转换为数据透视表的函数。
但我还有 1 个要求,它还应该显示 Value 列,即所有 Pivot 列单元格的总和。
e.g. : ORDER | SUM | PLANDATE
1 50 10-Oct-2012
1 10 10-Oct-2012
2 15 12-Oct-2012
PIVOT 之后应该是这样的
ORDER | SUM | 10-Oct-2012 | 12-Oct-2012
1 60 50 10
2 15 15
我的枢轴功能是:
DataTable Pivot(DataTable dt, DataColumn pivotColumn, DataColumn pivotValue) {
// find primary key columns
//(i.e. everything but pivot column and pivot value)
DataTable temp = dt.Copy();
temp.Columns.Remove( pivotColumn.ColumnName );
temp.Columns.Remove( pivotValue.ColumnName );
string[] pkColumnNames = temp.Columns.Cast<DataColumn>()
.Select( c => c.ColumnName )
.ToArray();
// prep results table
DataTable result = temp.DefaultView.ToTable(true, pkColumnNames).Copy();
result.PrimaryKey = result.Columns.Cast<DataColumn>().ToArray();
dt.AsEnumerable()
.Select(r => r[pivotColumn.ColumnName].ToString())
.Distinct().ToList()
.ForEach (c => result.Columns.Add(c, pivotColumn.DataType));
// load it
foreach( DataRow row in dt.Rows ) {
// find row to update
DataRow aggRow = result.Rows.Find(
pkColumnNames
.Select( c => row[c] )
.ToArray() );
// the aggregate used here is LATEST
// adjust the next line if you want (SUM, MAX, etc...)
aggRow[row[pivotColumn.ColumnName].ToString()] = row[pivotValue.ColumnName];
}
return result;
}
谢谢&任何帮助都会得到帮助...
Sample Data :
OrderStatus Qty Dated
New 100 10-Oct-2012
New 150 10-Oct-2012
New 100 10-Oct-2012
Conf 200 12-Oct-2012
New 100 12-Oct-2012
Reconf 300 12-Oct-2012
New 200 15-Oct-2012
New 200 15-Oct-2012
Reconf 100 18-Oct-2012
New 150 18-Oct-2012
Conf 150 18-Oct-2012
New 100 20-Oct-2012
Reconf 500 20-Oct-2012
New 100 30-Oct-2012
New 700 30-Oct-2012
New 100 30-Oct-2012
Conf 100 10-Oct-2012
更新代码:
private DataTable DataTableToPivot(DataTable dtNormalTable, DataColumn pivotColumn, DataColumn valueColumn)
{
cTracing.WriteTrace("Inside DataTableToPivot", "DataTableToPivot");
DataTable dtPivot = null;
DataTable tempPivot = null;
DataColumn sumColumn = new DataColumn();
string[] pkColumnNames = null;
try
{
sumColumn.ColumnName = valueColumn.ColumnName;
sumColumn.DataType = typeof(string);
sumColumn.DefaultValue = "0";
var allrows = dt.AsEnumerable().Select(delegate(DataRow r)
{
DataRow nr = dt.NewRow();
foreach (DataColumn item in dt.Columns)
{
nr.SetField(item.ColumnName, r[item.ColumnName] is DBNull ? string.Empty : r[item.ColumnName]);
}
return nr;
});
dtNormalTable = allrows.CopyToDataTable();
// find primary key columns
//(i.e. everything but pivot column and pivot value)
tempPivot = dtNormalTable.Copy();
tempPivot.Columns.Remove(pivotColumn.ColumnName);
tempPivot.Columns.Remove(valueColumn.ColumnName);
pkColumnNames = tempPivot.Columns
.Cast<DataColumn>()
.Select(c => c.ColumnName)
.ToArray();
// prep results table
dtPivot = tempPivot.DefaultView.ToTable(true, pkColumnNames).Copy();
dtPivot.PrimaryKey = dtPivot.Columns.Cast<DataColumn>().ToArray();
// include the sum column
dtPivot.Columns.Add(sumColumn);
try
{
dtNormalTable.AsEnumerable()
.Select(r => r[pivotColumn.ColumnName].ToString())
.Distinct()
.ToList()
.ForEach(c => dtPivot.Columns.Add(Convert.ToDateTime(c).ToString("dd-MMM-yyyy"), typeof(string)));
}
catch
{
dtNormalTable.AsEnumerable()
.Select(r => r[pivotColumn.ColumnName].ToString())
.Distinct()
.ToList()
.ForEach(c => dtPivot.Columns.Add(c, typeof(string)));
}
// load it
foreach (DataRow row in dtNormalTable.Rows)
{
// find row to update
DataRow aggRow = dtPivot.Rows.Find(
pkColumnNames
.Select(c => row[c])
.ToArray());
// the aggregate used here is LATEST
// adjust the next line if you want (SUM, MAX, etc...)
string columnName = string.Empty;
try
{
columnName = Convert.ToDateTime(row[pivotColumn.ColumnName]).ToString("dd-MMM-yyyy");
}
catch
{
columnName = row[pivotColumn.ColumnName].ToString();
}
if (aggRow.IsNull(columnName))
{
aggRow[columnName] = Convert.ToDecimal(row[valueColumn.ColumnName]);
}
else
{
aggRow[columnName] = Convert.ToDecimal(aggRow[columnName]) +
Convert.ToDecimal(row[valueColumn.ColumnName]);
}
if (numberFormat == "3")
{
// add the value to the sum
aggRow[sumColumn] = (Convert.ToDecimal(aggRow[sumColumn].ToString()) +
Convert.ToDecimal(row[valueColumn.ColumnName].ToString())).ToString("#0.000");
}
else if (numberFormat == "2")
{
// add the value to the sum
aggRow[sumColumn] = (Convert.ToDecimal(aggRow[sumColumn].ToString()) +
Convert.ToDecimal(row[valueColumn.ColumnName].ToString())).ToString("#0.00");
}
else if (numberFormat == "1")
{
// add the value to the sum
aggRow[sumColumn] = (Convert.ToDecimal(aggRow[sumColumn].ToString()) +
Convert.ToDecimal(row[valueColumn.ColumnName].ToString())).ToString("#0.0");
}
else
{
// add the value to the sum
aggRow[sumColumn] = (Convert.ToDecimal(aggRow[sumColumn].ToString()) +
Convert.ToDecimal(row[valueColumn.ColumnName].ToString())).ToString("#0");
}
}
return dtPivot;
}
catch (Exception ex)
{
cTracing.WriteTrace("Error inside DataTableToPivot", "DataTableToPivot");
cLogging.WriteLog(ex);
return null;
}
finally
{
if (dtPivot != null)
dtPivot.Dispose();
}
}
enter code here