プロシージャを別プロシージャの引数にする?

 

 

プロシージャ名を引数にして別プロシージャに渡す???

Application.Runメソッド

プロシージャの実行時間を計測するFunctionを作りたいなーと思って調べてみたら、

Application.Runメソッド

というものを使えばよいと分かったので、やってみた。

GetTickCount関数

時間を計るためには、おなじみの「GetTickCount関数」を使えばよい。

詳しいことは、コチラのチョー有名なOffice TANAKAさんのサイトをどうぞ。

基本的には、

[宣言セクションここから]
Declare Function GetTickCount Lib "kernel32" () As Long 
[宣言セクションここまで]
Public Sub hogeHoge()
  Dim startTime As Long
  Dim endTime As Long
  startTime = GetTickCount
       ・
       ・
       ・
  [任意の処理]
       ・
       ・
       ・
  endTime = GetTickCount
  Debug.Print endTime - startTime
End Sub

みたいな形にする。

コチラによると、

GetTickCountはWindows起動時からの時間をミリ秒で返す関数です。

ということなので、処理開始前と処理終了後にGetTickCount関数を用いてそれぞれWindows起動時からの経過時間をミリ秒単位で取得して引き算している、ということだ。

これを、プロシージャ名を引数にするみたいなイメージでFunction化した。

プロシージャの実行時間を計測するFunction

リスト1 標準モジュール
'宣言セクションここから'
Private Declare Function GetTickCount Lib "kernel32" () As Long    '……(1)'
'宣言セクションここまで'
Public Function getElapsedTime(ByVal procedureName As String) As Double    '……(2)'
  Dim startTime As Long
  Dim endTime As Long
  startTime = GetTickCount    '……(3)'
  Application.run procedureName    '……(4)'
  endTime = GetTickCount    '……(5)'
  getElapsedTime = (endTime - startTime) / 1000    '……(6)'
End Function

まず、モジュールの宣言セクションで、(1)

Private Declare Function GetTickCount Lib "kernel32" () As Long

このように宣言しておく。これでGetTickCount関数が使えるようになる。

(2)の

Public Function getElapsedTime(ByVal procedureName As String) As Double

では、引数と返り値を設定。

引数procedureNameでは、実行したいプロシージャ名を文字列で指定。返り値は、秒単位にするためにDouble型にした。

(3)の

startTime = GetTickCount

では、GetTickCount関数を用いて、処理開始前時点でのWindows起動時からの経過時間を取得。

(4)の

Application.run procedureName

では、Application.Runメソッドを用いて、引数procedureNameで渡されたプロシージャを実行する。

(5)の

endTime = GetTickCount

では、再びGetTickCount関数を用いて、処理終了後時点でのWindows起動時からの経過時間を取得。

あとは、(6)の

getElapsedTime = (endTime - startTime) / 1000

で処理にかかった時間(ミリ秒単位)を1000で割ったもの(秒単位)をreturnしておしまい。

使用実験

akashi-keirin.hatenablog.com

このときのリスト2のtestApplyFontTypeを呼び出して、時間を計ってみる。

スト2 標準モジュール
Public Sub testGetElapsedTime()
  Dim tmp As Double
  tmp = getElapsedTime("testApplyFontType")
  Debug.Print tmp & "秒"
End Sub

f:id:akashi_keirin:20180127102527j:plain

こんなふうに文字列を選択して、実行。

f:id:akashi_keirin:20180127102535j:plain

f:id:akashi_keirin:20180127102544j:plain

この通り、イミディエイトに経過時間が表示された。

おわりに

これで手軽に処理時間を把握できるなあ。

@akashi_keirin on Twitter