トップ回答者
SQLServerのDate型をTableAdapterからNUllでアップデートするには?

質問
-
こんにちは、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にする方法
以上よろしくお願いいたします。
回答
-
trapemiya さん
TH01 さん
ご親切な回答をありがとうございました。
trapemiyaさんのご指摘大変参考になりました。
Date型だけを自動バインディングさせないで確かめたら実現できました
ご指摘のサイト
http://msdn.microsoft.com/ja-jp/library/ms158047(VS.85).aspx
についてはまだ確かめておりませんが同様にできそうな気がしてきました。
TH01 さんのプログラムのサンプルをありがとうございます
こんな方法もあるのですね。大変勉強になりました。
ほかの時にも使えそうです。
trapemiya さん、TH01 さん、ありがとうございました。
すべての返信
-
自動でバインドする場合、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さん。買いかぶりすぎですよぉ。
-
1 については次のコードでできました。
Code SnippetPrivate 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 SubPrivate 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 Sub2 の件は、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 さんの後なので気合い入れて書きました。
-
trapemiya さん
TH01 さん
ご親切な回答をありがとうございました。
trapemiyaさんのご指摘大変参考になりました。
Date型だけを自動バインディングさせないで確かめたら実現できました
ご指摘のサイト
http://msdn.microsoft.com/ja-jp/library/ms158047(VS.85).aspx
についてはまだ確かめておりませんが同様にできそうな気がしてきました。
TH01 さんのプログラムのサンプルをありがとうございます
こんな方法もあるのですね。大変勉強になりました。
ほかの時にも使えそうです。
trapemiya さん、TH01 さん、ありがとうございました。