※本ブログのページには広告主との提携による広告や宣伝、プロモーションが含まれます。当ブログを経由しての商品の購入や、サービス申し込みが発生すると、それらの提携企業からの成果報酬を受けとる場合があります。

エクセルVBA|Withステートメントの使い方と注意点

エクセルVBAで同じオブジェクトに対して複数の操作を行うとき、どのようにコードを書いていますか?
オブジェクト名を何度も繰り返し書いていませんか?

エクセルVBAでは、同じオブジェクトに対して処理を書くときは、Withステートメントを使えます。
Withステートメントは、指定オブジェクトに対する処理をまとめて書くことができるため、マクロのコードをスッキリすることさせる効果があります。

Withステートメントをつかうことで、マクロの可読性の向上につながります。プログラミングでは、可読性の向上(読みやすくなること)は、不具合の原因を見つけやすくなることや、機能のアップデートなどでの作業ミスを防止する効果があります。

また、特定のオブジェクトで複数のプロパティを設定するときなどの場面では、オブジェクトを繰り返し参照する必要がなくなることから、何度もオブジェクトを参照するケースと比較して処理が早くなるといったメリットもあります。

この記事では、エクセルVBAでWithステートメントの基本的な使い方と使用時の注意事項について解説します。

WithステートメントはVBAのコードをスリム化できるものだよ。

独学だと中々スキルが身についた実感が湧かない。学習環境を見直してみませんか?

エクセルで繰り返しや転記作業で苦しい思いをした経験はありませんか?
今まで苦労してきたその作業を簡単なプログラムをおぼえるだけで解決できる可能性があります。
なるべくお金や時間をかけずにエクセルマクロVBAを習得したい人にはこちらの「1日速習講座」がおすすめです。

VBAにおけるWithステートメントの概要とメリット

Withステートメントとは、同じオブジェクトに対して複数のプロパティやメソッドを指定するときに使う構文です。Withステートメントを使うと、オブジェクト名を一度だけ書いて、その後の操作をピリオド(.)でつなげることができます。Withステートメントの書き方は以下です。

With オブジェクト
  .プロパティやメソッド
  .プロパティやメソッド
End With

Withステートメントの最大メリットは、VBAのコードがスリムになり見やすくなることです。
オブジェクト名を繰り返し書く必要がなくなるので、全体のコードの量が減り、読みやすく、理解しやすくなります。また、オブジェクト名を書き間違える可能性が減ることもメリットと言えます。

さらにWithステートメントを使うと、オブジェクトの参照が高速になるというメリットもあります。これは、Withステートメント内ではオブジェクトの参照が一時的に蓄積されることで素早く取り出せるためです。

あくまで個人的な感覚でのイメージで言えば、以下のように考えています。
以降の記事を読むにあたり、理解がしやすく感じていただけたらうれしいです。

ここでは「アーニャ・フォージャー」がオブジェクトとなりますので、マクロのコードでは「アーニャ・フォージャー」の部分が重複して書かれています。こちらのコードをWithステートメントをつかったものに書きかえることで下記のようになります。

「アーニャ・フォージャー」の部分をWithステートメントでまとめたことによって、それ以降の性別や学校、能力を説明する行では同じ言葉である「アーニャ・フォージャー」を省略できます。

って、ただそれだけ?だと思われるかもしれませんが、ここで説明した例では「アーニャ・フォージャー」といった言葉が短いため、文字数もそれほど変わりませんが、これが「アーニャ・フォージャーの父親の同僚の赤メガネの男性」のように長いものであった場合「アーニャ・フォージャーの父親の同僚の赤メガネの男性」の繰り返しを省略できる点がWithステートメントだとお伝えすれば、効果が想像しやすいのではないでしょうか。

それでは、次からはWithステートメントの書きかたを説明していきます。

VBAのWithステートメントの基本的な書き方

それでは、Withステートメントの基本的な書き方についてみていきましょう。

構文

With object [ statements ] End With

Withステートメントをつかうためには、With オブジェクト(Object)からEnd Withまでの間に指定したオブジェクトに対するプロパティやメソッドを書きます。さきほど紹介した文章をVBAのコードのように書いてみます。

