連載
» 2016年08月18日 05時00分 公開

Excelの醍醐味! 明日からできるデータの並べ替え、検索、置換、抽出Excelマクロ/VBAで始める業務自動化プログラミング入門(7)(2/5 ページ)

[薬師寺国安,PROJECT KySS]

データの検索

 図3のような表があり、「読みを入力」に「読み」を入力して「実行」ボタンをクリックすると、その「読み」に該当するセルが選択されるマクロを書いてみよう。「実行」ボタンはExcelメニューの[挿入]→[図形]から作成している。

図3 「読みを入力」と「実行」ボタン、表が表示されている

Findメソッドの使い方

 セルに入力されているデータを検索するには、Findメソッドを使用する。書式は下記の通りだ(参考「Range.Find Method(Excel)- MSDN」)。

Findメソッドの書式

Rangeオブジェクト.Find(What:={What},LookIn:={LookIn},LookAt:={LookAt})


  • 「What」には検索するデータを指定(必須)
  • 「LookIn」には検索対象の種類を表7から指定(オプション)
  • 「LookAt」には「完全一致」または「部分一致」かを表8から指定(オプション)
表7 LookInに指定する値
設定値 説明
xlFormulas 数式
xlValues
xlComments コメント


表8 LookAtに指定する値
設定値 説明
xlWhole 完全一致
xlPart 部分一致

表の検索を行ってみよう

 マクロはリスト2のようになる。「読みを入力」の欄に入力された「読み」を、完全一致検索で行う。

Sub 検索()
  Range("D8:D17").Find(What:=Range("C4").Value, LookAt:=xlWhole).Select
End Sub
リスト2 検索処理

 図3の「実行」ボタンを選択して、マウスの右クリックで表示されるメニューから[マクロの登録]を選択する。[マクロ登録]の画面が表示されるので、「検索」を選択して[OK]ボタンをクリックする。これで、「実行」ボタンにマクロが登録された。

 では、「C4」のセルに「読み」を平仮名で入力して「実行」ボタンをクリックしてみよう。図4のように該当するセルが選択されるはずだ。

図4 指定した「読み」に該当するセルが選択された

データの検索と条件分岐の組み合わせで、データがなかった場合の処理

 では、指定した「読み」のデータが見つからなかった場合はどうするか。プログラムでは、このようなデータがなかった場合の処理を書くことが非常に大切だ。データがなかった場合は「該当データがありません!」と表示させる心遣いが必要だ。その記述方法を解説しよう。

 データがなかった場合のマクロはリスト3のように書く。

Sub 検索()
  Dim result As Range
  Set result = Range("D8:D17").Find(What:=Range("C4").Value, LookAt:=xlWhole)
  If result Is Nothing = False Then
    result.Select
  Else
    MsgBox "該当データがありません!"
    Exit Sub
  End If
End Sub
リスト3 データがなかった場合の処理

 2〜3行目でRange型のオブジェクト変数「result」を宣言し、検索結果をresult変数にSetステートメントで格納する。

 4〜9行目では、「If〜Else〜End If」ステートメントで条件分岐を行っているが、この構文については前回の「If〜Thenによる二者択一の条件分岐」「Elseで指定した条件以外の処理」などを参照してほしい。

 データがある(データがない状態ではない)場合(4行目)は、そのセルを選択し(5行目)、ない場合(6行目)はMsgBox関数でメッセージを表示する(7行目)。MsgBox関数については、後の連載で解説する。

 実行結果は図5のようになる。

図5 該当データがない場合はメッセージが表示される

FindNextメソッドと繰り返し処理の組み合わせで自動化

 次に、同性同名の人物があった場合はどうするかを考えてみよう。膨大なデータの中には当然同姓同名の人物も存在する可能性は100%ある。そのような場合、全ての人物を選択する処理を書いてみよう。

FindNextメソッドの使い方

 このような場合の処理にはFindNextメソッドを使用する。書式は下記の通りだ。

FindNextメソッドの書式

Rangeオブジェクト.FindNext({After})


 引数{After}は省略可能で、セルの場所を指定する。指定したセルの次のセルから検索が開始される。

 FindNextメソッドを使うマクロはリスト4のように記述する。

Option Explicit
Sub 同姓同名検索()
  Dim firstFindCell As Range
  Dim firstCell As Range
  Dim result As Range
  
  Set firstFindCell = Range("D8:D20").Find(What:=Range("C4").Value, LookAt:=xlWhole)
  Set firstCell = firstFindCell
  Set result = firstFindCell
  
  Do
    Set firstFindCell = Range("D8:D20").FindNext(firstFindCell)
    If firstFindCell.Address = firstCell.Address Then
      Exit Do
    Else
      Set result = Union(result, firstFindCell)
    End If
  Loop
  result.Select
End Sub
リスト4 同姓同名検索

 最初に見つかったデータを格納するRangeオブジェクト変数「firstFindCell」と、最初に見つかったデータを保持しておくための変数「firstCel」、結果を格納するRangeオブジェクト変数「result」を宣言する(3〜5行目)。

 「読みを入力」で入力された平仮名の「読み」を完全一致で検索し(7行目)、最初に見つかったセルのデータをfirstCellにセットしておく(8行目)。resultにも最初に見つかったセルのデータfirstFindCellの値をセットしておく(9行目)。

「Exit Do」で繰り返し処理から抜ける

 Do〜Loopで繰り返し処理を行う(11〜18行目)。この構文については前回の「条件が成立している間、処理を繰り返すDo While〜Loop」を参照してほしい。ここでは、繰り返しを終了する条件の「While」を使っていない。「Exit Do」ステートメントで繰り返し処理から抜けることになる(14行目)。

 セルD8〜D20の範囲のセル内を、FindNextメソッドで、最初に見つかったデータを保持しているfirstFindCellの値で検索していく(12行目)。

 最初に見つかったデータのアドレスと、次のデータのアドレスが同じの場合、つまりデータが1個しかない場合(13行目)は、それのみを選択して、繰り返し処理を抜ける(14行目)。

セル範囲を集約するUnionメソッドの使い方

 それ以外は、Unionメソッドでresultのセル範囲とfirstFindCell範囲を、1つのRangeオブジェクトに集約して返す(16行目)。この場合は変数resultに検索結果のセル範囲が集約してセットされる。

 Unionメソッドの書式は下記の通り。第1引数と第2引数は必須だ。

Unionメソッドの書式

Set {Rangeオブジェクト変数}=Union({セル範囲1},{セル範囲2}、……)


実行結果

 最後にSelectメソッドで該当するデータを全て選択する(19行目)。

 実行すると、図19のようになる。

図6 同じ読みの人が全て選択された

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。