「よし、今月の残業時間を合計するマクロができたぞ!」
意気揚々と実行ボタンを押したのに、画面に表示されたのは「5:00」。本来は29時間のはずが、24時間を超えた分が消えてしまったかのように見えます。
これは、VBAを学び始めたばかりの頃に私も経験した失敗の一つです。
原因はExcelの仕組みである「シリアル値」を正しく理解していなかったことにあります。今回は、初心者がつまずきやすい「時間の壁」をわかりやすく解説します。
「1日=1」として数えるシリアル値のルール
Excelにとって時間は「文字」ではなく「数字(小数)」として扱われます。
これをシリアル値と呼びます。イメージとしては「1日24時間を1枚のホールピザ」として数えるルールだと思ってください。
- 1日(24時間) = 1枚
- 12時間 = 0.5枚(半分)
- 1時間 = 1÷24≒0.0416枚(1枚を24等分した1片)
私たちが「0.5」とセルに入力して表示形式を「時刻」に変えると「12:00」になるのは、Excelが「あ、ピザ半分(半日)のことね!」と理解しているからなんです。
VBAで時間を扱う際に注意すべき「型」と「書式」
VBAで時間を扱うとき、初心者がつまずきやすいポイント が2つあります。
①24時間を超えると表示がリセットされる問題
VBAのMsgBoxなどで合計時間を表示すると、標準では24時間で時計が1周してしまいます。
24時間を超えた累計時間を正しく表示するには、 Excelのセル側で[h]:mmという書式設定を使う必要があります。
余談ですが、「h:mm」を見たことがある人の方が多いかもしれません。
違いは、24時間を経過した後の表示方法にあります。
[h]:mmにすることで、24時間を超えてもリセットせず、そのまま加算して表示されます。
[]を付けない場合は、24時間を超えるとリセットされます。
②「時間」として認識させるCDate関数
文字列の「09:00」を数字として計算しようとするとエラーになることがあります。その際は、CDate関数を使って「これは日付・時刻データです」とプログラムに伝えます。
【コピペで使える】勤務時間を集計するVBAサンプルコード
A列に出勤時間、B列に退勤時間が入力されている場合に、実労働時間を計算してC列に出力するプログラムをご紹介します。
Sub CalculateWorkingHours()
Dim i As Long
Dim lastRow As Long
Dim startTime As Date
Dim endTime As Date
Dim restTime As Double
' 休憩時間は1時間(シリアル値で 1/24)
restTime = 1 / 24
' 最終行を取得
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To lastRow
' 文字列を日付・時刻型に変換
startTime = CDate(Cells(i, 1).Value)
endTime = CDate(Cells(i, 2).Value)
' ※マイナスになるとエラーになるので注意
Cells(i, 3).Value = (endTime - startTime) - restTime
' セルの書式を「24時間を超えても表示できる形式」に設定
Cells(i, 3).NumberFormatLocal = "[h]:mm"
Next i
MsgBox "集計が完了しました!"
End Sub
まとめ:仕組みの理解が上達への近道
時間は数値(シリアル値)で管理されていること、そして24時間を超える表示には書式設定が必要であること、この2点を押さえましょう。
これらの仕組みを知るだけで、Excel作業の自動化スキルは格段に向上します。
最初は「難しそう…」と思うかもしれませんが、仕組みそのものは以外とシンプル。ぜひ試してみてください!
VBAを独学で学び、業務自動化に5年以上携わってきた私が、「本当に実務で役立った!」と感じた2冊を紹介します。 もう本選びで失敗したくない方は、よければ参考にしてみてください。

コメント