
ExcelVBAシステムは、お使いのWindowsPCのスペックにより処理スピードも変化します。
みなさん、こんにちは。セルネッツ竹本です。
今回は、「処理スピードを評価する時間の計測」をテーマに、2種類の実測方法を解説したいと思います。
結論から言うと、VBAで処理時間を計るには、開始と終了の時刻を取得して差を求めます。
処理全体の秒数ならTimer関数、ファイルOpenのような短い処理ならGetTickCountが向いています。
この記事では、次のことがわかります。
- Timer・GetTickCount・Nowの違いと使い分け
- ファイルOpenや処理全体の時間を計るコード
- ステータスバーに進捗と経過時間を出す方法
- ブックを開くのが遅いときに確認すること
遅いマクロの高速化
ブックを開くだけで待たされるマクロ、速くします
- PCによってマクロの処理時間が大きく違う
- 大量のブックを開く処理で毎回待たされる
- どの処理が遅いのか分からず手が出せない
そのお悩み、処理時間の計測と高速化で解決できます。Excel専門のシステム開発会社『セルネッツ』なら、処理ごとの実測で遅い箇所を特定し、メモリ上での一括処理などで改修します。お使いのPCで、どこまで速くできるかもお伝えします。
\Excel専門特化 × 低価格 × スピード対応/
全国対応・お見積もり無料
VBAで処理時間を計測する方法は3つ
VBAで時間を計る方法は、Timer関数・GetTickCount・Now関数の3つです。
計りたい処理の長さに合わせて選びます。
| 方法 | 取得できる値 | 細かさ | 向いている用途 | 注意点 |
| Timer関数 | 午前0時からの経過秒数 | Windowsは秒の小数部まで、Macは1秒 | 処理全体の時間 | 午前0時に0へ戻る |
| GetTickCount | PC起動からの経過ミリ秒 | 通常10〜16ミリ秒の刻み | ファイルOpenなど短い処理 | Declare宣言が必要 |
| Now関数 | 現在の日付と時刻 | 1秒 | 日をまたぐ長い処理 | 1秒未満は計れない |
(参考:Microsoft Learn「タイマー関数」「GetTickCount 関数」)
処理スピードを実測する理由
同じマクロでも、PCの性能やデータ量で処理時間は大きく変わるためです。
ExcelVBAシステムは、基本Excelアプリケーション上でしか動作しません。
また、プログラムの処理スピードは、皆さんが普段お使いのパソコンの性能(特にCPU)に依存します。
このため、同じ大量データでも、AさんとBさんは大きな差が生じることもあるのです。
その速度が妥当かどうかは、たとえば、重いサイズのExcelブックをOpenする処理でもわかります。
手で開いたら20秒かかる重いブックは、物理的に20秒を要する、ということです。
時間、処理スピードに対する意識は、システム開発をしているプログラマーであれば、いかに高速なプログラムにできるか、日々、切磋琢磨していることと思います。
今回は、はじめに、GetTickCount関数を使ってみます。ミリ秒単位で計測できます(実際の刻みは、通常10〜16ミリ秒程度です)。
GetTickCountでファイルOpenの時間をミリ秒で計る
ファイルOpenの直前と直後で時刻を取り、その差を求めます。
以下は、Call元です。
“開始”なのか、”終了”なのかをパラメータ指定し、それぞれ別の変数に格納し、その”差異”を求めるだけです。
'時間の計測 開く直前
Call M_時間計測("開始", P_TimeStart, P_TimeEnd)
'ここで開きます
Workbooks.Open filename:=P_FullPath
'時間の計測 開いた直後
Call M_時間計測("終了", P_TimeStart, P_TimeEnd)
GetTickCountはExcelの関数ではなく、Windowsの機能です。
使う前に、モジュールの先頭(宣言セクション)に次の1行を書きます。
この宣言がないと、「Sub または Function が定義されていません。」というエラーになります。
Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
以下がCallされます。
Public P_TimeStart As Variant
Public P_TimeEnd As Variant
'+++++++++++++++++++++++++++++++++++
Sub M_時間計測(S_status As String, P_TimeStart, P_TimeEnd)
'+++++++++++++++++++++++++++++++++++
If S_status = "開始" Then
'開始時間の取得
P_TimeStart = GetTickCount
ElseIf S_status = "終了" Then
'終了時間の取得
P_TimeEnd = (GetTickCount - P_TimeStart) / 1000
End If
End Sub
“終了”で呼び出すと、P_TimeEndに開くまでの秒数(小数つき)が入ります。
Debug.Print P_TimeEnd などで確認してください。
精度の高い計測ならこっちですが・・・。実用的なのは、次の計測が良いでしょう。
Timer関数で処理全体の秒数を計る
処理にかかった全体の時間なら、宣言のいらないTimer関数の秒単位の計測で十分です。
通常、プログラムでは、複数の処理が実行されるので、【処理にかかった時間】を取得するには、以下の記述で計測できます。
'[開始時刻]を、Public型の変数に格納 全Module共通のため
P_Time始 = Timer
'(いろんな処理・・・・)
'[終了時刻] - [開始時刻] = 実測(秒数)
MsgBox "---------------------------------" & vbCrLf & _
"■開いたファイル名:xxxxxx.xlsx" & vbCrLf & _
"--------------------------------" & vbCrLf & vbCrLf & _
"※処理時間: " & Int(Timer - P_Time始) & " 秒", , "完了"
Int関数は小数を切り捨てるため、1秒未満の処理は「0 秒」と表示されます。
小数第2位まで見たいときは、Format関数で表示します。
また、Timerは午前0時に0へ戻るので、日付をまたぐと差がマイナスになります。
夜間に動かすマクロでは、次のように補正しておくと安心です。
Dim sngStart As Single
Dim sngSec As Single
sngStart = Timer
'(計測したい処理)
sngSec = Timer - sngStart
If sngSec < 0 Then sngSec = sngSec + 86400 '午前0時をまたいだときの補正
Debug.Print "処理時間: " & Format(sngSec, "0.00") & " 秒"
ステータスバーに進捗と経過時間を表示する
大量のファイルを順に処理するときは、経過時間を画面に出すと待つ人の不安が減ります。
月の集計レポートを作成したり、シンプル機能の処理なら「数秒」というのが多いですが、大量ファイルを順次処理する場合は、1ファイルにかかる時間が見えてきます。
- 処理中のファイル名
- 処理中のファイル数 / 全体のファイル数
- 現在の経過時間
上記をステータスバーで表示することで、ユーザの不安はだいぶ軽減されるので、UserFormも習得すると利便性がさらにアップしますね。
ステータスバーは、Application.StatusBarに文字を入れるだけで表示できます。
次は、3つのファイルを順に処理する例です。
Sub M_進捗表示の例()
Dim vntFiles As Variant
Dim strName As String
Dim lngTotal As Long
Dim i As Long
Dim sngStart As Single
vntFiles = Array("C:\Data\A.xlsx", "C:\Data\B.xlsx", "C:\Data\C.xlsx")
lngTotal = UBound(vntFiles) - LBound(vntFiles) + 1
sngStart = Timer
For i = LBound(vntFiles) To UBound(vntFiles)
strName = Mid(vntFiles(i), InStrRev(vntFiles(i), "\") + 1)
Application.StatusBar = "処理中: " & strName & _
" (" & (i - LBound(vntFiles) + 1) & " / " & lngTotal & " 件)" & _
" 経過 " & Format(Timer - sngStart, "0") & " 秒"
DoEvents
'(ここで1ファイル分の処理)
Next i
Application.StatusBar = False '最後に元の表示へ戻す
End Sub
最後のApplication.StatusBar = Falseを忘れると、マクロが終わっても文字が残ります。
エラーで止まったときも戻せるよう、エラー処理の中にも書いておきます。
フォルダを選んで中のファイルを一括処理する方法は、「フォルダ選択で複数ファイルを一括処理する定番の方法」で解説しています。
(参考:Microsoft Learn「Application.StatusBar プロパティ」)
ブックを開くのが遅いときの確認ポイント
計測してOpenが遅いとわかったら、PCの性能を疑う前にブックと保存場所を確認します。
| 確認すること | 遅くなる理由 | 対策 |
| ファイルサイズ | 読み込むデータが多い | 使っていないシートや過去データを別ブックへ分ける |
| 外部リンク | 開くたびに参照先のブックを見に行く | マクロでは UpdateLinks:=0 で開く |
| 保存場所 | 共有フォルダやOneDriveは通信を待つ | PC内のフォルダと開く時間を比べてみる |
| スタイル・名前の定義 | コピーを重ねると不要な定義が大量にたまる | 不要なものを一括削除する |
| 再計算 | 数式が多いと開いたあとの計算に時間がかかる | 数式を減らす・値に置き換える |
マクロで別のブックを開いて読むだけなら、次のように書けます。
UpdateLinks:=0 はリンクを更新せずに開き、ReadOnly:=True は読み取り専用で開く指定です。
Dim wb As Workbook
Application.ScreenUpdating = False '画面の更新を止める
Set wb = Workbooks.Open(Filename:=P_FullPath, UpdateLinks:=0, ReadOnly:=True)
'(データを読む処理)
wb.Close SaveChanges:=False
Application.ScreenUpdating = True
不要なスタイルの削除は「大量のスタイルの残がいを一括削除する方法」、名前の定義は「不要な名前の定義を一括削除する方法」で紹介しています。
OneDrive上のブックをマクロで開くときは、「OneDrive上のパスがhttpに変わってしまう対策」もあわせてご覧ください。
(参考:Microsoft Learn「Workbooks.Open メソッド」)
処理時間を計測するときの注意点
1回の計測だけで判断せず、条件をそろえて何回か計ることが大切です。
- 同じブックでも、1回目より2回目のほうが速く開くことがあります。何回か計って平均を見ます。
- ほかのアプリやウイルス対策ソフトが動いていると、結果がぶれます。
- MsgBoxを計測の途中に入れると、ボタンを押すまでの時間も含まれます。表示は計測のあとにします。
- GetTickCountは、PCを49.7日続けて動かすと0に戻ります。まれに結果がおかしいときは、計り直します。
- MacのExcelでは、Timerは1秒刻みです。GetTickCountはWindowsの機能なので使えません。
計測して遅い処理が見つかったら、書き方を見直します。
書き方で速さが変わる例は、「マスターの存在チェックで速度にも影響する書き方」で紹介しています。
よくある質問
Q. 計測するたびに結果が変わるのはなぜですか?
PCがほかの処理も同時に行っているためです。
2回目以降はファイルの読み込みが速くなることもあります。
3〜5回ほど計って、平均や一番遅い値で評価してください。
Q. ミリ秒より細かく計測できますか?
GetTickCountの刻みは、通常10〜16ミリ秒です。
もっと細かく計るには、Windowsの高分解能タイマーを使う方法があります。
ただ、業務マクロの速さを評価するなら、TimerかGetTickCountで十分です。
Q. 処理時間を短くするには、どこから手を付ければよいですか?
まず処理ごとに時間を計り、一番遅い処理を見つけます。
そのうえで、画面の更新を止める、セルを1つずつではなくまとめて読み書きする、などを試します。
遅い処理を直さずにほかを速くしても、全体はあまり変わりません。
まとめ
- 処理時間は、開始と終了の時刻の差で求める
- 処理全体はTimer、ファイルOpenなど短い処理はGetTickCount(宣言が必要)
- Timerは午前0時に0へ戻るので、夜間の処理は補正する
- 大量のファイル処理は、ステータスバーに進捗と経過時間を出す
- Openが遅いときは、外部リンク・保存場所・不要な定義を確認する
今回のテーマは、「処理スピードを評価する時間の計測」について、解説を行いました。
本記事が、Excel実務の効率化において、お役に立てれば幸いです。
相見積もり歓迎
高速化の改修費用は時間単価で明確にします
- 基本料金50,000円+時間単価で見積もり
- 開発の時間単価は10,000円(税別)
- PCの性能が原因なら、そうお伝えします
改修は基本料金50,000円+時間単価(要件定義12,000円・設計11,000円・開発10,000円、税別)でお見積もりします。相見積もりも歓迎です。PCの性能やデータ量が原因で改修の効果が小さい場合は、正直にお伝えします。
\Excel専門特化 × 低価格 × スピード対応/
全国対応・お見積もり無料
Excel業務改善事例ショート動画
文章だけでは伝わりにくい改善事例を、ショート動画でご覧いただけます。
◆よくある質問 ◆Excel業務改善の実例 ◆VBA・マクロ活用事例
