none
SQLServerのDate型をTableAdapterからNUllでアップデートするには? RRS feed

  • 質問

  •  

    こんにちは、VS2005(VB)ですが下記手順でプロジェクトに追加しました(VS2008でも同様かも)

    1、追加→新しい項目→データセットでxsdファイルを作成

    2、xsd画面で追加→AdapterでSQLServerデータベースからテーブルを作成

    3、データソース画面のテーブルを詳細に変更、Date型の項目をTextBoxに変更

    4、データソース画面のテーブルをFormにドラッグすると画面にテキストボックスで詳細画面が生成

    5、保存ボタンを画面に貼り付け、Clickイベントプロ氏ジャーに下記を記述

       xxxBindingSource.EndEdit()

       xxxTableAdapter.Update(Ds.Table)

     

    ここで作成した画面を実行したときに2つの解決できない状況があります

    1、Date型で連結した項目に年月日以外の項目を入力してしまうと正しい年月日が

      入力されるまでその他の操作ができない

    2、フィールドに強制的にSystem.Data.SqlTypes.SqlDateTime.Nullを代入すると

      データベースは1900年1月1日になってしまう。

     

    と言うことで、以下の解決方法をご存知でしたら教えてください

    1、空白だった年月日項目に間違えて入力した場合、そのTextBoxを空白にして抜け出す方法

    2、年月日情報が入っていたDBのフィールドをNULLにする方法

     

    以上よろしくお願いいたします。

     

     

    2008年5月7日 8:22

回答

  •  

    trapemiya さん

    TH01 さん

    ご親切な回答をありがとうございました。

     

    trapemiyaさんのご指摘大変参考になりました。

    Date型だけを自動バインディングさせないで確かめたら実現できました

    ご指摘のサイト

    http://msdn.microsoft.com/ja-jp/library/ms158047(VS.85).aspx

    についてはまだ確かめておりませんが同様にできそうな気がしてきました。

     

    TH01 さんのプログラムのサンプルをありがとうございます

    こんな方法もあるのですね。大変勉強になりました。

    ほかの時にも使えそうです。

     

    trapemiya さん、TH01 さん、ありがとうございました。

    2008年5月8日 0:16

すべての返信

  • 自動でバインドする場合、Bindingクラスのコンストラクタは以下が使われます。

     

    Binding コンストラクタ (String, Object, String, Boolean)
    http://msdn.microsoft.com/ja-jp/library/38zwt0w0(VS.85).aspx

     

    代わりに以下のコンストラクタでDBNull.Valueと空白を自動で変換してくれるようになりますので、手動で以下のコンストラクタでBindingオブジェクトを作成して割り当てて下さい。

     

    Binding コンストラクタ (String, Object, String, Boolean, DataSourceUpdateMode, Object)
    http://msdn.microsoft.com/ja-jp/library/ms158047(VS.85).aspx

     

    もしくは、

     

    TextBox1.DataBindings("Text").NullValue = String.Empty

     

    のようにしても良いです。

     

    #↓ TH01さん。買いかぶりすぎですよぉ。

    2008年5月7日 9:13
    モデレータ
  • 1 については次のコードでできました。

     

    Code Snippet

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        '(ここには既存コード)

     

        Dim bind As Binding = TextBox1.DataBindings("Text")
        bind.NullValue = String.Empty
        AddHandler bind.Parse, AddressOf bind_Parse
    End Sub

     

    Private Sub bind_Parse(ByVal sender As Object, ByVal e As ConvertEventArgs)
        '日付欄に無効な値が入力された場合は、値を DBNull にする(入力欄は空欄になる)
        Dim dt As DateTime
        If Not DateTime.TryParse(DirectCast(e.Value, String), dt) Then
            e.Value = DBNull.Value
        End If
    End Sub

     

    ただ、入力値が消えてしまうのもどうかと思いますので、上記のコードを使わずその代わりに、
    Me.AutoValidate = Windows.Forms.AutoValidate.EnableAllowFocusChange
    とする手もあります(AutoValidate は Form のプロパティ)。
    こうするとエラーがあってもフォーカスが移動できるようになります。
    最終的には正しい入力値が必要になるため、例えば自動生成されている BindingNavigatorSaveItem_Click イベントハンドラの Me.Validate() を次のように変更すると良いです。
    If Not Me.ValidateChildren() Then MessageBox.Show("入力値にエラー有り") : Exit Sub

     

    2 の件は、trapemiya さんの通りだと思います。

    # データセット デザイナで NullValue を変更してみましたが、無視されるみたいでわかりませんでした。

     

    「フィールドに強制的に~nullを代入」ですが、DBNull.Value を代入するか、自動生成された Set項目名Null メソッドを使用されると良いと思います。
    もし System.Data.SqlTypes.SqlDateTime.Null を DateTime 型に変換した場合は、「SqlDateTime 構造体<http://msdn.microsoft.com/ja-jp/library/system.data.sqltypes.sqldatetime(VS.85).aspx>」に書かれている「起点」の値になるようですね。

     

    # trapemiya さんの後なので気合い入れて書きました。

    2008年5月7日 10:33
  •  

    trapemiya さん

    TH01 さん

    ご親切な回答をありがとうございました。

     

    trapemiyaさんのご指摘大変参考になりました。

    Date型だけを自動バインディングさせないで確かめたら実現できました

    ご指摘のサイト

    http://msdn.microsoft.com/ja-jp/library/ms158047(VS.85).aspx

    についてはまだ確かめておりませんが同様にできそうな気がしてきました。

     

    TH01 さんのプログラムのサンプルをありがとうございます

    こんな方法もあるのですね。大変勉強になりました。

    ほかの時にも使えそうです。

     

    trapemiya さん、TH01 さん、ありがとうございました。

    2008年5月8日 0:16