DOBON.NET DOBON.NETプログラミング掲示板過去ログ

DataGridとDataTableの編集について

環境/言語:[VB.NET 2003 .NET Framework 1.1]
分類:[.NET]

2006/12/12(Tue) 11:23:09 編集(投稿者)
2006/12/12(Tue) 10:37:48 編集(投稿者)

初めて投稿させていただくyuueiという者です。
開発自体はWindowsCEを使っての開発なのですが、
VB.netでも同じような不可解な動作をしたので、
疑問を解消したく思い、投稿させて頂きました。

☆知りたい事☆
なぜこのような動作となるのか?

■動作内容■
・入力フォーム(アイテムIDと数量)と表示用Datagridを用意した画面があります。
・入力フォームにアイテムIDと数量を入れ、アイテムIDが表示用のDataGridになければ、そのアイテムIDと数量を追加。
・アイテムIDが既に存在している場合は、同じアイテムIDの数量を加算
という単純なプログラムです。
(行追加および行編集はDataTableを編集する形で実現しています。)

×エラー内容×
・WindowsCE(PDA)ではネイティブ例外が発生する。
・VB.net(WindowsApplication)ではindexの値がおかしくなる。

▼再現手順▼
適当なアイテムIDで5行追加した後、追加していった順に
アイテムIDの数量を変更していくと3行目でindexの値がおかしくなります。
例:
上から順に処理
ID=1 NUM=1 行追加
ID=2 NUM=1 行追加
ID=3 NUM=1 .
ID=4 NUM=1 .
ID=5 NUM=1 .

ID=1 NUM=2 (NUMに1を加算し、NUMが2に)
ID=2 NUM=2
ID=3 NUM=2 ←ここでおかしくなる(加算前と加算後でCurrentRowIndexの値が変化)

○回避方法○
DataTableを編集するのではなく、DataGridの値を直接編集する事で回避可能
→この方法で回避しましたが..腑に落ちません。。。
また、行追加する時にInsertAtで先頭行に追加していますが、
これをaddで最後行に追加したり、値更新時のAcceptChangesをやめるとエラーが発生しません。
(ただし、AcceptChangesをやめた場合は表示が変になります)

長くなりましたが、以上がこの度の質問になります。
識者の方々、どうかご教授下さい。

■編集内容■
・文言の変更
・ソースを別記事に移動
2006/12/12(Tue) 16:29:56 編集(投稿者)

編集内容:インデント/TextBox1(ID)とTextBox2(NUM)入替/ColumnsをIDへ

気になる記事を発見したのでご報告と

■FIX:既存の DataTable オブジェクトを編集することをまたは編集しているデータセットに新しい DataTable オブジェクトを追加しようとするとき、 Visual Studio 2005 が突然終了します。
リンク:h ttp://support.microsoft.com/kb/923147/ja

長かったので、ソースをこの記事に張らせて頂きました。
---------- ここから ----------
Private dt As DataTable = New DataTable("TEST_GRID")

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
  'DataTableの列設定
  dt.Columns.Add("ID", Type.GetType("System.String"))
  dt.Columns.Add("NUM", Type.GetType("System.Int32"))
  'DataGridへバインド
  DataGrid1.DataSource = dt
End Sub

Private Sub TextBox1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown
  Try
    If e.KeyCode = Keys.Enter Then
      Dim intcnt As Integer
      Dim str(2) As String
      Dim dr As DataRow

      If CStr(TextBox2.Text) = "" Then
      TextBox2.Text = 0
      End If

      For intcnt = 0 To dt.Rows.Count - 1
        If dt.Rows(intcnt).Item("ID") = TextBox1.Text Then
          str(0) = DataGrid1.CurrentRowIndex
          dt.Rows(intcnt).Item("NUM") += TextBox2.Text 'ここでおかしくなる
          str(1) = DataGrid1.CurrentRowIndex
          dt.AcceptChanges()
          'MessageBox.Show("NUM編集前:" & str(0) & vbCr & "NUM編集後:" & str(1))
          Exit Sub
        End If
      Next

      dr = dt.NewRow
      If dt.Rows.Count + 1 < TextBox1.Text Then
        dr.Item("ID") = TextBox1.Text
      Else
        dr.Item("ID") = dt.Rows.Count + 1
      End If
        dr.Item("NUM") = TextBox2.Text
        dt.Rows.InsertAt(dr, 0)
        dt.AcceptChanges()
    End If
  Catch ex As Exception

  Finally
    If e.KeyCode = Keys.Enter Then
      TextBox1.SelectAll()
      TextBox1.Focus()
    End If
  End Try
End Sub
---------- ここまで ----------

DOBON.NET | プログラミング道 | プログラミング掲示板