TIPS-Add Group-By And Sub-Total To DataGrid
| | | 0 | |
| EmpNo | Name | Expense |
| 001 | Jeffrey | 120 |
| 001 | Jeffrey | 256 |
| 001 | Jeffrey | 1,024 |
| 002 | Darkthread | 18 |
| 002 | Darkthread | 27 |
這是很常見的一項需求,題目很簡單,JOIN兩個Table得到的清單資料如上表,以DataGrid或GridView方式呈現,要怎麼Group By EmpNo並加上小計,變成以下的格式?
| EmpNo | Name | CombExpense | ||
| 001 | Jeffrey | 120 256 1,024 | ||
| ||||
| 002 | Darkthread | 18 27 | ||
|
這個問題的解法有很多種。例如可以從Client-Side以Javascript操弄Table Object,隱去不想顯示的資料及加上TR;而我個人則偏好善用DataTable的豐富功能。
廢話不多說,請看Sample Code,說明則在註解中。
protected void Page_Load(object sender, EventArgs e)
{ //懶得建DB,直接用DataTable Object建資料源 DataTable origTbl = new DataTable();origTbl.Columns.Add("EmpNo", typeof(string));
origTbl.Columns.Add("Name", typeof(string));
origTbl.Columns.Add("Expense", typeof(int));
origTbl.Rows.Add("001", "Jeffrey", 120);
origTbl.Rows.Add("001", "Jeffrey", 256);
origTbl.Rows.Add("001", "Jeffrey", 1024);
origTbl.Rows.Add("002", "Darkthread", 18);
origTbl.Rows.Add("002", "Darkthread", 27);
DataGrid1.DataSource = origTbl;
DataGrid1.DataBind();
//建立另一個加上加總的DataTable //DataTable.Clone()可以只建Schema,不複製資料DataTable sumTbl = origTbl.Clone();
//移去原本的費用欄 sumTbl.Columns.Remove("Expense"); //加上綜合整理過的費用欄,用字串格式sumTbl.Columns.Add("CombExpense", typeof(string));
//加上配合增加小計列及排序用的PK欄位sumTbl.Columns.Add("PK", typeof(string));
//加上主鍵值,方便查找sumTbl.PrimaryKey =
new DataColumn[] { sumTbl.Columns["PK"] };
//用個Hashtable來計加總值(.NET 2.0可用Dictionary<string, int>) Hashtable htSubTotal = new Hashtable();foreach (DataRow row in origTbl.Rows)
{string empNo = row["EmpNo"].ToString();
int exp = (int)row["Expense"];
string dispExp = string.Format("{0:#,###}", exp);
//Rows.Find(pkValues)可以快速找到某一筆資料DataRow findRow = sumTbl.Rows.Find(empNo);
//資料已存在,用Append的if (findRow != null)
{ findRow["CombExpense"] = findRow["CombExpense"].ToString() + "<br />" + dispExp;
htSubTotal[empNo] = (int)htSubTotal[empNo] + exp;}
else //否則新增一筆
{ sumTbl.Rows.Add(empNo, row["Name"], dispExp, empNo);htSubTotal.Add(empNo, exp);
}
}
//加上小計欄foreach (string empNo in htSubTotal.Keys)
sumTbl.Rows.Add("", "",
string.Format("<table width='100%'><tr>" +
"<td align='left'>SubTotal</td>" + "<td align='rigt'>{0:#,###}</td></tr></table>", htSubTotal[empNo]), empNo+"zSUM"); //要求Sort By PK,如此,小計會跟在各EmpNo資料下方DataGrid2.DataSource =
new DataView(sumTbl, "", "PK", DataViewRowState.CurrentRows);
DataGrid2.DataBind();
}
Comments
Be the first to post a comment