VBA

FindNextメソッドを使って同じ検索条件で続けて検索する方法

このページでわかること

FindNextメソッドで連続検索を実行することができます。

覚えること

  1. FindNextメソッドの使い方
  2. Do Loop文の使い方

こんにちはhokkyokunです。
Findメソッドを3回にかけてご紹介しましたが、
これでとりあえずFindメソッドは最後です。

範囲内すべて検索して該当のセル位置を返す方法をご紹介します。

FindNextメソッドとは

Findメソッドは最初に見つかったセルを返して終わりです。
FindNextメソッドをうまく使うことで連続して検索することが可能です。

FindNextメソッドは
Findメソッドと同じ条件で検索を行います。
引数にセルの位置を入れます。

構文:Rangeオブジェクト.FindNext(After)

引数に入れたセル位置の次のセルから検索を開始します。
引数のセルは最後に検索されます。

引数は省略可能ですが、
その場合はRangeオブジェクトの範囲の左上からの位置を指定したとみなされます。

FindNextメソッドで二個目のセルを検索しよう

やってみましょう。
下記のような表を作りました。
リンゴが何回か出てきます。

流れとしては

  1. 先ずFindメソッドで最初の検索をしてみる。
  2. FindNextメソッドでその次の検索をしてみる。
  3. メッセージボックスで二個目の検索ができているか確かめてみる。
Sub findnext()
'テーブル化
Dim table As ListObject
Set table = ActiveSheet.ListObjects(1)

Dim srcRng As Range '検索する範囲
Dim fndRng As Range 'findメソッドで検索するセル範囲
Set srcRng = table.Range 'テーブル化した全範囲

'リンゴを検索します。A2が検索されます。
Set fndRng = srcRng.Find(what:="リンゴ", lookat:=xlWhole)

'上記のFindメソッドと同じ条件で検索します。
'A2の次のセルから検索します。最初に検索されるセルを返します。
Set fndRng = srcRng.findnext(fndRng)
MsgBox ("二個目のリンゴのセル位置は:" & fndRng.Address)
End Sub

狙った通りの結果ですね。
今度はこれを最後までやってみましょう。

範囲内を連続検索する

基本的には上記の戦略の応用で

  1. 一番目はFindメソッドで検索
  2. 二番目以降はFindNextメソッドで検索
  3. 一番目の検索したセル位置を再び検索したら処理終了

です。
2.3.の処理はDo Loop文を使用します。
長くなるのでここでは詳しくやりませんが、
これを使うことで、
ある条件になるまで処理を繰り返すことができます。

今回の場合は、
一番最初のセル位置を再び検索する
という条件になったら終了です。

Sub findnext()
'表のテーブル化
Dim table As ListObject
Set table = ActiveSheet.ListObjects(1)

Dim srcRng As Range '検索する範囲
Dim fndRng As Range 'findメソッドで検索するセル範囲
Dim ffndRng As Range 'findメソッドで最初に検索したセル範囲
Set srcRng = table.Range 'テーブル化した全範囲

Dim msg As String 'メッセージボックスに表示させる文

'リンゴを検索します。A2が検索されます。
Set fndRng = srcRng.Find(what:="リンゴ", lookat:=xlWhole)


'検索に引っかからなければプログラム終了させます。
If fndRng Is Nothing Then
    Exit Sub
End If

'A2を最初の検索したセル位置として記録します。
'一周して再びこのセルを検索したらプログラム終了とします。
Set ffndRng = fndRng

'Do loopします。
Do
    '上記のFindメソッドと同じ条件で検索します。
    'A2の次のセルから最初に検索されるセルを返します。
    
    'メッセージボックスに表示させる文を作成
    msg = msg & fndRng.Address & vbCrLf
    Set fndRng = srcRng.findnext(fndRng)
    
Loop Until fndRng.Address = ffndRng.Address

MsgBox ("リンゴのセルは:" & vbCrLf & msg)

End Sub

セルを全て拾うことができましたね。

Findメソッドはいけてない関数か?

以上でFindメソッドの使い方は終了です。

いかがだったでしょうか。
使い勝手がいいと思った方も引数多い処理多いと思われた方もいるかもしれません。

個人的には
細かく検索できるので、どんどん使うべきだと思いますし、
実務でもバリバリ動かしてます。

しかし、使いにくい弱点もあります。

  • 検索条件が前回の設定に引っ張られる。
  • 遅い

検索条件ですが、
引数のLookIn、LookAt、SearchOrder、MatchByteは前回の使用時の設定が保存されます。
なので、うまく使わないと別のマクロなんかでうまく作動しないなんてこともあります。
そんなときは

Rangeオブジェクト = Range("A1").Find(what:="リンゴ", LookIn:=xlValues, lookat:=xlPart, SearchOrder:=xlByColumns, MatchByte:=False)

を最後に入れてあげると初期設定に戻りますので、試してみてください。

遅いということについては
全く持ってその通りです笑
別の記事でその遅さを検証した記事がありますので、よかったらこちらをご覧ください

個人的には数百程度のデータベースであれば全く気にする必要はないですし、
数千でも細かい検証ができるFindメソッドは処理の候補に入れるべきだと思います。

たくさん方法を知っておくことが重要だと思います。

ではでは