將下面表(1)格式的數據轉換為表(2)格式的數據。很明顯,這是一個行轉列的要求,本想在數據庫中行轉列,因為在數據庫中行轉列是比較簡單的,方法可以參考本站SQLServer中(行列轉換)行轉列及列轉行且加平均值及匯總值,但因其它需求,最終需將該轉化搬到C#中進行了。
(表1)
表(2)
不多說了,下面開始在DataTable行轉列示例:
//DataTable行轉列
private DataTable RCC(DataTable _outDataSource)
{
//從DataTable中讀取不重復的日期行,用來構造新DataTable的列
DataTable distinct_date = _outDataSource.DefaultView.ToTable(true, "日期");
DataTable new_DataTable = new DataTable();
//將客戶名稱列添加到新表中
DataColumn new_d_col = new DataColumn();
new_d_col.ColumnName = "客戶名稱";
new_d_col.Caption = "";
new_DataTable.Columns.Add(new_d_col);
StringBuilder str_sum = new StringBuilder();
//開始在新表中構造日期列
foreach (DataRow dr in distinct_date.Rows)
{
new_d_col = new DataColumn();
new_d_col.DataType = typeof(decimal);
new_d_col.ColumnName = dr["日期"].ToString();
new_d_col.Caption = dr["日期"].ToString();
new_d_col.DefaultValue = 0;
new_DataTable.Columns.Add(new_d_col);
//這個的目的是為合計列構造expression
str_sum.Append("+[").Append("日期").Append("]");
}
//將合計列添加到新表中
new_d_col = new DataColumn();
new_d_col.DataType = typeof(decimal);
new_d_col.ColumnName = "Sum";
new_d_col.Caption = "合計";
new_d_col.DefaultValue = 0;
new_d_col.Expression = str_sum.ToString().substring(1);
new_DataTable.Columns.Add(new_d_col);
/*好了,到此新表已經構建完畢,下面開始為新表添加數據*/
//從原DataTable中讀出不重復的客戶名稱,以客戶名稱為關鍵字來構造新表的行
DataTable distinct_object = _outDataSource.DefaultView.ToTable(true, "客戶名稱");
DataRow[] drs;
DataRow new_dr;
foreach (DataRow dr in distinct_object.Rows)
{
new_dr = new_DataTable.NewRow();
new_dr["客戶名稱"] = dr["客戶名稱"].ToString();
foreach (DataRow _dr in distinct_date.Rows)
{
drs = _outDataSource.Select("客戶名稱='" + dr["客戶名稱"].ToString() + "' and 日期='" + _dr["日期"].ToString() + "'");
if (drs.Length != 0)
{
new_dr[_dr["日期"].ToString()] = Math.Round(Convert.ToDecimal(drs[0]["金額"]), 2);
}
}
new_DataTable.Rows.Add(new_dr);
}
return new_DataTable;
}
從上面的代碼中看到我們並沒有為新表"合計"這一列賦值,這是因為該列具有表達式str_sum.Append("+[").Append("日期").Append("]"),所以這列的值是會自動填充的。
注意,在上面的表達式中,我們加了[],在DataTable的表達式中,如果列名是中文,一定要為列名加上[],要不然會報錯的,這也是我調試了好久才發現的。