このサイトはCocoonを使っています。現在「ミックスブルー [作者: y.hiroaki氏]」スキンを適用中です(^^)/

ExcelマクロVBA Withブロックの使い方(初心者向け8)

スポンサーリンク

今回もよろしくお願いしますm(_ _)m
少しずつだけど、なんだかマクロが楽しくなってきました!

くるみこ
くるみこ

おっ! いいね! 良い傾向ですね(^^♪
それでは、約束どおり前回記事で紹介した最適化するためのコードを「With」ブロックを使って汎用的に使えるようにしていきますね

前回のおさらいはこちらの記事です(^^)/ 下のカードをクリックすれば開きます

くるみこ
くるみこ

前回記事でわかったこと
・マクロ(VBA)実行時の動作をスピードアップする方法がわかりました
 「Application.ScreenUpdating」で画面描画抑止
 「Application.Calculation」で再計算を停止
 「Application.EnableEvents」でイベント発生抑止

【この記事でわかること】
Withでマクロ(VBA)実行速度がスピードアップします
・Withの使い方や注意点がわかります

スポンサーリンク

Withステートメントとは

・Withステートメントについて調べてみました

・With ステートメントの構文は 【With object [ statements ] End With】
object [必須] オブジェクトまたはユーザー定義型の名前
statements [省略可能]  object に対して実行する 1 つ以上のステートメント

「Withブロック」はどうも【With object [ statements ] End With】が一つのブロックになっているのでそう呼ぶようです
・実行時エラー 91では「オブジェクト変数または Withブロック変数が設定されていません」というメッセージがポップアップします。ここに「Withブロック変数」という表記が出てきています
・withステートメントは、指定したオブジェクトに対して複数の処理を行う場合に使用します
・withステートメントを使うことで、オブジェクトを1つ1つに書く手間の軽減とコードを見やすくできるというメリットがあります

Withステートメントの使用でスピードアップ

・Microsoft Docs Office VBA リファレンス を確認してみます

With ステートメントを使用すると、特定のオブジェクトに対してオブジェクト名の修飾を繰り返すことなく一連のステートメントを実行できます。 たとえば、1 つのオブジェクトにある複数の異なるプロパティを変更する場合は、With 制御構造の内側にプロパティの割り当てステートメントを配置してオブジェクトを 1 回参照します。これにより、プロパティの割り当てごとにオブジェクトを参照する必要がなくなります。

引用元:Microsoft Docs docs.microsoft.com › … › リファレンス › 財務諸表

・解説にはっきりと書いてありますね。オブジェクトを参照する回数が1回だけになるということですから、省略された参照回数分のロスを削減できるというわけです
これは処理を高速化するというメリットです。積極的に使っていくべきということですね !

Withステートメントを使ってみよう

・前回記事で使ったコードを使ってWithを使ってみます
・まずは前回記事のコードです。Applicationオブジェクトを何度も呼び出しています

Sub 最適化してマクロ連続実行()
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationAutomatic
    Application.EnableEvents = False
    '~この間に実際の処理が入ります~
    On Error Resume Next    'エラーを無視させます
    Call Macro1
    Call Macro2
    Call Macro3
    Call Macro4
    Call Macro5
    On Error GoTo 0         'エラー処理を戻す
    Application.EnableEvents = True
    Application.Calculation = xlCalculationManual
    Application.ScreenUpdating = True
End Sub

・こちらがWithステートメントを使って書き換えたものです

Sub 最適化してマクロ連続実行()
    With Application
        .ScreenUpdating = False
        .Calculation = xlCalculationAutomatic
        .EnableEvents = False
    End With
    '~この間に実際の処理が入ります~
    On Error Resume Next    'エラーを無視させます
    Call Macro1
    Call Macro2
    Call Macro3
    Call Macro4
    Call Macro5
    On Error GoTo 0         'エラー処理を戻す
    With Application
        .EnableEvents = True
        .Calculation = xlCalculationManual
        .ScreenUpdating = True
    End With
End Sub

・前半と後半で別々にしていますが、Applicationオブジェクトに対してWithステートメントを使用して記述しています
・前半と後半をまとめずにを書いたのには理由があります。その理由は後半の注意点で説明します

Withブロックをプロシージャにして汎用化しよう

・パフォーマンスを改善・高速化するためのApplicationオブジェクトのプロパティをプロシージャにまとめてしまいましょう

Sub マクロ開始()
    With Application
        .ScreenUpdating = False
        .Calculation = xlCalculationManual
        .EnableEvents = False
    End With
End Sub
Sub マクロ終了()
    With Application
        .ScreenUpdating = True
        .Calculation = xlCalculationAutomatic
        .EnableEvents = True
    End With
End Sub
Sub 最適化してマクロ連続実行()
    Call マクロ開始
    '~この間に実際の処理が入ります~
    On Error Resume Next    'エラーを無視させます
    Call Macro1
    Call Macro2
    Call Macro3
    Call Macro4
    Call Macro5
    On Error GoTo 0         'エラー処理を戻す
    Call マクロ終了
 End Sub

・こうしておけば、どこからでも呼び出して使うことが出来ます

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

実は、「マクロの記録」で自動記録したコードでもWithステートメントが使われていました。確認してみましょう

    'ソート実行
    With ActiveWorkbook.Worksheets("Sheet1").Sort
        .SetRange Range("A1:E11")   'ソートの範囲
        .Header = xlYes             '先頭行は見出し
        .MatchCase = False          '大文字小文字は区別しない
        .Orientation = xlTopToBottom '上下方向に
        .SortMethod = xlPinYin      'フリガナを使う
        .Apply                      'ここでソート実行
    End With
    With Selection.Font     'フォントの色を変更
        .Color = -16776961  '色指定
        .TintAndShade = 0   '色の明るさ(0=ニュートラル)
    End With
    With Selection.Interior 'セルの背景色設定
        .Pattern = xlSolid  '塗りつぶし(網かけ無し)
        .PatternColorIndex = xlAutomatic '自動
        .Color = 65535
        .TintAndShade = 0   '色の明るさ(0=ニュートラル)
        .PatternTintAndShade = 0
    End With
    With Selection.Borders(xlEdgeLeft)  '左辺の設定
        .LineStyle = xlContinuous       '直線
        .ColorIndex = 0                 '黒色
        .TintAndShade = 0               '影無
        .Weight = xlThin                '細線
    End With

・With の次に書かれているのがオブジェクトです
・End With までの間のコードには先頭に「.」があります。「.」を書くことでオブジェクトを省略しています
・省略しないで書く場合は次のようになります(ソートの部分だけ表示)

    'ソート実行
    ActiveWorkbook.Worksheets("Sheet1").Sort.SetRange Range("A1:E11")   'ソートの範囲
    ActiveWorkbook.Worksheets("Sheet1").Sort.Header = xlYes             '先頭行は見出し
    ActiveWorkbook.Worksheets("Sheet1").Sort.MatchCase = False          '大文字小文字は区別しない
    ActiveWorkbook.Worksheets("Sheet1").Sort.Orientation = xlTopToBottom '上下方向に
    ActiveWorkbook.Worksheets("Sheet1").Sort.SortMethod = xlPinYin      'フリガナを使う
    ActiveWorkbook.Worksheets("Sheet1").Sort.Apply                      'ここでソート実行

・いかがですか? これで「メリット」がわかりましたか
長いコードを何度も書く手間の削減とコードを見やすくするメリットです

Withステートメントを使う上での注意点

Withのネスト

・Withのネスト(入れ子)とは、Withブロックの中でうWithを使うことです
・先ほどのコードもあえてネストで記述することが出来ます

    'ソート実行
    With ActiveWorkbook.Worksheets("Sheet1")
        With .Sort
            .SetRange Range("A1:E11")   'ソートの範囲
            .Header = xlYes             '先頭行は見出し
            .MatchCase = False          '大文字小文字は区別しない
            .Orientation = xlTopToBottom '上下方向に
            .SortMethod = xlPinYin      'フリガナを使う
            .Apply                      'ここでソート実行
        End With
    End With

・ネストしている場合の注意点は、外側のネストは内側のネスト内ではオブジェクトを省略して書くことはできません
・内側のネスト内で外側のオブジェクトを使用する場合は、オブジェクトを含めてフルコードを書く必要があります。省略してしまうとエラーが発生したり、思わぬ結果になる可能性があるので注意が必要です

その他注意すべき点

・Withステートメントは、複数の異なるオブジェクトを指定することはできません
Withブロックの内外にジャンプしてはいけません。End Withステートメントが実行されない場合、プロシージャが終了するまでオブジェクトへの参照がメモリー内に残ったままになってしまうので注意しましょう。記事途中でApplicationオブジェクトを前半と後半に分けて書いたのはこの理由からです

くるみこ
くるみこ

どうですか。With ~ End With の使い方はわかりましたか(^^)

はい! よくわかりました! 「マクロ開始」と「マクロ終了」プロシージャも今後有効活用していきたいと思います(^^♪

くるみこ
くるみこ

今回はここまでで終了です!
この続きは次回の記事まで少しお待ちください・・・・
ご期待くださ~い(^^)/


まとめ(おわりに)

まとめと感想など

・Withを使うとオブジェクトへの参照回数が減るためマクロ(VBA)の実行速度がスピードアップすることがわかりました
・With ~ With Endのブロック内では、「.」を使ってオブジェクト名の記述を省略できるのでコード入力がスピードアップする
・Withを使うとコードがスッキリして見やすく(わかりやすく)なります
・Withをネストで使う場合、内側のWithブロック内では外側のWithのオブジェクトの省略はできません(使う場合はフルコードで書きます)
・Withブロック内から外へジャンプしたり、外からWithブロック内に入ってくることはしてはいけません

マクロ(VBA)を実行する際は必ずバックアップを取ってから行ってください
・マクロ(VBA)は実行後にファイルを保存すると元に戻すことはできません!
・実行後にファイルを保存せず終了すれば、実行前に戻すことができます!


ブログランキングに参加しています(^^)応援よろしくお願いしますm(_ _)m
にほんブログ村 IT技術ブログ VBAへ
にほんブログ村

Visual Basicランキング

今後の記事について

今回の記事はいかがだったでしょうか。皆さまのお役に立てたなら幸いです(^^;
当面は「初心者向けマクロ」の記事を継続して書いていきます

【検討中の今後の記事内容は・・・・・】
・実務に役立つものを提供できるよう現在検討中です
・その他雑記的に「小ネタなどいろいろ」・・・・・
・今後の記事にご期待ください(^^)/

サンプルファイルをダウンロードできます(下記リンク先へ)

記事で使用したサンプルファイルがダウンロードできるページを設置しています
こちら(このリンク先)からご利用ください