Microsoft Office製品に搭載されている簡易なプログラミング言語であるVBA。今回はExcelでの作業でよくありがちな「条件に一致した行(列)を選択する」というプログラムを作成した後、繰り返し使用する為にマクロを作成し、アドインで簡単に呼び出す方法を解説します。

チャレンジ&ナレッジ最終更新日: 20181116

時短テクニック Excel VBA:実践編 条件一致とアドイン化

  • このエントリーをはてなブックマークに追加

Microsoft Office製品に搭載されている簡易なプログラミング言語であるVBA。今回はExcelでの作業でよくありがちな「条件に一致した行(列)を選択する」というプログラムを作成した後、繰り返し使用する為にマクロを作成し、アドインで簡単に呼び出す方法を解説します。

VBAで条件に一致する行を選択するマクロ

今回は以下のような表から特定の条件を満たしている行を一瞬で選択状態にする方法を紹介したいと思います。

エクセル画像

具体的には、この表から、お住まいが東京の人(D列に「東京」と入力してある)の行だけを一発で選択する処理を書いていきます。今回、使用している文法の説明は後ほど行いますので、まずは以下のコードをVBE(Visual Basic Editor)の「標準モジュール*」の中にコピー&ペーストしてください。
*VBE(Visual Basic Editor)の起動方法については「時短テクニック Excel VBA:環境構築編」を参照してください

サンプルコード①

Sub Test()
   On Error Resume Next
   Dim cellObj As Range
   Dim myCells As Range
   For Each cellObj In Selection
      If cellObj.Value = "東京" Then
         If myCells Is Nothing Then
            Set myCells = cellObj
         Else
            Set myCells = Union(myCells, cellObj)
        End If
      End If
    Next cellObj
    myCells.EntireRow.Select
End Sub

標準モジュールの中にプログラムのコードをコピー&ペースト標準モジュールの中にプログラムのコードをコピー&ペースト

これでVBE側の準備は完了です。

マクロの実行方法

さて、ここから実際に行を選択する処理に移ります。

次に、Excelのワークシートの画面に戻ってください。この表の中のD列の、抽出したい行をドラッグして選択してください。今回のプログラムでは、「選択している範囲から“東京”と書いてあるセルを見つける」という判断の仕方をしているため、このようなやり方をします。

D列内の必要な行を選択。選択範囲にD列以外の列が含まれていても問題はないD列内の必要な行を選択。選択範囲にD列以外の列が含まれていても問題はない

次に、[開発]タブの中の[マクロ]をクリックしてください。そうすると次の画面のように「Test」というマクロ(プログラム)がリストの中に入っているはずです。これが先ほどVBEにコピー&ペーストしたプログラムです。すでに選択されている状態ですので、[実行]ボタンをクリックしてください。

マクロ

そうすると、作成したプログラムが実行され、以下のように、D列に「東京」と入力されてある行だけが選択状態になります。あとは、右クリックのメニューから[削除]をクリックするなり、コピーして別のシートに貼り付けるなどして抽出することができます。

D列に「東京」と書いてある行だけが一発で選択されたD列に「東京」と書いてある行だけが一発で選択された

プログラムの実行は、VBEの画面からも行えます。先ほどと同じように、D列内の抽出を行いたい行範囲を選択したうえで、VBEの画面を表示させ、マウスカーソルがこのプログラムコードの中にあることを確認した上で、画面上部にある「▶」の部分をクリックしてください。ただし、プログラムを実行しても画面は自動では遷移しないので、実行結果を見るには、Excelに戻ってください。

プログラムはもちろんVBEからでも実行できるプログラムはもちろんVBEからでも実行できる

使われている文法の解説

上記のコードは、実行ボタンを押すだけで動くので詳細な文法を理解していなくても使用できますが、どのような理屈で動いているのかを簡単にでも知りたいという方のために、使用されているVBAの文法を解説します。

