カテゴリ: 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
Office Scripts
Office Scriptsで日付判定!Excel条件付き書式を自動化して期限管理をラクにする方法
New2
Office Scripts
Office Scripts普及の歴史とMicrosoftの方向性!Excel自動化が進化してきた流れをやさしく解説
New3
Excel VBA
Excel VBA関数を用途別に作成!計算・文字列処理の基本を初心者向けに解説
New4
Office Scripts
Office Scriptsで条件付き書式を自動化!数値変化に応じてExcelの書式を自動更新する方法
人気記事
No.1
Java&Spring記事人気No1
Excel VBA
Excelマクロのセキュリティ設定の基本!安全に実行するための信頼センター設定まとめ
No.2
Java&Spring記事人気No2
Office Scripts
Office Scriptsでできること・できないことを完全整理!Excel自動化の基本と限界をやさしく解説
No.3
Java&Spring記事人気No3
Excel VBA
目的別にモジュールを分割する方法!処理単位で整理して見やすくするテクニック
No.4
Java&Spring記事人気No4
Excel VBA
Excel VBAとOffice Scriptsの違いを比較!初心者でもわかる学ぶべきスキル
No.5
Java&Spring記事人気No5
Excel VBA
Excel VBA基本文法の総まとめ!初心者が必ず押さえるべき20の基礎ポイント完全ガイド
No.6
Java&Spring記事人気No6
Office Scripts
Office Scriptsで条件付き書式を自動化!Excel自動化初心者向けスクリプト操作の基本
No.7
Java&Spring記事人気No7
Excel VBA
Excel VBAの開発環境を最速で整える!VBEの開き方から基本操作まで完全ガイド
No.8
Java&Spring記事人気No8
Excel VBA
Excel VBAプロジェクト構成とモジュール管理を完全解説!初心者でも迷わない基本の考え方