VBA Timer関数応用編:柔軟な時間計測をモジュール化で実現!

当ページのリンクには広告 (Amazonアソシエイト含む) が含まれています。
アイキャッチ

「VBAで処理時間を計測したいけど、簡単で再利用しやすい仕組みにしたい…」
このように悩んでいませんか?


コピペでTimer関数をすぐに使いたい

複数タスクの処理時間を統一的に管理したい

冗長にならずスッキリしたコードを書きたい

そんな課題を解決するのが
VBA Timer関数を活用した「時間計測モジュール」です!


この記事では、「Timer関数を応用して効率よく時間計測を行う方法」を初心者向けに分かりやすく解説します。

再利用可能な計測コードを作れば、効率的な時間管理が簡単に実現できます。
複数の処理を一括で計測し、Timer関数でどの処理が時間を浪費しているかを把握可能です。
計測部分をモジュール化することでコードの再利用性も向上し、業務効率化やマクロの最適化にも役立ちます。

これから紹介する内容を実践すれば、Timer関数を使った時間計測が驚くほど簡単になります!
ぜひ最後までお読みください。

Timer関数とは?という方は、以下の記事で基礎を解説しています。
合わせてご覧ください。

あわせて読みたい
VBA Timer関数で処理時間を正確に測定|コード改善の第一歩 「VBAで作成したコードの処理時間を測定してみたい…」このように悩んでいませんか? ・特定の処理にかかる「時間」を計測したい・長時間かかる処理のパフォーマンスをチ...

【 この記事の概要 】

よく使う度
難しさ
覚えておくと安心度

VBAをしっかり学びたいけれど、「どこから始めればいいかわからない」と迷っていませんか?

そんな方には、UdemyのVBA講座がおすすめです。

動画での丁寧な解説や、実践的な学習スタイルで、初心者でも無理なく基礎から応用まで習得できます。
自己学習を進める上で、何度でも繰り返し見返せる講座は非常に心強い味方になりますよ!

多彩な講座から自分に合った講座を探そう!
UdemyでVBAを検索
UdemyでVBAを検索 画像出典:Udemy

\  自分のペースで学べるVBA講座はこちら  /

目次

この記事で「できるようになる」こと

この記事を読むことで、次のことが分かるようになります。

スポンサーリンク

VBAで「時間計測モジュール」を作成し、時間管理が簡単になる理由

VBAでTimer関数をそのまま使用して処理時間を測定することは可能ですが、実際には以下のような課題があります。
このような問題を解決するのが、「時間計測モジュール」です。

このモジュールを利用することで、時間計測が驚くほど簡単になります。
※時間計測モジュールとは?
 ⇒ Timer関数を使った計測機能をモジュールとして整理した仕組みを指します。
   これは公式な名称ではなく、この記事内でわかりやすく表現するために使用しています。

以下で、Timer関数をそのまま使った場合の不便な点と、モジュールを使うことで解決できる理由を詳しく説明します。
それでは見ていきましょう。

VBA Timer関数をそのまま使うと起きる3つの問題

1. 毎回同じコードを書く必要がある

Timer関数を使って処理時間を測定するには、以下のようなコードを毎回記述する必要があります。

Dim startTime As Double
Dim endTime As Double
Dim elapsedTime As Double

startTime = Timer

'// ここに処理を記述

endTime = Timer

elapsedTime = endTime - startTime
Debug.Print "処理時間: " & elapsedTime & " 秒"

毎回これらのコードをコピペして修正するのは面倒であり、修正漏れや記述ミスのリスクも高まります。

2. 複数の処理を計測するのが大変

複数の処理を計測する場合、それぞれにTimer関数を記述する必要があり、コードが冗長になります。

'// 処理1
startTime = Timer

'// 処理1の内容
endTime = Timer
Debug.Print "処理1の時間: " & (endTime - startTime) & " 秒"

'// 処理2
startTime = Timer

'// 処理2の内容
endTime = Timer
Debug.Print "処理2の時間: " & (endTime - startTime) & " 秒"

このように処理ごとに毎回Timer関数を記載するとコードが冗長になり、可読性が下がります。
また、コード全体のメンテナンス性も悪化してしまいます。

3. 計測を一時的に無効化しにくい