Withステートメントは、繰り返しのオブジェクト参照をスリム化するために使います。そのため、指定項目では オブジェクト(Object)の指定は必須となります。オブジェクト(Object)には、ブック(ファイル)、セル、ワークシート、グラフ、フォームなどのほかに、クラスなどの作成したオブジェクトの参照も可能です。

With ステートメントを使用することで、特定のオブジェクトやユーザー定義型に対してオブジェクト名の指定を繰り返し書く必要がなくなり、Withステートメントでまとめて実行できます。 具体的には、1 つのオブジェクトにあるそれぞれのプロパティを変更したいときなどに有効です。

Withステートメントの指定項目について
指定項目 必須/省略可 説明
object 必須 参照したいオブジェクトやユーザー定義型の名前を指定します。
statements 省略可 object に対して実行する1つ以上のステートメントを指定します。

With object ~ End Withが間に書いたコードがまとめられるよ。

独学でプログラミングをはじめてみたけど、このままの学習方法に不安を感じているのなら、
オンラインスクールで現役エンジニアのサポートがあるテックアカデミーがおすすめ。
スキマ時間に学べて仕事も保証。必ず副業、始められます。まずは無料でプログラミング体験

VBAのWithの使ったサンプルコード

それでは、Withステートメントの使ったサンプルマクロを紹介します。ここでは、エクセルのシート1のA1セルからF6セルまでの編集をするマクロにおいて、ワークシートオブジェクトのシート1をWithステートメントで参照した場合と、Withステートメントなしで、繰り返しワークシートオブジェクトを参照するVBAコードで比較しています。(どちらも全く同じ処理をするマクロです)

Withステートメントありのサンプルコード
Option Explicit

Sub withステートメント使用例1()
    
    'Withステートメントでこのブック(ファイル)のワークシート1のオブジェクトを参照する
    With ThisWorkbook.Worksheets(1)
    
        'セルA1に"With"を入力する
        .Range("A1").Value = "With"
        
        'セルB2の背景色を3(赤色)にする
        .Range("B2").Interior.ColorIndex = 3
        
        'セルC3にC3セルのアドレスを入力する
        .Range("C3").Value = .Range("C3").Address
        
        'セルD4にセル(オブジェクト)数を入力する
        .Range("D4") = .Range("D4").Count
        
        'セルE5にE5セルの行数を入力する
        .Range("E5").Value = .Range("E5").Row
        
        'セルF6にF6セルの列数を入力する
        .Range("F6").Value = .Range("F6").Column
    
    End With

End Sub

ポイントは、Withステートメントをつかってシートオブジェクトのシート1を参照している点です。これによって、シート内のセルをするときにシートオブジェクトを何度も書く必要がなくなりました。Withステートメントでオブジェクトを参照している行は、ピリオド(.)から書きはじめます。

Withで参照している部分は、ピリオドをつけることを忘れないようにね。

Withステートメントなしのサンプルコード
Option Explicit

Sub withステートメント使用しない()

        'セルA1に"With"を入力する
        ThisWorkbook.Worksheets(1).Range("A1").Value = "With"
        
        'セルB2の背景色を3(赤色)にする
        ThisWorkbook.Worksheets(1).Range("B2").Interior.ColorIndex = 3
        
        'セルC3にC3セルのアドレスを入力する
        ThisWorkbook.Worksheets(1).Range("C3").Value = ThisWorkbook.Worksheets(1).Range("C3").Address
        
        'セルD4にセル(オブジェクト)数を入力する
        ThisWorkbook.Worksheets(1).Range("D4") = ThisWorkbook.Worksheets(1).Range("D4").Count
        
        'セルE5にE5セルの行数を入力する
        ThisWorkbook.Worksheets(1).Range("E5").Value = ThisWorkbook.Worksheets(1).Range("E5").Row
        
        'セルF6にF6セルの列数を入力する
        ThisWorkbook.Worksheets(1).Range("F6").Value = ThisWorkbook.Worksheets(1).Range("F6").Column

End Sub

Withステートメントをつかったサンプルコードと比較すると、オブジェクトを参照するためのコードの分だけ長くなっています。このサンプルマクロの規模であっても、かなりの文字数を減らせることができていますので、プログラムの規模が大きくなるにつれ文字数の削減の効果は大きくなっていくと言えます。

