我正在研究数据表。我想获得每个类别的小计和总计。
我想在每行的行末尾添加小计行。我的问题是我没有得到最后一个类别的小计。我不知道我哪里出错了。 任何能帮助我的人。
必需的输出:
+------------+------------+------------+-----------+----------+-------+-----------+
|CategoryID | Category | Orgname | Penalties | Interest | Admin |TotalAmount|
+------------+------------+------------+-----------+----------+-------+-----------+
| 1 | 1-Food | Spar | $10 | $0 | $15.3 | $20.3 |
+-------------------------+------------+-----------+----------+-------+-----------+
| 1 | 1-Food |Pick n’ Pay | $0 | $10 | $20 | $30 |
+------------+------------+------------+-----------+----------+-------+-----------+
| Subtotal | $10 | $10 | $30.3 | $50.3 |
+-------------------------+------------+-----------+----------+-------+-----------+
| 2 | 2-Auto | BMW | $0 | $30 | $55 | $85 |
| 2 | 2-Auto | Toyota | $9 | $0 | $14.5 | $23.5 |
| 2 | 2-Auto | Jaguar | $22.8 | $8.2 | $50 | $81 |
+-------------------------+------------+-----------+----------+-------+-----------+
| Subtotal | $31.8 | $38.2 | $119.5| $189.5 |
+-------------------------+------------+-----------+----------+-------+-----------+
| 3 | 3-Banking | Absa | $0 | $40 | $155 | $190 |
+-------------------------+------------+-----------+----------+-------+-----------+
| Subtotal | $0 | $40 | $155 | $190 |
+-------------------------+------------+-----------+----------+-------+-----------+
| Grand Total | $41.8 | $88.2 | $304.8| $429,8 |
+-------------------------+------------+-----------+----------+-------+-----------+
我的代码:
var query = (from _transaction in _entities.Transactions
join _cd in _entities.Organisations on _transaction.Refno equals _cd.Refno
join _category in _entities.Categorys on _transaction.CategoryID equals _category.CategoryID
group new { _trans = _transaction, cd = _cd, }
by new { _transaction.CategoryID, _transaction.Refno, _cd.Orgname, _category.Description }
into _group
orderby _group.Key.CategoryID
select new
{ CategoryID = _group.Key.CategoryID,
Category = _group.Key.CategoryID + " - " + _group.Key.Description,
Refno = _group.Key.Refno,
Orgname = _group.Key.Orgname,
Penalties = _group.Sum(x => x._trans.Penalties),
Interest = _group.Sum(x => x._trans.Interest),
Admin = _group.Sum(x => x._trans.Admin),
TotalAmount = _group.Sum(x => x._trans.TotalAmount),
});
DataTable dt = new DataTable();
DataSet ds = new DataSet();
ds.Tables.Add(query.CopyToDataTable()); ds.Tables[0].TableName = "Table1";
dt = ds.Tables[0];
//Get Subtotal
long _CategoryID = 0; double Admin = 0; double Interest = 0;
double Penalties = 0; double TotalAmount = 0; string Title = string.Empty;
for (int i = 0; i <= dt.Rows.Count - 1; i++)
{
if (i > 0)
{
if (dt.Rows[i]["Category"].ToString().ToLower() != dt.Rows[i - 1]["Category"].ToString().ToLower())
{
dt.Rows.InsertAt(dt.NewRow(), i);
dt.Rows[i]["CategoryID"] = _CategoryID;
_CategoryID = 0;
dt.Rows[i]["Category"] = Title;
Title = string.Empty;
dt.Rows[i]["Admin"] = Admin;
Admin = 0;
dt.Rows[i]["Interest"] = Interest;
Interest = 0;
dt.Rows[i]["Penalties"] = Penalties;
Penalties = 0;
dt.Rows[i]["TotalAmount"] = TotalAmount;
TotalAmount = 0;
i++;
}
}
Title = "Subtotal";
_CategoryID = Convert.ToInt64(dt.Rows[i]["CategoryID"]);
Admin += Convert.ToDouble(dt.Rows[i].IsNull("Admin") ? 0.0 : dt.Rows[i].Field<double>("Admin"));
Interest += Convert.ToDouble(dt.Rows[i].IsNull("Interest") ? 0.0 : dt.Rows[i].Field<double>("Interest"));
Penalties += Convert.ToDouble(dt.Rows[i].IsNull("Penalties") ? 0.0 : dt.Rows[i].Field<double>("Penalties"));
TotalAmount += Convert.ToDouble(dt.Rows[i].IsNull("TotalAmount") ? 0.0 : dt.Rows[i].Field<double>("TotalAmount"));
}
// Grand Total
var subtotal = query.GroupBy(x => x.CategoryID).Select(s => new
{
CategoryID = s.Key,
ISub = s.Sum(x => x.Interest),
ASub = s.Sum(x => x.Admin),
PSub = s.Sum(x => x.Penalties),
TASub = s.Sum(x => x.TotalAmount)
});
var GrandTotal = subtotal.Select(s => new
{
GI = subtotal.Sum(x => x.ISub),
GA = subtotal.Sum(x => x.ASub),
GP = subtotal.Sum(x => x.PSub),
GTA = subtotal.Sum(x => x.TSub)
}).Distinct();
//add grand total row to datatable
foreach (var a in GrandTotal)
{
var dr = dt.NewRow();
dr["Category"] = "Grand Total";
dr["Interest"] = a.GI;
dr["Admin"] = a.GA;
dr["Penalties"] = a.GP;
dr["TotalAmount"] = a.GTA;
dt.Rows.Add(dr);
}
答案 0 :(得分:2)
使用单个循环实现分组时,这是一个典型的错误。在这种情况下,最后一组不会被处理,并且在循环之后需要一些代码重复。
这就是我喜欢嵌套循环方法的原因。获取密钥,初始化聚合,处理直到密钥更改并使用组。
将它应用于您的特定情况将是这样的:
//Get Subtotal
for (int i = 0; i < dt.Rows.Count; i++)
{
// Initialize
long _CategoryID = Convert.ToInt64(dt.Rows[i]["CategoryID"]);
double Admin = 0; double Interest = 0;
double Penalties = 0; double TotalAmount = 0; string Title = string.Empty;
// Process
do
{
Admin += Convert.ToDouble(dt.Rows[i].IsNull("Admin") ? 0.0 : dt.Rows[i].Field<double>("Admin"));
Interest += Convert.ToDouble(dt.Rows[i].IsNull("Interest") ? 0.0 : dt.Rows[i].Field<double>("Interest"));
Penalties += Convert.ToDouble(dt.Rows[i].IsNull("Penalties") ? 0.0 : dt.Rows[i].Field<double>("Penalties"));
TotalAmount += Convert.ToDouble(dt.Rows[i].IsNull("TotalAmount") ? 0.0 : dt.Rows[i].Field<double>("TotalAmount"));
i++;
}
while (i < dt.Rows.Count && _CategoryID == Convert.ToInt64(dt.Rows[i]["CategoryID"]));
// Consume
dt.Rows.InsertAt(dt.NewRow(), i);
dt.Rows[i]["CategoryID"] = _CategoryID;
dt.Rows[i]["Category"] = "Subtotal";
dt.Rows[i]["Admin"] = Admin;
dt.Rows[i]["Interest"] = Interest;
dt.Rows[i]["Penalties"] = Penalties;
dt.Rows[i]["TotalAmount"] = TotalAmount;
}