デバッグやテストの際に計測を一時的に無効化したい場合、コメントアウトを手作業で行う必要があります。

以下のように複数のコードを手動で操作するのは手間がかかります。

'//startTime = Timer

'//処理内容

'//endTime = Timer
'//Debug.Print "処理時間: " & (endTime - startTime)

大規模なプロジェクトでは、このように多くのコードをコメントアウトしないといけなくなり、操作に多くの時間を費やす可能性があります。

時計

時間計測モジュールで解決する3つの理由

時間計測モジュールを使用すると、上記の不便さを簡単に解消できます。

以下の理由で作業が効率化され、コードの管理がスムーズになります。

1. 計測コードの再利用が可能

計測部分をモジュール化することで、同じコードを複数回書く必要がありません

必要な場所で呼び出すだけなので、コピペ作業が大幅に削減されます。

'// 計測開始
StartTimer

'// 処理内容
Call SomeProcess

'// 計測終了
EndTimer "SomeProcess"

このシンプルな記述だけで処理時間を計測できます。

2. 複数の処理も一括で管理

同じモジュールを使用することで、複数の処理を統一的に管理できます。

例えば、次のように記述するだけで、それぞれの処理時間が簡単に測定できます。

'// 処理1
StartTimer
Call Task1
EndTimer "Task1"

'// 処理2
StartTimer
Call Task2
EndTimer "Task2"

結果はイミディエイトウィンドウに自動的に出力されるため、効率的に処理時間を比較できます。

3. 計測の有効/無効を簡単に切り替えられる

時間計測を一時的に無効化したい場合、モジュール内のフラグを変更するだけで全ての計測が停止します。

これにより、デバッグ作業がスムーズになります。

Public Const ENABLE_TIMING As Boolean = False '// 計測を無効化

フラグをTrueに戻せば計測が再開されるため、柔軟な切り替えが可能です。

4. コードがスッキリして可読性が向上

時間計測モジュールを使うことで、コード全体が整理され、冗長な記述を省けるため、メンテナンスがしやすくなります。

特に大規模なプロジェクトで効果を発揮します。

VBA Timer関数を使った時間計測モジュールを作成しよう!

これまで解説してきた課題を解消する「時間計測モジュール」の完成形コードを紹介します。
このモジュールを利用することで、処理時間の計測が簡単かつ効率的に行えます。

以下にコードの全体像と、実際の使い方を解説していきます。

時間計測モジュールの完成形コード

以下のコードを新しい標準モジュール(例:Module2)にコピーして利用します。
専用の標準モジュールを作成しておくと、他のコードと分けて管理できるので便利です。

コードの記載場所

標準モジュールの作成方法・名前の変更方法について知りたい方は、下記をクリックしてください。

クリックして標準モジュールの追加方法を見る
  • 「開発タブ」をクリックします。
  • 「Visual Basic」をクリックし、VBAエディタを開きます。
    ※「Alt + Basic」を押しても問題ありません。
  • 左の空白部で「右クリック」を行います。
  • 開いたメニューから「挿入 (N)」を選択します。
  • その中の「標準モジュール (M)」をクリックすることで、新規で標準モジュールを作成することができます。
  • 「プロパティ – Module~」に記載されている「(オブジェクト名)」を変更したら、標準モジュール名を変更することができます。

コード : このコードをそのまま標準モジュールにコピペしてください。

Option Explicit

'// 計測を有効にするフラグ(Trueで計測有効、Falseで無効)
Public Const ENABLE_TIMING As Boolean = True

'// 開始時刻を記録する変数
Private startTime As Double

'// 計測開始関数
Public Sub StartTimer()
    If ENABLE_TIMING Then
        startTime = Timer
    End If
End Sub

'// 計測終了関数
Public Sub EndTimer(taskName As String)
    If ENABLE_TIMING Then
        Dim elapsed As Double
        elapsed = Timer - startTime
        Debug.Print taskName & " の処理時間: " & elapsed & " 秒"
    End If
End Sub

コードのポイント

ENABLE_TIMINGフラグ

Public Const ENABLE_TIMING As Boolean = True
説明

このフラグは計測機能を有効化 (True) もしくは無効化 (False) するスイッチです。

