実践サンプルで学ぶ【Excel VBA 活用編 No.1】

Excel VBA

こんにちは。ECF Tech担当
Michiharu.Tです。

本記事はExcel VBA 活用編ということで、実際の業務効率化に役立ちそうなVBAプログラムを作るための考え方やサンプルプログラムを紹介したいと思います。今回は、表の見た目を自動で整えるための簡単な機能のマクロを考えます。

本記事の構成

本記事は次の構成をとっており、初学者にもわかりやすい記事を目指しています。

  • 仕様の説明:どのようなマクロを作るかを説明します。
  • プログラミング手順:マクロを組む順番や説明、プログラムの構成などを説明します。
  • サンプルプログラムと解説:サンプルプログラムを示し、プログラムの解説を行います。

仕様の説明

最初に仕様を決めます。仕様とは、プログラムをどのように動作させるかをまとめたものです。今回は下のようなイメージで、章・節ごとの情報が記載できるExcelシートを作成したいと思います。弊社ではこのシートを出版物の校正状況を管理するツールとして活用していますが、大中小の見出しに分けて記載したい用途があれば、なんでも利用できます。

仕様説明01

H1(A列)、H2(B列)、H3(C列)はそれぞれ見出し1,2,3を表しており、各列に文字列を入力することで、その行の背景色と文字色が自動で次のように変わるものとします。

  • A列:背景色→濃い青、文字色→白
  • B列:背景色→青、文字色→白
  • C列:水色、文字色→変更なし

指摘事項列には文書内の訂正箇所を指摘する内容が入ります。修正列は修正したかどうかを入力することができます。

使いやすさの観点

ここでもう1つ仕様を追加したいと思います。これは筆者も実際に使ってみて気づいた使いやすさの観点なのですが、A,B,C列を空にした時に背景色が自動で元に戻らない点が、かなり使いづらく感じました。そこで「A,B,C列を空にしたときは、背景色を無しに設定する」という仕様を追加します。

プログラムの設計

プログラムの設計とは、プログラムをどのように組み立てるかを考えることです。今回のプログラムでポイントとなるのは、「文字列を入力した時点でプログラムが実行される」という点です。このようなプログラムを作成するには、イベントという考え方を理解する必要があります。

イベント

イベントは、プログラムが動くきっかけとなる動作のことです。次のような動作はすべてイベントとして考えることができます。

  • キーボードから文字を入力した
  • マウスをクリックした
  • ボタンをクリックした
  • セルを移動した

Excel VBAでは、Excel上で発生する様々なイベントに対応したプロシージャが用意されており、イベントプロシージャと呼ばれています。下はワークシートにおけるイベントに対応したプロシージャの一例です。

プロシージャ名 発生するタイミング
Worksheet_Change セルの値が変更された時
Worksheet_SelectionChange 選択範囲が変更された時
Worksheet_Activate ワークシートがアクティブになった時

用意されているといっても、用意されているのはプロシージャ名を含めた定義部分のみです。処理部分はプログラムする人が自由に書くことができます。たとえば、今回のようにセルに値が入力されたタイミングで何らかの処理をしたいのであれば、Worksheet_Changeプロシージャを定義して、処理を書けば良いことになります。

今回は、Worksheet_Changeというプロシージャを定義して以下の処理を行います。

  • A列に値が入力される → 背景色を濃い青、文字色を白に変更する。
  • B列に値が入力される → 背景色を青、文字色を白に変更する。
  • C列に値が入力される → 背景色を水色に変更する。

プログラムの作成

それでは、プログラムを作成しましょう。初めにイベント処理用のメソッドを追加します。

エディタ上部分左側のプルダウンメニューからオブジェクトとして「Whorksheet」を選択します(下図)。

図解01

次に右側のプルダウンメニューからプロシージャとして「Change」を選択します(下図)。

図解02

エディタ側にWorksheet_Changeというプロシージャ定義が自動で挿入されます(下図)。

図解03

操作中に意図しないプロシージャが挿入されてしまった場合は、エディタ上で直接削除してください。

プログラム

Worksheet_Change内の処理を記述します。次のようになります。

