2013年12月20日金曜日

VB DataGridView と CellValidated

前回 DataGridView の CellValidating について、書いてみました。 その続きです。
検証を二段構えにする例を書いてみたいと思います。
基本的な型の一致や空白不許可時の対応は CellValidating で、値の範囲については CellValidated で と分ける方法です。



勿論、全て、 CellValidating の中で済ませる書き方もありますね。
ここでは、敢えて、別にするのを書いて見ましょう。

ソフトの仕様に基づいて、値の範囲を限定する事は良くありますね。
これが、仕様変更で、許容範囲が変わる事も、また、多いですね。

そこで、先の様に、検証を二段構えにします。

共用範囲の外で、許可したくない(するべきではない)値の時に、セルにエラー・テキストを設定します。
これを指定する事で、セルに、赤く丸いマークのアイコンを表示させ、目を引きます。
セルの幅を、アイコンの表示スペース分、広げておいて下さい。

  これは、何か、変だぞ! と思って戴こう かと。
  丁度、 CellValidating で行頭に、同一のアイコンを表示した時と同じですね。
  

ついでにと言うのは変ですが、データの保存を行う ボタン 等のコントロールの制御も併せれば良いでしょう。
条件を満たさないと、次には行けないよ っと。

保存や次のステップの動作から見れば、
データ型や空白の検証 > 許容範囲の検証 > 入力不備の有無  
と、三段階の手順を経る形になります。
  前回の投稿にも書きましたが、各列(Column)相互の入力条件がある場合は、こんなに簡単には行きません。
  もう、ひとひねり、ふたひねりが いるでしょう。

さて、コードを書いてみましょうか。

Form に DataGridView と Button をひとつ用意します。
Button で次のステップに行くイメージです。
前回 同様、DataGridView の日付欄に検証を行い、今回は今年だけのデータに入力値を限定して見ましょうか。

先ず、イベントハンドラではなく、Form のクラス宣言直下に以下の変数をひとつ定義します。
   初期値 -1 セルのエラー数をカウントし 値 0  の場合のみ 次のステップに行ける様に。
Public Class Form1
    Private dataGridViewErrorCounter As Integer = -1

次に、前回 同様、CellValidating を。
コードは省略します。  前回 を参照下さい。

そして、件の許容範囲(今年 ? )の検証 と Button 有効化の判断材料(セルのエラー数の増減)を。 CellValidated 。
   最初の 1 行は、 CellValidating での検証が通ったので、行頭のアイコンを消す為です。
   前回にもありましたね。  説明用に、色を少し薄くして見ました。
    Private Sub DataGridView1_CellValidated(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellValidated
        Me.DataGridView1.Rows(e.RowIndex).ErrorText = String.Empty
        Dim headerText As String = Me.DataGridView1.Columns(e.ColumnIndex).HeaderText
        If headerText.Contains("New") Then
            Dim validatingDataNew As Date = CType(Me.DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value, DateTime)
            If Not validatingDataNew.Year = DateTime.Now.Year Then
                If Me.DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).ErrorText = String.Empty Then
                    dataGridViewErrorCounter = IIf(dataGridViewErrorCounter = -1, 1, dataGridViewErrorCounter + 1)
                Else            ' Already Error
                    dataGridViewErrorCounter = dataGridViewErrorCounter
                End If
               
                Me.DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).ErrorText = "Not This Year !"
            Else                ' Matching
                If Me.DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).ErrorText = String.Empty Then
                    dataGridViewErrorCounter = dataGridViewErrorCounter
                Else            ' Already Error
                    dataGridViewErrorCounter = IIf(dataGridViewErrorCounter = -1, -1, dataGridViewErrorCounter - 1)
                End If
                Me.DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).ErrorText = String.Empty
            End If
            'Reflect Button1 Enable
            ActivateButton1()
        End If
    End Sub

最後に Button の有効化 そのもの
Form_Load イベントに、無効化を入れておいて下さい。         Me.Button1.Enabled = False
判断材料の変数の増減は、先の検証の中で、一緒に行っています。
    Private Sub ActivateButton1()
        If dataGridViewErrorCounter = 0 Then
            Me.Button1.Enabled = True
        Else
            Me.Button1.Enabled = False
        End If
    End Sub


条件分岐が綺麗に書けていませんが、お許し下さい。
また、もっと、綺麗に書ける方が大勢いらしゃると思います。   ... 笑わないで下さいね。

おっと、書き落としました。
今回の検証は DataGridView での編集に対してのみ有効です。
つまり、既存データで問題があっても、何も表示してはくれません。 セルに入らなければ。
そこの所は、要注意ですね。


0 件のコメント:

コメントを投稿