【VBA】Findメソッドと FindNextメソッド
データベース研究所の記事です。今回は下のような住所録で氏名を検索して該当セルに移動するというマクロを作ってみましょう。もちろん Excel には最初から「検索と置換」機能が備わっていますが、VBA の Findメソッド の引数には検索開始位置を指定する After, 検索方向を指定する SearchDirection など、Excel の「検索と置換」にはない専用機能も備わっているので、Replace メソッドなどを組合わせると、もっと便利なデータベースアプリケーションを開発することもできます。
氏名 | 性別 | 年齢 | 住所 |
---|---|---|---|
波光佳 | 男 | 16 | 東京都港区北青山 2-3-2 |
中村未久 | 女 | 53 | 東京都足立区西新井 7-10-9 |
保母育実 | 女 | 17 | 東京都葛飾区宝町 2-47-8 |
高林園香 | 女 | 56 | 東京都板橋区仲宿 3-49-4 |
坪松嘉浩 | 男 | 33 | 東京都江戸川区鹿骨町 4-2-4 |
中村次郎 | 男 | 26 | 東京都新宿区四谷 1-28-8 |
土井響子 | 女 | 27 | 東京都江戸川区東葛西 6-45-4 |
千綿享典 | 男 | 60 | 東京都練馬区上石神井 2-47-0 |
三籐克昭 | 男 | 67 | 東京都世田谷区新町 2-9-8 |
井田聡美 | 女 | 67 | 東京都江東区大島 2-26-6 |
【VBA】「住所検索」マクロと「続けて検索」マクロ
それでは、Findメソッドと FindNextメソッドを使って簡単な検索マクロを作ってみますよ。
先にどんなことをやるのかってことを大まかに説明しておきます。上の図にあるように、たとえばユーザーさんが「保母育実」というキーワードで検索したときに、A 列の中から該当するキーワードのセルを Findメソッドで探し当てて、そのセルを含む行を選択します。もし該当するデータがなければ「そんなのないよ」てことを表示します。まあとにかく、下のマクロをコピーして試してみてくださいな。宣言セクションに変数のデータ型宣言をまとめて「住所検索」と「続けて検索」の2つのマクロを並べておきますよ。
'[VBA] 住所検索プログラム Dim wd As String Dim myMsg1 As String, myMsg2 As String Dim myTitle As String Dim myRange As Range, myField As Range '住所検索 Sub AddressSearch() myMsg1 = "検索キーワードを入力してください" myMsg2 = "見つかりませんでした" myTitle = "住所検索" 'ユーザーさんにキーワードの入力を促します wd = Application.InputBox(myMsg1, myTitle) 'セルA1のある表をオブジェクト型変数に入れます Set myField = Range("A1").CurrentRegion.Columns(1).Cells '入力した氏名に完全一致するデータを取得します Set myRange = myField.Find(What:=wd, Lookat:=xlWhole) 'データが空であれば「見つかりませんでした」と表示します If myRange Is Nothing Then MsgBox myMsg2 Exit Sub End If '該当するデータの行に移動します Rows(myRange.Row).Select End Sub '同じ氏名で続けて検索します Sub NextSearch() '現在の行のA列にあるセルを選択し直します ActiveCell.Cells(1, 1).Select Set myField = Range("A1").CurrentRegion.Columns(1).Cells '現在選択されているセルの次の行以降を探します Set myRange = myField.FindNext(ActiveCell.Offset(1)) Rows(myRange.Row).Select End Sub
さっそく「住所検索」と「続けて検索」を使ってみましょう。下の図のように、それぞれのマクロにボタンを用意してください。
まず「住所検索」をクリックして、現れたダイアログに「中村*」と入力してみます。「*」はワイルドカードです。「中村*」は「中村」が頭につく文字全てを対象にするという意味です。つまり「フルネーム思い出せないけど、確か苗字は中村だったよねー」て時に使うのです。[OK] ボタンを押すと「中村未久」さんのデータの行が選択されます。で、今度は同じキーワードでさらにその下を検索したいときは「続けて検索」をクリックします。すると次の「中村次郎」さんの行が選択されるのです。
コードの重要箇所を解説しておきます。まず Range型変数 myField にセル A1 を含むフィールド(表)の 1 列目を放り込みます。
Set myField = Range("A1").CurrentRegion.Columns(1).Cells
そして、Findメソッドによって、このオブジェクトから検索キーワードに一致するデータの入ったセルを抜き出して、Range 型変数 myRange に入れます。
Set myRange = myField.Find(What:=wd, Lookat:=xlWhole)
引数の what には「検索文字列」を指定します。このマクロではユーザーさんが入れたキーワードです。Lookat は「検索方法」で、上のように xlWhole と指定すれば「検索文字列に完全に一致するデータ」を探します。「部分一致」にしたい場合は xlPart を指定します。myRange.Row で該当セルの行番号が得られるので、
Rows(myRange.Row).Select
によって、該当セルの行全体を選択することになります。Findメソッドには他にも色々な引数を指定できるので、表にまとめておきますね。
Findメソッドの引数 | 説明 |
---|---|
What | 検索する文字列を指定 |
After | 検索を開始するセルを指定 |
LookIn | xlValue:セルの値、xlFormulas:数式 |
LookAt | xlWhole:全体一致、xlPart:部分一致 |
SearchOrder | xlByRows:行方向の検索を優先 xlByColumns:列方向の検索を優先 |
SearchDirection | xlNext:前方向を検索、xlPrevious:後方向を検索 |
MatchCase | True:大文字と小文字を区別する False:大文字と小文字を区別しない |
MatchByte | True:全角と半角を区別する False:全角と半角を区別しない |
SearchFormat | True:書式検索オン、False:書式検索オフ |
次は「続けて検索」マクロの解説です。
「住所検索」マクロの実行で行が選択されている可能性があるので、
ActiveCell.Cells(1, 1).Select
で A 列にあるセルを選択した状態に戻しておきます。たとえ別のマクロであっても、Findメソッドで指定した検索文字列は、新しい検索条件が指定されるまで、そのままの形で記憶されています。なので同じ条件で検索する場合にはあらためてキーワードを入力する必要はなく、FindNextメソッドを用いて直ちに次の検索を行なうことができるのです:
Set myRange = myField.FindNext(ActiveCell.Offset(1))
引数には「どこから次の検索を始めるのか」を指定します。今の場合は選択されている次のセルなので ActiveCell.Offset(1) と記述しています … ぜえぜえ。今回はさすがに話が長かったし、表まで作ったので疲れてしまいましたよ。こばとは小っちゃいので、キーボード叩くにも相当な体力を使ってしまうのです。ぜえぜえ。あとは皆さんで色々と応用してみてくださいな。
≫ データベース研究所
コメント
シート内をFind,Findnextで文字列”A”を含むセルを検出
検出セル内のみをReplaceで文字列”B”から”C”に置き換え
ということをしたかったのだけど
最初のFindで”A”を含むのセル検出ができ
Replaceで”B”から”C”に置き換えができるが
次のFindnextから”A”ではなく,”B”を検出し始める.
FindnextとReplaceの引数は独立していないのですか?
Replaceメソッドは指定文字を「検索」してから、 別の文字に置き換えるので、おそらく内部で Findメソッドを使用していると考えられます (仮にマイクロソフトが Replaceメソッドを用意していなかったとすれば、私たちは文字を置き換えるマクロを同じようなスタイルで書くはずです)。記事で述べている通り、Find で指定した検索文字列は Findnext に引き継がれるので、Replace の引数も間接的に Findnext に引き継がれることになります。
ChatGPTにVBAのFindとFindNextについて解説してもらいました。
[Q] VBAのFindメソッドをおばあさんが話すように教えてください。
[A] おばあさんがVBAのFindメソッドを教えてあげるわね。Findメソッドは、指定した範囲内から特定の文字列を検索することができるの。Excelの検索機能と同じようなものだわ。まずは、検索対象の範囲を指定するわ。例えば、A1からA10までの範囲から「りんご」という文字列を検索したい場合は、次のように書くわ。
Findメソッドは、指定した文字列が最初に出現するセルを返すわ。ただし、見つからなかった場合はNothingが返されるから、注意してね。また、検索する方向や検索の開始位置、大文字と小文字を区別するかどうかなど、検索条件を指定することもできるわ。例えば、A1からA10までの範囲から「りんご」という文字列を、下向きで検索して、大文字と小文字を区別しないようにしたい場合は、次のように書くわ。
Findメソッドは、VBAでよく使われるメソッドの1つよ。このメソッドを使えば、テキストデータを効率的に処理することができるから、覚えておくと便利よ。
[Q] VBAのFindNextについて、小学生が話すような口調で説明してください。
[A] ねえねえ、VBAのFindNextって知ってる?これは、指定した範囲内で、前回のFindで見つけた文字列の次の出現箇所を探すための命令文なんだよ。例えば、A1からA10までの範囲で、最初に見つけた「りんご」という文字列の次の出現箇所を探すには、まず最初にFindメソッドを使って「りんご」を検索するよ。すると、該当するセルが返されるんだ。そして、その次の出現箇所を探すには、FindNextメソッドを使うんだ。FindNextメソッドは、前回のFindで見つけた文字列の次のセルを返してくれるよ。例えば、以下のようなコードを書くと、最初に見つけた「りんご」の次の出現箇所を取得できるよ。
FindNextメソッドは、繰り返し処理をするときに便利なんだ。ぜひ覚えて、VBAを使ったテキストデータの処理に役立ててね!