QA@IT

データテーブルのループ処理の仕方

11995 PV

.Netでデータテーブル(dt1)の削除を致したく思います。

得意先コード9999を含むレコード全てを削除する場合、以下を考えました。

Dim keyValue = "9999"
For Each r1 As DataRow In dt1.Rows
If r1(0).ToString() = keyValue Then
dt1.Rows.Remove(r1)
End If
Next r1
dt1.AcceptChanges()
上記を実施しましたが、削除されておりません。
ご教授下さい。

宜しくお願い致します。

回答

SQL文が以前のコード( http://qa.atmarkit.co.jp/q/2829 )のままであれば、取引先コードが 4列目ですので、インデックスは 0ではなく 3ですね。
あとはDB列の型によっては空白が残るので

Dim keyValue = "9999"
For Each r1 As DataRow In dt1.Rows
    If r1(3).ToString().Trim() = keyValue Then
        dt1.Rows.Remove(r1)
    End If
Next r1
dt1.AcceptChanges()

となるでしょう。

ただせっかく応用してくれたものの、For Eachだとエラーになるような気がします。
(なので前回後ろからのカウントにしました。)

追記

ちなみにその場合、foreachやfor文以外でremoveするにはどうすればよいでしょうか?
For文の場合は先頭からremoveすると途中で数が合わなくなるので、後ろから除外していけばいいだけです。
For i = dt1.Rows.Count -1 to 0 step -1
というFor文にします。
(For Eachの場合ループに使っているリストを改変しちゃうので別ですが)

または前回の回答で yito さんが示したようにSelectで抽出して削るパターンもあります。

あとは冗長になりますが2回 For Eachするという手もあるでしょうか。

Dim keyValue = "9999"
Dim removeRows = new List(Of DataRow)

For Each r1 As DataRow In dt1.Rows
    If r1(3).ToString().Trim() = keyValue Then
        removeRows.Add(r1)
    End If
Next r1

For Each r1 As DataRow In removeRows
    dt1.Rows.Remove(r1)   
Next
dt1.AcceptChanges()

この場合はループに使っているリストを改変しないのでいけるんじゃないかな…
(動作確認はしていません)

後ろからのFor文とSelect文は前回のを見てください。
http://qa.atmarkit.co.jp/q/2851

編集 履歴 (1)
  • ちなみにFor Eachや頭からのFor文でうまくいかないだろうっていうのは、ループの途中でRemoveするとリストの構造が変わってしまうからです。 -
  • ちなみにその場合、foreachやfor文以外でremoveするにはどうすればよいでしょうか? -
  • → 追記します。 -
ウォッチ

この質問への回答やコメントをメールでお知らせします。