Withでオブジェクトのプロパティやメソッドを連続して指定する

Withステートメントでは、プロパティやメソッドを連続して指定ができます。さきほどのサンプルコードでは、Withステートメントでシート1を参照しました。これでシート1のプロパティやメソッドについてコードの冒頭にピリオドをつけることで扱えるようになりました。

こんどは、WithステートメントでA1セルを参照してみます。

シート1のA1セルをWithステートメントで参照したサンプルコード
Option Explicit

Sub withステートメント使用例3()
    
    'Withステートメントでこのブック(ファイル)のワークシートのA1セルのオブジェクトを参照する
    With ThisWorkbook.Worksheets(1).Range("A1")
    
        'ピリオドを書くだけでシート1のA1セルに対するメソッドやプロパティに対して指定ができる
        .Value = "A1セル" 'Valueプロパティで文字列を入力する
        .Interior.ColorIndex = 3 'Interiorプロパティ背景色を赤色にする
        .Copy 'Copyメソッドで文字列をコピーする
        .Offset(0, 1).PasteSpecial Paste:=xlPasteValues 'PasteSpecialメソッドとOffsetプロパティでA1セルの右隣のセルに貼り付ける

    End With
  Application.CutCopyMode = False'コピーモードを解除する

End Sub

A1セルをWithステートメントで参照して、メソッドやプロパティを以下のように指定しています。

  • Valueプロパティ
    A1セルに文字列”A1セル”を入力する指定をしています。
  • Interiorプロパティ
    A1セルの背景色を赤色にする指定をしています。
  • Copyメソッド
    A1セルをコピーする指定をしています。
  • PasteSpecialメソッド
    A1セルでコピーした値をB2セルに貼り付ける処理を指定しています。

Range(“A1”)セルのメソッドやプロパティを連続で指定して処理を実行できるね。

実行結果
withステートメント使用例3のマクロの実行結果画像

Withステートメントで参照したオブジェクトのメソッドやプロパティをまとめて処理できるね。

Withステートメントのネストや終了方法について

Withステートメントは、別のWithステートメントのなかに配置することで入れ子(ネスト)にできます。これは、オブジェクトの中にさらにオブジェクトがある場合に便利です。例えば、以下のコードでは、Rangeオブジェクトの中のFontオブジェクトに対してプロパティを指定しています。

Withステートメントを入れ子(ネスト)したサンプルコード
Option Explicit

Sub withステートメント使用例4()
    
    'Withステートメントでこのブック(ファイル)のワークシート1オブジェクトを参照する
    With ThisWorkbook.Worksheets(1)
    
        'Withステートメントを入れ子にしてA1セルオブジェクトを参照する
        With .Range("A1")
            .Value = "Withステートメントの(入れ子)ネスト" 'A1セルに文字を入力する
            
            'さらにWithステートメントを入れ子にしてFontオブジェクトを参照する
            With .Range("A1").Font
                .Bold = True'文字の太字にする

                .Color = vbYellow'文字色を黄色にする
                .Size = 12'文字の大きさを12にする
            End With 'Fontオブジェクトの参照を終了
        
        End With 'A1セルオブジェクトの参照を終了
    
    End With 'ワークシート1オブジェクトの参照を終了

上記のように、Withステートメントを入れ子(ネスト)にする場合、外側のWithステートメントのなかに新たなWith~End Withを書きます。

サンプルコードでは、ワークシート1を参照するためのWithステートメントのなかに、A1セルを参照したWithステートメントがあり、さらにそのなかにFontオブジェクトを参照して処理を実行しています。

Withステートメントで指定したオブジェクトの参照を終了するタイミングは、End Withの実行までとなりますので、参照の順番とは逆にフォントオブジェクトの参照が終了、つぎにA1セルの参照が終了、さいごにシート1の参照が終了といったながれです。

Withステートメントを入れ子(ネスト)にしたイメージ
Withステートメントを入れ子(ネスト)にしたイメージ図

ネストすることでオブジェクトの中のオブジェクトを参照することができるね。

WithステートメントでApplicationオブジェクトのプロパティを設定する

