【Excel VBA入門】Withステートメントを使ってプロパティを変更する

アイキャッチ

前回の記事では「右クリックメニューの追加」を紹介しましたが、今回はそのメニューに「書式の設定」を実装します。フォントと罫線の変更になりますが、難しいコードは出てきません。Withステートメントという命令文が出てきますが、これの雰囲気を掴んでもらえれば今回のお題はクリアです。

目次

覚える用語

Withステートメント

VBAで頻繁に使用する命令文です。

オブジェクト、プロパティ

用語だけ覚えて下さい。意味はわからなくても問題ありません。

Withステートメントで右クリックメニューに「書式を変更するメニュー」を追加

サブメニューに「書式の設定」を実装する

仕様は以下の通りです。

  1. 実行する内容は「書式を太字,赤色,赤色の下罫線(中太線)にする」
  2. 実行内容を解除(キャンセル)するメニューも作る

前回のサブメニューで書式の設定書式の解除を実行できるようにします。「VBA 書式設定」で検索してもいまいちだったので「VBA フォント」で探しました。

多分に漏れず、サンプルを頂戴します(ありがとうございます)。VBEを起動、標準モジュール を挿入、myMacroを書き換えます。

Sub 書式変更オン() 'マクロ名
    With Range("A1").Font 'A1セルのフォントを取得
        .Name = "MS明朝" 'フォントの種類を変更
        .Bold = True '太字に変更
        .Color = vbRed '赤色に変更
        .FontStyle = "斜体" '斜体に変更
        .OutlineFont = True 'これは無視して下さい
        .Size = 16 'サイズを16に変更
    End With
End Sub

Range(“A1”).FontA1セルのフォントを指定しているっぽいですね。とりあえず適当に動かして確認してみましょう。あらかじめA1セルに何かを入力しておきます。

マクロ実行の様子。詳細は以下。

Alt+F8でマクロ書式変更オンを実行すると、A1セルのフォントが変更されました。

先ほどのサイトに罫線の変更もサンプルがあったので引き続き改造してみます。

  • フォントを太字と赤色の変更のみ残し、他は削除
  • 罫線を赤色と中太線に変更
Sub 書式変更オン()
    With Range("A1").Font 'A1セルのフォントを取得
        .Bold = True '太字に変更
        .Color = vbRed '赤色に変更
        End With
    With Range("A1").Borders(xlEdgeBottom) 'A1セルの罫線を取得
        .Color = vbRed '赤色に変更
        .Weight = xlMedium '中太線に変更
    End With
End Sub
マクロに下罫線の書式変更を追加した様子。詳細は以下。

マクロ書式変更オンを実行すると、A1セルのフォント変更に加え、下罫線も追加されました。

もう一つのサブメニューに「書式の解除」を実装する

もう一つのサブメニューボタンで書式の解除を実行できるようにします。これは元に戻すだけなのでコードはサンプルのmyMacroがそのまま流用できそうです。

Sub 書式変更OFF()
    With Range("A1").Font 'A1セルのフォントを取得
        .Bold = False '太字を解除
        .Color = vbBlack '黒色に変更
    End With
    Range("A1").Borders(xlEdgeBottom).LineStyle = xlLineStyleNone '罫線を消す
End Sub

6行目のコードがmyMacroと若干変わっています。罫線を元の状態に戻すという事は「消す」事になります。ググるとLineStyle = xlLineStyleNoneで消せる事がわかりました。

ググりついでに書式をクリアできる事もわかりました。Range(“A1”).ClearFormatsでフォント含めて全ての書式設定がクリアできるので便利と思ったのですが、フォントの種類サイズもクリアされてしまいます。都合が悪いので、今回はフォントと罫線、それぞれ項目を指定して変更することにします。

この辺は仕様とにらめっこしながら適切なコードを使用する必要があります

設定した書式を解除する様子。詳細は以下。

マクロ書式変更OFFを実行すると、A1セルのフォントが元の状態に戻りました。

選択したセルでマクロを実行する

このままではA1セルしか変更できないので、選択したセルでマクロが実行できるようにします。「VBA セルの選択」で検索します。…が、検索上位を読んでみてもピンとこないですね。

