2

如果满足某些条件,我有以下代码循环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
定义, 1, 3, 6

它将处理两个 abc,但不处理 def。

dt2 应包含:

abc, 1, 2, 8, 2
定义, 1, 3, 6, 1

其中 8 是 dt 中第 4 列的总数,2 是 abc 行数。

我只得到这个

abc, 1, 2, 8, 2
4

2 回答 2

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根据第一列中的值对结果进行分组,然后生成一个新表,该表适当地聚合每个组的结果。这可能不是你所需要的,但它应该能让你大部分时间到达那里。

于 2012-09-19T17:19:56.723 回答
1

问题在于这一行:

if (nextRow != null && i < dt.Rows.Count && account != nextAccount) 

尝试将其更改为

if (account != nextAccount) 

我删除了:

nextRow != null

因为这会阻止添加最后一条记录。

我还删除了:

i < dt.Rows.Count

因为这已经由您的for循环强制执行。

注意:如果账户与上一行相同,最后一行可能不会添加。不确定您希望这里有什么行为。

于 2012-09-19T17:22:34.147 回答