【VBA】Findメソッドの使い方(FindNextメソッド)
Excel VBAにはRange.Findメソッドがあります。
これはCtrl Fで出てくる検索ウィンドウと同じ仕組みになります。
簡単に書けるのですが、注意点が多く、なんとなく書くとエラー原因となってしまいます。
主に下表のメリット、デメリットがあるため、仕組みを理解する上で使うようにしてください。
メリット | デメリット |
---|---|
コードがシンプルになる | 引数を省略するとエラー原因になる |
処理時間がかかる | |
複数ヒットの処理は難しい |
この記事では↓の内容が分かります。
- Findメソッドの使い方
- Findメソッドのデメリット
- 複数ヒットの処理方法 (FindNextメソッド)
Findメソッドの使い方
Sub Sample1()
'A1:E5セルに「検索したい文字列など」があるか検索
Dim hit As Range
Set hit = Range("A1:E5").Find( _
what:="検索したい文字列など", _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
MatchCase:=True, _
MatchByte:=True)
'ヒット無し⇒hitがNothingとなる
If hit Is Nothing Then
Debug.Print "ヒット無し"
Else
Debug.Print "ヒットしたセルのアドレス:" & hit.Address
End If
End Sub
このサンプルコードはA1:E5セルに「検索したい文字列など」と書かれたセルがないか検索して、アドレスを表示させます。
ヒットなしの場合、FindメソッドはNothingを返すため、ヒットしたときだけセルアドレスを表示します。
Findメソッドは引数whatに検索したい文字列などを入れて、他の引数で細かな検索条件を設定して使います。
Findメソッドの引数は下表のようになります。
名前 | 必須 / オプション | 省略は危険 | 説明 |
---|---|---|---|
What | 必須 | 検索するデータです。 指定できるのは、文字列、または任意の Microsoft Excel のデータ型です。 | |
After | 省略可能 | このセルの後から検索を開始します。 これは、ユーザー インターフェイスから検索が実行されたときにアクティブなセルの場所に対応しています。 | |
LookIn | 省略可能 | 危険 | 使用できるのは、XlFindLookIn定数: xlFormulas、xlValues、xlComments あるいは xlCommentsThreaded のいずれかです。 |
LookAt | 省略可能 | 危険 | 次のXlLookAt定数:xlWholeあるいはxlPartのいずれかになります 。 |
SearchOrder | 省略可能 | 危険 | 次のXlSearchOrder定数:xlByRowsあるいはxlByColumnsのいずれかになります 。 |
SearchDirection | 省略可能 | 次の XlSearchDirection 定数: xlNext あるいは xlPrevious のいずれかになります。 | |
MatchCase | 省略可能 | 危険 | 大文字と小文字を区別するには、True を指定します。 既定値は False です。 |
MatchByte | 省略可能 | 危険 | 2 バイトの言語サポートが選択またはインストールされている場合にのみ使用されます。 2 バイト文字が 2 バイト文字とだけ一致するようにする場合は、True を指定します。 2 バイト文字が同等の 1 バイト文字とも一致するようにする場合は、False を指定します。 |
SearchFormat | 省略可能 | 検索の書式を指定します。 |
表に省略は危険という項目を記載したのですが、LookIn、LookAt、SearchOrder、MatchCase、MatchByteは省略するとエラー原因となります。
Findメソッドを使うときは、この5つの引数を省略しないことを強く推奨します。理由は次のデメリットで説明します。
Findメソッドのデメリット
引数を省略するとエラー原因になる
先ほど述べたように引数を省略するとエラーの原因となります。
実はFindメソッドはCtrl + Fで出てくる検索ウィンドウと設定を共有しています。
(Findメソッドを使ったあとに、検索ウィンドウを表示してみてください。設定が変わっているはずです)
そのため、検索ウィンドウで画像の箇所の設定をしていると、Findメソッドを使ったときにもこの設定が反映されます。
そのため、先ほど述べた引数は必ず指定するようにしましょう。
処理時間がかかる
検索ウィンドウを使っているときを想像して欲しいのですが、結構調べるのに時間がかかりますよね。
Findメソッドはこれと同じのため、VBAとしてはかなり処理時間がかかります。
複数ヒットの処理は難しい
ヒットするセルが複数個あるときは、処理がなかなか難しいです。
この後、複数ヒットを処理するコードをお見せするのでご覧ください。
複数ヒットの処理方法(FindNextメソッド)
Sub Sample2()
'A1:E5セルに「検索したい文字列など」があるか検索
Dim hit As Range, searchRng As Range
Set searchRng = Range("A1:E5")
Set hit = searchRng.Find( _
what:="検索したい文字列など", _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
MatchCase:=True, _
MatchByte:=True)
If Not hit Is Nothing Then
'最初にヒットしたセルアドレスを変数に保存
Dim firstAddress As String
firstAddress = hit.Address
'すべて検索するまで処理をループする
Do
Debug.Print "ヒットしたセルのアドレス:" & hit.Address
'FindNextメソッドで次のセルを検索
Set hit = searchRng.FindNext(hit)
'ループを抜ける処理
If hit.Address = firstAddress Then Exit Do
Loop
End If
End Sub
複数ヒットを処理したいときには、このような複雑なコードを書く必要があります。
複数ヒットを処理するときにはFindNextメソッドを使います。
このメソッドは検索ウィンドウの「次を検索」ボタンを押すのと同じ動作をします。
つまり、複数ヒットをすべて処理するにはループを使って、FindNextメソッドを何度も実行する必要があります。 (このためコードが複雑になります)
'最初にヒットしたセルアドレスを変数に保存
Dim firstAddress As String
firstAddress = hit.Address
'すべて検索するまで処理をループする
Do
Debug.Print "ヒットしたセルのアドレス:" & hit.Address
'FindNextメソッドで次のセルを検索
Set hit = searchRng.FindNext(hit)
'ループを抜ける処理
If hit.Address = firstAddress Then Exit Do
Loop
サンプルコードのポイントはこの部分です。
複数ヒットをすべて処理するためDoループを使っています。
検索ウィンドウで「次を検索」を押し続けると分かるのですが、最初のセルに戻ってきます。
そのため、最初のセルアドレスを保存しておいて、アドレスが一致したときもループを抜けるようにしておきます。
複数ヒットを処理するときは、このループを抜ける処理を書く必要があるので覚えておいてください。