datagridviewでの型エラー取得

解決


vintage  2007-09-11 05:53:18  No: 137387

vb.netでdataridcontrolをdatatableを使用し、
BindingSourceしています。
datagridviewで数値型等のエラーが発生した際に「既定のエラーダイアログ」が表示されるので、DataErrorで処理を行おうと思っています。
数値欄に文字を入力した場合のエラーはdataErrorで拾いたいのですが
主キーの重複エラーとNULLエラーはdataerrorで拾いたくないのですが
こんな使い分けはできるのでしょうか。


魔界の仮面弁士  2007-09-11 10:49:07  No: 137388

エラー発生時に、入力された文字列を見て、自前で判断する必要があるかと。


vintage  2007-09-11 19:51:45  No: 137389

dataerror起動時にエラーとしない項目はshaincodeだけ
なのですが、(それ以外の項目はすべてdataerrorで検出してOK)
その場合は具体的にどうすればいいのでしょうか。

今はこのようなコードを書いています。
'DataErrorイベントハンドラ
Private Sub DataGridView1_DataError(ByVal sender As Object, _
  ByVal e As DataGridViewDataErrorEventArgs) _
  Handles DataGridView1.DataError
    If Not (e.Exception Is Nothing) Then
      MessageBox.Show(Me, _
         String.Format("({0}, {1}) のセルでエラーが発生しました。" + _
            vbCrLf + vbCrLf + "説明: {2}", _
              e.ColumnIndex, e.RowIndex, e.Exception.Message), _
            "エラーが発生しました", _
            MessageBoxButtons.OK, _
            MessageBoxIcon.Error)
    End If
End Sub


vintage  2007-09-11 20:20:15  No: 137390

回答して頂きありがとうございました。
詳細としては、

新しく行を追加した際に、入力後「確定」ボタンを
押すことでDBにデータを追加しにいく仕様になっています。
カーソルが新規行にいる場合は大丈夫なのですが、
他の行にあたった瞬間にdataerrorが走り、数値入力フィールドで
あれば新規行は消えないのですが、主キーのチェックが
入った場合は、エラーメッセージが表示された後、新規行自体
が消えてしまうんです。

どうにかならないでしょうか。


魔界の仮面弁士  2007-09-11 20:30:15  No: 137391

たとえば、こんな感じ。

Private Sub DataGridView1_DataError(……
  e.ThrowException = False
End Sub

Private Sub DataGridView1_CellValidating(……
  If e.ColumnIndex = 社員コード列 Then
    Dim value As Decimal
    If Not Decimal.TryParse(e.FormattedValue.ToString(), value) _
       OrElse value < 0D OrElse value > 99999D Then

      MessageBox.Show("0 から 99999 までの範囲の数値を入力してください。", _
          "入力エラー", MessageBoxButtons.OK, MessageBoxIcon.Warning)
    End If
  End If
End Sub

あるいは、目的のセルを数値型にせず、何でも入力可能な(String型)に
しておいて、MessageBox ではなくセルまたは行の ErrorText プロパティを
使って、エラーアイコンによる通知を使うという手もあるかと。


魔界の仮面弁士  2007-09-11 21:39:52  No: 137392

あぁ、重複エラーを処理したいということでしたか。
であれば、これでどうでしょう。

Public Class Form1
    Private table As New DataTable
    Private Const ShainCDColumn As Integer = 0
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        table = New DataTable
        table.Columns.Add("ShainCD", GetType(Integer))
        table.Columns.Add("ShainSei", GetType(String))
        table.PrimaryKey = New DataColumn() {table.Columns("ShainCD")}

        table.Rows.Add(1000, "田中")
        table.Rows.Add(2000, "中山")
        table.Rows.Add(3000, "山岡")
        table.Rows.Add(4000, "岡田")
        table.AcceptChanges()

        DataGridView1.EditMode = DataGridViewEditMode.EditOnEnter
        DataGridView1.DataSource = table
    End Sub

    '既存行の主キーを変更できなくする
    Private Sub DataGridView1_CellEnter(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles DataGridView1.CellEnter
        If e.ColumnIndex = ShainCDColumn Then
            Dim dgvRow As DataGridViewRow = DataGridView1.Rows(e.RowIndex)
            Dim dgvRowView As DataRowView = Nothing
            Try
                dgvRowView = DirectCast(dgvRow.DataBoundItem, DataRowView)
            Catch
            End Try
            If dgvRowView Is Nothing Then
                Return  '新規行
            End If
            If dgvRowView Is Nothing Then Return

            Dim row As DataRow = dgvRowView.Row
            Dim isNewRow As Boolean = (row.RowState = DataRowState.Detached OrElse row.RowState = DataRowState.Added)

            DataGridView1(ShainCDColumn, e.RowIndex).ReadOnly = Not isNewRow
        End If
    End Sub

    Private Sub DataGridView1_DataError(ByVal sender As Object, ByVal e As DataGridViewDataErrorEventArgs) Handles DataGridView1.DataError
        e.ThrowException = False
    End Sub

    Private Sub DataGridView1_RowValidating(ByVal sender As Object, ByVal e As DataGridViewCellCancelEventArgs) Handles DataGridView1.RowValidating
        Dim dgvRow As DataGridViewRow = DataGridView1.Rows(e.RowIndex)
        Dim dgvRowView As DataRowView = Nothing
        Try
            dgvRowView = DirectCast(dgvRow.DataBoundItem, DataRowView)
        Catch ex As Exception
            e.Cancel = True
        End Try

        If dgvRowView Is Nothing Then
            Return  '新規行
        End If

        Dim row As DataRow = dgvRowView.Row
        Dim isNewRow As Boolean = (row.RowState = DataRowState.Detached OrElse row.RowState = DataRowState.Added)
        If isNewRow Then
            Dim newValue As Object = DataGridView1(ShainCDColumn, e.RowIndex).Value
            For Each dataRow As DataRow In table.Rows
                If Integer.Equals(dataRow("ShainCD"), newValue) Then
                    If dataRow IsNot row Then
                        MessageBox.Show(String.Format( _
                            "社員コード{0}は、既に'{1}'として登録済みです。", _
                            newValue, dataRow("ShainSei")), _
                            "入力エラー", MessageBoxButtons.OK, MessageBoxIcon.Error)
                        e.Cancel = True
                        Return
                    End If
                End If
            Next
        End If
    End Sub

End Class


vintage  2007-09-13 06:34:57  No: 137393

解決しました。
本当にありがとうございました


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加