【VBA】画面更新・再計算を止めてマクロを高速化する方法(コピペOK)

VBA
スポンサーリンク
スポンサーリンク

完成イメージ(Before / After)

Before(高速化設定なし)


マクロ実行
→ 画面がチラチラ更新される(処理のたびにセルが書き換わるのが見える)
→ 数式が毎回再計算される
→ 1000行の処理に約5秒

After(高速化設定あり)


マクロ実行
→ 画面は一切更新されない(処理中は静止したまま)
→ 数式の再計算も停止
→ 1000行の処理が約1秒で完了
→ 処理後に画面が一括で更新され、最終結果が表示される

実務版の動作イメージ


マクロ実行
→ 高速化設定を一括ON(画面更新停止・再計算停止・イベント停止)
→ メインの処理を実行
→ 高速化設定を一括OFF(画面更新再開・再計算再開・イベント再開)
→ 「完了(1.23秒)」とメッセージ表示
※ エラーが発生しても設定は自動で元に戻る

実行前の準備

バックアップを取る

高速化設定自体はデータを破壊する操作ではありませんが、処理中に画面が更新されないため、途中経過が見えません。意図しない結果が出た場合に備えて、重要なブックは先にバックアップを取ってください。

Excelをマクロ有効ブック(.xlsm)で保存する

  1. Excelを開く(新規でも既存でもOK)
  2. 「ファイル」→「名前を付けて保存」
  3. ファイルの種類を 「Excel マクロ有効ブック (*.xlsm)」 に変更して保存

.xlsx のままだとマクロが保存されない。必ず .xlsm にすること。


手順(コピペ → 実行まで約5分)

VBE(コードを書く画面)を開く

Alt + F11 キーを押すとVBE(Visual Basic Editor)が開く。

一般的にはAlt + F11で開けるが、企業のセキュリティ設定でVBAが無効化されている場合は、IT部門に確認すること。

標準モジュールを挿入する

  1. VBEのメニュー「挿入」→「標準モジュール」をクリック
  2. 右側に白い画面(コードウィンドウ)が表示される

