質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

3回答

9980閲覧

日付の値をNullでAccessに書き込みたい

miniryu

総合スコア15

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2018/04/09 06:57

編集2018/04/09 08:32

エクセルのユーザーフォームからアクセスへの書き込むとき、日付が未入力の場合エラーがでてしまいます。

SQL文を最初は商品発送日 = #" & CDate(.TextBox3) & "#としてたのですが、「型が一致しません」というエラーが出てしまいました。

そこでNullが原因かと思い、空白の場合はNullを入れるように下記のようなSQLDateという変数を作って商品発送日 = #" & SQLDate(CDate(.TextBox3)) & "#としてみましたが、やはり同じエラーが出てしまいました。

vba

1'---日付が空白の場合にNullに変換 2Function SQLDate(val As Variant) As Variant 3 If IsDate(val) = True Then 4 SQLDate = val 5 Else 6 SQLDate = Null 7 End If 8End Function

私は最近vbaを始めた者で、まだ詳しい解決策が思いつかず…。知恵をお借しいただければと思い質問させていただきました。どうぞよろしくお願いいたします。

↓全文です

vba

1'---データベースを更新 2Sub UpdateDB() 3 Call ConnectDB(False) 4On Error GoTo Err_Handler 'エラーが起きたら"Err_Handler"へ 5 adoCn.BeginTrans 'トランザクションを開始 6 7 With EditForm 8 strSQL = "UPDATE テーブル SET シリアルナンバー = '" & .TextBox1 & "', 顧客コード = '" & .ListBox1.List(0, 8) & "', " & _ 9 "エージェントコード = '" & .ComboBox1 & "', 直送先 = '" & .TextBox2 & "', 商品発送日 = #" & SQLDate(CDate(.TextBox3)) & "#, " & _ 10 "修理・加工受付日(1) = #" & SQLDate(CDate(.TextBox4)) & "#, 修理・加工完了日(1) = #" & SQLDate(CDate(.TextBox5)) & "#, " & _ 11 "故障内容(1) = '" & .TextBox6 & "', 修理内容(1) = '" & .TextBox7 & "', 加工内容(1) = '" & .TextBox8 & "', " & _ 12 "修理・加工受付日(2) = #" & SQLDate(CDate(.TextBox9)) & "#, 修理・加工完了日(2) = #" & SQLDate(CDate(.TextBox10)) & "#, " & _ 13 "故障内容(2) = '" & .TextBox11 & "', 修理内容(2) = '" & .TextBox12 & "', 加工内容(2) = '" & .TextBox13 & "', " & _ 14 "修理・加工受付日(3) = #" & SQLDate(CDate(.TextBox14)) & "#, 修理・加工完了日(3) = #" & SQLDate(CDate(.TextBox15)) & "#, " & _ 15 "故障内容(3) = '" & .TextBox16 & "', 修理内容(3) = '" & .TextBox17 & "', 加工内容(3) = '" & .TextBox18 & "' " & _ 16 "WHERE シリアルナンバー = '" & .TextBox1 & "' ;" 17 End With 18 19 adoCn.Execute strSQL 'データベースの更新を実行 20 21 adoCn.CommitTrans 'トランザクションを終了(確定処理) 22 Call CutDB(False) 23 24 MsgBox "正常に更新されました。" 25 Exit Sub 26 27Err_Handler: 'エラーが起きたときの飛び先 28 adoCn.RollbackTrans 29 Call CutDB(False) 30 MsgBox Error$ 31 Debug.Print Error$ 32 Debug.Print strSQL 33 34End Sub

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ExcelVBAer

2018/04/09 07:35

なぜ入力必須等のエラーチェックが1つもないのですか?
ExcelVBAer

2018/04/09 07:36

空欄だった場合にNULLにしようとしてますが、テーブル側の該当項目はNULLが許可されているのでしょうか?
miniryu

2018/04/09 08:34

すみません、煩雑になるかと思い勝手に省いてしまいました。こういうときは正確が一番ということですよね。入力必須についてもSQLで制御できたりするのですか?素人でそれが存在することも知りませんでした。ちょっと調べてみます。
miniryu

2018/04/09 08:37

テーブル側のNullの許可ですが、「値の要求」が「いいえ」となっているので大丈夫だと認識しています。
guest

回答3

0