デフォルトではTrueに設定されていますが、デバッグ中や処理速度を測定しない場合には、Falseに切り替えるだけで計測機能を簡単に無効化できます。

メリット

フラグを切り替えるだけで、全てのStartTimerEndTimerの呼び出しを無効化できるため、計測コードを個別に削除したりコメントアウトする必要がありません。

例:フラグを無効化した場合
Public Const ENABLE_TIMING As Boolean = False

この状態でコードを実行すると、StartTimerEndTimerは動作せず、処理結果に影響を与えません。

startTime変数

Private startTime As Double
説明

startTimeは、計測の開始時刻を保存するための変数です。

型はDoubleで、小数点以下の秒数も記録できるようにしています。
これにより、短時間の処理でも正確な測定が可能です。

変数のスコープ

Private宣言により、この変数はモジュール内でのみアクセス可能です。

他のモジュールやプロシージャから直接変更されることはありません。

StartTimer関数

Public Sub StartTimer()
    If ENABLE_TIMING Then
        startTime = Timer
    End If
End Sub
説明

StartTimerは、計測の開始時刻を記録する関数です。

Timer関数を使って現在の経過秒数(0:00からの秒数)を取得し、モジュール内のstartTime変数に保存します。

構造のポイント

If ENABLE_TIMING Thenの条件分岐により、フラグがTrueの場合のみ計測が行われます。
これにより、不要な処理をスキップできます。

重要な注意点

StartTimerを呼び出すタイミングが重要です。
処理を正確に計測するために、測定対象の処理の直前で呼び出してください。

EndTimer関数

Public Sub EndTimer(taskName As String)
    If ENABLE_TIMING Then
        Dim elapsed As Double
        elapsed = Timer - startTime
        Debug.Print taskName & " の処理時間: " & elapsed & " 秒"
    End If
End Sub
説明

EndTimerは、計測の終了時刻を取得し、処理にかかった時間を計算する関数です。

Timer関数からstartTimeを引くことで、処理に要した経過秒数を計算します。

引数

taskNameは文字列型の引数で、計測している処理の名前を指定します。

これにより、どの処理の時間が表示されているのかを明確にできます。

結果の出力

計測結果はDebug.Printでイミディエイトウィンドウに出力されます。

処理結果
注意点

StartTimerと対で使用する必要があります。

同じ処理に対してStartTimerを呼び出さないと、正しい結果が得られません。

Debug.Printによる結果の表示

Debug.Print taskName & " の処理時間: " & elapsed & " 秒"
説明

Debug.Printを使って、計測結果をイミディエイトウィンドウに表示します。

これにより、Excelのセルやシートに影響を与えることなく、計測結果を確認できます。

イミディエイトウィンドウの表示方法
  1. VBAエディタを開く(Alt + F11)。
  2. メニューの「表示」→「イミディエイトウィンドウ」をクリック。
  3. コードを実行すると、計測結果がイミディエイトウィンドウに表示されます。
イミディエイトウィンドウの表示方法
スポンサーリンク

実際の時間計測モジュールの使い方を解説します。

VBAで処理時間を計測したいとき、「時間計測モジュール」を使えば、簡単にその機能を追加することができます。
このモジュールは、処理の開始時刻と終了時刻を記録し、経過時間をイミディエイトウィンドウに出力します。

ここでは、単一処理と複数処理を計測する方法を具体的な例を交えて解説します。
さらに、計測を無効化する方法についても触れます。

単一処理の時間計測を行う場合

元のコード

以下は、単純なループ処理を行うサブルーチンの例です。
処理時間の計測機能はまだ含まれていません。

Sub LongTask()
    '// サンプル:大きなループ処理
    Dim i As Long, total As Double

    total = 0

    For i = 1 To 1000000
        total = total + i
    Next i

    Debug.Print "合計: " & total
End Sub

時間計測モジュールを使用したコード

「時間計測モジュール」を導入すると、以下のように処理時間を計測できます。

Sub LongTask()
    '// サンプル:大きなループ処理
    Dim i As Long, total As Double
    
    '// 処理開始時刻を記録
    Call StartTimer
    
    total = 0
    
    For i = 1 To 50000
        total = total + i
    Next i
    
    Debug.Print "合計: " & total
    
    '// 処理終了時刻を記録
    EndTimer ("Long Task")
