You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 != "&nbsp;" && 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 == "&nbsp;" || 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 20:15:05