On Error Resume Next
VBAなどのプログラミング言語では、コードにエラーがあるとその部分で処理が止まってしまいます。2行目のOn Error Resume Nextとは、命令の一種で、もしエラーが起きても止めずにそのまま先の処理を続けたいときに用いられます。この1文は書かなくても実行は可能ですが、万が一何らかの理由でエラーが起こった際の回避策として記入しています。

Dim cellObj As Range / Dim myCells As Range
プログラミングには「変数」と呼ばれるものがあります。これは、取得した値を一時的に記憶してしまっておく箱のようなものだとお考えください。そして、しまっておく収納物(例えば、文字列なのか数字なのか)によって、変数の箱を使い分けます。つまり収納物に応じた箱の形があるということですが、この箱の形を変数の「型」と言います。

このDimから始まる文は、変数の型を宣言する(=箱の種類をあらかじめ指定し用意する)部分であり、次のように記述します。

dim [①変数の名前] as [②変数の型]

①の変数の名前は何でも構いません。日本語でも動作します。②の変数の型には、いろいろな種類があり、ここではすべて説明できませんが、ここではcellObjやmyCellsという変数名をつけて「Range型」に指定しているのだ、ということがわかれば良いと思います。ちなみに「Range型」には、「セルやセル範囲」を収納するための型です。

For Each ~ Next
このステートメントは、Excel内の集合しているオブジェクトそれぞれに対して繰り返し処理を行うためのもので、以下のような記述の仕方をします。

For Each [①オブジェクト変数] in [②処理対象のオブジェクトの集合/かたまり]
[③処理]
Next

②には、今回“Selection”というものを入れましたが、こちらもVBAに用意されている表現で、選択しているセルを表します。つまり、上記のFor Eachの例では、②選択範囲(D3からD22セル)を処理の範囲として、各セルを、①cellObjという名前の変数に当てはめて、③の処理を上のセルから1つ順番に実行し、選択範囲のセルすべてに対して処理が終わるまで繰り返すという意味になります。

If
Ifは以下のような形を取ります。条件式①が正しければ、[処理A]を実行し、そうでなければ[処理B]を実行するというものです。

If [条件式①] Then
[処理A]
Else
[処理B]
End If

このコードでは、1つのIfの中にもう1つ別のIfが入っており入れ子の構造になっています(以下のように、黄色いIfの中に青いIfのかたまりが入っているとお考えください)。

サンプルコード②

If cellObj.Value = "東京" Then
If myCells Is Nothing Then
Set myCells = cellObj
Else
Set myCells = Union(myCells, cellObj)
End If
End If

最初にある”If objCell.Value = “東京” Then”という表現ですが、先ほどのように、objCellは選択範囲の各セル1つひとつのことを表し、Valueは、セルに入力されている値のことを表します。つまり、このIf文は、「もしセルの値が”東京”であるならば」という意味になります。

その条件を満たした場合、上記サンプルコード②内コードの青で示した5行のコードを実行し、もし条件を満たさない場合は終了(End If)して、For Each~Nextの繰り返し処理によって、また次のセルが処理対象になり、同じことを行います。

Union
このコードの中で一番重要なところです。先にこのサンプルコード②で何をやろうとしているのかをお伝えすると、For Each~Nextの繰り返し処理によって、D3からD22のセルに対して順番に、値が“東京”であるかを調べます。そして、もしセルが“東京”であった場合、そのセルを “myCells”という名の変数に次々と入れていきます。こうすることで、For Each~Nextのループがすべて終わった頃には、該当セルがすべてmyCellsに格納されることになります。

しかし、複数のセルを1つの箱(=変数)に入れていくには簡単にはできず、そのための方法が“Union”です。これは、Union([セル1],[セル2],[セル3]・・・[セル30])と記述し、複数のセルを1つのセルのように扱うことができる表現です。

