WindowsAPI関数をクラスモジュールに封印するとメッチャ便利
WindowsAPIの関数をラップするクラスを作ったらメッチャ便利だった
タイトル通り。
そもそもは、
コチラの『VBA Developer's Handbook』で紹介されていたテクニックで、ちょっとやってみたら便利だったというだけの話。
ちなみに、コチラの書籍は、VBA四天王の一人、id:t-hom さんも
紹介しておられる。
WindowsAPIの関数をクラスに封印する
クラスモジュールを挿入して、テキトーな名前をつける。
私は「WindowsAPI
」という何のひねりもないそのままやんけなネーミングにしている。
WindowsAPIの関数をラップしたいだけ、すなわちプロパティやフィールドを持つ必要がないので、Attribute VB_PredeclaredId
の値をTrue
にしておく。
「Attribute VB_PredeclaredId
」については、
コチラをどうぞ。
たとえば
最近、IE操作関係でWindowsAPI関数を使うことが多いので、手始めにGetTickCount
とSleep
をクラスモジュールに封印してみる。
リスト1 クラスモジュール
オブジェクト名は「WindowsAPI
」、「Attribute VB_PredeclaredId
」の値はTrue
。
Option Explicit '(1)WindowsAPI関数の宣言' Private Declare Function GetTickCount Lib "kernel32" () As Long Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) '(2)GetTickCount関数呼び出しメソッド' Public Function callGetTickCount() As Long callGetTickCount = GetTickCount End Function '(3)Sleep関数呼び出しメソッド' Public Sub callSleep(ByVal milliSeconds As Long) Call Sleep(milliSeconds) End Sub '(4)GetTickCountとSleepを組み合わせた待機用メソッド' Public Sub waitFor(ByVal milliSeconds As Long) Dim startTime As Long startTime = GetTickCount Dim endTime As Long Do Sleep (1) DoEvents endTime = GetTickCount Loop Until endTime - startTime > milliSeconds End Sub
それぞれコード中の(1)~(4)に記した通り。
(1)の
Private Declare Function GetTickCount Lib "kernel32" () As Long Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
はおなじみのアレ。
ただし、いづれもPrivate
指定にして、直接外から呼び出すことができないようにクラス内に封印している。
そして、(2)、(3)は、GetTickCount
、Sleep
を呼び出すためのメソッド。
あと、(4)は、コメント通りGetTickCount
とSleep
を組み合わせて、引数で渡した時間だけ待機するメソッド。
単純にDo~While
でループさせるだけでなく、ループ中にSleep
をかましているところがミソ。
こんなふうに複数のWindowsAPIを組み合わせた処理を簡単に利用できるようにすることができる。
使ってみる
次のコードで実行してみる。
リスト2 標準モジュール
Public Sub disposableMacro01() Dim n As Long n = 1 Do Call WindowsAPI.waitFor(1000) '……(1)' Debug.Print "待機 " & n & " 回目" Debug.Print "ち~んw" n = n + 1 Loop Until n > 10 Call WindowsAPI.waitFor(2000) Debug.Print "おしまい" End Sub
上にも書いたように、WindowsAPI
クラスは、「Attribute VB_PredeclaredId
」の値をTrue
にしているので、インスタンス化せずに、(1)のように
Call WindowsAPI.waitFor(1000)
と書けばメソッドの利用ができる。
ここでは、GetTickCount
とSleep
を組み合わせた自作のwaitFor
メソッドを使っている。
Do
ループの中でこのメソッドを呼び出すことにより、1000
ミリ秒(メソッド内でSleep
を引数1
で実行しているので、正確には1001
ミリ秒+α)ごとにイミディエイト・ウインドウに、文字列を出力し、ループを抜けたところで再度しばらく時間をおいて文字列を出力することになる。
こんな感じ。
おわりに
めんどくさいWindowsAPI関数の利用が、非常に簡単になると思った。