「教えて!ピックアップ」リリース!

いつもお世話になっております。
ユーザーフォームにTextBox5が開始時間、TextBox6が終了時間で
TextBox7 = TextBox6 -TextBox5
と計算がしたいのですがうまくいきません。

例1)
開始時間が16:30 終了時間が23:00 の場合はうまくいきます。
    通常 TextBox7 = 5:30
深夜 TextBox27 = 1:00
例2)
開始時間が16:30 終了時間が24:00 がうまくいかない。エラーになります。

Sub test2()
Dim T1 As Date
Dim T2 As Date
Dim T3 As Date
Dim ST As Date
Dim ZAN As Date

T1 = TimeValue(UserForm1.TextBox5.Value)

T2 = TimeValue(UserForm1.TextBox6.Value)  ← ★ここでエラー型が違います。

ST = TimeValue("22:00")

If T2 > ST Then
T3 = ST - T1
ZAN = T2 - ST
UserForm1.TextBox7 = T3
UserForm1.TextBox27 = ZAN
UserForm1.CheckBox5 = True

Else
T3 = T2 - T1
UserForm1.TextBox7 = T3
End If
End Sub

どうかご教授をお願い致します。

質問者からの補足コメント

  • へこむわー

    お世話になります。

    先に文字列に変換 → 小数点変換 →  TimeValue に変換ですか?

    No.1の回答に寄せられた補足コメントです。 補足日時:2021/08/11 16:39
  • うれしい

    fujillinさんこんばんわ!
    ご親切な返答有難う御座います。

    こんなに難しいのですね。
    25:00 → 1日 + 1:00は理解できていましたが
    str2date = DateSerial(1900, 1, d - 1) +TimeSerial(Int(t(0)), Int(t(1)), 0)はもう少し
    勉強不足です。
    有難う御座いました。

    No.3の回答に寄せられた補足コメントです。 補足日時:2021/08/11 21:33

A 回答 (3件)

こんばんは



エラーの原因は既出の通りと思います。
24時より大きな時間を扱いたいのであれば、Time形式ではなくDate形式にして計算する必要があると思われます。

現状のままでなんとかなさりたいのであれば、(簡単なもので良ければ)以下の変換関数を利用することで、Date型として値を解釈するようになります。
使い方は、入力値を引数として与えればよいです。
例えば、ご提示の
>T1 = TimeValue(UserForm1.TextBox5.Value)
の代わりに、
 T1 = str2date(UserForm1.TextBox5.Value)
のようにすれば、24時間以上の値も解釈するようになります。

なるべくエラーが発生しないように、解釈不能な入力値は「0」として解釈するようにしてあります。
例えば、
 5 → 0:05
 9: → 9:00
 AA:10 → 0:10
 25:00 → 1日 + 1:00
などになりますが、24時間形式の入力決め打ちとしていますので
 10:30PM → 10:00
となりますのでご注意ください。(30PM は解釈不能と判断)
やっていることは左程難しいことではないので、ご覧になればわかるかと思います。
もしも、もっときちんと解釈したいようであれば、正規表現などを利用して入力値を解析すると良いでしょう。

また、ご提示のコードの他の部分で使っている
>ST = TimeValue("22:00")
などとの整合を保つために、関数 str2date の返す値は「1900/1/0 0:00:00」を規準とする経過時間にしてあります。
(↑ おかしな日付ですけれど、エクセルの仕様なのでそれに合わせてあります)

以下、ご参考にでもなれば。

Function str2date(ByRef s As String) As Date
 Dim t, d
 d = 0
 t = Split(Replace(s & " ", "-", ""), ":")
 If UBound(t) < 1 Then t = Split("0:" & t(0), ":")
 If Not IsNumeric(t(0)) Then t(0) = 0
 If Not IsNumeric(t(1)) Then t(1) = 0
If t(0) > 23 Then
 d = Int(t(0) / 24)
 t(0) = t(0) Mod 24
End If
str2date = DateSerial(1900, 1, d - 1) + _
 TimeSerial(Int(t(0)), Int(t(1)), 0)
End Function

注) 「25:30」等を解釈できますが、上限を設けていませんので「200:30」などの入力であっても解釈してしまいますのでご留意ください。(→ 8日と8:30)
この回答への補足あり
    • good
    • 0
この回答へのお礼

有難う御座いました。
勉強させて頂きます。

お礼日時:2021/08/11 21:36

>23:59:59 (午後 11 時 59 分 59 秒) まで


「24:00」以上の値を入力する予定であるなら、設計の見直しが必要です。
あと、「シリアル値」の理解も必要だと思います。
    • good
    • 0
この回答へのお礼

有難う御座いました。
勉強させて頂きます。

お礼日時:2021/08/11 21:36

文字列で表された時刻を小数に変換します。

この小数は 0 ~ 0.99988426 の範囲内の値であり、0:00:0 (午前 00 時) から 23:59:59 (午後 11 時 59 分 59 秒) までの時刻を表します。

https://support.microsoft.com/ja-jp/office/timev …
この回答への補足あり
    • good
    • 1

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング