C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: データベースの参照がうまくできません


(過去ログ 103 を表示中)

[トピック内 4 記事 (1 - 4 表示)]  << 0 >>

■61714 / inTopicNo.1)  データベースの参照がうまくできません
  
□投稿者/ trf (1回)-(2011/08/30(Tue) 23:58:27)

分類:[.NET 全般] 

初めまして。VB初心者です。
現在、コンボボックスで選択した内容をDataGridViewに表示、追加と削除ボタンを作成
追加ボタン:コンボボックスとテキストボックスの内容(Intake_TimeBox.Text, FoodComboBox.Text, Intake_calText.Text)をリストとしてDataGridViewに表示
削除ボタン:選択したリストをDataGridViewから削除
という内容にしたいのですが、
削除を行った後に追加を行うと、「削除された行を通して、その行の情報にアクセスすることはできません。」というエラーが出ます。
様々な質問サイト等で調べたのですが、どうしても書かれていた内容が理解できず、書き込みさせていただきました。

また、途中で出てくる目標カロリー、摂取カロリー(=今日の摂取カロリー)、残りカロリー、オーバーカロリーですが、
目標カロリー:DBに別テーブルで登録されている
今日の摂取カロリー:リストに表示したIntake_calText.Textの合計値
残りカロリー:目標カロリー - 今日の摂取カロリー
オーバーカロリー:残りカロリーが負になった場合、絶対値を表示
という内容になっています。
今回の質問にはそこまで関与しませんが…

また、自分はC言語しか触れた事がなく、オブジェクト指向についても勉強しながら、このプログラムを組んでいました。
そのため、過去の質問等を検索しても理解できなかった、という事もあります。

以下、プログラム。必要と思われる部分のみ抜き出しました。
お手数をおかけしますが、ご教授よろしくお願いいたします。

'追加ボタン押下
Private Sub AdditionButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AdditionButton.Click

'データベースの接続
Dim oleConn As OleDb.OleDbConnection
Dim oleCmd As OleDb.OleDbCommand
Dim oleAdp As OleDb.OleDbDataAdapter
Dim dts As DataSet
oleConn = New OleDb.OleDbConnection("Provider = Microsoft.Jet.OLEDB.4.0;Data Source = ..\..\diet.mdb;")

Dim count As Integer = DataGridView1.RowCount()
Dim i As Integer
Dim Table_1 As DataTable = CType(DataGridView1.DataSource, DataTable)
'重複チェック
Dim check As Integer = 0

For i = 0 To (count - 1)
If (Intake_TimeBox.Text = Table_1.Rows(i)(0)) And (FoodComboBox.Text = Table_1.Rows(i)(1)) Then
check = 1
End If
Next
If check = 0 Then
'データセットに入力項目を追加
Dim data As DataTable = CType(DataGridView1.DataSource, DataTable)
data.Rows.Add(New String() {Intake_TimeBox.Text, FoodComboBox.Text, Intake_calText.Text})
DataGridView1.Update()

'目標カロリー、摂取カロリー、残りカロリー、オーバーカロリーのセット
'今日の摂取カロリーのセット
 Dim cal_count As Integer = DataGridView1.RowCount
Dim cal_total As Integer
Dim Table As DataTable = CType(DataGridView1.DataSource, DataTable)
Dim j As Integer

For j = 0 To (cal_count - 1)
cal_total = cal_total + Table.Rows(j)(2) '←ここでエラーが出力されます
Next
End Sub


'削除ボタン押下
Private Sub DeleteButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DeleteButton.Click
If DataGridView1.SelectedRows.Count = 1 Then
Dim select_food As Integer = DataGridView1.SelectedRows(0).Index
DataGridView1.Rows.RemoveAt(select_food)
End If
End Sub
引用返信 編集キー/
■61717 / inTopicNo.2)  Re[1]: データベースの参照がうまくできません
□投稿者/ マサヤ (330回)-(2011/08/31(Wed) 10:04:02)
追加の処理で
>データセットに入力項目を追加
をしているのに、削除の処理でデータセットから項目を削除、ということをしていないからでは?
引用返信 編集キー/
■61718 / inTopicNo.3)  Re[1]: データベースの参照がうまくできません
□投稿者/ 魔界の仮面弁士 (2340回)-(2011/08/31(Wed) 10:12:08)
No61714 (trf さん) に返信
> 削除を行った後に追加を行うと、「削除された行を通して、その行の情報にアクセスすることはできません。」というエラーが出ます。

Table_1.Rows.Remove(…)
Table_1.Rows(…).Delete()
の違いは分かりますか?

前者は、行そのものを Rows から取り除きますが
後者は、行に削除マークを付けるだけで、Rows 内からは取り除かれません。


DataGridView から削除した場合、DataTable の行も削除されますが、
これは DataTable から取り除かれるのではなく、
削除済み行としてマーキングされるだけです。


DataTable の各行には、RowState プロパティと呼ばれる状態情報を有しており、
 Deleted …… 削除された行
 Added …… 追加された行
 Modified …… 変更された行
 Unchanged …… 変更されていない行
のいずれかの状態になっています。
(上記の他、DataTable 上にない行を表す 'Detached' があります)

削除された行も DataTable には存在していますが、削除済み行からは
現在の値を読み書きする事ができないのです。


ちなみに、Deleted な行であっても、
 Table_1.Rows(i)(列, DataRowVersion.Original)
のようにすると、削除前の値を読み取ることができます。
(Added 行の場合は Original 値がありません。Deleted 行の場合は Current 値がありません。)


> cal_total = cal_total + Table.Rows(j)(2) '←ここでエラーが出力されます
対処方法としては
 (案1) 削除処理後に AcceptChanges メソッドを呼び出して、編集結果を
  確定させておく。(Deleted 行は取り除かれ、Added や Modifiedは Unchanged になる)
 (案2) DataGridView から削除するのではなく、元となっている DataTable 上から
  取り除くようにする。
 (案3) DataView を利用して、削除されていない行のみをフィルタリングして読み取る。
 (案4) 列の値にアクセスする前に、RowState プロパティを確認して
  削除された行であったら読み飛ばすようにする。
などといった対処が考えられます。
引用返信 編集キー/
■61747 / inTopicNo.4)  Re[2]: データベースの参照がうまくできません
□投稿者/ trf (2回)-(2011/09/02(Fri) 00:31:16)
お返事が遅くなり、申し訳ありません。

>マサヤさん
DataGridView1.Rows.RemoveAt(select_food)
が削除だと思っていたのですが…(汗)

>魔界の仮面弁士さん
なるほど…
Deleteじゃなくて、Removeにしないとダメだよ、って言われたのはそんな理由だったのですね…

対策方法の2
>DataGridView から削除するのではなく、元となっている DataTable 上から取り除くようにする。
ですが、Removeでは取り除かれていないのでしょうか?

また、案4の
>列の値にアクセスする前に、RowState プロパティを確認して削除された行であったら読み飛ばすようにする。
を実行しようとしたのですが、プロパティの確認方法がわからず、断念してしまいました。
検索の仕方が悪く、また知識もないため、どのようなプログラムを書けば確認できるのかもわからず…
初心者がこのような場で質問をし、申し訳ないです。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -