【VBAサンプルコード】マクロ高速化のおまじない

Excel VBA VBAサンプルコード

【VBAサンプルコード】マクロ高速化のおまじない

マクロを作ってみたけどなんだか重く感じる。画面がたくさん切り替わってスマートじゃない。と思っている方はいらっしゃいませんか?そんな方に試して欲しい、マクロの処理時間を高速化する方法をご紹介します。

目次

マクロ高速化コード

Sub マクロ名()  
    With Application '自動更新の停止
        .Calculation = xlCalculationManual
        .ScreenUpdating = False    
        .EnableEvents = False
        .Cursor = xlWait
    End With

    'メインコード
    
    With Application '自動更新の再開
        .Calculation = xlCalculationAutomatic
        .ScreenUpdating = True
        .EnableEvents = True
        .Cursor = xlDefault
    End With
End Sub
※Withステートメントの説明は割愛します。

自動更新の停止コードと自動更新の再開コードをメインコードを挟むように貼り付けましょう。
この2つのコードはセットで使用します。万が一、マクロが途中で停止してしまった場合、マウスポインターの形状がくるくるしたままになってしまうので、再開のコードだけをSubプロシージャで実行してくださいね。

コード解説

Application.Calculation

  • xlCalculationManual:手動計算にする
  • xlCalculationAutomatic:自動計算にする

エクセルの計算方法に関するコードです。手動にすることで、マクロ実行中に都度シート上で計算が行われなくなり、処理速度を上げることができます。

Application.ScreenUpdating

  • False:画面の更新を無効にする
  • True:画面の更新を有効にする

マクロの実行中に画面を更新しないようにし、処理速度を上げることができます。頻繁に画面の切り替わりが発生するマクロに有効です。

Application.EnableEvents

  • False:イベントの発生を無効にする
  • True:イベントの発生を有効にする

イベントとはオブジェクトへの操作によって発生するトリガーのことです。例えばマクロが登録されたボタンをクリックする→"Clickイベントが発生"→マクロが実行されます。また、セルの値が変わる度に"Changeイベントが発生"しています。
イベントの発生を止めることで処理速度を上げることができます。

Application.Cursor

  • xlWait:くるくる、砂時計にする
  • xlDefault:デフォルトの状態にする

マウスポインターの形状を変更することができます。マクロの実行中にマウスポインターのチラつきが気になる人は設定してみてください。

高速化の小ワザ

”Select”でセルを選択しない

画面の切り替わりが発生する原因です。私たちが手動で操作をするときは、セルやシートを選択することから始めますが、VBAは選択しなくていいんです。直接値を取得したり、書き換えたりすることができます。できるだけSelectを使わない書き方をしましょう。

値貼り付けは”Value”で行う

A1からA1000までの1,000行に適当な数字(123でもなんでもOK)を入力し、上から順番にB列へ値貼り付けするマクロを作ります。CopyとPasteSpecialを使うんでしょ?と思ったアナタ!もちろん正解です。ですが、セルの値を取得・書込むためのValueを使っても同じように値貼り付けをすることができるんです。しかもValueの方が速い。マクロの実行時間を測るためにTimer関数を使って、さっそく比較してみましょう。

Sub コピペ_高速化あり()
    With Application '自動更新停止のおまじない
        .Calculation = xlCalculationManual
        .ScreenUpdating = False
        .EnableEvents = False
        .Cursor = xlWait
    End With
    
    Dim startTime As Double, endTime As Double
    Dim i As Long
    
    startTime = Timer '開始時間の取得
    
    For i = 1 To 1000
        Cells(i, 1).Copy
        Cells(i, 2).PasteSpecial xlPasteValues
    Next i
        
    endTime = Timer '終了時間の取得
    Debug.Print endTime - startTime
    
    With Application '自動更新再開のおまじない
        .Calculation = xlCalculationAutomatic
        .ScreenUpdating = True
        .EnableEvents = True
        .Cursor = xlDefault
    End With
End Sub
Sub Value_高速化あり()
    With Application '自動更新停止のおまじない
        .Calculation = xlCalculationManual
        .ScreenUpdating = False
        .EnableEvents = False
        .Cursor = xlWait
    End With
    
    Dim startTime As Double, endTime As Double
    Dim i As Long
    
    startTime = Timer
    
    For i = 1 To 1000
        Cells(i, 2).Value = Cells(i, 1).Value
    Next i
        
    endTime = Timer
    Debug.Print endTime - startTime
    
    With Application '自動更新再開のおまじない
        .Calculation = xlCalculationAutomatic
        .ScreenUpdating = True
        .EnableEvents = True
        .Cursor = xlDefault
    End With
End Sub
※高速化なしVer.は「With~End With」を削除してください。

コピペ
(高速化なし)
コピペ
(高速化あり)
Value
(高速化なし)
Value
(高速化あり)
1回目 18.296875 5.71875 0.0234375 0.015625
2回目 18.6796875 5.1953125 0.0234375 0.0078125
3回目 18.859375 5.0234375 0.0234375 0.015625
4回目 18.8515625 4.734375 0.0234375 0.015625
5回目 18.8125 4.9453125 0.0234375 0.0078125

その差は一目瞭然!圧倒的にValueを使う方が早く処理が終わりました。また、今回が上から順番に値貼り付けをするマクロでしたが、書き込む回数を減らすことで処理時間を限りなく0秒に近づけることができます。それでは、1,000行の値を1回値貼り付ける方法をご説明します。
「For i ~ Next i」までのコードを

「Range("B1:B1000").Value = Range("A1:A1000").Value」

に書き換えるだけ!Valueは指定範囲のセルについても一括で値の取得・書き込みをすることができます。実際に処理時間が何秒になるかやってみてくださいね。


自分の写真
りり
高速化のおまじない、ぜひ使ってみてください♪

QooQ