サンプルコード②の4行目の部分を抜き出したのが以下サンプルコード③です。後半の黄色の部分でmyCellsとcellObjを合体させています。myCellsとは前述の通り、“東京”に合致したセルが入っている箱(変数)であり、そこに新たに“東京”と記入されたcellObjを合体させ、それを新たにmyCellsという箱(前半の緑の部分)に格納する、というのが以下のコードです。

サンプルコード③

Set myCells = Union(myCells, cellObj)

myCellsとcellObjという箱を新たにmyCellsという箱に収納する、といいましたが、ループの1週目ではmyCellsには何も値が収納されていません(その状態でサンプルコード③の部分を実行するとエラーになります)。そこで行うのが、以下の処理です。

If myCells Is Nothing Then
Set myCells = cellObj

もしmyCellsという箱がNothing(空)の場合は、まずmyCellsにcellObj(※上記の表の場合、最初に“東京”に合致するD5セルのこと)を格納してあげるのです。

EntireRow
EntireRowは、行全体を参照するための表現です。ここまでの処理でmyCellsにはD列が“東京”という値のセルすべてがつまっているため、以下の表現は

myCells.EntireRow.Select

「“東京”という値のセルの行全体を選択する」という意味になります。
これが今回のコードの全容です。

作ったコードをカスタマイズしてみる

これで最初の目的を達成しましたが、このままではまったく汎用性がありませんので少々改造してみましょう。最初に示したコード内の6行目に以下の記述があります。

If cellObj.Value = "東京" Then

これは説明の通り、「もし選択している各セルの値が“東京”ならば」という意味を表しています。そこで、もしここに“東京”以外の条件を入れたい場合は、違う文字列に変えてください。

また、空白のセルを探したい場合、以下のように記述します。

If cellObj.Value = "" Then

またExcelで表を管理するときに、行に何らかの区別をつける目的でセルの背景に色を塗ることは多いと思います。例えば、以下の表を見てください。

表で特定行に色をつけるのはよく見られる光景だ表で特定行に色をつけるのはよく見られる光景だ

この表から「色を塗っている行だけを選択する」というプログラムを作る場合、先ほどのIfから始まる6行目を以下のように変更します(※塗っている色は何色でも構いません)。

If Not cellObj.Interior.ColorIndex = xlNone Then

この記述は「もし選択している各セルの背景の色(=ColorIndex)が塗りつぶしなし(=xlNone)でないならば」という意味を表しています。つまり何らかの色がある、という条件になります。

6行目を上記に書き換え、抽出したい行範囲をドラッグして選択した上で、プログラムを実行してください。上記の表での場合7行目、15行目、20行目が選択されます。すべての列に色が塗ってあるので、選択する列は、先ほどと同じようにD列である必要はありません。また複数列を選択していても動作します。

ちなみに、今回では条件に該当する「行」を選択しましたが、「列」を選択する場合はどうすればよいでしょうか。この場合、14行目に「myCells.EntireRow.Select」という記述を以下のように変更してください。

myCells.EntireColumn.Select

あとは表の中で条件を判定するための行を選択した上で、同じようにプログラムを実行するだけです。例えば、以下のように、23行目に「選択」と書いてある列だけを選択する例を紹介します。

エクセル画像23行目に「選択」と書かれた列(上図赤枠)だけを選択したい

23行目のA列からI列までドラッグして選択した上で、以下のコードを実行してください。最初に紹介したプログラムから変更している箇所を赤字で示します。

Sub Test()
   On Error Resume Next
   Dim cellObj As Range
   Dim myCells As Range
   For Each cellObj In Selection
      If cellObj.Value = "選択" Then
         If myCells Is Nothing Then
            Set myCells = cellObj
         Else
            Set myCells = Union(myCells, cellObj)
        End If
      End If
  Next cellObj
  myCells.EntireColumn.Select
End Sub

23行目に「選択」と書いている列だけ選択されました。

エクセル画像

作成したプログラムをExcelアドインにする