コードを貼り付けて実行する

  1. 下の「コード(最小版)」をコピーして、コードウィンドウに貼り付ける
  2. Alt + F8 を押す(または VBE上で F5
  3. マクロ名を選択して「実行」

コード(最小版)— ScreenUpdating=Falseで画面更新を止める

まずはこれだけで動く。Application.ScreenUpdating = False を1行追加するだけで画面の再描画が止まり、処理速度が改善される。


Sub SpeedTest_ScreenUpdating()

    Dim ws As Worksheet
    Dim i As Long
    Dim startTime As Double

    Set ws = ActiveSheet

    ' === テスト1:高速化設定なし ===
    startTime = Timer

    For i = 1 To 1000
        ws.Cells(i, 1).Value = "テストデータ " & i
    Next i

    MsgBox "高速化なし:" & Format(Timer - startTime, "0.00") & " 秒"

    ' セルをクリア
    ws.Range("A1:A1000").ClearContents

    ' === テスト2:ScreenUpdating=False ===
    startTime = Timer
    Application.ScreenUpdating = False

    For i = 1 To 1000
        ws.Cells(i, 1).Value = "テストデータ " & i
    Next i

    Application.ScreenUpdating = True
    MsgBox "高速化あり:" & Format(Timer - startTime, "0.00") & " 秒"

End Sub

ポイント:

  • Application.ScreenUpdating = False — 画面の再描画を停止する。処理中にセルが書き換わるのが見えなくなる
  • Application.ScreenUpdating = True — 処理後に画面の再描画を再開する。必ず True に戻すこと
  • Timer関数で処理前後の時刻差を計算し、処理時間を表示している
  • 1000行程度でも体感で2〜3倍速くなることがある。データが多いほど効果は大きい

注意:この最小版にはエラー復帰処理(On Error GoTo)が含まれていない。 エラーが発生すると ScreenUpdating=False のまま止まり、画面が真っ白になる可能性がある。本番環境では、次の「実務版」を必ず使うこと。エラー処理の基本は[記事022(エラー処理で止まらないマクロを作る方法)]を参照。


コード(実務版)— 4設定一括ON/OFF+処理時間計測テンプレート

実務で使う高速化テンプレート。4つのApplication設定を一括でON/OFFするサブプロシージャ(SpeedOn / SpeedOff)と、エラー時の自動復帰処理を備えている。


' ============================================================
' 高速化テンプレート(実務版)
' - 4つのApplication設定を一括ON/OFF
' - エラー時も設定が確実に戻る
' - 処理時間を計測して表示
' ============================================================

Sub MainProcess()

    Dim ws As Worksheet
    Dim i As Long
    Dim lastRow As Long
    Dim startTime As Double

    Set ws = ActiveSheet
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

    ' データ存在チェック
    If lastRow < 2 Then
        MsgBox "データがありません(2行目以降にデータを入力してください)。", vbExclamation
        Exit Sub
    End If

    startTime = Timer

    ' --- 高速化ON ---
    Call SpeedOn

    On Error GoTo ErrorHandler

    ' ★★★ ここにメイン処理を書く ★★★
    ' 例1:セルの値を加工する
    ' 例2:複数シートをループして集計する(記事015参照)
    ' 例3:複数ファイルを統合する(記事005参照)
    ' (以下はサンプル:A列の値をもとにB列に結果を書き込む)
    For i = 2 To lastRow
        ws.Cells(i, 2).Value = ws.Cells(i, 1).Value & "(処理済)"
    Next i

CleanUp:
    ' --- 高速化OFF(エラー時もここに来る) ---
    Call SpeedOff

    MsgBox "完了(" & Format(Timer - startTime, "0.00") & " 秒)", vbInformation
    Exit Sub

ErrorHandler:
    MsgBox "エラーが発生しました:" & vbCrLf & _
           "エラー番号:" & Err.Number & vbCrLf & _
           "内容:" & Err.Description, vbCritical
    Resume CleanUp

End Sub


' === 高速化ON:4設定を一括で無効化 ===
Sub SpeedOn()
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    Application.EnableEvents = False
    ' シート削除・上書き保存を自動化する場合に有効。不要ならこの行を削除してもよい
    Application.DisplayAlerts = False
End Sub


' === 高速化OFF:4設定を一括で元に戻す ===
Sub SpeedOff()
    Application.DisplayAlerts = True
    Application.EnableEvents = True
    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True
End Sub

コードの読み方

意味
Call SpeedOn 4つの高速化設定を一括でONにする
On Error GoTo ErrorHandler エラー発生時にErrorHandlerラベルへジャンプ
For i = 2 To lastRow 2行目からデータの最終行までループ
CleanUp: 正常終了時もエラー時もここに来る
Call SpeedOff 4つの高速化設定を一括でOFFに戻す
Resume CleanUp ErrorHandlerからCleanUpラベルへ移動して設定を復帰

各設定の意味

設定 効果 戻し忘れるとどうなるか
ScreenUpdating = False 画面の再描画を停止。チラつきがなくなる 画面が真っ白のまま何も表示されない
Calculation = xlCalculationManual 数式の自動再計算を停止 数式が更新されなくなる(手動で再計算が必要)
EnableEvents = False イベントプロシージャの発火を停止 Worksheet_Changeなどのイベントが動かなくなる
DisplayAlerts = False 確認ダイアログを非表示にする 「保存しますか?」などの確認が出なくなる

ポイント:

  • SpeedOn / SpeedOff をサブプロシージャにしているので、どのマクロからでも Call SpeedOn / Call SpeedOff で呼び出せる
  • On Error GoTo ErrorHandler → Resume CleanUp の流れで、エラーが発生しても設定が必ず元に戻る。これが最も重要な安全対策
  • ★★★ ここにメイン処理を書く ★★★ の部分を自分の処理に書き換えるだけで使える
  • 処理時間はTimer関数で計測。結果がMsgBoxで「完了(1.23秒)」のように表示される

SpeedOnの中身を個別にカスタマイズしたい場合は、不要な設定をコメントアウト(先頭に ' を付ける)すればよい。たとえばDisplayAlertsだけ残したい場合は、SpeedOnの Application.DisplayAlerts = False の行を 'Application.DisplayAlerts = False にする。

大量データ(1万行以上)を扱う場合は、セルへの直接アクセスを減らす「配列」テクニックと組み合わせるとさらに高速化できる。配列の使い方は[記事036(配列を使ってVBAの処理速度を10倍にする方法)]を参照。


4つの高速化設定の解説

VBAの高速化テクニックは大きく2種類ある。

  1. Excelの裏側の処理を止める(本記事)— 画面更新・再計算・イベントなど、マクロ実行中の「余計な処理」を一時停止する
  2. セルアクセスそのものを減らす([記事036(配列を使ってVBAの処理速度を10倍にする方法)])— 配列を使ってセルへのアクセス回数を激減させる

本記事は1のテクニックを深掘りする。2と組み合わせれば最大の効果が得られる。

1. Application.ScreenUpdating(画面更新の停止)

最も基本的な高速化設定。セルに値を書き込むたびにExcelは画面を再描画するが、これを止めることで描画コストを削減する。


Application.ScreenUpdating = False  ' 停止
' (処理)
Application.ScreenUpdating = True   ' 再開
  • 効果: 約2〜3倍の高速化(環境やデータ量による)
  • おすすめ場面: すべてのマクロに入れてよい。デメリットはほぼない
  • 注意: 処理中に画面が更新されないため、進捗が見えない。長時間処理ではステータスバーで進捗を表示する方法がある([記事026(処理の進捗をステータスバーに表示する方法)]を参照)

2. Application.Calculation(再計算の停止)

セルに値を書き込むたびに、シート内のすべての数式が再計算される。数式が多いブックでは、この再計算が処理時間の大部分を占めることがある。


Application.Calculation = xlCalculationManual     ' 停止
' (処理)
Application.Calculation = xlCalculationAutomatic   ' 再開(再開時に全数式が一括再計算される)
  • 効果: 数式が多いブックでは劇的(数十倍になることも)。数式がないブックでは効果なし
  • おすすめ場面: VLOOKUP、SUMIFS、INDEX/MATCHなどの数式が多いブック
  • 注意: 戻し忘れると数式が一切更新されなくなる。手動復帰は「数式」タブ→「計算方法の設定」→「自動」。また、再開時(xlCalculationAutomatic に戻したとき)に全数式が一括再計算されるため、数式が非常に多いブックでは再計算に数秒かかることがある

3. Application.EnableEvents(イベント抑止)

Worksheet_ChangeやWorkbook_Openなどのイベントプロシージャが設定されている場合、セルに値を書き込むたびにイベントが発火する。これを止めることで、余計な処理の連鎖を防ぐ。


Application.EnableEvents = False  ' 停止
' (処理)
Application.EnableEvents = True   ' 再開
  • 効果: イベントプロシージャがある場合に有効。ない場合は効果なし
  • おすすめ場面: Worksheet_Change等でセルの変更を監視しているブック
  • 注意: 戻し忘れるとすべてのイベントが動かなくなる。手動復帰はイミディエイトウィンドウで Application.EnableEvents = True

4. Application.DisplayAlerts(警告抑止)

「このシートを削除しますか?」「保存しますか?」などの確認ダイアログを非表示にする。ダイアログが表示されるとマクロが一時停止するため、自動処理の流れが中断される。


Application.DisplayAlerts = False  ' 停止
' (処理)
Application.DisplayAlerts = True   ' 再開
  • 効果: ダイアログ待ちの時間がなくなる。高速化よりも「自動化」の意味合いが強い
  • おすすめ場面: シートの削除やブックの上書き保存を自動化する場合
  • 注意: 確認なしで処理が進むため、意図しない削除や上書きのリスクがある。複数シートの一括操作([記事015(複数シートを一括処理する方法)])やファイル統合([記事005(複数Excelファイルを1つに統合)])で使うことが多い

よくある落とし穴5選

# 症状 原因 対策
1 エラーで止まり画面が真っ白になった ScreenUpdating=Falseのまま処理が中断した On Error GoTo でCleanUpラベルを設け、必ず True に戻す。手動復帰はVBEのイミディエイトウィンドウで Application.ScreenUpdating = True を実行
2 マクロ実行後、数式が更新されなくなった Calculation=xlCalculationManualのまま終了した On Error GoTo で必ず xlCalculationAutomatic に戻す。手動復帰は「数式」タブ→「計算方法の設定」→「自動」
3 Worksheet_Changeなどのイベントが動かなくなった EnableEvents=Falseのまま終了した On Error GoTo で必ず True に戻す。手動復帰はイミディエイトウィンドウで Application.EnableEvents = True
4 ScreenUpdating=Falseにしても速くならない 処理のボトルネックが画面更新ではなくセルアクセスにある セルに1つずつアクセスしている場合は、配列による一括読み書きが効果的。[記事036(配列を使ってVBAの処理速度を10倍にする方法)]を参照
5 SpeedOn/SpeedOffを入れ子で呼んだら設定がおかしくなった 内側のSpeedOffでTrueに戻してしまい、外側の処理中に設定が解除された 入れ子にしない。高速化設定のON/OFFは呼び出し元の最上位プロシージャでのみ行う。 内側のプロシージャでは呼ばない

FAQ

Q1: ScreenUpdating=Falseだけで十分?他の設定もすべて必要?

ScreenUpdating=Falseだけでも効果はある。数式が多いブックなら Calculation=xlCalculationManual を追加するとさらに効く。実務版テンプレートでは4設定をまとめてON/OFFしているので、迷ったらテンプレートごとコピペすれば安全。

Q2: ScreenUpdating=Falseのまま止まってしまった。どうすればよい?

VBEを開き(Alt+F11)、イミディエイトウィンドウを表示し(Ctrl+G)、以下を1行ずつ入力してEnterを押す。


Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
Application.DisplayAlerts = True

すべての設定が元に戻る。

Q3: DisplayAlerts=Falseにすると何が起きる?

「このシートを削除しますか?」「保存しますか?」などのExcel標準の確認ダイアログがすべてスキップされ、デフォルトの選択肢(はい/OK相当)で自動的に進む。意図しない削除や上書きのリスクがあるため、必要な箇所だけで使い、処理後は必ずTrueに戻すこと。

Q4: 高速化設定と配列(記事036)はどちらを先に試すべき?

まずは高速化設定(本記事)を試すのがおすすめ。コードを1行も変えずに速度が改善する可能性がある。それでも遅い場合は、配列による一括読み書き([記事036(配列を使ってVBAの処理速度を10倍にする方法)])を検討する。最終的には両方を組み合わせるのがベスト。既存マクロの高速化は業務内容に応じた最適化が必要です。ココナラで相談できます。

Q5: 処理中に進捗を表示したい場合、ScreenUpdating=Falseと共存できる?

できる。ScreenUpdating=Falseのままでも、Application.StatusBar を使えばステータスバーに進捗を表示できる。画面は更新されないがステータスバーは更新される。


Application.StatusBar = "処理中... " & i & " / " & lastRow & " 件完了"

環境によっては DoEvents を入れないとStatusBarの表示が即座に反映されない場合がある。詳しくは[記事026(処理の進捗をステータスバーに表示する方法)]を参照。


まとめ

この記事では、VBAのマクロを高速化する4つのApplication設定を解説した。

  • 最小版Application.ScreenUpdating = False を1行追加するだけで2〜3倍速
  • 実務版:4設定の一括ON/OFF(SpeedOn/SpeedOff)+エラー復帰+処理時間計測のテンプレート

高速化設定は「コードを変えずにマクロを速くする」最も手軽な方法。まずはScreenUpdating=Falseから始めて、必要に応じてCalculation・EnableEvents・DisplayAlertsを追加するとよい。On Error GoTo による復帰処理を忘れずに入れることが、安全に使うための最重要ポイント。

関連記事:

  • [記事022(エラー処理で止まらないマクロを作る方法)] — On Error GoToの詳細
  • [記事026(処理の進捗をステータスバーに表示する方法)] — 高速化設定と組み合わせて進捗を表示
  • [記事036(配列を使ってVBAの処理速度を10倍にする方法)] — 配列と組み合わせてさらに高速化
  • [記事015(複数シートを一括処理する方法)] — DisplayAlertsの活用場面
  • [記事005(複数Excelファイルを1つに統合)] — DisplayAlertsの活用場面

次にやりたくなること:

  • 配列を使ってセルアクセスそのものを減らしたい → [記事036(配列を使ってVBAの処理速度を10倍にする方法)]
  • 長時間処理の進捗バーを表示したい → [記事026(処理の進捗をステータスバーに表示する方法)]

もっとカスタマイズしたい場合

「既存のマクロに高速化設定を組み込みたい」「大量データの処理を最適化したい」「配列と組み合わせた高速処理テンプレートを作りたい」など、業務に合わせたカスタマイズが必要な場合は、ココナラで相談できます。

相談時に以下の情報があるとスムーズです:

  • Excel のバージョン / OS
  • 現在のマクロの処理内容(何をしているか)
  • データの行数・列数(目安)
  • 現在の処理時間と目標時間
  • 数式やイベントプロシージャの有無

関連記事

コメント

タイトルとURLをコピーしました