VBAのWith入れ子はアリかナシか?|ネストの限界と変数代入への切り替え基準

VBAのWith構文は入れ子にすることができますが、2段階までなら読みやすく、3段以上になると対応関係が追いにくくなります。深くネストするくらいなら、オブジェクトを変数に代入して操作する方がシンプルで保守しやすいコードになります。

この記事では、次の内容を順番に解説します。

  • With構文の基本と使うメリット
  • Withを入れ子にする書き方と注意点
  • 入れ子が深くなるときの代替パターン
  • With・入れ子・変数化の使い分け基準

With構文の基本と使うメリットを知るには?

With構文は、同じオブジェクトに対する操作をまとめて書くための構文です。オブジェクトを繰り返し書かずに済むため、コードが短くなりミスも減ります。

'Withなし(オブジェクトを繰り返し書く)
Cells(1, 1).Value = "商品A"
Cells(1, 1).Font.Bold = True
Cells(1, 1).Font.Color = vbRed
Cells(1, 1).Interior.Color = RGB(255, 255, 200)

'Withあり(スッキリまとまる)
With Cells(1, 1)
    .Value = "商品A"
    .Font.Bold = True
    .Font.Color = vbRed
    .Interior.Color = RGB(255, 255, 200)
End With

Withを使うメリットは3つです。コードの行数が減る、オブジェクト名の書き間違いが減る、後からオブジェクトを変更するときに1か所直すだけで済む。

Withを入れ子にする書き方を知るには?

With構文は入れ子にできます。外側のWithオブジェクトのプロパティに対してさらにWithを使う形です。

'1段階の入れ子(読みやすい)
With Cells(1, 1)
    .Value = "商品A"
    With .Font
        .Bold = True
        .Color = vbRed
        .Size = 12
    End With
End With

1段階の入れ子なら対応関係が追いやすく問題ありません。ただし2段以上になると急に読みにくくなります。

'2段階以上の入れ子(読みにくい)
With ThisWorkbook
    With .Worksheets("売上")
        With .Range("A1")
            With .Font
                .Bold = True
                .Color = vbRed
            End With
        End With
    End With
End With

どのEnd WithがどのWithに対応しているか、すぐにはわかりません。

入れ子が深くなるときの代替パターンを知るには?

入れ子が2段以上になりそうな場合は、オブジェクトを変数に代入してから操作する方がシンプルです。

'変数に代入して操作(読みやすい)
Sub CleanVersion()

    Dim ws   As Worksheet
    Dim rng  As Range
    Dim fnt  As Font

    Set ws  = ThisWorkbook.Worksheets("売上")
    Set rng = ws.Range("A1")
    Set fnt = rng.Font

    rng.Value     = "商品A"
    fnt.Bold      = True
    fnt.Color     = vbRed
    fnt.Size      = 12

End Sub

WithとオブジェクトVariableを組み合わせることもできます。深いオブジェクトを変数に取り出してからWithで操作するのが実務でよく使われるバランスの良い書き方です。

'Withと変数の組み合わせ(バランスが良い)
Sub CombinedVersion()

    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("売上")

    With ws.Range("A1:D1")
        .Font.Bold = True
        .Interior.Color = RGB(68, 114, 196)
        .Font.Color = RGB(255, 255, 255)
        .HorizontalAlignment = xlCenter
    End With

End Sub

With・入れ子・変数化の使い分け基準を知るには?

状況おすすめの書き方
同じセル・シートに複数の操作をまとめたいWith構文
Fontなど直下のサブオブジェクトにも複数操作したい1段階のWith入れ子
入れ子が2段以上になりそう変数に代入して操作
同じオブジェクトを複数のSubプロシージャで使う変数に代入(オブジェクト変数)

まとめ

  • With構文は同じオブジェクトへの複数操作をまとめる仕組み。コードが短くなり修正が1か所で済む
  • 入れ子は文法上は問題ないが、1段階までなら読みやすく、2段以上は読みにくくなる
  • 入れ子が深くなるなら、オブジェクトを変数に代入してから操作する方がシンプル
  • 実務では 「変数でシートを取り出し、WithでセルやFontをまとめる」 という組み合わせが使いやすい
  • 「簡潔さ」と「読みやすさ」はトレードオフ。後から見て意味がわかるコードを優先する

よくある質問

Withの中で別のSubを呼び出すことはできますか?

できます。Withブロック内でCallや他のSubを呼び出しても問題ありません。ただし呼び出し先のSubの中ではWithブロックは有効にならないため、オブジェクトの参照は明示的に書く必要があります。

Withブロックを途中で抜けたいときはどうすればいいですか?

Withブロックは Exit SubGoTo でブロックの外に抜けることができます。ただし End With を通らずに抜けるとオブジェクトへの参照が残ったままになる場合があるため、なるべくEnd Withまで到達する設計にするのがベストです。

WithとSet変数の違いは何ですか?

Withはブロック内に限定した一時的な省略記法で、ブロックを出ると効力がなくなります。Set変数はプロシージャ全体(またはモジュール全体)で使え、何度でも参照できます。一度だけまとめて設定したいならWith、繰り返し参照するなら変数が向いています。

入れ子のWithでどちらのEnd WithがどちらのWithに対応するか見分ける方法はありますか?

VBEではインデントが揃っていれば対応関係を視覚的に追えます。また、各WithとEnd Withに短いコメントを添えると確認しやすくなります。例:With .Font 'Font用End With 'Font用 のように。

Withを使うとコードは速くなりますか?

Withを使うと内部的にオブジェクトへの参照が1回解決されるため、微妙に速くなる可能性があります。ただし体感できるほどの差はほとんどなく、主なメリットは可読性と保守性です。処理速度を上げたい場合は配列化やScreenUpdating=Falseの方が効果的です。


動画で学びたい方へ

「記事を読んでも、実際に自分で書けるか不安…」という方には、動画で基礎からじっくり学べる講座がおすすめです。

VBAが初めての方を前提に、つまずきやすいポイントを先回りして解説しています。サンプル動画は無料でご覧いただけます。

動画で学ぶExcelマクロ|JIMOVEオンラインスクール

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール