カテゴリ: Excel VBA 更新日: 2026/02/09

Excel VBAでループが遅い原因と高速化のコツ!DoEventsやWith構文を解説

Excel VBAでループが遅い原因と高速化のコツ(DoEvents・With構文など)
Excel VBAでループが遅い原因と高速化のコツ(DoEvents・With構文など)

先生と生徒の会話形式で理解しよう

生徒

「先生、大量のデータをループ処理で書き換えるマクロを作ったのですが、動かしている間Excelが固まってしまって、すごく時間がかかるんです…。」

先生

「それは『VBAあるある』ですね。実は、書き方を少し工夫するだけで、処理速度を何十倍も速くすることができるんですよ。」

生徒

「何十倍もですか!?パソコンが壊れかけているのかと思っていました。」

先生

「大丈夫、壊れていませんよ。Excelが一生懸命描画しようとするのを止めたり、無駄な動きを減らしたりするテクニックを教えますね!」

1. なぜVBAのループ処理は遅くなるのか?

1. なぜVBAのループ処理は遅くなるのか?
1. なぜVBAのループ処理は遅くなるのか?

Excel VBA(エクセル・ブイビーエー)で繰り返し処理(ループ)を行う際、初心者の方が書いたコードが遅くなる最大の原因は、「Excelの画面描画」と「無駄なアクセス」にあります。

プログラムが1行書き換えるたびに、Excelは「画面を新しく書き直さなきゃ!」と頑張ってしまいます。人間には見えないほど一瞬の動作ですが、これが数千回、数万回と重なると、パソコンに大きな負担がかかり、結果としてマクロが遅くなってしまうのです。

また、セルの情報を読み書きするために何度もエクセルのシートにアクセスすることも時間がかかる原因です。これを解決するための「高速化のコツ」を順番に見ていきましょう。

2. 劇的に速くなる!画面更新の停止(ScreenUpdating)

2. 劇的に速くなる!画面更新の停止(ScreenUpdating)
2. 劇的に速くなる!画面更新の停止(ScreenUpdating)

最も効果が高く、かつ簡単な方法が「画面更新の停止」です。マクロが動いている間、Excelが画面を書き換えるのを一時的に禁止します。

例えるなら、部屋の模様替えをするときに、家具を一つ動かすたびに「どうかな?」と確認するのではなく、全部動かし終わるまでカーテンを閉めておき、最後にパッと開けるようなイメージです。


Sub FastLoopExample()
    ' 画面更新を停止して高速化!
    Application.ScreenUpdating = False
    
    Dim i As Long
    For i = 1 To 5000
        Cells(i, 1).Value = "テスト中"
    Next i
    
    ' 最後に必ず元の状態(True)に戻す
    Application.ScreenUpdating = True
    MsgBox "処理が完了しました。"
End Sub

この Application.ScreenUpdating = False をコードの最初に入れるだけで、体感速度が数倍から数十倍に跳ね上がります。マクロ作成の必須テクニックです。

3. 無駄な再計算を止める(Calculation)

3. 無駄な再計算を止める(Calculation)
3. 無駄な再計算を止める(Calculation)

エクセルのシートにたくさんの数式が入っている場合、VBAで一つのセルを書き換えるたびに、すべての数式が「再計算」されます。これもループが遅い大きな原因です。これを「手動計算」に切り替えることで高速化できます。


Sub StopCalculation()
    ' 計算方法を手動(Manual)に切り替え
    Application.Calculation = xlCalculationManual
    
    Dim i As Long
    For i = 1 To 1000
        Cells(i, 2).Value = i * 1.1
    Next i
    
    ' 最後に自動計算に戻して、最新の状態にする
    Application.Calculation = xlCalculationAutomatic
End Sub

これを忘れると、計算結果が古いままになってしまうので、必ず最後に xlCalculationAutomatic に戻しましょう。

4. With構文で「無駄な名前呼び」を省略する

4. With構文で「無駄な名前呼び」を省略する
4. With構文で「無駄な名前呼び」を省略する

With(ウィズ)構文を使うと、コードがスッキリするだけでなく、処理もわずかに速くなります。同じ対象(例えば特定のシートやセル)に対して何度も命令を送るとき、その名前を何度も呼ぶ必要がなくなるからです。

例えば、「Sheet1のセルに色を塗って、文字を太くして、値を書き込む」という場合、毎回 Sheets("Sheet1") と書くのは、パソコンにとっても「そのシートはどこだっけ?」と探す手間になります。


Sub WithExample()
    ' Sheet1に対してまとめて命令を出す
    With Sheets("Sheet1").Range("A1")
        .Value = "完了"
        .Font.Bold = True
        .Interior.Color = vbYellow
    End With
End Sub

ドット(.)から始まる命令が、With の後ろに書いた対象にかかります。読みやすさも向上するので積極的に使いましょう。

5. 固まるのを防ぐ「DoEvents」の正しい使い方

5. 固まるのを防ぐ「DoEvents」の正しい使い方
5. 固まるのを防ぐ「DoEvents」の正しい使い方

長時間かかるループを回していると、パソコンが「応答なし」と表示されて固まってしまうことがあります。このとき、パソコンに「ちょっとだけ休憩して、他の作業(マウス操作など)を受け付けていいよ」と許可を与えるのが DoEvents(ドゥ・イベンツ) です。