ただ読んでみて何となくわかったのですが、いま求めている事は「セルを選択する」事ではなく、「選択されたセル」をどうにかしたい訳です。今度は「VBA 選択したセル」で検索します。

おっと、お目当てのサイトが見つかったようです。

Selectionプロパティを使えと書いてあります。Range(“A1”)Selectionに置き換えたら動きそうな気配(適当)。やってみましょう。

Sub 書式変更オン()
    With Selection.Font
        .Bold = True
        .Color = vbRed
        End With
    With Selection.Borders(xlEdgeBottom)
        .Color = vbRed
        .Weight = xlMedium
    End With
End Sub

Sub 書式変更オフ()
    With Selection.Font
        .Bold = False
        .Color = vbBlack
    End With
    Selection.Borders(xlEdgeBottom).LineStyle = xlLineStyleNone
End Sub
選択したセルでマクロを実行する様子。詳細は以下。

適当なセルに何か入力し、そこを選択した状態で右クリックから書式変更ONを選択すると、書式が設定されました。同じく書式変更OFFを選択すると書式が解除されました。が…

できました。と言いたいところですが不十分でした。複数範囲を選択した時、罫線の設定が範囲の一番下しか変更されません。そりゃそうですよね、下罫線ですから。

つまり中罫線も設定してやれば解決するのではないでしょうか?

Sub 書式変更オン()
    With Selection.Font
        .Bold = True
        .Color = vbRed
        End With
    With Selection.Borders(xlEdgeBottom)
        .Color = vbRed
        .Weight = xlMedium
    End With
    With Selection.Borders(xlInsideHorizontal) '選択したセルの中罫線を取得
        .Color = vbRed
        .Weight = xlMedium
    End With
End Sub

Sub 書式変更オフ()
    With Selection.Font
        .Bold = False
        .Color = vbBlack
    End With
    With Selection
        .Borders(xlEdgeBottom).LineStyle = xlLineStyleNone
        .Borders(xlInsideHorizontal).LineStyle = xlLineStyleNone '選択したセルの中罫線を消す
    End With
End Sub
複数範囲を選択した状態でマクロを実行する様子。詳細は以下。

複数範囲を選択しても、全てのセルで下罫線が設定、解除できました。セルを一つしか選択していない状態でも問題ありません(中罫線でエラーになる事はない) 。

これで希望通りの動きになりました。ちなみに21行目から24行目にWithステートメントを使ってみました。これ、要は同じコードを何回も書かなくていい仕組みです。

Withステートメント

構文

Officeリファレンスからの引用です。

With object
    [ statements ]
End With

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

https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/with-statement

意味分かりませんよね。ヘルプ読んでこんなの出てきたらやる気削がれます。ただ、その内ここに書かれていることが理解できるようになるはずです。

22,23行目でざっくり説明します。当該部をWithステートメントなしで記述するとこうなります。

 Selection.Borders(xlEdgeBottom).LineStyle = xlLineStyleNone
 Selection.Borders(xlInsideHorizontal).LineStyle = xlLineStyleNone

リファレンス引用部のオブジェクトとはコード上のSelectionにあたります。プロパティBorders(xlEdgeBottom).LineStyleBorders(xlInsideHorizontal).LineStyleです。

1つのオブジェクトにある複数の異なるプロパティ」とは「 Selectionにある Borders(xlEdgeBottom).LineStyleBorders(xlInsideHorizontal).LineStyle」と置き換えることができます。

引用に戻って要約すると、「Withで1回Selectionを参照したら、Borders(xlEdgeBottom).LineStyleBorders(xlInsideHorizontal).LineStyleは先頭にSelectionを記述しなくてもいい」となります。

With Selection  'Withでオブジェクトを参照したら
    .Borders(xlEdgeBottom).LineStyle = xlLineStyleNone  'プロパティの先頭にオブジェクトを記述しなくてもいい
    .Borders(xlInsideHorizontal).LineStyle = xlLineStyleNone
End With

オブジェクトプロパティの理解は後回しにしましょう。ここではSelectionを省略している事が理解できればOKです。

