• ベストアンサー

エクセルマクロで時間計算のエラー処理

エクセルマクロで、仕事の「開始時間」「終了時間」をInputBox関数を使って入力しています。 質問なんですが、 時間を入力するとき、不正な値を入力したときのエラー分岐をしたいのです。 例えば 6:00 と入力すべき所を誤って 6::0 になったり ただの数字 6 だったり、開始時間より終了時間が小さかったり した場合 どのような構文で分岐したら良いのでしょうか 開始時間・終了時間はデータ型を宣言していません なので マクロ実行時、型はEmpty 値となって If 開始時間 ="" Then ・・・としているだけで 空白以外は全て受け付けてしまう仕様になっています。 これを時刻形式の表示(hh:mm) 以外を拒否するためには どのようすれば良いか分かりません データ型をDim 開始時間 As Date にしてみたのですが、このときエラー時分岐判断はどのように すれば良いのでしょうか また他に良い方法があれば教えてください

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

  • ベストアンサー
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.4

こんにちは。#1です。 #2 さんの >#1さんほどスマートじゃないけど。 最初に、「いいえ!」 本当は、標準的には、 >On Error GoTo ER: とするのが普通なのですね。後で、もう一度触れます。 最初に、以下は、ひとつのフレーズです。 >If 開始時間 = "" Or VarType(開始時間) = vbBoolean Then Exit Sub >この VarType(開始時間) = vbBoolean  ・・・は >どのような意味になるのでしょう? 変数「開始時間」というのは、Variant 型なので、そこには、二種類の型が入ります。 ひとつは、文字型で、もうひとつは、キャンセルを押したときには、Boolean 型です。戻り値は、False です。もともと、True, False が入るということは予想していませんから、そこで、プロシージャから離脱させるように作ります。 だから、ここがミソです。  Dim 開始時間 As Variant もしも、InputBox 関数で書くと、同じ内容でも、もう少し、難しくなってしまいます。 もともと、InputBox 自体がレガシー(過去の遺物)なのですが、InputBox関数と同じ機能を持たせるためには、いわゆる「レガシー機能=StrPrt関数」という方法を使わざるを得なくなるからです。 > If Not (InStr(開始時間, ":") > 1 And IsDate(開始時間)) 例えば、数字のみを入れた場合は、IsDate として、日にちとして、受け取ります。 それでは、時間を受け取れることが出来ません。そこで、例 12:12 として、必ず、「: (コロン)」は、2以上の場所にあることが条件になります。しかし、例: 12:12:12:12 では、時間としては受け取れませんので、両方が成り立つときにだけ、ループを離脱して、改めて、 変数「開始時間」は時間として扱うことが出来る、という仕組みになっています。 ところで、これは、「Goto を使うな」というのは、構造化言語を開発した人間の提唱した言葉で、あえて、それに100%従うのはナンセンスなのですが、こういう方法もある、ということぐらいで十分だと思います。 エラー処理は、やはり、Error トラップが簡単です。しかし、なぜ、Errorになるか、ということを良く分かった上で作ったほうがよいと思います。

JOX
質問者

お礼

すごく分かりやすい説明ありがとうございます #papayuka 様の構文と併せて勉強させてもらいます あかげでなんとか自分なりにマクロが出来そうな目処が立ちました 本当にありがとうございます

その他の回答 (3)

  • imogasi
  • ベストアンサー率27% (4737/17069)
回答No.3

不完全回答と思いますが Sub test01() t = InputBox("開始時刻") If IsDate(t) Then MsgBox "OK" Else MsgBox "時刻エラー" End If End Sub をやってみましたが、チェックが完全ではないようです。 ある程度は「時刻としておかしなもの」は指摘するが。 ーー >開始時間より終了時間が小さかったり などは常識的で単独の値でOKになってしまえばチェックは簡単ですが ーー 時刻にふさわしい入力値かどうかのチェックは、意外に難しく、色々条件をコードに作りこまないといけないように感じました。

JOX
質問者

お礼

>時刻にふさわしい入力値かどうかのチェックは、意外に難しく、 >色々条件をコードに作りこまないといけないように感じました。 本当に難しいですね 忙しい中色々と考えていただきありがとうございます。 感謝いたします

  • papayuka
  • ベストアンサー率45% (1388/3066)
回答No.2

既に回答が出てますが、せっかく書いたので載せます。 #1さんほどスマートじゃないけど。 Sub Test() Dim stTime, edTime On Error GoTo ER: stTime = TimeValue(Application.InputBox _      ("開始時刻(hh:mm)は?", "時刻", Type:=2)) edTime = TimeValue(Application.InputBox _      (stTime & " ~ 終了時刻(hh:mm)は?", "時刻", Type:=2)) If stTime < edTime Then   MsgBox "開始:" & stTime & " ~ 終了:" & edTime & "", vbInformation Else   MsgBox "終了は開始より後じゃなきゃ!", vbCritical, "ダメよ" End If Exit Sub ER:   If MsgBox("時刻指定に誤りがあります。" & vbCrLf & _    "再度入力しますか?", vbYesNo + vbExclamation) = vbYes Then Resume End Sub

JOX
質問者

お礼

>#1さんほどスマートじゃないけど。 いえいえ。本当に助かります。 私のマクロより数段すばらしいです。 エラー処理は難しくマクロ構文の収拾がつかなくなってきました (ーー;) ひとつ、ひとつ分解して勉強させていただきます。 ありがとうございました 感謝いたします。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.1

こんばんは。 InputBox は、InputBox メソッドに切り替えてください。 それから、 >データ型をDim 開始時間 As Date とすると、違ったものが入ると、マクロ自体のエラーを出してしまいます。どちらかと言えば、Variant 型がで受けるか、InputBox 側の戻り値とは別の変数を使用します。 以下の場合は、キャンセルボタンや空のエンターの時は終わらせるようにしています。間違って入力したら、メッセージが出ますし、12:12:12:12 でも、時間とは認識しないので、メッセージが出て、再び、InputBox に戻ります。 例: Sub TestTime() Dim 開始時間 As Variant  Do  開始時間 = Application.InputBox("時間を入力してください。(例:12:15)", Type:=2)  If 開始時間 = "" Or VarType(開始時間) = vbBoolean Then Exit Sub  If Not (InStr(開始時間, ":") > 1 And IsDate(開始時間)) Then MsgBox "時間を入れてください。", 64  Loop Until InStr(開始時間, ":") > 1 And IsDate(開始時間)    MsgBox 開始時間 End Sub 出来れば、変数に2バイト文字は避けて英字にしたほうがよいです。

JOX
質問者

お礼

ありがとうございます。 甘えついでに2~3質問してもよろしいでしょうか >If 開始時間 = "" Or VarType(開始時間) = vbBoolean Then Exit Sub この VarType(開始時間) = vbBoolean  ・・・は どのような意味になるのでしょう? > If Not (InStr(開始時間, ":") > 1 And IsDate(開始時間))  この部分の意味もお願いいたします InStr関数はなんとなく判るのですが(マクロの本を紐解きながらですが (^_^;) ) 後の部分がわからなくて苦戦しています。 どうか宜しくお願いいたします。

関連するQ&A

専門家に質問してみよう