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

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

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

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

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

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

今回はFindメソッドについて、使い方をわかりやすく解説します!

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(ゼロ)以外の数値を返しますので、その場合に複数の条件を満たす検索結果を出力表示するようにしています。

VBAの将来性

VBAのスキルを学んで業務を効率化したい

このように思っている人は多いでしょう。

VBAの用途はさまざまで、

  • VBAのスキルがあれば転職できるのでは?
  • 業務効率化のスキルは需要が高そうだから

などが上げられます。確かに、業務効率化はどこの企業も目指していて、需要が高いように見えます。ただ、VBAを扱えることが強みになるかといわれると、すこし疑問があります。

VBAは基本的にエクセル上でしか使用することができません。しかし、最近では社内書式をスプレッドシートで管理している企業も増えており、今後エクセル自体の需要が少なくなってしまう可能性も考えられます。

そうなってしまうと、VBAを習得しても活躍の場が限られてしまいますよね。そう考えると将来的にVBAの需要はあまり高くないといえます。

ではVBAを学んでいる人はどうすればいいのでしょう。VBAの将来性や今後の対策などをこちらの記事でまとめているのでぜひご確認ください。

VBAより将来的にWebプログラミング言語がおすすめな3つの理由
更新日 : 2019年10月9日

まとめ

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

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

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

LINEで送る
Pocket

SEからWebエンジニアへ転職した理由

侍エンジニア塾卒業生の小池さんは、以前は社内SEとして約5年ほど勤務していました。しかし業務内容は社内のヘルプデスク対応など、プログラムを書く仕事は全くなかったそうです。

SEながらプログラムを書けない現状に「将来仕事がなくなるんじゃないか」と不安を感じ、プログラミング学習を決意。

弊社スクールで学習し、無事ベンチャー企業のプログラマーとして転職に成功しました。そんな小池さんの学習法や転職体験談を伺いましたので、是非ご覧ください。

「プログラミングができないSEは仕事がなくなる」不安を感じたSEが未経験から転職成功するまで
更新日 : 2019年10月7日

書いた人

長野 透

長野 透

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

おすすめコンテンツ

あなたにぴったりなプログラミング学習プランを無料で診断!

プログラミング学習の効率を劇的に上げる学習メソッドを解説