※注意:DoEventsを入れると処理速度自体は少し遅くなります。しかし、「今どれくらい進んでいるか」を確認したり、途中で停止させたりするために役立ちます。


Sub DoEventsExample()
    Dim i As Long
    For i = 1 To 10000
        Cells(i, 3).Value = "データ入力中"
        
        ' 500回に1回、OSに制御を戻す(固まるのを防ぐ)
        If i Mod 500 = 0 Then
            DoEvents
        End If
    Next i
End Sub

毎回 DoEvents を呼び出すと遅くなりすぎるため、上記のサンプルのように「500回に1回」など、間隔を空けて実行するのがプロのコツです。

6. オブジェクト変数を使ってアクセスを速める

6. オブジェクト変数を使ってアクセスを速める
6. オブジェクト変数を使ってアクセスを速める

何度も同じシートや範囲(レンジ)を指定する場合、その対象を変数に入れておく「オブジェクト変数」の活用も効果的です。特に、別のブックやシートを横断して処理する際に威力を発揮します。


Sub ObjectVariableSpeed()
    ' シートという「物」を変数にセットする
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("Sheet1")
    
    Dim i As Long
    ' 毎回長い名前を書かなくて済むので速い!
    For i = 1 To 1000
        ws.Cells(i, 4).Value = i
    Next i
End Sub

パソコンの内部では、「どのシートか探す」という工程が1回で済むようになるため、非常に効率的になります。

7. セルに直接アクセスする回数を減らす考え方

7. セルに直接アクセスする回数を減らす考え方
7. セルに直接アクセスする回数を減らす考え方

究極の高速化は、「セルを1回ずつ触らない」ことです。例えば、1万個のセルに値を書き込むとき、1万回 Cells(i, 1).Value = ... と命令するよりも、いったん「配列(はいれつ)」というパソコンのメモリ上のリストにデータを溜め込み、最後に一気にシートへ貼り付ける方が圧倒的に速いです。

これは少し応用的な内容になりますが、「ループの中でシートをいじるのは最小限にする」という意識を持つだけで、マクロの設計が大きく変わります。まずは画面更新の停止から始め、慣れてきたらデータの扱い方を工夫してみましょう。

8. 高速化コードを書く際のテンプレート

8. 高速化コードを書く際のテンプレート
8. 高速化コードを書く際のテンプレート

これまでに紹介した高速化テクニックを組み合わせた、最も一般的で使いやすい「マクロの型」を紹介します。新しいマクロを作るときは、この形をベースにすると失敗が少なくなります。


Sub SpeedTemplate()
    ' --- 1. 高速化の開始設定 ---
    With Application
        .ScreenUpdating = False          ' 画面更新停止
        .Calculation = xlCalculationManual ' 手動計算
        .EnableEvents = False           ' イベント停止(応用)
    End With

    ' --- 2. メインのループ処理 ---
    ' ここにあなたのループコードを書く

    ' --- 3. 設定を必ず元に戻す ---
    With Application
        .ScreenUpdating = True
        .Calculation = xlCalculationAutomatic
        .EnableEvents = True
    End With
    
    MsgBox "すべての処理が終わりました!"
End Sub

このように、最初に止めて、最後に必ず戻すという流れをセットにすることで、安全で爆速なExcel VBAプログラムを作成することができます。これだけで、あなたの業務効率は劇的に向上するはずです!

カテゴリの一覧へ
新着記事
New1
Excel VBA
Excel VBAで業務自動化!初心者でもわかる定型作業の自動化例
New2
Excel VBA
VBAの基本構造を理解しよう!モジュール・プロシージャ・関数の役割まとめ
New3
Office Scripts
Office Scriptsで大量シートを効率管理!Excelワークブック最適構造と自動化テクニック
New4
Excel VBA
Excel VBAが今でも使われ続ける理由とは?現場で評価されるポイントを徹底解説
人気記事
No.1
Java&Spring記事人気No1
Office Scripts
Office Scriptsで別ブックを開いてデータ取得する方法|OneDrive・SharePoint連携でExcel自動化
No.2
Java&Spring記事人気No2
Excel VBA
Excel VBA参照設定エラー「参照が見つかりません」を完全解説!初心者でも原因と対処法がわかる
No.3
Java&Spring記事人気No3
Excel VBA
Excel VBAモジュール共有術!複数のブックでマクロを使い回す最適構成
No.4
Java&Spring記事人気No4
Excel VBA
Excel VBAの開発環境を最速で整える!VBEの開き方から基本操作まで完全ガイド
No.5
Java&Spring記事人気No5
Excel VBA
Excel VBAは今後なくなる?将来性と企業での活用状況を詳しく解説
No.6
Java&Spring記事人気No6
Excel VBA
VBAのコメントの書き方を完全ガイド!初心者でもわかる説明文の付け方
No.7
Java&Spring記事人気No7
Excel VBA
Excel VBAで列の追加・行の削除を自動化!InsertとDeleteの使い方を初心者向けに徹底解説
No.8
Java&Spring記事人気No8
Excel VBA
個人用マクロブック(PERSONAL.XLSB)で作る最強の共通ライブラリ化ガイド