【VBA入門】Find、FindNextで検索(完全一致、部分一致、複数一致)

Findメソッドって使っていますか?

Excelのシート上であるデータを含むセルを検索したい場合ってありますよね。そんな場合にFindメソッドを使用します。

この記事では、Findメソッドについて

  • Findメソッドとは
  • Findメソッドの使い方
  • FindNextで複数一致
  • FindPreviousで逆順で複数一致
  • 複数の条件で検索する方法

など基本的な内容から、応用的な内容についても解説していきます。

目次

Findメソッドとは

Findメソッドは、Excelシート上のあるセル範囲の中で指定したデータを含むセルを検索します。

検索には指定したデータの全てが一致するか検索する全文一致と、データの一部分が一致するか検索する部分一致があります。Findメソッドでは引数を指定することで全文一致か部分一致か条件を設定することができます。

詳しい使い方についてみていきましょう!

Findメソッドの使い方

Findメソッドは以下のように記述します。

Object.Find(What, After, LookIn, LookAt, SearchOrder, SearchDirection, MatchCase, MatchByte, SearchFormat)

Objectにはセル範囲のRangeオブジェクトを指定します。

データがみつかった場合は、見つかったセルのRangeオブジェクトを返します。データを含むセルが存在しない場合にはNothingを返します。

Findメソッドは引数で検索条件を指定します。引数が多いのでそれぞれの引数の説明を表にまとめました。

引数定数説明
What検索するデータを指定
After検索を開始するセルを指定
LookInxlFormulas検索対象を数式に指定
xlValues検索対象を値に指定
xlComents検索対象をコメント文に指定
LookAtxlPart一部が一致するセルを検索
xlWhole全部が一致するセルを検索
SearchOrderxlByRows検索方向を列で指定
xlByColumns検索方向を行で指定
SearchDirectionxlNext順方向で検索(デフォルトの設定)
xlPrevious逆方向で検索
MatchCaseTrue大文字と小文字を区別
False区別しない(デフォルトの設定)
MatchByteTrue半角と全角を区別する
False区別しない(デフォルトの設定)

引数のWhatのみ必ず指定する必要があります。その他の指定は省略することができます。なお、FindメソッドはObjectで指定するセル範囲の2番目のセルから検索を始めますので、注意して使いましょう!

完全一致の場合

全部が一致するセルを検索する場合は、Findメソッドの引数LookAtをxlWholeで指定します。

サンプルコードでみていきましょう。

Sub macro1()
    Dim myRange As Range
    Dim myObj As Range
    Dim keyWord As String
    
    Set myRange = Range("A1:A4")
    keyWord = "エンジニア"
    Set myObj = myRange.Find(keyWord, LookAt:=xlWhole)
    
    If myObj Is Nothing Then
        MsgBox "'" & keyWord & "'はありませんでした"
    Else
        MsgBox "'" & keyWord & "'は" & myObj.Row & "行目にあります"
    End If
End Sub
Find01
実行結果

このサンプルコードでは、Findメソッドを使って文字列’エンジニア’を検索しています。Findメソッドの引数LookAtをxlWholeで指定して、全部が一致するセルを検索するように設定しています。

検索してみつかったセルのRangeオブジェクトからRowプロパティを呼び出し表示しています。なお、Findメソッドを使ってセルがみつからなかった場合はNothingを返します。

NothingにはRowというプロパティは存在しないので、戻り値がNothingの場合Rowプロパティを呼び出そうとするとエラーが発生します。

このサンプルコードではFindメソッドが返す値がNothingかどうかIfステートメントで判定処理を行うことで、エラーが発生しないように対応しています。

部分一致の場合

一部が一致するセルを検索する場合は、Findメソッドの引数LookAtをxlPartで指定します。

サンプルコードでみていきましょう。

Sub macro2()
    Dim myRange As Range
    Dim myObj As Range
    Dim keyWord As String
    
    Set myRange = Range("A1:A4")
    keyWord = "侍エンジニア"
    Set myObj = myRange.Find(keyWord, LookAt:=xlPart)
    
    If myObj Is Nothing Then
        MsgBox "'" & keyWord & "'はありませんでした"
    Else
        MsgBox "'" & keyWord & "'は" & myObj.Row & "行目にあります"
    End If
End Sub
Find02
実行結果

このサンプルコードでは、Findメソッドを使って文字列’侍エンジニア’を検索しています。Findメソッドの引数LookAtをxlPartで指定して、一部が一致するセルを検索するように設定しています。

