题 如何在dataTable中对列进行求和?


如何获取数据表中所有列的总和?说我有下表。如何计算“总”行?将总行添加到数据表应该很容易。

         Columns    hits     uniques    sigups, etc...
Rows                  
1                      12         1         23
2                       1         0          5
3                       6         2          9


total                  19          3        37

更新

我最终得到了这个。这是我唯一可以上班的事情。

 For Each col As DataColumn In TotalsTable.Columns    
    If col.DataType.Name = "DateTime" Then
            count = count + 1
                Continue For
        End If

        Dim colTotal As Double = 0
        Dim value As Double

        For Each row As DataRow In TotalsTable.Rows
            If Double.TryParse(row(col), value) Then
                    colTotal += Double.Parse(row(col))
                    End If
        Next

    totalRow(count) = colTotal
        count = count + 1

  Next

15
2018-04-08 23:26


起源


一共什么? - Jeff Mercado


答案:


尝试这个:

            DataTable dt = new DataTable();
            int sum = 0;
            foreach (DataRow dr in dt.Rows)
            {
                foreach (DataColumn dc in dt.Columns)
                {
                    sum += (int)dr[dc];
                }
            } 

7
2018-04-08 23:37



根据我对此的回答 - chobo
最后,我得到了你真正想要的答案。非常感谢你 - shafi7468


还有一种方法可以在没有循环的情况下使用 DataTable.Compute方法。以下示例来自该页面。您可以看到使用的代码非常简单:

private void ComputeBySalesSalesID(DataSet dataSet)
{
    // Presumes a DataTable named "Orders" that has a column named "Total."
    DataTable table;
    table = dataSet.Tables["Orders"];

    // Declare an object variable. 
    object sumObject;
    sumObject = table.Compute("Sum(Total)", "EmpID = 5");
}

我必须补充一点,如果你不需要过滤结果,你总是可以传递一个空字符串:

sumObject = table.Compute("Sum(Total)", "")

40
2017-08-16 14:17



+1这应该是正确的答案。这个框架的确切特征正是这个问题的真正要求。 - toddmo


我怀疑这是你想要的,但你的问题有点模糊

Dim totalCount As Int32 = DataTable1.Columns.Count * DataTable1.Rows.Count

如果您的所有列都是数字列,您可能需要这样:

你可以用 DataTable.Compute 至 Sum 列中的所有值。

 Dim totalCount As Double
 For Each col As DataColumn In DataTable1.Columns
     totalCount += Double.Parse(DataTable1.Compute(String.Format("SUM({0})", col.ColumnName), Nothing).ToString)
 Next

在您编辑了问题并添加了更多信息后,这应该有效:

 Dim totalRow = DataTable1.NewRow
 For Each col As DataColumn In DataTable1.Columns
     totalRow(col.ColumnName) = Double.Parse(DataTable1.Compute("SUM(" & col.ColumnName & ")", Nothing).ToString)
 Next
 DataTable1.Rows.Add(totalRow)

4
2018-04-08 23:31



抱歉。我想总结一个dataTable中的所有列。 - chobo
@chobo:添加了另一种方法来对所有列的所有行求和。 - Tim Schmelter
那么使用您的技术,您可以计算列的总和,并计算所有行的因子? - chobo
@choco:是的,Datatable.Compute与聚合函数 Sum 将计算列的所有行,您甚至可以根据需要指定过滤器。我遍历所有列。 - Tim Schmelter
@choco:在您提供更多信息后编辑我的答案。 - Tim Schmelter


您可以遍历DataTable中的DataColumn和DataRow集合:

// Sum rows.
foreach (DataRow row in dt.Rows) {
    int rowTotal = 0;
    foreach (DataColumn col in row.Table.Columns) {
        Console.WriteLine(row[col]);
        rowTotal += Int32.Parse(row[col].ToString());
    }
    Console.WriteLine("row total: {0}", rowTotal);
}
// Sum columns.
foreach (DataColumn col in dt.Columns) {
    int colTotal = 0;
    foreach (DataRow row in col.Table.Rows) {
        Console.WriteLine(row[col]);
        colTotal += Int32.Parse(row[col].ToString());
    }
    Console.WriteLine("column total: {0}", colTotal);
}

注意:上面的代码在将对象转换为int之前不进行任何类型的检查。

编辑:添加显示列总和的DataRow

尝试使用此操作创建一个新行以显示列总和:

DataRow totalsRow = dt.NewRow();
foreach (DataColumn col in dt.Columns) {
    int colTotal = 0;
    foreach (DataRow row in col.Table.Rows) {
        colTotal += Int32.Parse(row[col].ToString());
    }
    totalsRow[col.ColumnName] = colTotal;
}
dt.Rows.Add(totalsRow);

如果您的任何DataTable的DataRows的数据类型都是非数字的,或者您希望在求和时检查每个单元格的值,则此方法很好。否则我相信@Tim的回应使用 DataTable.Compute 是更好的。


2
2018-04-08 23:38



有没有一种简单的方法可以将总数分配给该数据表的新行? - chobo
@chobo我更新了如何添加显示列总和的DataRow。 - Jay Riggs


很遗憾使用.NET而不使用集合和lambda来节省时间和代码行 这是一个如何工作的例子: 根据“FILTER_ROWS_FIELD”列,将yourDataTable转换为Enumerable,根据需要对其进行过滤,如果需要,可以按“A_GROUP_BY_FIELD”对数据进行分组。 然后得到计数,总和,或任何你想要的。 如果你想要一个没有数据的计数和总和,就不要对数据进行分组

var groupedData = from b in yourDataTable.AsEnumerable().Where(r=>r.Field<int>("FILTER_ROWS_FIELD").Equals(9999))
                          group b by b.Field<string>("A_GROUP_BY_FIELD") into g
                          select new
                          {
                              tag = g.Key,
                              count = g.Count(),
                              sum = g.Sum(c => c.Field<double>("rvMoney"))
                          };

1
2017-09-18 09:54



我同意。虽然我还在回顾这篇文章,但我很震惊,没有立即看到一个lambda解决方案。 - Lopsided


 for (int i=0;i<=dtB.Columns.Count-1;i++)
 {
   array(0, i) = dtB.Compute("SUM([" & dtB.Columns(i).ColumnName & "])", "")                   
 }

0
2018-04-30 08:54



在解决方案的开头有一个小解释是个好主意。 - ughai