Withステートメントは、Applicationオブジェクトを参照することもできます。
ApplicationオブジェクトとはExcelアプリケーションのことで、このオブジェクトは画面の更新、アラート通知、数式の計算方法の切り替えなど、マクロの動作を早くするための設定をもっているため、大規模なマクロを動作する直前や直後にまとめて設定すると良いでしょう。

Withステートメントで”Applicationオブジェクト”を参照してまとめて設定値を変更するコード
Option Explicit

Sub 処理前設定()

    With Application 'アプリケーションオブジェクトを参照(Excel)
        .ScreenUpdating = False '画面更新オフ
        .DisplayAlerts = False 'エラー通知オフ
        .Calculation = xlManual '自動計算オフ
    End With

End Sub
Option Explicit

Sub 処理後設定()

    With Application 'アプリケーションオブジェクトを参照(Excel)
        .ScreenUpdating = True '画面更新オン
        .DisplayAlerts = True 'エラー通知オン
        .Calculation = xlAutomatic '自動計算オン
    End With

End Sub

Callで呼び出せるように、メインとは別のプロシージャで作っておくと便利だね。

Withステートメントでクラスオブジェクトのプロパティを設定する

Withステートメントは参照するオブジェクトを指定できることは解説しました。オブジェクトはブックやシート、セルなどがありますが、他にもクラスオブジェクトの参照ができます。

次に紹介するサンプルコードは、氏名・身長・体重を入力することで、BMIを計算し、計算結果のBMIによる判定をセルに出力するサンプルマクロです。ここでは、Withステートメントを使ってクラス内で宣言した変数に値を代入する処理をおこなっています。

Withはオブジェクトを参照できるなら、クラスもあつかえるってことだね。

まずは、出力するシートは以下のとおり。

Withステートメントでクラス内の変数に値を代入するサンプルコードを説明するためのシート

このサンプルエクセルシートに名前・身長・体重を入力して、BMIと判定結果を出力します。

このマクロのコードは以下のとおりです。

クラスモジュールのコード
Option Explicit

Public 氏名 As String
Public 身長 As Double
Public 身長M As Double
Public 体重 As Double
Public BMI As Double

氏名・身長・体重・BMIと、身長をメートル表示にした値を代入する変数をパブリック(Public)で宣言しています。パブリック(Public)で宣言する理由は、標準モジュールからクラス内の変数に値を代入する処理ができるようにするためです。なお、ここではクラスモジュールのオブジェクト名は”身体情報”としています。

続いて、標準モジュールに書いたサンプルコードです。

標準モジュールのコード
Option Explicit

Sub 身体情報を入力する()

    Dim 情報入力 As 身体情報
    Set 情報入力 = New 身体情報
    
    'Withステートメントでクラスオブジェクト(身体情報)を参照する
    With 情報入力
        'クラス変数に数値を代入する処理
        .氏名 = Application.InputBox("氏名を入力してください", "情報入力", Type:=2)
        
        .身長 = Application.InputBox("身長をcmで入力してください", "情報入力", Type:=1)
        
        .身長M = Application.WorksheetFunction.RoundUp(.身長 / 100, 1)
        
        .体重 = Application.InputBox("体重をkgで入力してください", "情報入力", Type:=1)
        
        .BMI = .体重 / (.身長M * .身長M)
    End With 'クラスオブジェクト(身体情報)の参照を終了する
        
    'Withステートメントでシート名がSheet5を参照する
    With ThisWorkbook.Worksheets("Sheet5")
        '2行目から開始する
        Dim Row As Long: Row = 2
        
        '空白行でないなら、ひとつ下の行へ
        Do Until .Cells(Row, 1) = ""
            Row = Row + 1
        Loop
        
        '情報をセルに出力する
        .Cells(Row, 1) = 情報入力.氏名
        .Cells(Row, 2) = 情報入力.身長
        .Cells(Row, 3) = 情報入力.体重
        .Cells(Row, 4) = 情報入力.BMI
        
        'BMIから判定結果を出力する
        If .Cells(Row, 4) >= 5.5 And .Cells(Row, 4) <= 9.9 Then
            .Cells(Row, 5) = "低い"
            
        ElseIf .Cells(Row, 4) >= 10 And .Cells(Row, 4) <= 19.9 Then
            .Cells(Row, 5) = "標準"
            
        ElseIf .Cells(Row, 4) >= 20 And .Cells(Row, 4) <= 24.9 Then
            .Cells(Row, 5) = "やや高い"
        
        ElseIf .Cells(Row, 4) >= 25 Then
            .Cells(Row, 5) = "高い"
            
        End If
    
    End With 'Withステートメントでシート名がSheet5の参照を終了する