End Sub
単一処理の計測の時間計測モジュールを使用した結果

変更点の解説

1. Call StartTimerの追加
Call StartTimer

処理の開始部分に挿入します。

処理開始時刻を記録する機能を有効にします。

2. Call EndTimerの追加
Call EndTimer("LongTask")

処理の終了部分に挿入します。

処理終了時刻を記録し、経過時間をイミディエイトウィンドウに出力します。

引数には、処理の名前(サブルーチン名や処理内容を表す文字列)を指定します。
例:「LongTask」「データ集計処理」など。

複数処理の時間計測を行う場合

元のコード

以下は、単純なループ処理を行うサブルーチンの例です。
処理時間の計測機能はまだ含まれていません。

Sub MultipleProcesses()

    Call Task1

    Call Task2

End Sub


Sub Task1()
    '// 簡単な処理例
    Dim i As Long, sum As Double

    sum = 0

    For i = 1 To 50000
        sum = sum + i
        Cells(i, 1) = i
    Next i

    Debug.Print "Task1の合計: " & sum
End Sub


Sub Task2()
    '// 別の処理例
    Dim i As Long, product As Long

    product = 1

    For i = 1 To 10
        product = product * i
    Next i

    Debug.Print "Task2の積: " & product
End Sub

時間計測モジュールを使用したコード

「時間計測モジュール」を導入すると、以下のように処理時間を計測できるコードに変わります。

Sub MultipleProcesses()
    '// 処理1
    Call StartTimer

    Call Task1

    Call EndTimer("Task1")

    '// 処理2
    Call StartTimer

    Call Task2

    Call EndTimer("Task2")
End Sub


Sub Task1()
    '// 簡単な処理例
    Dim i As Long, sum As Double

    sum = 0

    For i = 1 To 50000
        sum = sum + i
        Cells(i, 1) = i
    Next i

    Debug.Print "Task1の合計: " & sum
End Sub


Sub Task2()
    '// 別の処理例
    Dim i As Long, product As Long

    product = 1

    For i = 1 To 10
        product = product * i
    Next i

    Debug.Print "Task2の積: " & product
End Sub
複数処理の時間計測の時間計測モジュール結果

変更点の解説

1. Call StartTimerの追加
Call StartTimer

各サブルーチンの処理開始部分に挿入します。

処理開始時刻を記録します。

2. Call EndTimerの追加
Call EndTimer("Task1")

Call EndTimer("Task2")

各サブルーチンの処理終了部分に挿入します。

処理終了時刻を記録し、経過時間をイミディエイトウィンドウに出力します。

引数には、処理の名前(サブルーチン名や処理内容を表す文字列)を指定します。
例:「Task1」「Task2」など。

無効化

計測を一時的に無効化したい場合

計測機能を一時的に使用しない場合は、モジュール内のフラグをFalseに設定するだけで、全ての計測が無効化されます。
この方法を活用することで、デバッグ中や計測が不要な場面で簡単に計測コードをスキップできます。

全体のコード (単一処理の時間計測を行う場合)

Sub LongTask()
    '// サンプル:大きなループ処理
    Dim i As Long, total As Double
    
    '// 処理開始時刻を記録
    Call StartTimer
    
    total = 0
    
    For i = 1 To 50000
        total = total + i
    Next i
    
    Debug.Print "合計: " & total
    
    '// 処理終了時刻を記録
    EndTimer ("Long Task")
End Sub


'//ここからは、「時間停止モジュール」のコード
Option Explicit

'// 計測を有効にするフラグ(Trueで計測有効、Falseで無効)
Public Const ENABLE_TIMING As Boolean = False

'// 開始時刻を記録する変数
Private startTime As Double

'// 計測開始関数
Public Sub StartTimer()
    If ENABLE_TIMING Then
        startTime = Timer
    End If
End Sub

'// 計測終了関数
Public Sub EndTimer(taskName As String)
    If ENABLE_TIMING Then
        Dim elapsed As Double
        elapsed = Timer - startTime
        Debug.Print taskName & " の処理時間: " & elapsed & " 秒"
    End If
End Sub

具体的な変更点

Public Const ENABLE_TIMING As Boolean = False

