Selectメソッドを使わない方が速い
RangeプロパティやCellsプロパティでセルを参照する際に、そのセルをSelectメソッドで選択することがあります。
選択しておいて、ActiveCellオブジェクトに対する各種メソッドやプロパティでの処理を行う場合などですね。
しかし、Selectをせずとも対象セルのメソッドやプロパティは利用可能です。
また、Selectをするのとしないのとではかなりの処理速度の差があります。
不要であればSelectは使わない
結論から言うと、Selectを使わない方が処理速度が速くなります。
それも、劇的に速くなります。
例えば、セルの値を参照するためにValueプロパティを使うことはよくある処理ですが、その際にセル選択のSelectをせずに直接Valueプロパティを利用すると処理速度が速くなります。
他の処理速度方法ではコードが長くなったり、可読性が落ちるなどの弊害も出てくることがあるのですが、この改善方法はコード量も減りますし、可読性も低下しません。
テストコードで検証
以下のソースで実測してみました。
10000回セルの参照を行うテストです。
1つはSelectを行ってValueを取得するパターンで、もう1つはSelectを行わずにValueを取得するパターンです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
Sub RangeCellsOffsetCellSelectTest() Dim tmStart As Double Dim tmEnd As Double Dim tmDiff As Double Dim i As Long Dim s '// 処理前の時間を取得 tmStart = Timer '// 計測対象の処理 For i = 1 To 10000 Cells(i, 1).Select s = ActiveCell.Value Next '// 処理後の時間を取得 tmEnd = Timer tmDiff = tmEnd - tmStart Debug.Print "Selectあり:" & tmDiff & "秒" '// 処理前の時間を取得 tmStart = Timer '// 計測対象の処理 For i = 1 To 10000 s = Cells(i, 1).Value Next '// 処理後の時間を取得 tmEnd = Timer '// 処理前後の差を取得 tmDiff = tmEnd - tmStart Debug.Print "Selectなし:" & tmDiff & "秒" End Sub |
検証結果
上記のテストコードの実行結果は以下の通りです。
Selectあり:3.8466796875秒
Selectなし:0.0380859375秒
数値上はSelectの有無で100倍以上の差があることが分かりますが、100倍というよりも、直接Valueで指定すると即時処理が終わっている、と見た方がいいでしょうね。
Selectすると遅い理由
Selectすることで遅くなる理由は、画面描画やイベント処理に時間が掛かっていることと、ActiveCellオブジェクトなどの選択セルの状態の書き換えに時間が掛かることが原因と思われます。
以下は画面描画などのApplication.ScreenUpdatingなどを無効にした場合のテストコードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
Sub RangeCellsOffsetCellSelectTestB() Dim tmStart As Double Dim tmEnd As Double Dim tmDiff As Double Dim i As Long Dim s With Application .ScreenUpdating = False .Calculation = xlCalculationManual .EnableEvents = False .PrintCommunication = False End With '// 処理前の時間を取得 tmStart = Timer '// 計測対象の処理 For i = 1 To 10000 Cells(i, 1).Select s = ActiveCell.Value Next '// 処理後の時間を取得 tmEnd = Timer tmDiff = tmEnd - tmStart Debug.Print "Selectあり:" & tmDiff & "秒" '// 処理前の時間を取得 tmStart = Timer '// 計測対象の処理 For i = 1 To 10000 s = Cells(i, 1).Value Next '// 処理後の時間を取得 tmEnd = Timer '// 処理前後の差を取得 tmDiff = tmEnd - tmStart Debug.Print "Selectなし:" & tmDiff & "秒" With Application .ScreenUpdating = True .Calculation = xlCalculationAutomatic .EnableEvents = True .PrintCommunication = True End With End Sub |
実行結果
Selectあり:0.236328125秒
Selectなし:0.041015625秒
確かにApplicationのプロパティを無効にすると速くはなりますが、それでもActiveCellの書き換えを行う分、Selectしている方が遅いです。でもまあここまでくればOKでしょうけどね。