End Sub

Dim 情報入力 As 身体情報 ~ Set 情報入力 = New 身体情報

上記にてクラスオブジェクトとして変数を宣言しています。そして、次の行のコードで”情報入力”という変数でクラスオブジェクトを使えるようにしています。
ここでは詳しく書きませんが、これをインスタンス(実体化)と言います。

With 情報入力 ~ End With

Withステートメントを使って、クラスオブジェクトである身体情報クラスを参照しています。
Withの中でクラスが持つ変数に値を代入する処理をしていますが、このサンプルコードでは、Application.InputBoxを使ってユーザーから入力された値を受け取り、それぞれの変数に代入しています。

With ThisWorkbook.Worksheets(“Sheet5”) ~ End With

Withステートメントを使って、ワークシート名が”Sheet5″のシートを参照しています。
Withの中では、クラス変数に代入した値を参照したエクセルシートに出力する処理をしています。さいごの判定(E)列は、BMI(D)列に入力された値を判定するためにIf文を使って、範囲ごとの判定結果を返す処理となっています。

サンプルマクロの実行結果(※10名分のデータを入力した状態)
Withステートメントでクラス内の変数に値を代入するサンプルコードを説明するためのシート(実行結果)

Withステートメントでクラスオブジェクトを参照して、それぞれの変数に値を代入することとシートへの出力ができました。

独学の学習効率でお悩みの人必見!
<動画学習見放題サービス>

初心者にやさしいチューターなら今すぐにはじめられる

オンラインで学習したい
プログラミングで副業をはじめたい
パソコン・エクセルの学習をしたい

VBAにおけるWithステートメントを使うときの注意点

Withステートメントを入れ子にするときは、以下の点に注意してください。

Withステートメントは必ずEnd Withステートメントで終了しなければなりません。入れ子にした場合は、内側から順にEnd Withステートメントを記述します。

入れ子にしたWithステートメント内で、ピリオドから始まったコードは、直前(そのステートメントが含まれる最も内側)のWithステートメントで指定したオブジェクトのプロパティやメソッドとみなされます。

入れ子にしたWithステートメント内で、外側のWithステートメントで指定したオブジェクトのプロパティやメソッドにアクセスする場合は、完全修飾オブジェクト参照(すべての親オブジェクト名を含む)を指定する必要があります。

Withステートメントを入れ子にすると、コードの可読性が悪くなる可能性があるため、Withステートメントを入れ子(ネスト)にする場合は、変数などでオブジェクトを参照する方法などと比較してコードの書きかたを検討することをおすすめします。

例えば、以下のサンプルコードでは、シート1のA1セルからE4セルまでのセル範囲をWithステートメントで参照しています。

Option Explicit

Sub withステートメント使用例6()
        
    'Withステートメントでこのブック(ファイル)のワークシート1オブジェクトを参照する
    With ThisWorkbook.Worksheets(1).Range("A1:E4")
        .Value = 10 '範囲内のセルに10を入力する
        .Font.Size = 11 '範囲内のセルのフォントサイズを11にする
        .Font.Color = 0 '範囲内のセルのフォントカラーをクリアにする
        .Font.Bold = False '範囲内のセルの太字を通常に戻す
    End With 'ワークシート1オブジェクトの参照を終了

End Sub

このVBAコードを、オブジェクト変数をつかった参照に書きかえると以下となります。

Option Explicit

Sub 変数でセル範囲を参照したコード()
    
    'オブジェクト変数にセル範囲("A1:E4")を代入する
    Dim セル範囲 As Range: Set セル範囲 = ThisWorkbook.Worksheets(1).Range("A1:E4")
    
    セル範囲.Value = 10 '範囲内のセルに10を入力する
    セル範囲.Font.Size = 11 '範囲内のセルのフォントサイズを11にする
    セル範囲.Font.Color = 0 '範囲内のセルのフォントカラーをクリアにする
    セル範囲.Font.Bold = False '範囲内のセルを太字を戻す

