今回はちょっと変わったクラスモジュールのテクニック案。
異端扱いされそうな気がするので、思いついた私自身、採用には慎重なのだけれど、アイデアとしては面白いと思ったので備忘録として公開してしまうことにした。
さて、過去にPropertyプロシージャを使った高速化テクニックというのをやった。
thom.hateblo.jp
今回も基本的にはApplication設定を変更するだけなのだが、クラスモジュールを使って更に怠慢にやろうという話。
作り方
クラスモジュールを挿入し、オブジェクト名を「OneTimeSpeedBooster」に変更する。
このクラスの名前付けは超重要!!
そもそも馴染みのない異端テクニックなので、何がしたいのか名前で示さないと訳が分からなくなる。
クラスに書くコードはこちら。
PrivateSub Class_Initialize()With Application .ScreenUpdating =False.Calculation = xlCalculationManual .EnableEvents =False.PrintCommunication =FalseEndWithEndSubPrivateSub Class_Terminate()With Application .ScreenUpdating =True.Calculation = xlCalculationAutomatic .EnableEvents =True.PrintCommunication =TrueEndWithEndSub
見ての通り、コンストラクタとデストラクタしかない。
コンストラクタで高速化設定を行い、デストラクタで標準設定にもどしている。
使い方
OneTimeSpeedBoosterを使う前に、まずは時間のかかるマクロを作ってみる。
計算が必要かつ、画面更新が発生するものが良い。
九九を100×100まで計算させつつ、セルの色をランダムで塗りつぶすようにしてみよう。
コードはこのとおり。
Sub hoge()Dim t AsDouble: t =TimerFor i =1To100For j =1To100With Sheet1.Cells(i, j).Value="="& i &"*"& j .Interior.Color = RandomColor EndWithNextNext Debug.PrintTimer- t EndSubFunction RandomColor() RandomColor =RGB( _Int(256*Rnd), _Int(256*Rnd), _Int(256*Rnd))EndFunction
完成!
タイムは、3.7秒。はやっ!
では、ズームで10%まで小さくして、画面に入る描画範囲を増やしてみよう。
タイムは、9秒。
ではこれがどれだけ早くなるか。
コードは次のとおり。
Sub hoge()Dim t AsDouble: t =TimerDim booster: Set booster =New OneTimeSpeedBooster For i =1To100For j =1To100With Sheet1.Cells(i, j).Value="="& i &"*"& j .Interior.Color = RandomColor EndWithNextNext Debug.PrintTimer- t EndSubFunction RandomColor() RandomColor =RGB( _Int(256*Rnd), _Int(256*Rnd), _Int(256*Rnd))EndFunction
タイムは、1.16秒!
9秒から1秒なので実に90%も高速化したことに、、、、なる、、のか。。
っ!計算に自信がない!!
で、肝心のコードだけれど、足したのは以下の1行のみ。
Dim booster: Set booster = New OneTimeSpeedBooster
名前付けが超重要と書いたのは、上手い名前を付けていても変数宣言してセットしたはいいけど何も使われていないアホなコードに見えるのに、まして下手な名前なんてつけたら。。ということ。
OneTimeSpeedBoosterのインスタンスが作られるとコンストラクタによって各種アプリケーション設定が変更され、プロシージャの終了とともにこのbooster変数は破棄されるので、デストラクタによってアプリケーション設定がもとに戻る仕組み。
あるいは、Withを使ってこの区間ブーストするみたいな表記もアリか。
Sub hoge()Dim t AsDouble: t =TimerWithNew OneTimeSpeedBooster For i =1To100For j =1To100With Sheet1.Cells(i, j).Value="="& i &"*"& j .Interior.Color = RandomColor EndWithNextNextEndWith Debug.PrintTimer- t EndSub
ま、今回は思考実験みたいなものなので、あまり真に受けないでほしい。
特にマジに批判するとかはナシで!!
良いと思った方は自己責任でどうぞ!