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
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
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 に答える