End Sub

Dim セル範囲 As Range: Set セル範囲 = ThisWorkbook.Worksheets(1).Range(“A1:E4”)

オブジェクト変数の”セル範囲”に参照したセル範囲を代入しています。これを実行すると、以降は”セル範囲”で参照したセル範囲に対する処理が実行できます。

どちらも同じ処理を実行するよ。

変数のとり扱い方については以下の記事で解説しています。変数の基本的な使い方について知りたい人は以下の記事もあわせてご覧ください。

Withステートメント内で変数や関数を使うときの注意点

Withステートメント内では、ピリオドから始まるステートメントは、Withで指定したオブジェクトのプロパティやメソッドとみなされます。しかし、変数や関数を使う場合は、ピリオドをつけないようにしてください。ピリオドをつけると、変数や関数がオブジェクトのメンバーとして解釈されてしまい、エラーになる可能性があります。

以下のサンプルコードでは、変数iや関数MsgBoxをWithステートメントの中で使っていますが、ピリオドをつけるとエラーが発生します。

Option Explicit

Sub withステートメント使用例7()
    
    Dim i As Long
    
    'Withステートメントでワークシート4のA1セルからE4セルまでの範囲を参照する
    With ThisWorkbook.Worksheets(4).Range("A1:E4")
    
        For i = 1 To .Count 'Withステートメントで参照した範囲内のセルの個数分(20)繰り返す
            MsgBox .Cells(i).Value'メッセージボックスで各セルに入力された値を表示する
        Next i
    
    End With 'ワークシート4オブジェクトの参照を終了

End Sub

For i = 1 To .Count

ForNext文をつかって繰り返し回数を指定していますが、.Conut ではWithステートメントで参照しているセル範囲のセルの数という意味です。参照しているA1からE4までのセルの個数は20であることから、変数iが1から20の間は処理を繰り返します。

実行結果としては、A1セルからE4セルに入力された値を順番にメッセージボックスに表示します。

Withステートメント内で変数や関数を使うときは、ピリオドをつけないように。

繰り返し文については、以下の記事でくわしく解説しています。For文以外の繰り返しの書きかたについても紹介していますので、あわせて参考にしてください。

Withで参照しているオブジェクトの位置や状態は変更しない

Withステートメントで参照しているオブジェクトの位置や状態が変わってしまうコードは書かないようにしましょう。なぜなら、あとからコード読むときに読み取れなくなってしまうからです。

では、位置や状態が変わってしまうケースを以下に紹介します。

サンプルのエクセルのシート1のA1 セルにA2セルにはそれぞれ文字が入力されています。

Withステートメントで注意すべきコードを説明するためのサンプル画像

上記のエクセルのA1セルをWithステートメントで参照したサンプルコード

Option Explicit

Sub withステートメント参照している位置や状態がかわるコード()
    
    'Withステートメントでこのブック(ファイル)のワークシート1のA1セルを参照する
    With ThisWorkbook.Worksheets("sheet1").Range("A1")
                   
        Debug.Print .Value 'A1セルの内容をイミディエイトウィンドウに出力する[1]
        
        'シート1の1行目に行を挿入する
        ThisWorkbook.Worksheets("sheet1").Rows(1).Insert
        
        Debug.Print .Value 'A1セルの内容をイミディエイトウィンドウに出力する[2]
        
        'シート1の1列目に列を挿入する
        ThisWorkbook.Worksheets("sheet1").Columns(1).Insert
        
        Debug.Print .Value 'A1セルの内容をイミディエイトウィンドウに出力する[3]
        
        'シート1のA1セルの入力された文字を削除する
        ThisWorkbook.Worksheets("sheet1").Range("A1").ClearContents
        
        Debug.Print .Value 'A1セルの内容をイミディエイトウィンドウに出力する[4]
        
    End With 'ワークシート1オブジェクトの参照を終了

End Sub

サンプルコードのプロシージャでは、全部で4つの「Debug.Print .Value」があります。そしてそれぞれの「Debug.Print .Value」の間には、シートに行や列を挿入したり、セル内の文字を削除するなどを実行しています。つまりWithで参照しているA1セルが行や列の挿入によって移動してしまっています。

