\ お問い合わせはこちら! /

【最新版】Excel VBA高速化テクニック完全ガイド

  • このマクロ、もっと早くならない?
  • すごく処理が遅い気がする

このような方に向けて書きました。

Excel VBAの学習直後は「動くコード」を書くことに精一杯で、どうしてもパフォーマンスは度外視になってしまいます。

その流れで複雑なコードを書いてしまうと、とても遅いマクロができあがってしまうことも珍しくありません。

そこで本記事では、マクロの基本を学び終わった方に向けて高速化テクニックをお伝えします。

【最新版】Excel VBA高速化テクニック完全ガイド

ここでは、次の内容を解説します。

  • 無駄なSelectを削除する
  • セルの読み書きはまとめて行う
  • ワークシート関数を積極的に活用する
  • 値貼り付けはValue代入で済ませる
  • 同じオブジェクトは変数に入れる

それぞれ気をつけることで、高速化を図ることができるはずです。

無駄なSelectを削除する

マクロ記録をすると操作対象をわざわざ選択してから処理する書き方になりますが、これが処理速度ダウンの大きな原因です。

例えば、あるセルをコピーして別シートに貼り付けるだけでも、記録したままのコードは次のようになります。

VB
Range("A1").Select
Selection.Copy
Sheets("Sheet2").Select
Range("A1").Select
ActiveSheet.Paste

選択と画面切り替えを繰り返していますね。

内部的には、その度にExcelの描画処理が発生するので処理が遅くなります。

これを1行にまとめると次のとおり。

VB
Sheets("Sheet1").Range("A1").Copy Sheets("Sheet2").Range("A1")

これでかなり高速化することができます。

karo

無駄なSelectActivateは、徹底的に削りましょう!

セルの読み書きはまとめて行う

VBAで最も時間がかかる処理のひとつが「セルへのアクセス」です。

例えば次のようなものです。

VB
For i = 1 To 10000
    Cells(i, 2).Value = Cells(i, 1).Value * 2
Next i

上記のコードでは、10000回分セルにアクセスして値を入れています。

これでは相当遅くなってしまうので、配列を使って1度のアクセスで済むようにしましょう。

VB
Dim arr As Variant
arr = Range("A1:A10000").Value
For i = 1 To UBound(arr)
    arr(i, 1) = arr(i, 1) * 2
Next i
Range("B1").Resize(UBound(arr), 1).Value = arr

セルへのアクセスは2回になりました。

処理速度は比べ物にならないくらい、高速になるはずです。

karo

ループ処理を使う前に、配列が使えないか検討しましょう!

ワークシート関数を積極的に活用する

大量のデータを集計や検索する場合、ループを回すよりもExcelのワークシート関数を呼び出した方が圧倒的に速いです。

例えば10万行の合計は、次のようにも書けます。

VB
Dim total As Double
For i = 1 To 100000
    total = total + Cells(i, 1).Value
Next i

でも、そもそもExcelにはSUM関数があるので、それを使った方が早い。

VB
Dim total As Long
total = WorksheetFunction.Sum(Range("A1:A100000"))

コードが簡潔になりますし、何より処理も高速です。

値貼り付けはValue代入で済ませる

値貼り付けのPasteSpecial xlPasteValuesはとても遅いです。

VB
Cells(1, 2).Copy
Cells(1, 3).PasteSpecial xlPasteValues

次のように、で繋いで値を入力させた方が早いです。

VB
Cells(1, 3).Value = Cells(1, 2).Value

簡単な対策なので、すぐにでも実践できますね。

同じオブジェクトは変数に入れる

シートやブックを何度も参照する場合、その都度書くのではなく変数やWith構文でまとめましょう。

処理はわずかに速くなり、コードも読みやすくなります。

VB
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
    .Range("A1").Value = "A"
    .Range("B1").Value = "B"
    .Range("C1").Value = "C"
End With

速度面はそこまでではないですが、保守性が上がるのでぜひ導入してほしい書き方です。

おわりに

高速化の第一歩は「余計なことをしない」ことです。

現代のPCは高スペック化が進んでいますが、それでも書き方次第で処理時間が何十倍も変わることは珍しくありません。

コードを書き終えたら、まずは自分の処理が「無駄な動きをしていないか」を見直してみましょう。

この記事が気に入ったら
フォローしてね!

シェア・記事の保存はこちら!

この記事を書いた人

CFXLOGのアバター CFXLOG プログラマ

メイン言語はPython。本ブログでは、実務や普段の学習で学んだことをアウトプットしています。
基本情報技術者試験合格者。

コメント

コメントする

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)