VB.NET で、データセットから作成したビューのレコードを、ループさせながらインデックス指定で直接削除すんなよという話。
インデックスを指定してレコードを削除する場合も、例えば、
みたいな使い方であれば問題ないんだけど、ループしながらインデックスをアップしつつ消しちゃうと、その瞬間にレコードが削除されたことでその後のレコードのインデックスが変化してしまい、正常にデリートできない(削除予定のレコードが並んでいた場合、次のレコードを飛ばしちゃうことになっちゃう)という話。
ビューの Delete メソッドは直接レコードを削除しちゃうんだよね。
例えば、
みたいにしちゃうと、view(i).Delete() しちゃった時点で、以降のレコードのインデックスがひとつ減っちゃう。
本来、view(i + 1) だったレコードが view(i) になっちゃうということ。
つまり、上に書いたように、削除予定のレコードが並んでた場合、削除したレコードの次のレコードの処理は飛ばされてしまうということだ。あかん。
どうしてもビューの中身を頭から舐めながら処理を行いたい場合は、一旦データテーブル等にコピーして処理を行う必要がある。
みたいな感じ。
データテーブルの Delete メソッドはビューと違って「実際に削除するのではなく、削除マークをつけるだけ」なので、最後に AcceptChanges するまではインデックスが変化することもなく、問題なく最後まで削除処理を行うことができる。
これも、知らずにやっちゃうと相当ハマる。特に、レコード件数が多い時はデバッグで問題を見つけ出すのも大変(^^;
Tweet
インデックスを指定してレコードを削除する場合も、例えば、
view.AllowDelete = True
Do
Dim i As Integer = view.Find("消したいレコードに含まれているキーワード")
If i <> -1 Then
view.Delete(i)
Else
Exit Do
End If
Loop
みたいな使い方であれば問題ないんだけど、ループしながらインデックスをアップしつつ消しちゃうと、その瞬間にレコードが削除されたことでその後のレコードのインデックスが変化してしまい、正常にデリートできない(削除予定のレコードが並んでいた場合、次のレコードを飛ばしちゃうことになっちゃう)という話。
ビューの Delete メソッドは直接レコードを削除しちゃうんだよね。
例えば、
view.AllowDelete = True
Dim max As Integer = view.Count - 1
For i = 0 To max
if view(i).hoge = "消したいレコードに含まれているキーワード" Then
view(i).Delete()
End If
Next
みたいにしちゃうと、view(i).Delete() しちゃった時点で、以降のレコードのインデックスがひとつ減っちゃう。
本来、view(i + 1) だったレコードが view(i) になっちゃうということ。
つまり、上に書いたように、削除予定のレコードが並んでた場合、削除したレコードの次のレコードの処理は飛ばされてしまうということだ。あかん。
どうしてもビューの中身を頭から舐めながら処理を行いたい場合は、一旦データテーブル等にコピーして処理を行う必要がある。
Dim dt As HogehogeDs.hogeDataTable = CType(view.Table, HogehogeDs.hogeDataTable)
Dim max As Integer = dt.Count - 1
For i = 0 To max
If dt(i).hoge = "消したいレコードに含まれているキーワード" Then
dt(i).Delete()
End If
Next
dt.AcceptChanges()
view = dt.DefaultView
みたいな感じ。
データテーブルの Delete メソッドはビューと違って「実際に削除するのではなく、削除マークをつけるだけ」なので、最後に AcceptChanges するまではインデックスが変化することもなく、問題なく最後まで削除処理を行うことができる。
これも、知らずにやっちゃうと相当ハマる。特に、レコード件数が多い時はデバッグで問題を見つけ出すのも大変(^^;
コメントする