サイトについて      連絡先   検索

VBA の処理を高速化する

はじめに

Excel VBA マクロの処理を高速化する方法を紹介します。

Application.ScreenUpdating で描画を止めるのが簡単に高速化できます。またセルを配列化してまとめて処理をすると効果的です。

Timer 関数で処理時間を計測する方法も紹介します。

  • 目次
    • 高速化
    • 処理時間を計測する
    • その他の高速化

高速化

次の「描画を停止」と「セルを配列化」する方法を組み合わせれば、ほぼ最速になります。

描画を停止

VBA の処理を高速化する 1 番簡単な方法は、描画を停止することです。

Range("A1").Value = "あいう"のようにセルに対して操作すると、そのたびに Excel の画面が更新されます。これに時間がかかるため描画を停止させます。

描画を停止するには Application.ScreenUpdating = False のように指定します。


Public Sub Tips
    Application.ScreenUpdating = False ' 描画を停止する

    ' 時間のかかる処理

    Application.ScreenUpdating = True  ' 描画を再開する
End Sub

処理の最後に Application.ScreenUpdating = True にして描画をするのを忘れないようにします。これだけで、十分に高速化を期待できます。

何分もの間、描画を停止するとフリーズしているように見えるので、途中で更新したいときは次のようにします。


Public Sub Tips
    Application.ScreenUpdating = False

    Dim count As Long
    Dim i As Long
    For i = 0 To 10000 ' ループ処理
        count = count + 1
        
        ' 処理

        ' 1000 回に 1 回描画する
        If count Mod 1000
            Application.ScreenUpdating = True
            Application.ScreenUpdating = False
        Next
    Next

    Application.ScreenUpdating = True
End Sub

描画したいタイミングで Application.ScreenUpdating = True にし、その後 False に戻します。

セルを配列化

次に効果的なのは同じセルを 2 回以上読み書きしないことです。さらに、1 つずつセルを読み書きしないで、必要なセルの値をすべて配列に入れて、その中で処理をして、最後に配列をまとめてセルに設定します。

VBA でとても遅い処理は、セルに値を設定することです。その回数を減らすために、配列にして処理の最後に 1 回だけにします。書き込むセルの数が多くなるほど、配列でまとめて値を設定した方が効果が大きくなります。


Public Sub Tips
    Dim 二次元配列 As Variant
    二次元配列 = Range("A1:C2") ' 各セルの Value のみが配列の要素になる
                                ' 二次元配列(1,1) = A1 インデックスは 1 から始まる
                                ' 二次元配列(1,2) = B1
                                ' 二次元配列(1,3) = C1
                                ' 二次元配列(2,1) = A2 
                                ' 二次元配列(2,2) = B2
                                ' 二次元配列(2,3) = C2

    ' 二次元配列に対して処理をする

    Range("A1:C2") = 二次元配列 ' 配列の値をセルの Value に書き込み
End Sub

Range("A1:C2")だと二次元配列(1 To 2, 1 To 3)の配列になります。

読み込み時と書き込み時のセルは、違う場所でも設定できます。セルの範囲と配列の要素数が違ってもその分だけ設定されます。

まとめて書式設定

フォントなどの書式設定についても、同じセルに 2 回以上設定しないようにします。書式設定は配列化できませんが、複数のセルに対してまとめて書式設定できます。


Public Sub Tips
    With Range("A1:B2") ' セルの範囲
        .Font.Color = RGB(255, 0, 0)   ' 文字色
        .Font.Name = "MS Pゴシック" ' 名前
        .Font.Size = 11                ' サイズ
        .Font.Bold = True              ' 太字
    End With

    With Selection ' 選択範囲
        .Font.Color = RGB(255, 0, 0)   ' 文字色
        .Font.Name = "MS Pゴシック" ' 名前
        .Font.Size = 11                ' サイズ
        .Font.Bold = True              ' 太字
    End With
End Sub

処理時間を計測する

Timer 関数」を使用して処理時間を計測できます。


Public Sub WatchTime
    Dim t As Single
    t = Timer

    ' 時間のかかる処理

    Debug.Print (Timer - t) ' 1.23 など秒数が確認できます
End Sub

1 ミリ秒もかからないような処理は 0 秒となり計測できません。同じ処理を 1000 回くらい繰り返せば、計測できるようになります。


Public Sub WatchTime
    Dim startTime As Double
    Dim stopTime As Double

    startTime = Timer

    Dim i As Integer
    For i = 1 To 1000
        ' 時間のかかる処理
    Next

    stopTime = Timer

    Debug.Print (stopTime - startTime) ' 1000 回分の経過時間
    ' 1000 で割ると 1 回の時間になる
End Sub

その他の高速化

描画を停止する以外に高速化するポイントを紹介します。効果は微妙だと思います。

コードを短くする

コードを書けば書くほど処理が多くなります。できるだけ短く、少ない行数でやる方法を見つけます。

無駄な処理をやめる

セルを初期化するときに、書式設定していないのに書式を初期化するなどやらなくていい処理はやめます。

本当に必要な処理だけをやれば高速化につながります。

型を指定する

Variant や Object などあいまいな型で処理をするより、Integer など型を指定した方が高速化します。

  • 目次
    • 高速化
    • 処理時間を計測する
    • その他の高速化