• ベストアンサー

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 宜しくお願いいたします。

  • 8607
  • お礼率87% (35/40)

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

  • ベストアンサー
  • 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

  • VBA テキストボックスを選択状態にしたい

    Access2003 VBA で開発しています。初心者です。 テキストボックスに入力した値が、不正な値の場合、 次のオブジェクトに移動せずに、その値を選択状態にしたいのですが、 やり方が分かりません。 txtコード.SetFocus txtコード.SelStart = 0 txtコード.SelLength = Len(txtコード.Value) としてもうまくいきません。 初歩的な質問ですが、解決法をご教授いただければ幸いです。 よろしくお願いいたします。

  • コピー時のエラー表示を変更したい

    コードビルダ選択時での基礎知識が不足しています。ご面倒をお掛けしますが、宜しくお願いします。 テキストボックスのデータをコピーする際の方法として、イベントの「ダブルクリック」で「コードビルダ」を選択して下記を記述しています。うっかりデータがないテキストボックスをダブルクリックした時にでるエラー表示を「データがありません」に変更したいと思っています。ご指導をお願いします。 Private Sub 用例_DblClick(Cancel As Integer) Me!用例.SelStart = 0 Me!用例.SelLength = Len(Me!用例.Text) DoCmd.RunCommand acCmdCopy End Sub 以上、宜しくお願いします。

  • 困っています

    ACCESSのフォームにテキストボックスとコマンドボタンをつくり テキストボックスのBeforeUpdateに If Len(Me.テクスト) = 1 Then MsgBox "Error" End If コマンドボックスのClickイベントに MSGBOX "クリック" のように書いたとき テキストボックスに1文字入れてコマンドボタンを押すと 先に "Error"が出てしまいます コマンドボタンをクリックしたときにクリックイベントを先に走らす方法って有るのでしょうか? もしくはテキストの BeforeUpdate か LostFocus イベントでコマンドボタンをクリックしたのを判別する方法って有るのでしょうか? よろしくお願いします

  • 「エラー:…は宣言されていません。」について

    下記のようなスクリプトコードがあります。 <html> <head> <%@ page contentType="text/html; charset=Windows-31J" %> <meta http-equiv="Cache-Contorol" content="no-cache"/> <meta http-equiv="Expires" content="-1"/> <title>test</title> <script type="text/javascript"> <!-- function dispText(id) { var filePath = document.getElementById("fileMei").value; var ret; if (!filePath) { return ret; } var fileTypes = filePath.split("."); var len = fileTypes.length; if (len === 0) { return ret; } ret = fileTypes[len - len]; var filename; if (!ret){ return ret; } filename = ret.split("\\"); len = filename.length; if (len === 0) { return ret; } ret = filename[len - 1]; document.getElementById(id).value = ret; } --> </script> </head> (一部抜粋) <logic:iterate name="fileInfoForms" id="fileInfoForm" indexId="index"> <tr> <bean:define id="idx">bunsyoMei<bean:write name="index" /></bean:define> <td class="listdetail<%=index%2%>" id="<%=index%2%>"> <html:text name="fileInfoForm" property="bunshoMei" styleId="idx" size="72" maxlength="50" style="ime-mode:active" indexed="true"/></td> <td class="listdetail<%=index%2%>"> <input type="file" id="fileMei" name="fileInfoForm[<%=index%>].fileMei" onkeydown="return checkEvent();" onbeforeeditfocus="return false;" onchange='<%="dispText("+idx+")"%>'/> --(1) </td> </tr> </logic:iterate> 参照ボタンよりファイルを選択し、ファイル名をテキストに表示したいのですが (1)の箇所で「エラー:'bunsyoMei0'は宣言されていません。」と表示されます。 回避させる方法はありますか?

  • 空白の認識

    VB6.0で開発しています。 EXCELのD2のセルが空白の時の処理をしたいのですがうまくいきません。 If exl.Cells(2, 4).Value = "" Then Ret = MsgBox("棚卸数が入力されていません", vbInformation + vbOKOnly, Me.Caption) End If 上記のように書くと空白時も空白では無いときもメッセージが出てしまいます。 何故でしょうか?教えてください。

  • データシートフォームでのSellength

    Access2010 データシートフォームの先頭のタブ位置(タブストップ0)に フォーカス時に全選択状態にしたいテキストボックスがあり、 Private Sub テキスト_Enter() Me!テキスト.SelStart = 0 Me!テキスト.SelLength = Nz(Len(Me!テキスト.Text)) End Sub のモジュールを入力しています。 普段はモジュール通りに機能するのですが、一つ前のレコードの最後のタブからEnterを押して レコード移動後このテキストボックスにフォーカスが移った場合に限り、全選択にならない事があります。 (このフォームではレコード移動時のモジュールは使用していません) ブレークポイントを入れて途中確認したところ内部上ではSelLengthの値は文字数通りになっているのですが、実際の画面ではおかしいままなので余計に分かりません 一応SendKeys "{F2}"に置き換えると全選択になったのでこれでやり過ごしているのですがどうすれば元のモジュールで正しく動いてもらえるのでしょうか?

  • 「Cancel = True」とはどういう意味でし

    ダブルクリックしたら全体を選択する方法をgooで調べていたら、 http://okwave.jp/qa/q4899232.html に辿りつきました。 Private Sub txt00_DblClick(Cancel As Integer)   Me.txt00.SelStart = 0   Me.txt00.SelLength = Len(Me.txt00.Text)   Cancel = True End Sub で、やりたいことが行えたのですが、一つ疑問があります。 Cancel = True はどういう意味なのでしょうか? 試しに、Cancel = Trueの部分をコメントアウトしてみたら、 テキストボックスが選択状態になりませんでした。 ということは、「Cancel = True」は、「実行!」みたいな意味なのでしょうか? ご回答よろしくお願いします。

  • ユーザーフォーム データ消去の時の処理

    環境:Excel2002です ユーザーフォームのテキストボックスの入力チェックをしています Rem**************** Rem TextBox5 Check Rem**************** Private Sub TextBox5_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean) If Len(Me.TextBox5.Text) = 0 Then '未入力Check If IsNumeric(Me.TextBox5.Text) = False Then '数値入力Check MsgBox "数値で入力してください", _ vbExclamation, "納品書作成ツール" Me.TextBox5.SetFocus Exit Sub End If MsgBox "入力してください", _ vbExclamation, "納品書作成ツール" Me.TextBox5.SetFocus Exit Sub End If Me.TextBox5.Text = Format(Me.TextBox5.Text, "#,##0") End Sub 入力したデータを消去して Enterキーを押すか、マウスでクリックした時のいずれでも Len(Me.TextBox5.Text) = 0 と認知されて "数値で入力してください"のメッセージが表示されてしまいます このメッセージが出ないようにするにはどうしたらいいのでしょうか ご教示願います

  • カンマの付け方

    ファンクションの中で記述した数式の結果に 三桁区切りでカンマをつけたいのですが、 どうすればよろしいのでしょうか。 lstArariYosan.value = Math.floor(lstUriageYosan.value.replace(",","") * lstArariRitu.value); 今は、こんな感じでカンマを外して計算しています。 計算結果を出した後、逆にカンマをつけてから 表示するようにしたいのですが、 何かいい方法はありますか? また、下記がカンマ編集のメソッドの様ですが、 これを使って表示しようとするとエラーになります。 function addComma(su) {  var ret="";  var fugou="";  if(su.length>0 && su.substring(0, 1) == "-") {    ret = su.substring(1, su.length);    fugou = "-";  } else { ret = su; }  if(ret.length>3){    for(i=3;i<ret.length;i+=4){    var moji=ret.substring(0,ret.length-i)+','+ret.substring(ret.length-i,ret.length);    ret = moji;  } } return (fugou + ret); }

  • Access Dlookup関数について

    Dlookupで悩んでいます。 ExcelのVlookと違い、“数字”のコードでなければ引っ張ってこれないのでしょうか? 以下、がその内容です。 「T_得意先マスタ」の得意先コードフィールドに aaa というコードがあり、得意先名フィールドに ○○商事 とあります。 どうやってもできないのです。 なぜか、aaa ではなく、数字(例. 123)にすると出ます。 教えてください。 Private Sub 得意先コード_AfterUpdate() Dim a As Variant, b As String b = "得意先コード = " & Me![得意先コード] a = DLookup("得意先名", "T_得意先マスタ", b) If IsNull(a) = True Then Me.テキスト1.Value = "該当がありません。": Me![得意先コード] = Null Else Me.テキスト1.Value = a End If End Sub

専門家に質問してみよう