Excel VBAで時刻を扱っていると、「9:30」や「18:45」といった文字列を、そのまま時刻として処理したい場面があります。
見た目では時刻に見えていても、VBAでは文字列と時刻は同じものではありません。文字列のまま比較や計算を行おうとすると、想定した結果にならなかったり、データによってエラーが発生したりすることがあります。
そこで利用できるのがTimeValue関数です。TimeValue関数を使うと、時刻として認識できる文字列や値から「時刻部分」を取得し、VBAで扱える時刻値へ変換できます。
この記事では、TimeValue関数の基本的な使い方だけでなく、どのような値を渡せるのか、日付が含まれている場合はどうなるのか、実務ではどのように利用すべきなのかまで整理して解説します。
✅ VBAのTimeValue関数とは?文字列を時刻として扱う仕組み
TimeValue関数は構文だけを見ると非常にシンプルですが、実務では「文字列を時刻に変換する関数」とだけ覚えていると判断を誤ることがあります。特に注意したいのが、ExcelやVBAでは時刻が内部的には数値として管理されている点です。そのため、画面上で「9:30」と表示されていても、データの状態によって扱い方が異なる場合があります。
また、TimeValueは現在時刻を取得するTime関数とは役割が違います。この違いを曖昧にしたままコードを書くと、後から時刻の比較や計算を追加するときに処理が分かりにくくなります。まずはTimeValueが何をする関数なのかを押さえておきましょう。
・TimeValue関数で文字列から時刻を取得する基本構文
TimeValue関数の基本構文は次のとおりです。
TimeValue(time)
timeには、VBAが時刻として認識できる文字列や式を指定します。
たとえば、「9:30」という文字列を時刻として取得する場合は次のように記述できます。
Sub ConvertTextToTime()
Dim workStartTime As Date
' 文字列の時刻をDate型の値へ変換する
workStartTime = TimeValue("9:30")
MsgBox workStartTime
End Sub
このコードでは、文字列として記述した "9:30" をTimeValue関数へ渡し、その結果をworkStartTimeへ格納しています。
変数名を単純なxやtime1などにせず、workStartTimeとしているのは、後からコードを見た人にも「業務開始時刻を扱っている」と分かるようにするためです。
時刻を扱う処理では複数の時刻変数が登場しやすいため、何の時刻なのかが分かる変数名にしておくことが保守性の面でも重要です。
・TimeValueの戻り値をDate型で受け取る理由
TimeValueという名前から、専用の「Time型」が返されるように感じるかもしれません。しかし、VBAでは日付と時刻を扱う場合、基本的にDate型を使用します。
そのため、実務では次のようにDate型の変数で受け取る形が分かりやすくなります。
Dim closingTime As Date
closingTime = TimeValue("17:30")
ExcelやVBAの日付・時刻は、内部では連続した数値を利用して管理されています。時刻はそのうち1日を基準とした小数部分として表現されるため、取得した値を利用して時刻同士を比較したり、一定時間を加減したりできます。
ここがTimeValueを使う大きな意味です。
単に「17:30」という見た目を作るのではなく、後続処理で時刻として比較・計算できる状態に変換するために利用できます。
VBAで時刻の比較や計算を正しく行うには、Excelの日付・時刻が内部でどのような数値として管理されているかを理解しておくと、TimeValueの動作も分かりやすくなります。時刻計算の仕組みを詳しく知りたい場合は、「【VBA】時間の計算ができる仕組みとは?シリアル値を理解して日付・時刻を正しく扱う方法」もあわせて確認してみてください。
✅ VBAでTimeValueを使って文字列を時刻に変換する方法
実務では、コード内に固定された時刻だけを扱うとは限りません。セルやCSVなどから取り込んだデータが文字列になっており、それを時刻として利用したいケースもあります。このとき「9:00と書かれているから時刻だろう」と見た目だけで判断するのは危険です。文字列のまま処理すると、後から比較条件を追加した際に思わぬ不具合につながる可能性があります。
一方で、すべての値へ無条件にTimeValueを適用すればよいわけでもありません。入力データが時刻として解釈できることを意識した設計が必要です。
・セルの文字列をTimeValueで時刻に変換する例
たとえば、セルA2に文字列として時刻が入力されているとします。
その値を取得して時刻へ変換する場合は、次のように記述できます。
Sub ConvertCellValueToTime()
Dim sourceTimeText As String
Dim convertedTime As Date
' セルから変換対象の文字列を取得する
sourceTimeText = Range("A2").Value
' 取得した文字列を時刻へ変換する
convertedTime = TimeValue(sourceTimeText)
Range("B2").Value = convertedTime
End Sub
処理の流れは次のとおりです。
- セルA2から元の値を取得する
sourceTimeTextへ文字列として格納する- TimeValue関数で時刻へ変換する
- 変換結果を
convertedTimeへ格納する - セルB2へ結果を書き込む
あえて取得用と変換後の変数を分けているのがポイントです。
短いコードであれば、次のように直接記述することもできます。
Range("B2").Value = TimeValue(Range("A2").Value)
こちらの方がコード量は少なくなります。
しかし、実務では後から「変換前の値をチェックしたい」「不正な入力なら処理を止めたい」といった仕様が追加されることがあります。
そのため、処理が発展する可能性がある場合は、取得した値と変換後の値を分けて管理した方が修正しやすいというメリットがあります。
・時刻だけを取り出したい場合にもTimeValueを利用できる
TimeValueは、日付と時刻を含む値から時刻部分を扱いたい場合にも利用できます。
たとえば、次のような日時があるとします。
2026/8/28 14:30:00
この値から時刻部分を取得する例が次のコードです。
Sub ExtractTimeFromDateTime()
Dim recordedDateTime As Date
Dim recordedTime As Date
recordedDateTime = #8/28/2026 2:30:00 PM#
' 日時から時刻部分を取得する
recordedTime = TimeValue(recordedDateTime)
MsgBox recordedTime
End Sub
このように、日時を持つデータから「14:30:00」のような時刻部分を利用したい場合にもTimeValueを活用できます。
たとえば、処理日時そのものではなく「何時に処理されたのか」だけを条件判定に利用したい場合などに便利です。
ただし、ここで重要なのは、TimeValueを使えばどのような文字列でも安全に時刻へ変換できるわけではないという点です。
セルの値が空白だったり、時刻として解釈できない文字列が含まれていたりすると、エラー対策が必要になります。
また、「日付と時刻を両方保持したい」「時刻として変換できるか事前に確認したい」といった目的では、TimeValueだけで処理を完結させるのではなく、CDateやIsDateなどとの使い分けも重要になります。
✅ VBAのTimeValue関数で時刻を比較・判定する方法
TimeValueで時刻へ変換するメリットが特に大きいのが、業務時間や締切時刻などの判定に利用するときです。文字列の見た目だけを基準に比較すると、入力形式の違いによって意図しない判定になる可能性があります。
また、現在時刻を取得する処理と文字列を時刻へ変換する処理は役割が異なるため、同じものとして扱わないことも重要です。実務では「17:00を過ぎたら処理を変える」「指定された開始時刻より後かを調べる」といった条件判定がよくあります。TimeValueの役割を理解しておけば、このような処理を読みやすく組み立てられます。ただし、日付をまたぐ時間計算には別の考慮が必要になるため、単純な時刻比較で対応できる範囲も把握しておきましょう。
・指定した時刻より前か後かを判定する例
たとえば、セルA2に入力された時刻が17:00以降かどうかを判定するとします。
Sub CheckClosingTime()
Dim inputTime As Date
Dim closingTime As Date
' 入力値と基準時刻を時刻として取得する
inputTime = TimeValue(Range("A2").Value)
closingTime = TimeValue("17:00")
If inputTime >= closingTime Then
MsgBox "17:00以降です。"
Else
MsgBox "17:00より前です。"
End If
End Sub
処理の流れは次のとおりです。
- セルA2から判定対象となる時刻を取得する
- TimeValueで比較可能な時刻へ変換する
- 基準となる17:00も時刻として取得する
If文で2つの時刻を比較する- 条件に応じて処理を分岐する
ここではclosingTimeという変数を用意し、「何と比較しているのか」がコードから読み取れるようにしています。
もちろん、次のように直接比較することも可能です。
If TimeValue(Range("A2").Value) >= TimeValue("17:00") Then
短い処理なら問題ありませんが、基準時刻を何度も使用する場合は変数へ格納した方が管理しやすくなります。
たとえば、将来「17:00から17:30へ変更する」という仕様変更が発生しても、基準となる値を一か所修正するだけで対応しやすくなります。
・TimeValueを時刻の計算へつなげる考え方
TimeValueで取得した値は、時刻として計算に利用できます。
たとえば開始時刻と終了時刻の差を求める基本的な例は次のとおりです。
Sub CalculateWorkingTime()
Dim startTime As Date
Dim endTime As Date
Dim workingTime As Double
startTime = TimeValue("9:00")
endTime = TimeValue("17:30")
' 時刻の差を日単位の数値として取得する
workingTime = endTime - startTime
MsgBox "経過時間:" & Format(workingTime, "h:mm")
End Sub
このコードでは、TimeValueそのものが経過時間を計算しているわけではありません。
TimeValueで時刻として扱える値を用意し、その値同士を減算しているという点が重要です。
そのため、「TimeValue=時間計算をする関数」と覚えるより、
文字列などを時刻として扱える状態に整え、比較や計算などの後続処理につなげる関数
と理解しておく方が実務では応用しやすくなります。
なお、23:00から翌日の2:00までのように日付をまたぐ処理では、単純な時刻同士の減算だけでは期待した結果になりません。日付情報を含めて計算するなど、別途設計が必要です。
TimeValueで変換した時刻を「現在時刻」と比較したい場合は、現在の時刻を取得する方法も押さえておくと処理の幅が広がります。TimeとNowでは取得できる情報が異なるため、「【VBA】現在時刻を取得する方法|Time・Nowの違いと使い分け」で使い分けを確認しておくと、時刻判定のコードを組み立てやすくなります。
✅ VBAでTimeValueを使うときのエラーと安全な対処方法
TimeValueを実務コードへ組み込む場合、正常な時刻だけが渡されることを前提にするのは避けたいところです。セルには空白が含まれることもあれば、「未入力」「確認中」など時刻ではない文字列が入力されている場合もあります。その状態でTimeValueによる変換を実行すると、実行時エラーにつながる可能性があります。特に大量の行を自動処理するマクロでは、1件の不正データによって処理全体が停止すると影響が大きくなります。
一方で、エラーを無視するだけの設計では原因の発見が難しくなります。そこで重要なのが、変換前に入力値を確認してからTimeValueを実行する考え方です。
・IsDateで確認してからTimeValueを実行する
セルの内容が時刻として解釈できるか分からない場合は、IsDateによる確認を組み合わせる方法があります。
Sub ConvertTimeSafely()
Dim sourceValue As Variant
Dim convertedTime As Date
sourceValue = Range("A2").Value
' 日付または時刻として認識できる値だけ変換する
If IsDate(sourceValue) Then
convertedTime = TimeValue(sourceValue)
Range("B2").Value = convertedTime
Else
MsgBox "A2セルの値を時刻として変換できません。"
End If
End Sub
この書き方では、いきなりTimeValueを実行していません。
最初にIsDate(sourceValue)で判定し、変換可能な場合だけTimeValueへ値を渡しています。
実務では、このように入力値の検証と実際の変換処理を分けることで、想定外のデータに強いコードにできます。
ただし、IsDateは時刻だけではなく日付として解釈できる値にもTrueを返します。
「時刻形式だけを許可したい」など、入力条件を厳密に限定する必要がある場合は、IsDateだけで業務上の入力ルールを完全に保証できるわけではありません。必要に応じて追加の条件判定を設けることが大切です。
・On Error Resume Nextだけで処理しない
次のように、エラーを無視して処理を続ける方法もあります。
On Error Resume Next
convertedTime = TimeValue(sourceValue)
しかし、TimeValueの入力チェックを目的として、これだけに頼る設計はおすすめできません。
エラーが発生しても処理が継続するため、変換に失敗したこと自体を見落としやすくなるからです。
特に複数の処理をまとめてOn Error Resume Nextの対象にすると、TimeValue以外で発生した不具合まで見逃す可能性があります。
入力値を事前に確認できる場合は、まず条件判定によって正常系と異常系を明確に分ける方が、後からコードを修正する人にも処理意図が伝わりやすくなります。
TimeValueへ渡す値を事前に確認する場合は、IsDateだけでなくCDateやDateValue、VarTypeとの違いを理解しておくと、入力データに応じた判定がしやすくなります。日付・時刻として扱える値の判定方法は、「【VBA】日付かどうか判定する方法|IsDate・CDate・DateValue・VarTypeの使い分け」で詳しく整理しています。
また、エラーを単純に無視する目的でOn Error Resume Nextを広い範囲に使用すると、本来確認すべき不具合まで見逃す原因になります。エラーを無視する処理の注意点については、「【VBA】On Error Resume Nextでエラーを無視してエラーの制御|危険な理由」も参考にしてください。
✅ VBAのTimeValueとCDate・Time・Hour関数を使い分ける
VBAには日付や時刻に関係する関数が複数あるため、TimeValueとの違いが曖昧になりやすいところです。特にCDate、Time、HourなどはTimeValueと一部用途が近く見えます。
しかし、それぞれが担当する処理は同じではありません。ここを整理せずにコードを書くと、本来不要な変換を繰り返したり、日付情報まで必要なのに時刻だけを取り出してしまったりすることがあります。関数名を個別に暗記するより、「取得・変換・分解」のどの処理をしたいのかで選ぶと判断しやすくなります。既存の時刻関連コードを改修するときにも役立つ考え方です。
・目的からTimeValueと関連関数を選ぶ
代表的な関数との違いを整理すると、次のようになります。
| 関数 | 主な役割 | 使用例 |
|---|---|---|
TimeValue | 時刻として認識できる値から時刻を取得 | "17:30"を時刻として扱う |
CDate | 値をDate型へ変換 | 日付・時刻を含む値を変換する |
Time | 現在時刻を取得 | マクロ実行時点の時刻を調べる |
Now | 現在の日付と時刻を取得 | 処理日時を記録する |
Hour | 時刻から「時」を取得 | 17:30から17を取得する |
Minute | 時刻から「分」を取得 | 17:30から30を取得する |
Second | 時刻から「秒」を取得 | 17:30:15から15を取得する |
たとえば、現在時刻を取得したいのであれば、TimeValueを使う必要はなくTimeが適しています。
反対に、セルなどから取得した "17:30" を時刻として比較したいのであれば、TimeValueが候補になります。
また、日時全体を保持する必要がある場合は、TimeValueで時刻だけを取り出すのではなく、CDateなどを利用して日付情報も維持した方が適切なケースがあります。
「どの関数が高機能か」ではなく、「最終的に何の情報を残したいか」で選ぶことが重要です。
TimeValueは時刻部分を扱いたい場合に便利ですが、日付と時刻を含む値そのものをDate型へ変換したい場合はCDateが適しているケースがあります。CDateを含むVBAの型変換については、「【VBA】型変換(CInt/CLng/CStr/CDate)の使い分けと注意点|実務のデータ処理」で、ほかの型変換関数との違いも確認できます。
変換した時刻から「時・分・秒」を個別に取り出して条件判定などに利用したい場合は、「【VBA】Hour 関数、Minute 関数、Second 関数の使い方と活用例」もあわせて確認すると、TimeValueから次の処理へ発展させやすくなります。
✅ VBAでTimeValueを実務利用するときに意識したい設計
TimeValueを使ったコードは数行でも作成できますが、実務では入力データが増えるほど設計の違いが影響します。固定文字列を変換するだけなら問題がなくても、セルから取得するようになると空白や入力ミスへの対応が必要です。さらに、複数行をループ処理する場合は、どのデータで変換に失敗したのか分かる仕組みも重要になります。
短く書くことだけを優先すると、後から条件追加が発生したときにコードが複雑になりがちです。TimeValueはあくまで変換を担当させ、入力確認や業務上の判定とは役割を分けると保守しやすくなります。小さなマクロでも、この考え方を持っておくと再利用しやすいコードにつながります。
・変換と業務条件を分けると修正しやすい
たとえば勤務開始時刻を判定する処理なら、
- セルから元データを取得する
- 入力値を検証する
- TimeValueで時刻へ変換する
- 基準時刻と比較する
- 判定結果に応じた処理を実行する
というように、処理を段階的に考えるのがおすすめです。
この構成なら、「空白の場合はスキップする」「基準時刻をセルから取得する」といった仕様変更にも対応しやすくなります。
また、Excel VBAで時刻処理を自動化していく場合は、TimeValueだけでなく、現在時刻を取得するTimeやNow、時・分・秒を取り出すHour・Minute・Secondなどを組み合わせることで、より柔軟な処理を作成できます。
TimeValueですべてを処理しようとせず、時刻への変換はTimeValue、現在時刻の取得はTime、時刻の分解はHour・Minute・Secondというように役割を分けることが、読みやすいVBAコードにつながります。
VBAではなくExcelのワークシート上で時刻を作成・計算したい場合は、TIME関数を利用する方法もあります。VBAのTimeValueとは役割が異なるため、セルの数式で時刻を扱いたい場合は「【Excel】TIME関数の使い方|時刻入力・時間計算を効率化する方法」を参考にしてください。
✅ まとめ:VBAのTimeValueで文字列を時刻へ正しく変換しよう
TimeValue関数は、文字列などの値を時刻として扱いたいときに役立つVBAの関数です。
- TimeValueは、時刻として認識できる値から時刻を取得できる
- 文字列の時刻を比較や計算へ利用したい場合に便利
- 戻り値はDate型の変数で扱える
- 日時から時刻部分を利用したい場合にも活用できる
- 時刻同士を減算すれば経過時間の計算にもつなげられる
- 日付をまたぐ時間計算では、日付情報を含めた設計が必要
- セルの入力値を扱う場合は、IsDateなどによる事前確認も重要
- エラーを単純に無視するのではなく、正常値と不正値を分けて処理する
- 現在時刻の取得ならTime、日時全体ならNowやCDateなど、目的に応じて使い分ける
- Hour・Minute・Secondは時刻から個別の要素を取り出す場合に利用する
TimeValueを単なる「時刻変換の構文」として覚えるだけでなく、入力されたデータを後続の比較・計算に利用できる状態へ整えるための関数として理解すると、実務での使い道が見えやすくなります。
時刻を扱うVBAでは、取得・変換・判定・計算を一つの処理に詰め込まず、それぞれの役割を分けて設計してみてください。仕様変更にも対応しやすく、後から見ても処理内容を把握しやすいコードを作成できます。