「時間計測モジュール」について詳しくはこちらをご覧ください。
「時間計測モジュール」についてもう一度見る。


これにより、以下のようなメリットがあります。

  • 計測コードを削除したりコメントアウトする必要がありません。
  • 再び計測を有効化したい場合は、フラグをTrueに戻すだけです。
スポンサーリンク

Timer関数を活用する際の注意ポイント

Timer関数は、処理時間を測定する際に非常に便利ですが、使用する際にはいくつか注意すべきポイントがあります。

特に、深夜をまたぐ処理などで正確な結果を得るためには工夫が必要です。

ここでは、Timer関数の仕様と、それを考慮した対処法を解説します。

注意1: 日付をまたぐ場合の問題

Timer関数は、午前0時(00:00:00)から現在時刻までの経過秒数を返す関数です。

この仕様により、日付をまたぐ場合にタイマーがリセットされるという特性があります。

例えば、以下のケースでは問題が発生します。

問題が発生するパターン
  • 開始時刻:23:59(86340秒)
  • 終了時刻:翌日00:01(60秒)

解決方法:条件分岐を追加する

日付をまたぐ可能性がある場合、Timer関数の戻り値がリセットされたことを考慮した条件分岐を追加する必要があります。

以下の修正版コードをご覧ください。

Sub HandleTimerAcrossMidnight()
    Dim startTime As Double
    Dim endTime As Double
    Dim elapsedTime As Double

    '// 計測開始時刻を記録
    startTime = Timer

    '// 5秒待機(深夜をまたぐケースを想定)
    Application.Wait Now + TimeValue("00:00:05")

    '// 計測終了時刻を記録
    endTime = Timer

    '// 日付をまたぐ場合の処理
    If endTime < startTime Then
        elapsedTime = (86400 - startTime) + endTime ' 86400秒 = 1日
    Else
        elapsedTime = endTime - startTime
    End If

    '// 結果を出力
    Debug.Print "経過時間: " & elapsedTime & "秒"
End Sub
修正版コードのポイント
  • Timer関数のリセットを考慮
    • If endTime < startTime Thenで、日付をまたぐ場合の条件分岐を行っています。
    • 86400は1日の総秒数(24時間 × 60分 × 60秒)を表し、リセット後の秒数を加算して正しい経過時間を計算します。
  • 日付をまたがない場合
    • 条件分岐のElse部分で、通常の計算(endTime - startTime)を行います。
  • デバッグやテストに便利なApplication.Wait
    • 5秒待機することで、コードを簡単にテストできます。
      実際の業務コードでは適宜置き換えてください。

注意2: 短時間処理では精度が低下する場合がある

Timer関数の精度はミリ秒単位ではなく、小数点以下数桁の秒数です。

そのため、極めて短い処理では正確な計測ができない場合があります。

短い処理を測定したい場合は、繰り返し実行して合計時間を測定し、1回あたりの平均時間を計算する方法が有効です。

注意3: 環境に依存する可能性

Timer関数はシステムクロックを基準に動作するため、OSやシステム設定によって動作に差が出ることがあります。

特に高精度が求められる場合は、APIを使用する方法(QueryPerformanceCounterなど)を検討してください。

注意4: 複数の計測を同時に行う際の注意

計測対象が複数の場合、開始時刻(StartTimer)と終了時刻(EndTimer)が競合しないように、モジュールやプロシージャを適切に分けるか、別々の変数を使用して管理する必要があります。

スポンサーリンク

この記事のまとめ|Timer関数と時間計測モジュールをマスターしよう!

この記事では、VBAのTimer関数を活用した時間計測モジュールについて、基礎から応用まで詳しく解説しました。

重要なポイントを以下に整理しましたので、復習にご活用ください。

ポイントのおさらい

さらに学ぶために

Timer関数と時間計測モジュールを活用することで、VBAスクリプトの効率化が可能です。

このスキルを基に、さらなる応用にも挑戦してみましょう!

あわせて読みたい
サイトマップ このページは、本サイトの記事を分かりやすくまとめました。ぜひご覧ください。 目次 「VBA」を見る 「Officeスクリプト」を見る 「ワークシート関数」を見る 「Python...
スポンサーリンク
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次