There are lots of examples of how to get the sum of each cell in a column. I have not been able to find an example of how to sum each cell in a row and add that total into the new column called "Total" for example.
C# DataTable has the DataTable1.Compute("SUM(["Column Name"])", "")
Example of What I would like to do below. However I would also like to be able to exclude specific columns as they may not contain numbers.
Edit The table is dynamic and the number of columns may change.
You can use this loop:
table.Columns.Add("Total", typeof(decimal));
foreach (DataRow row in table.Rows)
{
decimal rowSum = 0;
foreach (DataColumn col in table.Columns)
{
if(!row.IsNull(col))
{
string stringValue = row[col].ToString();
decimal d;
if(decimal.TryParse(stringValue, out d))
rowSum += d;
}
}
row.SetField("Total", rowSum);
}
This should work with any column type.
DataTable has capability to create calculated columns. In your case you can create "Total" column as
DataTable1.Columns.Add("Total", typeof(Double));
DataTable1.Columns["Total"].Expression = "C1+C2+C3";
Example code for Yuriy's answer:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
namespace DynamicColumns
{
class MainClass
{
public static void Main (string[] args)
{
Console.WriteLine ("Total all quantity columns");
var dt = new DataTable ();
dt.Columns.Add ("ProductName", typeof(string));
dt.Columns.Add ("Qty1", typeof(int));
dt.Columns.Add ("Qty2", typeof(int));
dt.Columns.Add ("Qty3", typeof(int));
{
var dr = dt.NewRow ();
dr ["ProductName"] = "Keyboard";
dr ["Qty1"] = 2;
dr ["Qty2"] = 5;
dr ["Qty3"] = 6;
dt.Rows.Add (dr);
}
{
var dr = dt.NewRow ();
dr ["ProductName"] = "Mouse";
dr ["Qty1"] = 5;
dr ["Qty2"] = 1;
dr ["Qty3"] = 2;
dt.Rows.Add (dr);
}
string expression =
string.Join (" + ",
dt.Columns.OfType<DataColumn>()
.Where(x => x.DataType == typeof(int))
.Select(x => x.ColumnName)
.ToArray() );
dt.Columns.Add("Total", typeof(int)).Expression = expression;
Console.WriteLine ("Expression: {0}",expression);
Console.WriteLine ("\nProduct and totals");
foreach (var r in dt.Rows.OfType<DataRow>()) {
Console.WriteLine ("{0} {1}", r["ProductName"], r["Total"]);
}
}
}
}
Output:
Expression: Qty1 + Qty2 + Qty3
Product and totals
Keyboard 13
Mouse 8
I would hazard a guess this (.Expression) is the most performant solution compared to lambda-ing our way to each row to each column, and even compared to looping each row and each column
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With