おさらいで全てのプロシージャでWithステートメントなしで記述してみます。

Sub 書式変更オン()
    Selection.Font.Bold = True
    Selection.Font.Color = vbRed
    Selection.Borders(xlEdgeBottom).Color = vbRed
    Selection.Borders(xlEdgeBottom).Weight = xlMedium
    Selection.Borders(xlInsideHorizontal).Color = vbRed
    Selection.Borders(xlInsideHorizontal).Weight = xlMedium
End Sub

Sub 書式変更オフ()
    Selection.Font.Bold = False
    Selection.Font.Color = vbBlack
    Selection.Borders(xlEdgeBottom).LineStyle = xlLineStyleNone
    Selection.Borders(xlInsideHorizontal).LineStyle = xlLineStyleNone
End Sub

Withステートメントを使ったコードと比較してもらえれば、どちらが読みやすいか分かると思います。日本語で、文脈的に主語がわかりきっているのに何回も主語を言われたら冗長ですよね?それと同じでプログラムもわかりきっている事は省略できます。

ここではWithステートメントが何となく読めるようになればOKです。記述は回数を重ねれば簡単に習得できます。

右クリックメニューに実装する

いよいよ実装です。前回のコードと今回のコードを組み合わせます。マクロ名とメニュー名は書き換えます。

Sheet1(Sheetモジュール)
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
    On Error Resume Next
    CommandBars("Cell").Controls("書式変更").Delete
    With CommandBars("Cell").Controls.Add(Before:=1, Type:=msoControlPopup)
        .Caption = "書式変更"
            With .Controls.Add
                 .Caption = "ON"
                 .OnAction = "書式変更ON" 'subプロシージャの[書式変更ON]を実行する
            End With
            With .Controls.Add
                 .Caption = "OFF"
                 .OnAction = "書式変更OFF" 'subプロシージャの[書式変更OFF]を実行する
            End With
    End With
End Sub

Private Sub Worksheet_Deactivate()
    On Error Resume Next
    CommandBars("Cell").Controls("書式変更").Delete
End Sub
ThisWorkBook(Bookモジュール)
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
    On Error Resume Next
    CommandBars("Cell").Controls("書式変更").Delete
    With CommandBars("Cell").Controls.Add(Before:=1, Type:=msoControlPopup)
        .Caption = "書式変更"
            With .Controls.Add
                 .Caption = "ON"
                 .OnAction = "書式変更ON" 'subプロシージャの[書式変更ON]を実行する
            End With
            With .Controls.Add
                 .Caption = "OFF"
                 .OnAction = "書式変更OFF" 'subプロシージャの[書式変更OFF]を実行する
            End With
    End With
End Sub

Private Sub Worksheet_Deactivate()
    On Error Resume Next
    CommandBars("Cell").Controls("書式変更").Delete
End Sub
Module1(標準モジュール)
Sub 書式変更オン()
    With Selection.Font
        .Bold = True
        .Color = vbRed
        End With
    With Selection.Borders(xlEdgeBottom)
        .Color = vbRed
        .Weight = xlMedium
    End With
     With Selection.Borders(xlInsideHorizontal)
        .Color = vbRed
        .Weight = xlMedium
    End With
End Sub

Sub 書式変更オフ()
    With Selection.Font
        .Bold = False
        .Color = vbBlack
    End With
    With Selection
        .Borders(xlEdgeBottom).LineStyle = xlLineStyleNone
        .Borders(xlInsideHorizontal).LineStyle = xlLineStyleNone
    End With
End Sub

今回もほとんど知識なしでサンプルいじって完成です。「動けばいい」の精神でサンプルから少しずつ知識を吸収していけば、その内自分でマクロを作れるようになります。焦らずにたくさんのサンプルに触れましょう。

おさらい

With [オブジェクト]と記述することでEnd Withまでの間、[オブジェクト]の記述を省略できます。

  • 同じ記述を繰り返さなくていいので入力が省力化できる
  • 可読性(読みやすさ)が上がる
よかったらシェアしてね!
  • URLをコピーしました!
目次