記述による処理速度の違い
記述の違いで、どの程度処理速度に変化があるかを検証します。
1.変数の型指定
以下の2通りのプログラムで検証しました。
Sub Test11()
Dim i As Long, j As Long, k As Long
Dim v1,
v2
Debug.Print Now
For i = 1 To 1000
For j = 1 To
1000
For k = 1 To 1000
v1 = 1
v2 =
v1
Next
Next
Next
Debug.Print Now
End Sub
Sub Test12()
Dim i As Long, j As Long, k As Long
Dim v1 As
Long, v2 As Long
Debug.Print Now
For i = 1 To 1000
For
j = 1 To 1000
For k = 1 To 1000
v1 = 1
v2 =
v1
Next
Next
Next
Debug.Print Now
End
Sub
Test11とTest12の違いは太字の部分だけです。
つまり、
テストは変数に型指定するかしないかで、処理速度がどの程度変化するかの検証です。
Test12=7秒
つまり、
20億回ですよ。
地球シミュレーターじゃないのですから、そんな処理は普通はしないですよね。
つまり、
その場合でも差は、4秒/1000=0.004秒です。
少なくとも、体感として速度差を感じることは無いでしょう。
つまり、
変数における型指定は、処理速度の面ではあまり意味を持たないということです。
ではなぜ、
私の書くプログラムは、型指定を全て書くようにしているのでしょうか。
例えば、
Integerの変数なら行数はいれないですよね、値がオーバーしてしまいますから。
つまり、
読み手に対し、「この変数には行数は入れません」、と宣言しているのです。
Integerを宣言するというより、「小さい整数しか入れません」、と読み手に宣言しているのです。
Functionの戻り値の型では、単にObjectでは、どんなオブジェクトを返す関数か、
プログラムの内容を見ないと分かりません。
正確な型を指定することで、プログラムの内容を見なくても、
「あー、このFunctionはRangeを返す」と直ぐに理解できるようにしているのです。
もちろん、
コメントを書くことで伝える事はできますのでそれはそれで必要ですが、
その前に、まずはソースプログラムで伝えているのです。
ですから、
プログラムを他人に見せる事がないなら、それほど意味を持たない場合も出てきます。
2.罫線の引き方
以下の2通りのプログラムで検証しました。
Sub Test21() Dim i As Long, j As Long Application.ScreenUpdating = False Debug.Print Now For i = 1 To 10000 Range(Cells(i, 1), Cells(i, 100)).Select Selection.Borders(xlDiagonalDown).LineStyle = xlNone Selection.Borders(xlDiagonalUp).LineStyle = xlNone With Selection.Borders(xlEdgeLeft) .LineStyle = xlContinuous .ColorIndex = xlAutomatic .TintAndShade = 0 .Weight = xlThin End With With Selection.Borders(xlEdgeTop) .LineStyle = xlContinuous .ColorIndex = xlAutomatic .TintAndShade = 0 .Weight = xlThin End With With Selection.Borders(xlEdgeBottom) .LineStyle = xlContinuous .ColorIndex = xlAutomatic .TintAndShade = 0 .Weight = xlThin End With With Selection.Borders(xlEdgeRight) .LineStyle = xlContinuous .ColorIndex = xlAutomatic .TintAndShade = 0 .Weight = xlThin End With With Selection.Borders(xlInsideVertical) .LineStyle = xlContinuous .ColorIndex = xlAutomatic .TintAndShade = 0 .Weight = xlThin End With Selection.Borders(xlInsideHorizontal).LineStyle = xlNone Next Debug.Print Now Application.ScreenUpdating = True End Sub |
Sub Test22() Dim i As Long, j As Long Application.ScreenUpdating = True Debug.Print Now For i = 1 To 10000 Range(Cells(i, 1), Cells(i, 100)).Borders.LineStyle = xlContinuous Next Debug.Print Now Application.ScreenUpdating = False End Sub |
100列のセルの四辺に実線を引く、これを10000行繰り返す。
結果は、複数回の平均で、
Test22=1秒
もちろん、
これは罫線だけでなく、セルをSelectしている事も大きく関係しています。
初心者がマクロの自動記録で作ったマクロがいかに遅くなってしまうかの検証です。
3.行高の変更
以下の2通りのプログラムで検証しました。
Sub Test31()
Dim i As Long
Debug.Print Now
For i = 1 To
10000
Rows(i).RowHeight = 15
Next
Debug.Print Now
End
Sub
Sub Test32()
Dim i As Long
Debug.Print Now
For i = 1 To
10000
If Rows(i).RowHeight <> 15
Then
Rows(i).RowHeight = 15
End
If
Next
Debug.Print Now
End Sub
10000行の行高の変更です。
Test32=1回目:7秒、2回目1秒未満
IF文での判定がある分Test2が若干遅い場合も出てきます。
実際の行高は変化しないのに、Test1では常に同じ時間がかかっています。
この結果は、当然といえば当然です。
問題は、行高の変更の処理時間が結構かかるということです。
実際に高さが変わらないのなら、変更しないようにしたほうが良いということです。
Test31の2回目が極端に遅い(1回目の数倍かかる)という現象が確認されました。
その計測は、決して間違いではなかったのですが、改めて再計測したところ、
現時点(Windows10+Excel2019(64bit))では、2回目も同タイムでしか計測できませんでした。
そこで、
PCを変えて、Ecel2010の32bitと64bitで何度か計測したところ、
2回目の方が多くの時間がかかる現象自体は再現されました。
しかし、
常に2回目の方が時間がかかるという現象が発生するわけではなく、
発生する場合と、発生しない場合があるようです。
3台のPCで検証しているので、決して特定の環境のみで発生するものではないと思われます。
どのような状況で発生するかまで特定できませんでしたが、
Excel2010をお使いの場合は注意しておく必要があります。
上記のコードは、速度差を単純比較するために1行ずつ行高変更していますが、
もちろん変更する範囲を一括で行高変更するほうがはるかに速くなります。
4.配列を使用した処理
以下の2通りのプログラムで検証しました。
Sub Test41()
Dim i As Long, j As Long, k As Long
Dim v As
Variant
Application.ScreenUpdating = False
Debug.Print Now
For i = 1 To
100
For j = 1 To 100
For k = 1 To 100
Cells(j, k) =
1
Next
Next
Next
Debug.Print Now
For i = 1 To
100
For j = 1 To 100
For k = 1 To 100
v = Cells(j,
k)
Next
Next
Next
Debug.Print Now
Application.ScreenUpdating = True
End Sub
Sub Test42()
Dim i As Long, j As Long, k As Long
Dim v As
Variant
Dim ary As Variant
Application.ScreenUpdating = False
Debug.Print Now
ary =
Range(Cells(1, 1), Cells(100, 100))
For i = 1 To 100
For j = 1 To
100
For k = 1 To 100
ary(j, k) =
1
Next
Next
Range(Cells(1, 1), Cells(100, 100)) =
ary
Next
Debug.Print Now
For i = 1 To 100
For j = 1 To
100
For k = 1 To 100
v = ary(j,
k)
Next
Next
Next
Debug.Print Now
Application.ScreenUpdating = True
End
Sub
プログラムは全然違いますが、やっていることは同じです。
2.100行100列のセルから値を変数に取り出す、これを100回繰り返す。
Test42=3秒、1秒未満
これほどの時間差が付くのです。
しかし、
これとて、100万回のセルに対する読み書きなので、度々やることではないかもしれません。
ただし、
VBAにおいては、むやみにセルを参照するのは、なるべく控えた方が良い事も事実です。
そして、
処理速度が遅いマクロがあった場合の対処としては、
配列使用は極めて有効な対策となります。
処理速度を早くする為には
1.画面描画を停止、計算を手動
Application.ScreenUpdating = False '画面描画を停止
Application.Calculation = xlCalculationManual '計算を手動に
後は最初のうちはそんなに気にする必要が無いと思います。
今回は、難しい話では無かったので、参考にはなったと思います。
同じテーマ「マクロVBA技術解説」の記事
配列の使い方について
VBAの配列まとめ(静的配列、動的配列)
最終行の判定、Rangeオブジェクトと配列、高速化の為に
記述による処理速度の違い
速度比較決定版【Range,Cells,Do,For,ForEach】
エクセルVBAのパフォーマンス・処理速度に関するレポート
VBAのFindメソッドの使い方には注意が必要です
マクロVBAの高速化・速度対策の具体的手順と検証
動的2次元配列の次元を入れ替えてシートへ出力(Transpose)
大量データで処理時間がかかる関数の対処方法(SumIf)
大量データにおける処理方法の速度王決定戦
新着記事NEW ・・・新着記事一覧を見る
TRIMRANGE関数(セル範囲をトリム:端の空白セルを除外)|エクセル入門(2024-08-30)
正規表現関数(REGEXTEST,REGEXREPLACE,REGEXEXTRACT)|エクセル入門(2024-07-02)
エクセルが起動しない、Excelが立ち上がらない|エクセル雑感(2024-04-11)
ブール型(Boolean)のis変数・フラグについて|VBA技術解説(2024-04-05)
テキストの内容によって図形を削除する|VBA技術解説(2024-04-02)
ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.繰り返し処理(For Next)|VBA入門
3.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
4.変数宣言のDimとデータ型|VBA入門
5.RangeとCellsの使い方|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.セルのクリア(Clear,ClearContents)|VBA入門
8.メッセージボックス(MsgBox関数)|VBA入門
9.条件分岐(Select Case)|VBA入門
10.ブック・シートの選択(Select,Activate)|VBA入門
- ホーム
- マクロVBA応用編
- マクロVBA技術解説
- 記述による処理速度の違い
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。