この場合、「Debug.Print .Value」の[1]~[4]の結果としてはどうなるでしょうか。

結果から言えば、これらすべて「これはA1セルです。」がイミディエイトウィンドウに出力されます。
Withステートメントで参照しているオブジェクトはA1セルですが、[2]の出力時は行が挿入されて元はA1セルであったセルはA2セルになっています。
さらに[3]の出力時は列も挿入されているためB2セルに変わったとしても、結果は変わらず「これはA1セルです。」を表示します。

この結果から、Withステートメントの参照は、参照を開始した時点でのA1セルを参照していると言えます。その証拠に、このプロシージャを2回目実行した場合は、新たなA1セルを参照しており、そのセル内には何も入力されていないため、イミディエイトウィンドウに空白が返ってきます。

Withで参照しているオブジェクトの位置や状態を変更させることは控えておきましょう。

なぜなら、可読性が著しく悪くなるためです。
詳しく言えば、自分以外の人がコードを読むことや、書いた時点から時間が経過したあとであっても、不具合があった場合や、機能の拡張で過去に書いたコードを改めて理解する必要が出てくる可能性があるからです。
また、Withステートメントを使う目的がそもそも可読性を上げることを含めたものであるので、Withの内側で参照している位置や状態が変わって読みづらくなるのであれば、本来の効果とは逆になってしまいます。

これらを考えた場合、Withステートメントで参照しているオブジェクトをWithの内側で移動させたり、状態を変更することは避けておくほうが無難であると言えます。

Withステートメントを使いすぎるとコードが読みにくくなる可能性

Withステートメントを使うと、コード量がスリムになり、同じオブジェクトを記述する必要もなくなるためコードの入力も楽になります。しかし、Withステートメントを使いすぎることで、かえってコードが読みにくくなる場合があります。

特に、以下のような場合は注意が必要です 。

  • Withステートメントを入れ子(ネスト)にする場合
  • Withステートメント内で複数の異なるオブジェクトを操作する場合
  • Withステートメント内でオブジェクトの位置や状態を変更するようなコードを書く場合

これらの場合は、Withステートメントを多用せずに、それぞれのオブジェクト名を明示的に書き込んだ方が読み取りやすくなります。またWithステートメント以外の参照方法として、指定のオブジェクトを変数に代入する書きかたを選択した方が可読性や安全性は良くなります。

VBAのWithステートメントに関する記事まとめ

本記事では、エクセルVBAにおけるWithステートメントで特徴と使い方について解説しました。Withステートメントをうまく使うことでVBAのコードを書くボリュームを減らすことができ、可読性が良くなる効果が期待できます。

また、WithステートメントはWithステートメント中にさらにWithステートメントを書きこむことで入れ子(ネスト)にできますが、多用することで逆効果として可読性が下がってしまう点には注意が必要です。

それでは、本記事のさいごにWithステートメントについてまとめていきます。

Withステートメントの利用方法と注意点

Withステートメントは、VBAでオブジェクトのプロパティやメソッドを連続して指定するときに便利な書きかたであり、使い方次第でコードの記述量を大きく減らすことができます。しかし、Withステートメントを扱うときには、いくつかの注意事項を意識しておく必要があります。

以下にWithステートメントの利用方法と注意点をまとめます。

どのオブジェクトを参照しているかが分かりにくくなってしまうのなら使用は控えようね。

以上、エクセルVBAでWithステートメントの利用方法と注意点の解説をしました。プログラミングでは、大規模で複雑な処理であってもシンプルで読みやすいコードで実装できることが、スキルアップにつながります。

今回紹介したWithステートメントも、使い方次第ではコード量を減らす効果はありますので、効率よくコードが書けるようになります。ただし、適切な使用方法での運用でなければ、コードを書く文字量は減らせても、プログラム全体の可読性が低下し、何をしているのかわかりにくいコードとなってしまうことに注意が必要です。

Withステートメントを適切に使うことが、マクロ開発者としてのスキルが向上するものだと覚えておくと良いでしょう。

今回はここまで。

コダマのもりブログはにほんブログ村に登録しています。
ブログの記事が役に立ったと感じて頂けたら、フォローお願いいたします。

コメント

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