ASP.Net C# GridView实现列数值相乘求和与重复单元格合并
问题描述
我有一个已绑定到GridView数据源的DataTable,具体需求如下:
- 将「Quantity」列的值与「Part1 qty」列的值相乘,依此类推计算到「column5」单元格值重复的位置
- 运算结果需要显示在对应原值的下方
我已经编写了GridView1_DataBound事件处理代码,但未达到预期效果,以下是原有代码:
protected void GridView1_DataBound(object sender, EventArgs e) { int gridViewCellCount = GridView1.Rows[0].Cells.Count; string[] columnNames = new string[gridViewCellCount]; for (int k = 0; k < gridViewCellCount; k++) { columnNames[k] = ((System.Web.UI.WebControls.DataControlFieldCell)(GridView1.Rows[0].Cells[k])).ContainingField.HeaderText; } for (int i = GridView1.Rows.Count - 1; i > 0; i--) { GridViewRow row = GridView1.Rows[i]; GridViewRow previousRow = GridView1.Rows[i - 1]; var result = Array.FindIndex(columnNames, element => element.EndsWith("QTY")); var Arraymax=columnNames.Max(); int maxIndex = columnNames.ToList().IndexOf(Arraymax); decimal MultiplicationResult=0; int counter = 0; for (int j = 8; j < row.Cells.Count; j++) { if (row.Cells[j].Text == previousRow.Cells[j].Text) { counter++; if (row.Cells[j].Text != " " && result < maxIndex) { var Quantity = GridView1.Rows[i].Cells[1].Text; var GLQuantity = GridView1.Rows[i].Cells[result].Text; var PreviousQuantity= GridView1.Rows[i-1].Cells[1].Text; var PreviousGLQuantity= GridView1.Rows[i-1].Cells[result].Text; var GLQ = GLQuantity.TrimEnd(new Char[] { '0' }); var PGLQ = PreviousGLQuantity.TrimEnd(new char[] { '0' }); if (GLQ == "") { GLQ = 0.ToString(); } if (PGLQ == "") { PGLQ = 0.ToString(); } MultiplicationResult = Convert.ToDecimal(Quantity) * Convert.ToDecimal(GLQ) + Convert.ToDecimal(PreviousQuantity) * Convert.ToDecimal(PGLQ); object o = dt.Rows[i].ItemArray[j] + " " + MultiplicationResult.ToString(); GridView1.Rows[i].Cells[j].Text = o.ToString(); GridView1.Rows[i].Cells[j].Text.Replace("\n", "<br/>"); result++; } else result++; if (previousRow.Cells[j].RowSpan == 0) { if (row.Cells[j].RowSpan == 0) { previousRow.Cells[j].RowSpan += 2; } else { previousRow.Cells[j].RowSpan = row.Cells[j].RowSpan + 1; } row.Cells[j].Visible = false; } } else result++; } } }
解决方案
原有代码问题梳理
- 字符串替换操作未将结果回写到单元格,导致换行不生效
- 错误地将计算结果赋值给了即将被隐藏的当前行单元格,最终结果无法展示
- 数值转换缺少异常校验,容易因空值、非法值触发运行报错
- QTY列索引的边界判断逻辑存在偏差,会出现漏计算/越界问题
修正后可运行代码
protected void GridView1_DataBound(object sender, EventArgs e) { // 先获取所有列名 int cellCount = GridView1.Rows[0].Cells.Count; string[] columnNames = new string[cellCount]; for (int k = 0; k < cellCount; k++) { columnNames[k] = ((System.Web.UI.WebControls.DataControlFieldCell)(GridView1.Rows[0].Cells[k])).ContainingField.HeaderText; } // 找到第一个以QTY结尾的列索引 int firstQtyIndex = Array.FindIndex(columnNames, element => element.EndsWith("QTY")); // 从下往上遍历行,处理合并和计算 for (int i = GridView1.Rows.Count - 1; i > 0; i--) { GridViewRow currentRow = GridView1.Rows[i]; GridViewRow prevRow = GridView1.Rows[i - 1]; int currentQtyIndex = firstQtyIndex; // 从第9列(索引8)开始处理 for (int j = 8; j < currentRow.Cells.Count; j++) { string currentCellText = currentRow.Cells[j].Text.Trim(); string prevCellText = prevRow.Cells[j].Text.Trim(); // 跳过空值、不相等的单元格 if (string.IsNullOrEmpty(currentCellText) || currentCellText == " " || currentCellText != prevCellText) { currentQtyIndex++; continue; } // 计算乘积和 decimal result = 0; try { // 取当前行和上一行的Quantity值 decimal currentQty = Convert.ToDecimal(currentRow.Cells[1].Text.Trim()); decimal prevQty = Convert.ToDecimal(prevRow.Cells[1].Text.Trim()); // 取对应QTY列的值,处理尾部多余的0和小数点 string currentGlQtyStr = currentRow.Cells[currentQtyIndex].Text.Trim().TrimEnd('0').TrimEnd('.'); string prevGlQtyStr = prevRow.Cells[currentQtyIndex].Text.Trim().TrimEnd('0').TrimEnd('.'); decimal currentGlQty = Convert.ToDecimal(string.IsNullOrEmpty(currentGlQtyStr) ? "0" : currentGlQtyStr); decimal prevGlQty = Convert.ToDecimal(string.IsNullOrEmpty(prevGlQtyStr) ? "0" : prevGlQtyStr); result = currentQty * currentGlQty + prevQty * prevGlQty; } catch { // 转换失败默认赋值0,可根据业务需求调整 result = 0; } // 把原数值和计算结果拼接,用<br/>换行,结果添加红色高亮 prevRow.Cells[j].Text = $"{prevCellText}<br/><span style='color:red;'>{result}</span>"; // 处理单元格合并 if (prevRow.Cells[j].RowSpan == 0) { prevRow.Cells[j].RowSpan = currentRow.Cells[j].RowSpan == 0 ? 2 : currentRow.Cells[j].RowSpan + 1; } else { prevRow.Cells[j].RowSpan += 1; } // 隐藏当前行重复单元格 currentRow.Cells[j].Visible = false; currentQtyIndex++; } } }
额外优化说明
- 新增了数值转换的异常捕获,避免空值、非数字内容导致程序崩溃
- 计算结果默认添加红色样式,和需求的高亮效果匹配
- 优化了QTY列空值的判断逻辑,避免多余的0和小数点导致计算错误
内容的提问来源于stack exchange,提问作者Shaktiman
相关产品推荐
相关产品推荐

