【VBA入門】Withの使い方、入れ子(ネスト)で使う方法

ExcelVBAでは、Withステートメントで同じオブジェクト名を省略することができます。

オブジェクト名が長ければ長いほど何度も記述することは避けたいですよね。そのようなときのためにWithステートメントがあります。

この記事では、Withステートメントで同じオブジェクト名を省略する方法について

  • Withステートメントとは
  • Withステートメントの使い方

といった基本的な内容から

  • Withを入れ子(ネスト)で使う方法
  • Withブロック変数エラーの対処法
  • WithEventsの使い方

など応用的な使い方についても解説していきます。

今回はWithステートメントについて、使い方をわかりやすく解説します!

目次

Withステートメントとは

ExcelVBAでは一つのオブジェクトに対して、複数の処理を行うことがあります。Withステートメントとは、そのような場合にオブジェクト名を省略する構文です。

Withステートメントで、オブジェクト名を省略するためには次のように記述します。

With 省略するオブジェクト名
    .処理1
    .処理2
    ...
End With

このように処理を「.」(ドット)から始まる式で記述することができて、オブジェクト名を省略できます。

以降では、具体的な例を示して解説しています。

Withステートメントの使い方

例えば、次のようなサンプルコードがあるとします。

Sub Sample()
    Worksheets("Sheet1").Cells(1, 1).Offset(0, 0).Value = 0
    Worksheets("Sheet1").Cells(1, 1).Offset(0, 1).Value = 1
    Worksheets("Sheet1").Cells(1, 1).Offset(1, 0).Value = 2
    Worksheets("Sheet1").Cells(1, 1).Offset(1, 1).Value = 3
End Sub

[実行結果]
vba_with01 0

これは、Withステートメントを使用して次のように記述することができます。

Sub Sample()
    With Worksheets("Sheet1").Cells(1, 1)
        .Offset(0, 0).Value = 0
        .Offset(0, 1).Value = 1
        .Offset(1, 0).Value = 2
        .Offset(1, 1).Value = 3
    End With
End Sub

[実行結果]
vba_with01 0

「.Offset(0, 0).Value」のようにWithステートメントの中で省略したオブジェクトを使用するためにはドットから始まる式を記述します。

Withステートメントを使用したサンプルコードでは、「Worksheets(“Sheet1”).Cells(1, 1)」は一度しか出てきていませんね。

どちらのサンプルコードでも実行結果に違いはありません。

Withを入れ子(ネスト)で使う方法

Withステートメントは入れ子(ネスト)にすることができます。入れ子(ネスト)にするとは、自身と同じ構造をその内部に持つことを意味します。

Withステートメントの中でドットから始まる式で記述するオブジェクトにおいて、さらに処理を複数記述する場合に入れ子(ネスト)で使用します。

Withを入れ子(ネスト)で使うためには、次のように記述します。

With 省略するオブジェクト名1
    .処理1
    .処理2
    ...
 
    With 省略するオブジェクト名2
       .処理3
       .処理4
       ...
    End With
End With

次は、Withを入れ子(ネスト)で使うサンプルコードです。

Sub Sample()
    With Worksheets("Sheet1").Cells(1, 1)
        .Offset(0, 0).Value = 0
        .Offset(0, 1).Value = 1
        .Offset(1, 0).Value = 2
        .Offset(1, 1).Value = 3
 
        With .Font
            .Name = "MS Pゴシック"
            .Size = 16
            .Bold = True
            .ColorIndex = 3
        End With
    End With
End Sub

[実行結果]
vba_with02 0

まず、最初のWithステートメントで「Worksheets(“Sheet1”).Cells(1, 1)」を省略しています。

その中でもう一度、Withステートメントを使用して、今度は「Font」を省略しています。

Withブロック変数エラーの対処法

VBAでは実行時エラーで、「オブジェクト変数またはWithブロック変数が設定されていません」と表示されることがあります。

これはWorksheetやRangeなどのオブジェクトに格納する際に、Setステートメントを付けていないことが原因でよく発生します。以下のようにSetを付けて記述するようにしましょう。

Dim オブジェクト変数名 As オブジェクト型名
Set オブジェクト変数名 = オブジェクト

Setステートメントの使い方については、こちらで詳しく解説していますので、ぜひ参考にしてください。

WithEventsの使い方

VBAではWithステートメントの他にWithEventsキーワードというモノがあります。

WithEventsキーワードの使うと、指定した条件でイベントを発生させることができます。Withステートメントの使い方とは大きく異なります。

WithEventsキーワードの使い方も参考のためにご紹介しておきます。WithEventsキーワードは、クラスモジュールで使用します。

Class1(クラスモジュール)

Public WithEvents myEvent As Application

Private Sub myEvent_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
    Target.Value = Target.Address
End Sub

Module1(標準モジュール)

Dim c1 As New Class1

Sub Sample()
    Set c1.myEvent = Application
End Sub

実行結果:
WIthEvents01

このサンプルコードでは、まずクラスモジュールClass1を作成し、WithEventsキーワードを使ってApplicationオブジェクトmyEventを宣言しています。

下図のように宣言したmyEventを選択するとイベントを選択できるようになります。
WIthEvents02

ここでは選択するセルが変わった場合の処理として、セルのアドレスの値をセル内に表示するように定義しています。

そして標準モジュール内でDim As Newステートメントを使ってClass1のインスタンスc1を生成しています。

さらにSetステートメントを使ってc1から呼び出したmyEventにApplicationオブジェクトを格納することで、指定したイベントが発生したときに定義した処理が行われるようにしています。

まとめ

いかがでしたか?今回は、Withステートメントで同じオブジェクト名を省略する方法について解説しました。

これで長いオブジェクト名を何度も記述することが避けられます。また、同じことを記述する回数が減るため修正箇所が少なくなることもメリットの一つです。

もし、Withステートメントで同じオブジェクト名を省略する機会があれば、この記事を思い出してみてください!

この記事を書いた人

フリーランスのエンジニアです。
最近では、プログラミング関連の記事を作成するライターとしても活動しています。

趣味と業務の両方でプログラミング言語をいくつも学んできたので
その経験を活かして分かりやすい記事を作成できればと考えています。

目次