• ベストアンサー

Nullの使い方が不正です。

いつもお世話になっております。 VBAを独学で勉強している者です。 請求処理メニューを作っている最中なのですが、取引先マスターを入力していくフォームの入力値にいくつか機能を持たせることにしました。 取引先コードは10桁文字数で管理されるという設定なので10桁以外で入力した際は、BeforeUpdateイベントでエラーが出るようにし、重複した数値が入力した際もBeforeUpdateイベントでエラーが出るようにしたいのですが、実行してみると【実行時エラー’94 Nullの使い方が不正です。】となります。下記は作成途中のプログラムをコピペしたものです。 ▲がついている部分が黄色く反転しています。 参考書を元に作成していったのですが、エラーがでる原因がわからないためアドバイスをいただきたいです☆  Private Sub 取引先コード_BeforeUpdate(Cancel As Integer) Dim length As Long 'len関数の戻り値  Dim ret As String 'DLookup関数の戻り値。   length = Len(Me!取引先コード) If length <> 10 Then MsgBox "取引先コードは10桁の数値でなければなりません", vbOKOnly + vbInformation, "入力値エラー" Cancel = True Me!取引先コード.SelStart = 0 Me!取引先コード.SelLength = Len(Me!取引先コード) End If ▲ret = DLookup("取引先コード", "取引先マスターT", "取引先コード='" & Me!取引先コード & "'") '重複のチェック If IsNull(ret) Then Exit Sub Else MsgBox Me!取引先コード & " は登録済みです", vbCritical + vbOKOnly, "入力値エラー" Cancel = True Me!取引先コード.SelStart = 0 Me!取引先コード.SelLength = Len(Me!取引先コード) End If End Sub 宜しくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • x0000x
  • ベストアンサー率52% (67/127)
回答No.1

Dim ret As String にはNULLを格納できないことからエラーが発生しているのでは? If length <> 10 Then  ~ Cancel = True exit sub 'エラー時は以下を処理しない。 End If 10桁エラーと重複エラーの両方をメッセージ表示したいのであれば Dim ret As Variant が良いでしょう。

8607
質問者

お礼

ありがとうございました! お蔭様で上手く機能しました!! データ型をもっと勉強していきたいと思います☆

その他の回答 (4)

  • nicotinism
  • ベストアンサー率70% (1019/1452)
回答No.5

>・・・とメッセージが出てしまうことです これは新規レコードの入力ではなく既存レコードの場合だけですよね? 「取引先コード」は一旦登録してしまえば変更の必要が発生する事は稀有なので 私だったら、誤変更を避けるために 「取引先コード」のプロパティのその他の中にあるタブストップを「いいえ」にしておくとか フォームのレコード移動時に Me.NewRecord で判断して 「取引先コード」の「編集ロック」を「はい」とかにします。

8607
質問者

お礼

>「取引先コード」のプロパティのその他の中にあるタブストップを「いいえ」にしておくとか 思いつきませんでした!! 簡単な設定で大分使いやすくなりますね! プロパティの内容も全部把握できていないので勉強しなおします☆ 補足にまで答えていただいてありがとうございました!!

noname#140971
noname#140971
回答No.4

Variant を使わない場合・・・。 Private Sub 取引先コード_BeforeUpdate(Cancel As Integer)   Cancel = CBool(Len(Me.取引先コード & "") <> 10)   If Cancel Then     MsgBox "取引先コードは10桁の数値でなければなりません", vbOKOnly + vbInformation, "入力値エラー"   Else     Cancel = Len(Nz(DLookup("取引先コード", "取引先マスターT", "取引先コード='" & Me.取引先コード & "'")))     If Cancel Then       MsgBox Me!取引先コード & " は登録済みです", vbCritical + vbOKOnly, "入力値エラー"     End If   End If   If Cancel Then     Me.取引先コード.SelStart = 0     Me.取引先コード.SelLength = Len(Me.取引先コード)   End If End Sub ×Length = Len(Me!取引先コード)・・・・・・・・・・未入力の場合、エラーが発生します。 ○Length = Len(Me.取引先コード & "")・・・・・・"" を付加することでエラーが回避できます。 ×DLookup("取引先コード", "取引先マスターT", "取引先コード='" & Me!取引先コード & "'") ○Nz(DLookup("取引先コード", "取引先マスターT", "取引先コード='" & Me!取引先コード & "'")) NZ関数は、戻り値がヌルであれば""に置換します。

8607
質問者

お礼

Husky2007サン、いつもありがとうございます! NZ関数や、CBool等・・・・・ 正直今初めてみた単語たちでした~^^; 恥ずかしながらまだ基礎の基礎も出来ていないド素人です。。 もう少し勉強して教えていただいた方法も検討してみますね!!

  • nicotinism
  • ベストアンサー率70% (1019/1452)
回答No.3

もう少し「ツッコミ」入れさせてもらいます。 >取引先マスターを入力していく とのことなので、Accessの話ですか? なら テーブルデザインで、取引先コードを主キーにすれば、 重複入力を排除できますし、 10桁チェックも入力規制欄に、Len([取引先コード]) = 10 エラーメッセージ欄に、"取引先コードは10桁の数値でなければなりません" とすればコードを書かなくて済みます。 また DLookup("取引先コード", "取引先マスターT", "取引先コード='" & Me!取引先コード & "'") は、取引先コード がテキスト型なら問題ありませんが 数値型なら DLookup("取引先コード", "取引先マスターT", "取引先コード=" & Me!取引先コード) です。 Variant型の指摘ついては他の方と一緒。 あるいは、DlookUp ではなくて Dcount で判断するとか・・

8607
質問者

補足

お返事ありがとうございます☆ ご指摘の通り、Accessです。 取引先コードを主キーに設定していて、テーブルデザインでの規制も検討しましたが、エラーの出るタイミングや、エラーの出た後のカーソルの行方の仕様が思うように出来ず、VBAで操作に当たった次第です。 取引先コードは頭が0で始まる事も視野にいれ、テキスト型に設定しています。 データベースをコピペしてテーブル設計のみでの規制もまた検討してみます!! 色々実験していくと、システム開発の難しさを痛感します。 現在困っているのは、取引先コードに重複規制をかけたせいなのか、あらかじめ”1234567890”で取引先コードを登録しておき、以後会社名などのデータ変更時等でマスター変更をしたい時、誤って”1234567890”のコードを消してしまったときに、前回登録時と同じコードの”1234567890”と入力しなおして登録しても「1234567890は登録済みです。」とメッセージが出てしまうことです。 まだまだ勉強が必要ですネ^^; 上記のような現象の回避策はあるのでしょうか?? お手すきのときで構いませんのでアドバイスいただけませんか??

  • Q_ani
  • ベストアンサー率37% (6/16)
回答No.2

DLookupの戻り値がNullでそれを受ける「ret」がstring設定されているためでは? > Dim ret As String 'DLookup関数の戻り値。 ↑とりあえずはこれを Dim ret As Variant 'DLookup関数の戻り値。 に変えてみてはどうでしょうか?

8607
質問者

お礼

ありがとうございました! おっしゃる通りでした^^; データ型をもっと勉強したいと思います! お二方の早急な対応に本当に感謝いたします。

関連するQ&A