需求:報表顯示最近 5 個月統計,欄位隨時間推移自動變化(最舊月份消失、新月份加入)。使用 Repeater,Header/Item/Footer 三區塊皆內嵌 Table,Label ID 編號對應索引(LabelH0~LabelH5、LabelI0~LabelI5、LabelF0~LabelF5),後置程式碼以迴圈動態繫結。



PrintLog objPrintLog = new PrintLog();
DataTable objDt;
decimal c1, c2, c3, c4, c5; // 5個月份累加變數
private void Data_Binding() {
DateTime now = DateTime.Now;
objPrintLog.Year = now.Year;
objPrintLog.Month = now.Month;
objPrintLog.Months = 5;
objDt = objPrintLog.GetSummaryReportByYearMonth();
RepeaterLFMS.DataSource = objDt;
RepeaterLFMS.DataBind();
}
protected void RepeaterLFMS_ItemDataBound(object sender, RepeaterItemEventArgs e) {
// Header
if (e.Item.ItemType == ListItemType.Header) {
for (int i = 0; i <= 5; i++) {
Label lh = (Label)e.Item.FindControl("LabelH" + i);
lh.Text = objDt.Columns[i].ColumnName;
}
}
// Item
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) {
DataRowView drv = (DataRowView)e.Item.DataItem;
for (int j = 0; j <= 5; j++) {
Label li = (Label)e.Item.FindControl("LabelI" + j);
if (j == 0) li.Text = drv[objDt.Columns[0].ColumnName].ToString();
else {
decimal v = Convert.ToDecimal(drv[objDt.Columns[j].ColumnName]);
li.Text = v.ToString();
// 累加到對應變數
switch(j) { case 1: c1+=v; break; case 2: c2+=v; break; case 3: c3+=v; break; case 4: c4+=v; break; case 5: c5+=v; break; }
}
}
}
// Footer
if (e.Item.ItemType == ListItemType.Footer) {
for (int k = 0; k <= 5; k++) {
Label lf = (Label)e.Item.FindControl("LabelF" + k);
if (k == 0) lf.Text = "Total";
else {
decimal total = k==1?c1:k==2?c2:k==3?c3:k==4?c4:c5;
lf.Text = total.ToString();
}
}
}
}
const int dynamicColumns = 5 取代硬編碼ViewState["c"+j] 陣列取代 c1~c5 變數本文展示「寫死但能動」的初版實作,理解此基礎後再進行重構,能更深刻體會「消除重複」的重構價值。