ちなみに引数LookAtをxlWholeで指定すると、全部が一致するセルはありませんのでFindメソッドはNothingを返し、「’侍エンジニア’はありませんでした」と表示されます。

見つからなかった場合の注意点

Findメソッドを使って検索した結果、セルがみつからなかった場合はNothingを返します。

NothingにはRowというプロパティは存在しないので、戻り値がNothingの場合Rowプロパティを呼び出そうとするとエラーが発生します。

エラーが発生しないように、IfステートメントでFindメソッドが返す値がNothingかどうか判定処理を行うなどの対処をしましょう!

FindNextで複数一致

これまでは検索で該当するセルが1つの場合を扱ってきました。でも、該当するセルが複数の場合も当然ありますよね?

そんな場合にはFindNextメソッドを使います。

FindNextメソッドはFindメソッドで開始された検索を継続します。FindNextメソッドは引数で指定したセルの直後のセルから検索を継続します。

検索の条件はFindメソッドと同じ条件で、引数で指定する必要はありません。

サンプルコードで確認していきましょう。

Sub macro3()
    Dim myRange As Range
    Dim myObj As Range
    Dim keyWord As String
    
    Set myRange = Range("A1:A8")
    keyWord = "エンジニア"
    Set myObj = myRange.Find(keyWord, LookAt:=xlPart)
    
    If myObj Is Nothing Then
        MsgBox "'" & keyWord & "'はありませんでした"
        Exit Sub
    End If
    
    Dim msg As String
    Dim myCell As Range
    Set myCell = myObj
    Do
        msg = msg & "'" & keyWord & "'は" & myCell.Row & "行目にあります" & vbCrLf
        Set myCell = myRange.FindNext(myCell)
    Loop While myCell.Row <> myObj.Row
    
    MsgBox msg
End Sub
Find03
実行結果

このサンプルコードでは、Findメソッドを使って文字列’エンジニア’を検索しています。Findメソッドの引数LookAtをxlPartで指定して、一部が一致するセルを検索するように設定しています。

セルの範囲中には該当するセルが複数あるので、FindNextメソッドを使って該当するセルの次から検索を継続するようにしています。

継続するためにDo Loop Whileステートメントを使用していますが、Findメソッドで最初にみつけたセルの行数と一致しなければ繰り返すように記述しています。

繰り返す時には無限ループにならないように注意しましょう!

実行結果を確認すると、Findメソッドは1行目の「エンジニア」ではなく、3行目の「エンジニア」を初めに検索結果として返しています。これはFindメソッドが指定した範囲の2番目のセルから検索を始めるためで、1番目セルは最後に検索され表示されています。

順番が重要になる場合は、あとで説明する「複数の条件で検索する方法」の「Or検索」のサンプルコードのようにFindメソッドを使って1セルずつ検索する必要があります。

FindPreviousで逆順で複数一致

先ほどはFindNextメソッドを使って、該当するセルが複数の場合の検索についてみてきました。

該当するセルが複数の場合、検索する順番を順方向か逆方向かどちらか指定したいですよね? そんなときはFindNextメソッドを使う場合は順方向で検索します。

では逆方向で検索する場合にはFindPreviousメソッドを使います。

Sub macro4()
    Dim myRange As Range
    Dim myObj As Range
    Dim keyWord As String
    
    Set myRange = Range("A1:A8")
    keyWord = "エンジニア"
    Set myObj = myRange.Find(keyWord, LookAt:=xlPart)
    
    If myObj Is Nothing Then
        MsgBox "'" & keyWord & "'はありませんでした"
        Exit Sub
    End If
    
    Dim msg As String
    Dim myCell As Range
    Set myCell = myObj
    Do
        msg = msg & "'" & keyWord & "'は" & myCell.Row & "行目にあります" & vbCrLf
        Set myCell = myRange.FindPrevious(myCell)
    Loop While myCell.Row <> myObj.Row
    
    MsgBox msg
End Sub
Find04
実行結果

このサンプルコードでは、先ほどのFindNextメソッドを使ったサンプルコードをFindPreviousメソッドに変更して、検索する順番を逆方向にしています。

実行結果を確認すると、逆方向に検索していることがわかります。

複数の条件で検索する方法

これまでは1つのデータを検索する場合についてみてきました。つぎは複数のデータを検索する場合についてみていきましょう!

