TL;DR —
Timer関数は何も一時停止しませんし、何かをスケジュールに従って実行することもありません。深夜 0 時からの経過秒数を小数で返すだけで、コードのかたまりにかかった時間を測るために、その前後で読みます。
Sub HowLongDoesItTake()
Dim t As Double
t = Timer ' ストップウォッチを始動
' ... 測りたいコード ...
Range("A1:A100000").Sort Key1:=Range("A1"), Order1:=xlAscending, Header:=xlNo
Debug.Print "Took " & Format(Timer - t, "0.00") & " seconds"
End Sub
Timer は VBA で最も名前負けしている関数です。その名前はカウントダウンやスケジューラを約束するので、人は「5 分ごとに実行」や「待ってから発火」を求めて「vba timer」を検索します — けれど Timer はそのどちらもしません。これはストップウォッチ、「あれはどれだけかかったか?」に答える手段です。本記事はこの 1 つの考えを軸にしています。Timer をストップウォッチと見た瞬間に、その本当の仕事(ベンチマーク)と二つの罠(スケジューラではないこと、深夜 0 時またぎ)がそのまま導かれるからです。
この記事で学べること
- 考え方の軸 —
Timerはストップウォッチ(経過時間を測る)であって、カウントダウンやスケジューラではない - その本当の仕事 — ベンチマーク、そして パフォーマンスのスイッチ が本当に効いたと証明する方法
- ナンバーワンの誤った期待 — 「N 分ごとに実行」が欲しいなら、欲しいのは
Application.OnTime - 負の経過時間を生む深夜 0 時またぎのバグと、そのガード
- その分解能 — およそ 100 分の 1 秒 — と、それが向くこと・向かないこと
考え方の軸:二度読むストップウォッチ
ストップウォッチは何も起こしません。鳴りもせず、レースを止めもせず、走者をスタートさせもしません。文字盤の時間を教えるだけで、時間の長さは二度読んで引き算して得ます。Timer はまさにそれです。呼び出すと「深夜 0 時からの秒数」を Single で返し(だから 00:01:30 の Timer は 90.0 を返します)、コードにかかった時間は前後で読んで測ります。
Dim t As Double
t = Timer ' 文字盤を読む: 例 43521.14
' ... 処理 ...
Debug.Print Timer - t ' もう一度読んで引く: 経過秒数
ここに「一時停止」も「後で発火」もありません。Timer はマクロのすることを決して変えません — その一部がどれだけ続いたかを教えるだけです。Timer にコードを遅延してほしかったのなら、それは Sleep か Application.Wait であって、Timer ではありません。
その本当の仕事:変更が本当にマクロを速くしたと証明する
ストップウォッチのモデルは、Timer が何のためにあるかをまっすぐ指し示します — ベンチマークです。Application.ScreenUpdating を切る、Application.Calculation を手動に切り替える、セル単位のループを配列に置き換える — そのとき、速くなったと信じるのではなく、測るべきです。Timer がその方法です。
Sub ProveTheSwitchHelps()
Dim t As Double
t = Timer
Application.ScreenUpdating = True ' あえて遅いやり方
WriteTenThousandRows
Debug.Print "ScreenUpdating on: " & Format(Timer - t, "0.00") & "s"
t = Timer
Application.ScreenUpdating = False ' 速いやり方
WriteTenThousandRows
Application.ScreenUpdating = True
Debug.Print "ScreenUpdating off: " & Format(Timer - t, "0.00") & "s"
End Sub
これは、あらゆるパフォーマンスの助言に対する正直な補完です。ScreenUpdating や Calculation などはやる価値がありますが、Timer は、俗説を繰り返すのではなく、それらがこのブックで効いたと知るための方法です。遅い行を見つける方法でもあります。怪しい数か所を Timer の読み取りで挟み、直感ではなく数字に、時間がどこへ消えるかを語らせましょう。
ナンバーワンの誤った期待:Timer はスケジューラではない
ほとんどの人を検索エンジンへ送り込む誤解がこれです。マクロに5 分ごとに自分で走ってほしい、あるいは遅延の後に何かしてほしい、そして Timer という名前のものがそれに違いないと思い込む。違います。Timer は経過時間を報告するだけで、何かを引き起こすことは決してありません。
本当に欲しいものを名指ししましょう。
- マクロを後で、あるいは繰り返しのスケジュールで実行する(「5 分ごとに更新」「午前 9 時に実行」)—
Application.OnTime。Excel に時刻とマクロ名を渡し、その呼び出しを予約します。 - マクロを一定の遅延だけ一時停止する —
Sleep(ミリ秒)またはApplication.Wait(整数秒)。 - 何かにどれだけかかったかを測る —
Timer。これだけ、これに限ります。
Timer で「N 秒ごとに繰り返す」ループを組もうとしている自分に気づいたら、やめましょう。欲しいのは OnTime です。ループの中の Timer は、クロックを読むだけで CPU を燃やします。
深夜 0 時またぎのバグ
Timer は深夜 0 時からの秒数を測るので、0 時に 0 へリセットされます。だから 23:59:58 に始まり 00:00:03 に終わるマクロは、Timer - t をおおよそ 3 - 86398 = -86395 と計算します — 負の経過時間です。まれですが、実在し、「マクロにマイナス 24 時間かかった」という不可解なバグ報告を一度ならず生んできました。
実行が深夜 0 時をまたぐ可能性が少しでもあるなら、それをガードするか、代わりに Now で測りましょう。
Dim elapsed As Double
elapsed = Timer - t
If elapsed < 0 Then elapsed = elapsed + 86400 ' 一日分の秒数を足す
何時間も走りうるものには、日付ベースのタイミング(Now、あるいは Date + Timer の組み合わせ)を選び、深夜 0 時の越境が結果を壊せないようにしましょう。よくあるケース — 秒や分で終わるかたまりを測る — では、素の Timer - t で完璧です。
分解能:100 分の 1 秒
Timer は Windows でおよそ10 ミリ秒ごと(約 100 分の 1 秒)に更新されます。Timer が本来答えるべき問いには、それで十分です。「バージョン A は B より速いか?」「このインポートにどれだけかかるか?」「この 3 行のどれが遅いのか?」。マイクロベンチマークには足りません — 100 分の 1 秒を大きく下回る処理を測っても、0 としか報告されません。その精度が要るときは、処理を数千回ループして割るか、QueryPerformanceCounter API まで下りましょう。日々の「速くして、それを証明する」仕事には、Timer がまさに適役です。
ExcelMaster の活用
Timer は単純ですが、うまく使うことは小さな習慣の束です。Double に読み込む、正しい順序で引く、読みやすいよう結果を Format する、長い実行では深夜 0 時のケースをガードする、そして — 人が飛ばす部分 — 計測が意味を持つように正しいコードをちゃんと挟む。そして目的が「これをスケジュールで実行」や「ここで止める」なら、Timer はまったく間違った道具です。
ExcelMaster は、あなたが述べた内容に合った道具を選びます。「マクロにかかる時間を測って」と頼めば、整った Timer ベースのベンチマークを、書式化した Debug.Print とともに落とし込みます。「5 分ごとに実行して」と頼めば、代わりに Application.OnTime を配線します。「少し止めて」と頼めば、Wait か Sleep に手を伸ばします。スケジューラのふりをした Timer ループではなく、欲しかった計測が手に入ります。
よくある質問
VBA でマクロにかかる時間を測るには?
測りたいコードの前後で Timer 関数を読み、引き算します。始めに t = Timer、終わりに Debug.Print Timer - t。Timer は深夜 0 時からの秒数を小数で返すので、その差が経過時間(秒)です。読みやすい結果にするには Format(..., "0.00") で包みましょう。
VBA の Timer 関数はコードを止めたりスケジュール実行したりしますか?
いいえ。Timer は深夜 0 時からの経過秒数を報告するだけで、マクロを止めることも、何かを引き起こすこともありません。止めるには Sleep か Application.Wait を、マクロを後で・繰り返しのスケジュールで実行するには Application.OnTime を使います。Timer は、経過時間を測るためのストップウォッチにすぎません。
VBA の経過時間が負になるのはなぜですか?
Timer が深夜 0 時にゼロへリセットされるからです。マクロが 0 時の直前に始まり直後に終わると、Timer - t は大きな「開始前」の値を小さな「終了後」の値から引いて負になります。結果が負のときは 86400(一日分の秒数)を足してガードするか、0 時をまたぎうる実行では Now で測りましょう。
Timer と Application.OnTime の違いは何ですか?
Timer は経過時間を測ります — コードにどれだけかかったかを知るために読みます。Application.OnTime は、特定の時刻や遅延の後に走るようマクロを予約します。人はよくスケジューラを求めて「vba timer」を検索しますが、その仕事は Timer ではなく Application.OnTime のものです。
VBA の Timer 関数はどれくらい正確ですか?
Timer は Windows でおよそ 100 分の 1 秒(約 10 ミリ秒)の分解能です。二つのやり方を比べたりインポートの時間を測ったりするには十分ですが、約 10 ミリ秒より速い処理は 0 と報告されます。マイクロベンチマークには、処理を何度も繰り返して割るか、QueryPerformanceCounter という Windows API を使いましょう。
検証環境
検証環境: Excel 365 (Windows 11), VBA 7.1 — 最終確認 2026-08-19。
関連ガイド: VBA Wait · VBA Sleep · VBA ScreenUpdating · VBA Calculation · VBA DoEvents
