【Excel VBA】withブロックを活用して処理を高速化する

ExcelVBAヘッダー Excel VBA

今回は、withステートメントを活用したコーディングの仕方について、解説していきます。

具体的な解説の前に、まず、思いだしてほしいことがあります。

中学校の時の「因数分解」。

私も苦労した記憶がありますが、共通項(共通因数)をカッコの外に出して括っていくやつを思い出してください。

今回のwithステートメントを使って、因数分解をExcelVBAでやりましょう。

共通のオブジェクトをwithで括ろう

因数分解の共通項(共通因数)をオブジェクトに見立て、因数分解のカッコをwithステートメントに置き換えて考えていきます。

withステートメントを使った構文は次のようになります。

ExcelVBAのWithブロックイメージ

理解を深めるために例を挙げて考えていきます。

例えば、下のようなコードがあったとします。

Public Sub WithSample()

    ThisWorkbook.Sheets("Sheet1").Range("A1").Value = "ブロックサンプル1"
    ThisWorkbook.Sheets("Sheet1").Range("A1").NumberFormatLocal = "@"
    ThisWorkbook.Sheets("Sheet1").Range("A1").Font.Bold = True
    ThisWorkbook.Sheets("Sheet1").Range("A1").Font.ColorIndex = 3
    ThisWorkbook.Sheets("Sheet1").Range("A2").Value = "ブロックサンプル2"
    ThisWorkbook.Sheets("Sheet1").Range("A2").NumberFormatLocal = "@"
    ThisWorkbook.Sheets("Sheet1").Range("A2").Font.Bold = True
    ThisWorkbook.Sheets("Sheet1").Range("A2").Font.ColorIndex = 5
    
End Sub

なんだか、同じような文字列が並んでいるのが目につくのではないでしょうか。

「ThisWorkbook.Sheets(“Sheet1”)」なんて、全ての行で書かれていて、無駄な感じがすますよね。

そこで、Withステートメントを使って、工夫してみます。

Public Sub WithSample()

    With ThisWorkbook.Sheets("Sheet1")
        .Range("A1").Value = "ブロックサンプル1"
        .Range("A1").NumberFormatLocal = "@"
        .Range("A1").Font.Bold = True
        .Range("A1").Font.ColorIndex = 3
        .Range("A2").Value = "ブロックサンプル2"
        .Range("A2").NumberFormatLocal = "@"
        .Range("A2").Font.Bold = True
        .Range("A2").Font.ColorIndex = 5
    End With
    
End Sub

「ThisWorkbook.Sheets(“Sheet1”)」という共通オブジェクトをWithステートメントを使って、外に出してしまっています。

このようにして、Withブロックを作っていきます。

Withブロックの最後を意味する「End With」を忘れないようにしましょう。

下の例では、「ThisWorkbook.Sheets(“Sheet1”).Range(“A1”)」、「ThisWorkbook.Sheets(“Sheet1”).Range(“A2”)」という共通オブジェクトをWithステートメントを使って、外に出しています。

Public Sub WithSample()

    With ThisWorkbook.Sheets("Sheet1").Range("A1")
        .Value = "ブロックサンプル1"
        .NumberFormatLocal = "@"
        .Font.Bold = True
        .Font.ColorIndex = 3
    End With
        
    With ThisWorkbook.Sheets("Sheet1").Range("A2")
        .Value = "ブロックサンプル2"
        .NumberFormatLocal = "@"
        .Font.Bold = True
        .Font.ColorIndex = 5
    End With
    
End Sub

2つ例を挙げましたが、どれも結果は同じです。

Withブロックのネスト

Withブロックはネスト(入れ子)にすることもできます。

先ほどの例をさらにネストさせて、考えてみましょう。

Public Sub WithSample()

    With ThisWorkbook.Sheets("Sheet1")
        With .Range("A1")
            .Value = "ブロックサンプル1"
            .NumberFormatLocal = "@"
            .Font.Bold = True
            .Font.ColorIndex = 3
        End With
        With .Range("A2")
            .Value = "ブロックサンプル2"
            .NumberFormatLocal = "@"
            .Font.Bold = True
            .Font.ColorIndex = 5
        End With
    End With
    
End Sub

外側のブロックでは、「ThisWorkbook.Sheets(“Sheet1”)」を外に出しています。

さらに内側のブロックでは、「Range(“A1”)」と「Range(“A2”)」を外に出しています。

このようにすると、とても整理されたスマートなコードになりますよね。

もう一歩、踏み込んでみましょう。

Public Sub WithSample()

    With ThisWorkbook.Sheets("Sheet1")
        With .Range("A1")
            .Value = "ブロックサンプル1"
            .NumberFormatLocal = "@"
            With .Font
                .Bold = True
                .ColorIndex = 3
            End With
        End With
        With .Range("A2")
            .Value = "ブロックサンプル2"
            .NumberFormatLocal = "@"
            With .Font
                .Bold = True
                .ColorIndex = 5
            End With
        End With
    End With
    
End Sub

さらに内側でネストさせ、「font」でWithブロックを作っています。

もちろん、実行結果は今までと同じになります。

withブロックの効果

withステートメントの使い方、withブロックの作り方について、理解いただけたと思いますので、今度はその効果について、解説していきます。

効果は次の2つ。

  • わかりやすいコード
  • 高速化

コードのわかりやすさについては、実例を挙げて説明してきましたので、おわかりいただけたのではないでしょうか。

Withブロックを作って、コーディングしていった方が、誰が見てもわかりやすいコードになります。

それと結構大事なことですが、コーディング作業の時間短縮にもなります。

次に高速化ということですが、Withステートメントにオブジェクトやプロパティを一度、書いておけば、コンピューターがそれを参照する回数も一度でいいわけです。

オブジェクトやプロパティを何度も書けば、その回数分、コンピューターは参照しにいきます。

Withブロックにオブジェクトやプロパティをまとめておけば、コンピューターがそれを参照する回数を減らすことができます。

これが、処理の高速化につながります。

Withブロックは、やるよりやった方が絶対にいいです。

ぜひ、マスターして、どんどん活用していってください。

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