VBA性能向上委員会

VBAプログラミングの実行速度に関して、より速い性能を求めて徹底検証をします。


HOME > VBA性能徹底検証 > 画面の更新を停止(初心者が陥りやすいミス)

画面の更新を停止(初心者が陥りやすいミス)

『画面の更新を停止すること』について、以前、検証をしましたが、

ここでは初心者が陥りやすいミスについて紹介します。


以前の記事はこちら。『画面の更新を停止するのは基本中の基本』

まずは、次にあります3つのプログラムで検証をしてみます。

ScreenUpdating検証サンプルソース

Sub Sample1()
Application.ScreenUpdating = False
MsgBox Application.ScreenUpdating    ' 画面の更新状態を表示
End Sub

Sub Sample2()
MsgBox Application.ScreenUpdating    ' 画面の更新状態を表示
End Sub

Sub Sample3()
Application.ScreenUpdating = False
Call Sample2    ' Sample2を実行
End Sub

Sample1は、画面の更新を停止した後に、画面の更新状態を表示するソースです。

Sample2は、プロシージャ開始直後の、画面の更新状態を表示するソースです。

Sample3は、画面の更新を停止した後に、他のプロシージャで画面の更新状態を表示するソースです。

それぞれのプロシージャでは、MsgBoxに何が表示されるでしょうか?(True or False)

結論から言うと、

 Sample1 : False

 Sample2 : True

 Sample3 : False

です。



サンプルソースの解説

ここで注目したい点は、Sample2Sample3で、結果が違う点です。

『Application.ScreenUpdating = False』をひとつ覚えしている初心者は、ここで意外な落とし穴にはまります。


どちらもSample2プロシージャで画面の更新状態を表示している点は同じですが、

Sample3では呼び出し前にすでにFalseに設定している点が違います。


つまりここで言いたいことは、他のプロシージャを呼び出す際、Application.ScreenUpdatingの値は引き継がれているということです。

それでは次の実行速度検証で、なぜ初心者が陥りやすいか検証します。


検証

次の2つのソースで検証をします。


1つ目は、呼び出し先のプロシージャでも画面の更新を停止するもの。

2つ目は、呼び出し先では停止させないものです。


ScreenUpdating検証サンプルソース1

Sub Test1()
Dim x As Long
Dim y As Long

Application.ScreenUpdating = False    ' 画面の更新を停止

For y = 1 To 99 Step 1
For x = 1 To 99 Step 1
Call SubPro1(x, y)
Next x
Next y
End Sub

Sub SubPro1(ByVal x As Long, ByVal y As Long)
Application.ScreenUpdating = False    ' 画面の更新を停止
ActiveSheet.Cells(y, x).Value = y * x
End Sub

ScreenUpdating検証サンプルソース2

Sub Test2()
Dim x As Long
Dim y As Long

Application.ScreenUpdating = False    ' 画面の更新を停止

For y = 1 To 99 Step 1
For x = 1 To 99 Step 1
Call SubPro2(x, y)
Next x
Next y
End Sub

Sub SubPro2(ByVal x As Long, ByVal y As Long)
ActiveSheet.Cells(y, x).Value = y * x
End Sub

この2つのサンプルソースの実行結果は次のとおりです。

回数Test1 秒数Test2 秒数
1回目1.7351.000
2回目1.6561.141
3回目1.7501.062
4回目1.7191.062
5回目1.7651.078
6回目1.7971.078
7回目1.7651.078
8回目1.6561.063
9回目1.8121.078
10回目1.6561.062
平均1.7311.070

※単位はすべて『秒』


約62パーセント性能向上しています。



解説

検証サンプルソース1は、まさに初心者にありがちなパターンです。


プロシージャの開始直後に『Application.ScreenUpdating = False』をしましょう。

処理が終わったら『Application.ScreenUpdating = True』を忘れずに。


といったような、お決まりごととして理解している入門サイト様を数多く見受けます。

そのお決まりごとを鵜呑みにした場合、約62パーセントの損をすることになりますので気を付けましょう。


さて、本題の解説ですが、これは完全に処理の冗長です。

サンプルソースでも解説したとおり、別のプロシージャを呼ぶ前に設定した値が引き継がれているため、何度も同じ処理が繰り返されている、ということになります。

ロジックの性能向上のためには、処理の助長をやめるのが一番の近道です。

もともと性能向上のために書いていた『Application.ScreenUpdating』ですが、これほどまでに差が出るのであれば、本当に性能改善をしたいのか疑問となります。

このパターンは意外と見落としがちですので、今一度ソースを確認するのをお勧めします。