ベストアンサー

コードから推測するに、各テキストボックスが未入力の場合にCDate("")となってしまい、「型が一致しません」と言われているのではないでしょうか?

これを回避するならCDateの結果ではなく、CDateの中身(テキストボックスの値)を判定してあげる必要があると思います。

例えばSQLDate関数を

'---日付が空白の場合にNullに変換 Function SQLDate(val As String) As String If IsDate(val) = True Then SQLDate = "#" & val & "#" Else SQLDate = "Null" End If End Function

といった具合に、SQL文に組み込む文字列として日付を返すように変更します。

そしてこれを使う部分を、例えば
"', 商品発送日 = #" & SQLDate(CDate(.TextBox3)) & "#, "
から
"', 商品発送日 = " & SQLDate(.TextBox3) & ", "
と変更すれば、期待する動きになるのではないでしょうか?

※Accessの動作確認環境がないためはずしていたらすみません。

参考になれば幸いです。

投稿2018/04/09 07:38

jawa

総合スコア3013

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miniryu

2018/04/09 08:47

期待した動作をしてくれました。ありがとうございます!
jawa

2018/04/10 00:44

解決されたようで、よかったです。 余談になりますが、質問欄での回答についても補足しておきます。 >入力必須についてもSQLで制御 というのはちょっと考え方がずれてしまっています。 今回作成している更新処理(UpdateDB関数)は、ボタンクリックなど何らかのタイミングで実行されるものと思います。 しかし「必須項目が入力されていない」「不正な値が入力されている」等、入力の状態によってはまだ更新処理を行うべきではない場合もあります。 そこで、更新処理を実行する前に入力チェック処理を行い、不正な場合は更新処理を行わないようにする、というのが一般的な流れです。 入力チェックのタイミングとしては ・入力内容を変更した時点で、入力項目ごとの個別チェック ・更新処理などの前に必要な項目をまとめて一括チェック などあります。 ここらへんは、 ・不正な値は入力時点ではじく⇒個別チェック ・他の項目の内容によって不正の判断が変わる(From~Toの大小比較など)⇒一括チェック といった使い分けが一般的でしょうか。 もちろん両チェックを行うのもアリです。 参考までに。
guest

0

提示のUpdateDBプロシージャの問題点は
『入力チェックをsql文作成の段階で行っていること』
だと思います。

大体のコーディングの場合、『入力チェックを行って、ダメならキャンセル』、『オッケーならsql文発行、トランザクション処理』とするものです。

予め入力チェックが済んでいればUpdateDBは単純になって

vba

1"修理・加工受付日(1) =" & Nz("#" + .TextBox4.Value + "#","null")

こんな感じで済むかと思います。

投稿2018/04/09 09:02

sousuke

総合スコア3828

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sousuke

2018/04/09 09:11

終わってたぞい(´・ω・`)
jawa

2018/04/10 01:14

横から失礼しますm(__)m 本回答について気になる点が2つあります。 ①Accessアプリケーションの関数であるNz関数は、ExcelVBAでは提供されていません。 今回は「VBA」「EXCEL」タグでの質問でしたので、念のため。 ②AccessのNz関数は、第1引数がNULL値の場合に第2引数の値を返してくれるものだったと思います。 提示いただいたコードでは第1引数が必ず"#"で括られた文字列となり、例えばテキスト未入力の場合でも"##"となってしまうのでNULL値はとらないように思えます。 ※Access動作確認環境が手元にないので見当違いな指摘でしたらすみません。
sousuke

2018/04/10 01:53

あら、nzないのね。それは失礼。しかしvbaの仕様ではアンパサンドでnullと文字列を連結するとnullは空文字列のように扱われますがプラスで連結するとnullになるんですよ。 "#"+null+"#"はnullで"#"&null&"#"が"##"です。なので前者はnzで置換可能です。
jawa

2018/04/10 02:07

なるほど、そうでしたか。 それならAccessVBAでなら動作しそうですね。失礼しました。
guest

0

Nz関数を使えばいいのでは?

投稿2018/04/09 07:37

ExcelVBAer

総合スコア1175

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miniryu

2018/04/09 08:45

IIF関数とIsNull関数で、疑似的にNz関数の動作をさせる方法があるようでした。いろいろ応用できそうです。貴重さ示唆をいただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問