- こあら
- 大ベテラン
- 会議室デビュー日: 2007/06/26
- 投稿数: 157
|
投稿日時: 2008-08-12 12:17
引用: |
|
One.netさんの書き込み (2008-08-12 11:52) より:
こあらさん、ありがとうございます。
IndexOfメソッドは NN文字列の中にパラメータ指定した文字列存在チェック(又は最初に見つかった位置)
に使うもので数字(NN)には使用できない思っていましたし、配列変数(NN())の全てをチェックできないと
思っています。
また実際のご指摘のコードをテストしますと「この引数の数を受け付ける"IndexOf"がないため
オーバーロードの解決に失敗しました」と表示されビルドが失敗します。
何か間違ってテストしているのでしょうか。
|
そうですか。indexOfではチェックできないのですね。
間違った書き込みで惑わせてしまい大変申し訳ありませんでした。
One.netさんのコードが最適解でした。
|
- rain
- ぬし
- 会議室デビュー日: 2006/10/19
- 投稿数: 549
|
投稿日時: 2008-08-12 13:09
Integer配列のかわりに、List(Of Integer) を使ってみました。
コード: |
|
Dim NN As New List(Of Integer)
NN.AddRange(New Integer() {2, 4, 6, 8, 10, 12})
For Each dr As DataRow In DataSet1.table1.Rows
Dim ZZ As Integer = CInt(dr("番号"))
If NN.Contains(ZZ) Then
dr.Delete()
End If
Next
|
|
- One.net
- 大ベテラン
- 会議室デビュー日: 2008/03/01
- 投稿数: 202
|
投稿日時: 2008-08-12 13:48
こあらさん、ありがとうございました。
何とか皆様のご指導で正常に動作できました。
rainさん、ありがとうございます。
また私には使ったことのない List(Of Integer) について少し勉強してみます。
ただ今回は「指定した複数のレコードを削除したい」が主題なので、For〜Next文の
使用順序を逆にすることで解決いたしました。
諸先輩からのご指導感謝します。ありがとうございました。
|
- Jitta
- ぬし
- 会議室デビュー日: 2002/07/05
- 投稿数: 6267
- お住まい・勤務地: 兵庫県・海手
|
投稿日時: 2008-08-18 22:20
引用: |
|
One.netさんの書き込み (2008-08-11 15:48) より:
table1 の指定した複数のレコードを削除したく、次のコードを実行しましたが
「削除された行を通して、その行の情報にアクセスすることはできません。」と
エラーメッセージが表示されてしまいます。
(略)
このことは i = 0 でDataRowオブジェクトにDeleteマークを付けてから i = 1 で
再度参照しようとしたのでエラーが発生するのだろうと考え
|
その解釈で正しいです。
考え方のバリエーションその1。
SQL での DELETE 文発行1回でやるなら、
DELETE FROM table WHERE "番号" IN (2, 4, 6, 8, 10, 12)
のような感じ。一意にする情報を覚えて、DataTable からは Remove しちゃって、DELETE 1回にした方が、ラウンドトリップは確実に減る。
考え方のバリエーションその2。
DataTable を編集して、ぐるぐる回したいなら、ループする順番を変えればいい。
コード: |
|
Me.table1TableAdapter.Fill(Me.DataSet1.table1)
Dim NN(10) As Integer
NN(0) = 2 : NN(1) = 4 : NN(2) = 6
NN(3) = 8 : NN(4) = 10 : NN(5) = 12
For row As Integer = 0 To DataSet1.table1.Rows.Count
DataRow dr = DataSet1.table1(row)
For Each n As Integer In NN
If CInt(dr("番号")) = n Then
dr.Delete()
Exit For
End If
Next
Next
'--更新処理
Me.Validate()
Me.table1BindingSource.EndEdit()
table1TableAdapter.Update(Me.DataSet1.table1)
|
考え方のバリエーションその3。
ループの順番を元のまま、エラーを無くしたいなら、RowState をチェックする。
コード: |
|
Me.table1TableAdapter.Fill(Me.DataSet1.table1)
Dim NN(10) As Integer
NN(0) = 2 : NN(1) = 4 : NN(2) = 6
NN(3) = 8 : NN(4) = 10 : NN(5) = 12
For Each n As Integer In NN
For row As Integer = 0 To DataSet1.table1.Rows.Count
DataRow dr = DataSet1.table1(row)
If dr.RowState == RowState.UnChanged _
AndAlso CInt(dr("番号")) = n Then
dr.Delete()
End If
Next
Next
'--更新処理
Me.Validate()
Me.table1BindingSource.EndEdit()
table1TableAdapter.Update(Me.DataSet1.table1)
|
NN は、ループ中は固定したコレクションなので、For Each 文を使ってかまいません。
Delete メソッドは、その行を「削除」とマークするだけのようですが、RowState.Added な行はコレクションから取り除くため、コレクションを変更してしまう可能性があります。このため、For Each 文は使えません。
考え方の基本。
ループの順番を変えるのは、より早くループが終わることを考えてみるといいでしょう。テーブルに、行が100あるとします。元の順番なら、必ず600回、If 文を通ります。しかし、順番を入れ替えると、行を参照する100回は変わらないけど、「この配列にあるか?」のチェックで、配列内にあればそれ以降のチェックはしなくなります。削除対象の行が存在しないなら600回通るけど、すべての行が NN(0) にマッチするなら、100回しか通らないことになるというわけです。
文章で書いてもわからなかったら、各行でそれぞれの変数がいくらになるか書き出して、確認してみるといいでしょう。(←これ、初心者のうちは重要)
開発の基本。
引用: |
|
(2008-08-12 11:52) より:
IndexOfメソッドは NN文字列の中にパラメータ指定した文字列存在チェック(又は最初に見つかった位置)に使うもので数字(NN)には使用できない思っていましたし、配列変数(NN())の全てをチェックできないと思っています。
また実際のご指摘のコードをテストしますと「この引数の数を受け付ける"IndexOf"がないためオーバーロードの解決に失敗しました」と表示されビルドが失敗します。
|
で、調べました?→Array..::.IndexOf メソッド<microsoft.com>
引数1つを受け取る IndexOf メソッドがないだけです。じゃぁ、引数の数が合うものを探せばいい。
今回の用にあうのは、これ、「IndexOf(Array, Object)」。ループがひとつ少なくなります。
コード: |
|
Me.table1TableAdapter.Fill(Me.DataSet1.table1)
Dim NN(10) As Integer
NN(0) = 2 : NN(1) = 4 : NN(2) = 6
NN(3) = 8 : NN(4) = 10 : NN(5) = 12
For row As Integer = 0 To DataSet1.table1.Rows.Count
DataRow dr = DataSet1.table1(row)
If Array.IndexOf(NN, CInt(dr("番号"))) > -1 Then
dr.Delete()
End If
Next
'--更新処理
Me.Validate()
Me.table1BindingSource.EndEdit()
table1TableAdapter.Update(Me.DataSet1.table1)
|
なお、コードはすべて直打ち未検証。
|
- One.net
- 大ベテラン
- 会議室デビュー日: 2008/03/01
- 投稿数: 202
|
投稿日時: 2008-08-19 07:25
Jittaさん、ありがとうございました。
レコードの削除だけでもこれほどの方法があるのですね。特に「考え方のバリエーションその3。」は
RowState をチェックとCInt(dr("番号"))のチェックをAndAlsoで選択すればDeleteマークが付いた
レコードの参照がなくなることは勉強になりました。
また、少し難しいようですが以下のことも勉強します。
引用: |
|
引用: |
|
(2008-08-12 11:52) より:
IndexOfメソッドは NN文字列の中にパラメータ指定した文字列存在チェック(又は最初に見つかった位置)に使うもので数字(NN)には使用できない思っていましたし、配列変数(NN())の全てをチェックできないと思っています。
また実際のご指摘のコードをテストしますと「この引数の数を受け付ける"IndexOf"がないためオーバーロードの解決に失敗しました」と表示されビルドが失敗します。
|
で、調べました?→Array..::.IndexOf メソッド<microsoft.com>
引数1つを受け取る IndexOf メソッドがないだけです。じゃぁ、引数の数が合うものを探せばいい。
|
ありがとうございました。
|