我有以下代码循环遍历DataTable
并在满足某些条件的情况下构建另一个代码。但是,正在跳过初始DataTable中的最后一行。
for (int i = 0; i < dt.Rows.Count; i++ )
{
DataRow row = dt.Rows[i];
DataRow nextRow = i < dt.Rows.Count - 1 ? dt.Rows[i + 1] : null;
string account = row[1].ToString();
string nextAccount = "";
if (nextRow != null)
{
nextAccount = nextRow[1].ToString();
}
numberOfItems++;
totalAmount += Convert.ToDecimal(row[2]);
row[4] = "D";
row[5] = c;
row[6] = Sequence;
if (nextRow != null && i < dt.Rows.Count && account != nextAccount)
{
dt2.Rows.Add("N",
c,
row[1],
row[2],
row[3],
numberOfItems,
totalAmount,
Sequence);
numberOfItems = 0;
totalAmount = 0m;
Sequence++;
}
}
在上面的代码中,如果我有一个表,如:
abc, 1, 2, 3 abc, 1, 2, 5 def, 1, 3, 6
它将同时处理abc,但不会处理def。
dt2应包含:
abc, 1, 2, 8, 2 def, 1, 3, 6, 1
其中8是dt中第4列的总和,2是abc行的数量。
我只是得到了这个
abc, 1, 2, 8, 2
答案 0 :(得分:2)
这是因为看起来每行的生成不仅取决于初始表中的行,还取决于初始表中相应行之后的行。最后一行没有“后面的行”。编写代码使得它不会做任何事情(对于最后一行),而不是通过尝试访问不存在的行来崩溃和刻录。
因此,看看你实际上要做什么,我会建议采用类似于此的解决方案:
foreach (var group in dt.AsEnumerable()
.GroupBy(row => row[0]))
{
DataRow firstInGroup = group.First();
dt2.Rows.Add(
firstInGroup[0],
firstInGroup[1],
firstInGroup[2],
group.Sum(row => row[3] as decimal?));
}
您可以使用GroupBy
根据第一列中的值对结果进行分组,然后生成一个新表,该表可以适当地聚合每个组的结果。有可能这不是你所需要的,但它应该让你在那里大部分时间。
答案 1 :(得分:1)
问题在于这一行:
if (nextRow != null && i < dt.Rows.Count && account != nextAccount)
尝试将其更改为
if (account != nextAccount)
我删除了:
nextRow != null
因为这会阻止添加最后一条记录。
我也删除了:
i < dt.Rows.Count
因为for
循环已经强制执行。
注意:如果帐户与上一行相同,则可能无法添加最后一行。不知道你希望在这里做什么行为。