Private Sub Worksheet_Change(ByVal Target As Range)
    If Target.Count <> 1 Then '①
        '変更されたセルが1つで無い場合はプロシージャ終了
        Exit Sub '②
    End If
    If Target.Column = 1 Or Target.Column = 2 Or Target.Column = 3 Then '③
        '変更された列が1~3列目の場合
        If IsEmpty(Target.Value) Then '④
            '空に変更された場合
            '背景色を無しにする
            Range("A" & Target.Row & ":E" & Target.Row).Interior.ColorIndex = 0 '⑤
            '文字色を黒にする
            Range("A" & Target.Row & ":E" & Target.Row).Font.ColorIndex = 1
            Exit Sub
        Else
            '何らかの値が各列に入力された場合
            If Target.Column = 1 Then '1列目に入力された
                Range("A" & Target.Row & ":E" & Target.Row).Interior.Color = RGB(65, 105, 225)
                Range("A" & Target.Row & ":E" & Target.Row).Font.ColorIndex = 2
            ElseIf Target.Column = 2 Then '2列目に入力された
                Range("A" & Target.Row & ":E" & Target.Row).Interior.Color = RGB(100, 149, 237)
                Range("A" & Target.Row & ":E" & Target.Row).Font.ColorIndex = 2
            ElseIf Target.Column = 3 Then '3列目に入力された
                Range("A" & Target.Row & ":E" & Target.Row).Interior.Color = RGB(240, 255, 255)
                Range("A" & Target.Row & ":E" & Target.Row).Font.ColorIndex = 1
            End If
        End If
    End If
End Sub

Worksheet_Changeというプロシージャ名で自動作成されたプロシージャの処理を記述したものです。プロシージャの定義部分にはByVal Target As Rangeの記述があります。これは「Targetという名前の引数で、Rangeオブジェクトを受け取る」ことを示しています。

イベントプロシージャはイベントが発生すると自動的に実行されます。この時、引数にオブジェクトが渡されます。このオブジェクトは、イベントに関する様々な情報が詰まったカプセルのようなものと考えると良いでしょう。

Worksheet_Changeプロシージャの引数Targetは、変更対象となったセルの情報をRangeオブジェクトとして持っています。プログラムを書く際は、Targetという名前を使ってオブジェクトを利用できます。

それでは、プログラムのポイントを順に確認しましょう。全体的な流れは、プログラム中のコメントを参考にしてください。以下の①~⑤は、プログラム中の①~⑤と対応しています。

If Target.Count <> 1 Then
 Targetは変更対象となるセル範囲を表します。Countプロパティは対象セルの数を表すプロパティですので、Target.Count <> 1と書くことで変更セルが1か所でなければ、という条件式となります。

Exit Sub
 プロシージャを途中終了する命令文です。

If Target.Column = 1 Or Target.Column = 2 Or Target.Column = 3 Then
 Columnプロパティは、変更されたセル範囲の最初の列の値を表します。この値を使うことで、変更された列が1列目、2列目、3列目のいずれかの時だけ処理をするようにしています。

If IsEmpty(Target.Value) Then
 IsEmpty(引数)は、引数が空かどうかをチェックします。変更された値(Target.Value)を引数として渡すことで、変更した値が空になったかどうかをチェックしています。

Range("A" & Target.Row & ":E" & Target.Row).Interior.ColorIndex = 0
セルが空になった場合の処理は上の処理になっています。分解してみていきましょう。

  1. Target.Rowは変更されたセルが何行目かを表しています。
  2. &は値同士を結合する役割があります。"A" & Target.Rowとすることで「A」という文字と行番号を結合します。Target.Row2だとしたらA2となります。"A" & Target.Row & ":E" & Target.Rowのように & を使って次々と値をつなげることで、「A2:E2」という文字列が完成します。
  3. Range(~)は引数部分に文字列を入れて、セル範囲を指定することができます。()内には2.で結合された文字列が入っていますので、Range(A2:E2)のようになり、変化したセルを含む行のA~E列を表すことになります(下図)。

図解04

  1. Range(~)で示される部分はRangeオブジェクトです。InteriorはRangeオブジェクトが示すセル範囲の内部状態に関するオブジェクトです。Interior.ColorIndexを設定することで、セルの塗りつぶし色を変更できます。「0」は無色を表します。
  2. Fontは文字に関するオブジェクトです。Fontオブジェクトの持つColorIndexプロパティを設定することで、文字色を設定できます。
    0は無色、1は、2はを表します。

プログラムの説明は以上になります。完成したら、次のような動作確認をしてみましょう。

  • A,B,C列に何らかの文字列を入れたら、背景色が変化すること
  • A,B,C列を空にしたら、背景色が白に戻ること

おわりに

今回はここまでとさせて頂きます。最後までご覧いただき、ありがとうございました。ご紹介したサンプルプログラムは、ごく基本的な機能を実装しただけのものになりますので、次のような動作に不都合を感じるかもしれません。

  • A列に値が入っているにも関わらず、B列やC列を空にする操作をすると背景色が白に戻ってしまう。

本サンプルをさらにカスタマイズし、ご自身の使いやすいツール作成を目指してみて頂ければ幸いです。

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