ここまで、特定の処理を行うプログラム(マクロ)を作成して実行する例を示しましたが、このままではまだ使い勝手がよくありません。せっかくプログラムを書いても、それはそのExcelファイルを開いていないと呼び出せないからです。これを他のExcelファイルでも使うには、その度に「VBEを開いてコードをコピペして…」ということ行わなければなりません。

その不便を解消するために、Excelには作成したVBAのプログラムを「アドイン」という拡張機能として保存することができます。こうすることで、そのパソコンのユーザーはどのExcelファイルからでもそのプログラムを呼び出せるようになります。以下、その手順です。

まず、先ほど作成したプログラムを含むExcelファイルの[ファイル]タブから[名前を付けて保存]をクリックし、「Excel アドイン(*.xlam)」の形式で保存します。ここで保存したファイル名がそのままExcel内で表示されるアドイン名になるので、わかりやすい名前をつけたほうがよいでしょう。ここでは「RowSelect.xlam」というファイル名にします。

[名前を付けて保存]をクリックし「Excelアドイン(*.xlam)形式」を選択する[名前を付けて保存]をクリックし「Excelアドイン(*.xlam)形式」を選択する

その後、プログラムを含むExcelファイルを閉じて、何か別のExcelファイルを開いてみてください。そして、[開発]タブの中にある[Excelアドイン]をクリックすると、先ほど作成した「RowSelect」という項目が現れていますので、チェックボックスをオンにしてください。これで、どのExcelファイルからでも使用できるようになります。

[開発]タブ、[Excelアドイン]の中から該当するアドインのチェックボックスをオンにする[開発]タブ、[Excelアドイン]の中から該当するアドインのチェックボックスをオンにする

試しに、[開発]タブの中の[Visual Basic]をクリックしてVBEを立ち上げると、RowSelectのプログラムが呼び出せるようになっています。

VBEにアドインのプログラムを表示させたところ。もちろんここでコードを修正して実行することもできるVBEにアドインのプログラムを表示させたところ。もちろんここでコードを修正して実行することもできる

ただし、Excelアドインの場合、先ほどのように[開発]タブ内の[マクロ]から呼び出すことはできないため、基本はVBEから起動することになります。もしそれさえも煩わしいという方は、「クイックアクセスツールバー」に登録するとよいでしょう。以下にその方法を示します。

まず、Excelの上部にある下図のボタンをクリックしてください。

画面上部から、「クイックアクセスツールバー」のユーザー設定を行う画面上部から、「クイックアクセスツールバー」のユーザー設定を行う

その中から[その他のコマンド]をクリックすると、以下のようにクイックアクセスツールバーを編集する画面が開きます。左のエリアの「コマンドの選択」中から、[マクロ]を選択すると「Test」というプログラムがリスト内に表示されますので、それを選択したうえで、画面中央の[追加]をクリックして画面右下の[OK]をクリックします。

「コマンドの選択」から[マクロ]を選び、リストの中に出てきた「Test」を追加する「コマンドの選択」から[マクロ]を選び、リストの中に出てきた「Test」を追加する

クイックアクセスツールバーにアイコンが追加されます。あとは、このアイコンをクリックするだけで、作成したプログラムを実行できるようになります。

クイックアクセスツールバーに、アドインのプログラムを追加したクイックアクセスツールバーに、アドインのプログラムを追加した

今回紹介したのは、とてもシンプルなプログラムで文法の解説までは行いませんでしたが、VBA言語の文法などを深く学習すれば、自分の思い通りにさらに高度な自動化処理を作ることができます。日々の仕事の中で「Excelを使っていつも同じような作業している」という方はぜひVBAによる自動化プログラムとアドインを作って、あなたならではの時短テクニックに加えてください。

パソコン工房 NEXMAG[ネクスマグ]編集部アイコン画像
ライタープロフィール パソコン工房NEXMAG
[ネクスマグ] 編集部

パソコンでできるこんなことやあんなこと、便利な使い方など、様々なパソコン活用方法が「わかる!」「みつかる!」記事を書いています。

記事を
シェア