Как суммировать столбцы в dataTable?

Как я могу получить сумму для всех столбцов в datatable? Скажем, у меня была следующая таблица. Как я могу рассчитать "итоговую" строку? Легко добавить общую строку в 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

Ответы

Ответ 1

Попробуйте следующее:

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

Ответ 2

Существует также способ сделать это без циклов, используя метод 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)", "")

Ответ 3

Я сомневаюсь, что это то, что вы хотите, но ваш вопрос немного расплывчатый.

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

Вы можете прокручивать коллекции DataColumn и DataRow в своем DataTable:

// 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.

EDIT: добавьте 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 лучше.

Ответ 5

Очень жаль использовать .NET и не использовать коллекции и лямбда, чтобы сэкономить время и строки кода Это пример того, как это работает: Преобразуйте yourDataTable в Enumerable, отфильтруйте его, если хотите, в соответствии с столбцом "FILTER_ROWS_FIELD", и, если хотите, группируйте свои данные с помощью "A_GROUP_BY_FIELD". Затем получите счет, сумму или что угодно. Если вы хотите, чтобы счет и сумма без grouby не группировали данные

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"))
                          };

Ответ 6

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