ただし、Findメソッドは複数の条件を指定することができませんので、自作する必要があります。

Or検索

複数の条件のいずれか1つでも満たせばよいOrで検索する方法についてみていきます。

Or検索で結果を複数取得し、順方向で出力表示しようとするとFindメソッドを使って1セルずつ検索することになります。

サンプルコードで確認していきましょう。

Sub macro5()
    Dim myRange As Range
    Dim myObj As Range
    Dim keyWord As String, keyWord2 As String
    keyWord1 = "侍"
    keyWord2 = "塾"
    
    For i = 1 To 8
        Set myRange = Range("A" & i)
        
        Set myObj = myRange.Find(keyWord1, LookAt:=xlPart)
        If myObj Is Nothing Then
        Else
            msg = msg & "'" & keyWord1 & "'は" & myRange.Row & "行目にあります" & vbCrLf
        End If
        
        Set myObj = myRange.Find(keyWord2, LookAt:=xlPart)
        If myObj Is Nothing Then
        Else
            msg = msg & "'" & keyWord2 & "'は" & myRange.Row & "行目にあります" & vbCrLf
        End If
    Next i
    
    If msg = "" Then
        MsgBox "'" & keyWord1 & "'と'" & keyWord2 & "'のどちらも含むセルはありませんでした"
    Else
        MsgBox msg
    End If
End Sub
Find05
実行結果

このサンプルコードでは、Findメソッドを使って1つのセル範囲で検索を行い、Forステートメントでそれを順送りに繰り返しています。

1つのセルに対して、それぞれの条件で検索を行っています。

And検索

複数の条件をすべて満たすAndで検索する方法についてみていきます。まずひとつめの条件でセル範囲を検索し、みつかった場合は別の条件もセルの値に含まれていればOKとします。

サンプルコードで確認していきましょう。

Sub macro6()
    Dim myRange As Range
    Dim myObj1 As Range, myObj2 As Range
    Dim keyWord1 As String, keyWord2 As String
    
    Set myRange = Range("A1:A8")
    keyWord1 = "侍"
    keyWord2 = "塾"
    Set myObj = myRange.Find(keyWord1, LookAt:=xlPart)
    
    If myObj Is Nothing Then
        MsgBox "'" & keyWord1 & "'と'" & keyWord2 & "'のどちらも含むセルはありませんでした"
        Exit Sub
    End If
    
    Dim msg As String
    Dim myCell As Range
    Set myCell = myObj
    Do
        If InStr(myCell.Value, keyWord2) <> 0 Then
            msg = msg & "'" & keyWord1 & "'と'" & keyWord2 & "'は" & myCell.Row & "行目にあります" & vbCrLf
        End If
        Set myCell = myRange.FindNext(myCell)
    Loop While myCell.Row <> myObj.Row
    
    If msg = "" Then
        MsgBox "'" & keyWord1 & "'と'" & keyWord2 & "'のどちらも含むセルはありませんでした"
    Else
        MsgBox msg
    End If
End Sub
Find06
実行結果

このサンプルコードではFindメソッド、FindNextメソッドを使ってひとつめの条件で検索したセルを複数取得しています。

セルを複数取得する際に、セルの値に別の条件が含まれていれば出力表示するようにしています。セルの値に別の条件が含まれているかどうかはInStrメソッドを使って判定しています。

InStrメソッドは第1引数に検索の対象となる文字列を指定します。第2引数には第1引数に指定した文字列の中から検索する文字列を指定します。

第2引数に指定した文字列を検索して、見つかった場合は先頭からの位置を返します。見つからなかった場合は0(ゼロ)を返します。

別の条件も含んでいれば0(ゼロ)以外の数値を返しますので、その場合に複数の条件を満たす検索結果を出力表示するようにしています。

まとめ

ここでは、Findメソッドの使い方について説明しました。

FindメソッドとFindNextメソッドやFindPreviousメソッドを組み合わせることで、検索結果を複数取得することができます。

使いこなすことができるように、この記事を何度も参考にして下さいね!

この記事を書いた人

熊本在住のフリープログラマ兼ライターです。C/C++/C#、Java、Python、HTML/CSS、PHPを使ってプログラミングをしています。専門は画像処理で最近は機械学習、ディープラーニングにはまっています。幅広くやってきた経験を活かしてポイントをわかりやすくお伝えしようと思います。
お問合せはこちらでも受け付けています。
info@sss-lab.com

目次