マクロを作ったはいいが、動作が遅い。データが増えるとさらに遅くなる。「VBAって遅いよね」と言われた——そんな経験はありませんか?
正直に言うと、データが増えれば遅くなるのはVBAの特性として避けられない部分があります。でも、コードの書き方を変えることで「できる限り速い状態」に最大化することはできます。対策を打ったうえで、あとはマクロに任せればいい——それがVBAとの正しい付き合い方です。
この記事では、次のことを解説します。
- VBAの処理が遅くなる根本的な理由
- 今すぐ使える3つの基本対策
- 「それでも遅い」と感じたときの考え方
VBAの処理が遅くなる根本的な理由
VBAが遅くなる原因は、大きく分けると3つあります。
たとえば1万件のデータをループで処理するケースを考えてみます。
- 処理のたびにExcelが画面を再描画している
- セルに値を書き込むたびに、シート上の数式を全部再計算している
- セルが変わるたびに、イベントと呼ばれる自動処理が走っている
これらがループの中で毎回走ることで、1万行の処理が数十秒かかる、という事態になります。データが増えるほど、この差は大きくなります。
これらは、コードに数行追加するだけで止めることができます。
今すぐ使える3つの基本対策
① ScreenUpdating = False 画面の再描画を止める
VBAがセルに値を書き込むたびに、Excelは画面を「消して・描き直す」という作業を行います。これを「再描画」といいます。
人間の目には一瞬の変化ですが、1万行のループで毎回この再描画が行われると、1万回の「消して・描く」が繰り返されます。これが処理時間の大きな無駄になります。
これを止めるだけで、体感速度が大きく変わります。
Application.ScreenUpdating = False '処理前に止める
'ここに処理を書く
Application.ScreenUpdating = True '処理後に必ず戻す
処理後は必ずTrueに戻してください。戻し忘れると、以降Excelの画面が更新されなくなります。
② Calculation = xlCalculationManual 自動再計算を止める
シートに数式がある場合、セルに値を書き込むたびにExcelはシート全体の数式を再計算しようとします。数式が多いブックほど、この負荷が大きくなります。
Application.Calculation = xlCalculationManual '自動計算を止める
'ここに処理を書く
Application.Calculate '最後に1回だけ再計算
Application.Calculation = xlCalculationAutomatic '元に戻す
数式がないシートでは効果は薄いですが、習慣として入れておいて損はありません。
③ EnableEvents = False イベントの発火を止める
Excelには「セルが変わったときに自動で何かをする」という仕組み(イベント)があります。VBAでセルを1万行書き換えると、このイベントが1万回発火します。イベントが重い処理を持っている場合、これが大きな遅延の原因になります。
Application.EnableEvents = False 'イベントを止める
'ここに処理を書く
Application.EnableEvents = True '元に戻す
戻し忘れに特に注意してください。Falseのまま終了すると、以降は手動でセルを編集してもイベントが一切発火しなくなります。Excelを再起動するまで直らないこともあります。
3つをセットにした「黄金テンプレート」
3つをまとめて使うときは、エラーが起きても必ず元に戻るようにOn Error GoToと組み合わせて使います。
Sub 処理名()
Application.ScreenUpdating = FalseApplication.Calculation = xlCalculationManualApplication.EnableEvents = False
On Error GoTo Cleanup
'ここに処理を書く
Cleanup:Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
End Sub
On Error GoTo Cleanupを入れることで、処理の途中でエラーが起きてもCleanup節に飛んで、必ず3つが元に戻ります。このテンプレートを覚えてしまえば、どのマクロにも使えます。
「それでも遅い」と感じたときの考え方
3つの基本対策を入れてもまだ遅い場合があります。その多くは、ループの中でセルに何度もアクセスしていることが原因です。
セルへのアクセスは、VBAにとって比較的重い処理です。セルがいわば「棚の奥にある引き出し」だとすると、1万行のループで毎回引き出しを開け閉めしているイメージです。
この問題には「配列」を使う方法が有効です。配列とは、VBAがデータを一時的に手元に置いておくための仕組みです。引き出しを何度も開け閉めする代わりに、最初に一度全部取り出して目の前の作業台に並べ、処理が終わったら一括で戻す。「作業台に並べたデータのかたまり」が配列です。セルへのアクセスが1万回から2〜3回になります。
また、コピー&ペーストをValue直接代入に変える、揮発性関数(NOW・TODAY・INDIRECTなど)をシートに残さないなど、さらに効果的なテクニックがあります。揮発性関数については、先ほどの動作を止めるコードを書いても止まりません。
これらの対策を打ったうえで「それでもデータが多ければ多少時間がかかる」のは仕方ない部分もあります。手作業で1時間かかる処理が数秒〜数分で終わるなら、それはすでに十分な成果です。マクロに任せて、その間に別の仕事をすればいい。
さらに詳しい高速化テクニックは、JIMOVEの動画講座で解説しています。
まとめ
VBAの処理速度について、整理します。
- データが増えれば遅くなるのは、VBAの特性として避けられない部分がある
- でも、3つの基本対策を入れるだけで「できる限り速い状態」に最大化できる
- 手作業と比べれば、最適化したマクロは圧倒的に速い
「VBAは遅い」ではなく、「対策を打ったらあとはマクロに任せればいい」。それがVBAとの正しい付き合い方です。
よくある質問
Q. 3つの設定を戻し忘れたらどうなりますか?
ScreenUpdatingがFalseのままだと画面が更新されません。CalculationがManualのままだと数式が自動再計算されません。EnableEventsがFalseのままだとイベントが発火しません。いずれもExcelを再起動すれば元に戻ります。本文のCleanupパターンを使うと、エラーが起きても必ず戻るので安心です。
Q. データが1万行以下なら対策しなくていいですか?
少量であれば対策なしでも速く動きます。ただし、処理内容によります。ScreenUpdating・Calculation・EnableEventsの3つは数行追加するだけなので、習慣として常に入れておくことをおすすめします。
Q. マクロの記録で作ったコードはなぜ遅いですか?
マクロの記録はSelectを多用するため、画面描画を伴う処理が増えます。また、ループを使わず同じ処理を繰り返し書くことになりやすいです。記録したコードにこの記事の対策を加えるだけでも、速度が改善することがあります。
Q. さらに速くする方法はありますか?
あります。配列を使ったデータの一括読み書き、Copy&PasteをValue直接代入に変える、揮発性関数をシートに残さないなど、上級の高速化テクニックがあります。これらはJIMOVEの動画講座で詳しく解説しています。
基本の対策から、配列を使った上級の高速化テクニックまで、体系的に学びたい方は、JIMOVEの動画講座をご覧ください。
動画で学びたい方へ
「記事を読んでも、実際に自分で書けるか不安…」という方には、動画で基礎からじっくり学べる講座がおすすめです。
VBAが初めての方を前提に、つまずきやすいポイントを先回りして解説しています。サンプル動画は無料でご覧いただけます。



