文字列を探す「Find」メソッド

今回の目標

「この文字列はどこにある?」や「この文字があるセルだけ処理をしたい」と、思ったあなたへ。 この記事では、Findメソッドの使い方を解説します!
基本的なだけでなく、実務で使える実例集付きです。

目標リスト

  • 文字列を検索できるようになる
  • 自作関数で文字列を検索した結果を取得できるようになる

説明

Findメソッドとは

FindメソッドはRangeオブジェクトの持つメソッドで、文字列がどこにあるかを返します。

セルの範囲内に検索文字が見つからなかった場合は「Nothing」を返します。

Findメソッドの構文と引数一覧

Findメソッドは、マクロ処理が完了するまでに2回以上使用したとき、2回目以降の規定値は『前回、指定した引数の値』となります。このため、規定値に頼らず、使用するたびに指定しましょう。

名前省略規定値説明
What不可(省略不可)検索する文字列
After可能(アクティブなセル)検索を開始するセル。
LookIn可能xlFormulas種別を指定する。セルの値(xlValues)、数式(xlFormulas)、コメント(xlComments )、スレッド(xlCommentsThreaded )のいずれかを指定。
LookAt可能xlPart検索文字は部分一致(xlPart)か、完全一致(xlWhole)か指定する。
SearchOrder可能xlByRows検索する方向は、行方向(xlByRows)か、列方向(xlByColumns)か指定する。
SearchDirection可能xlNext次に検索する方向は、前方向(xlNext)か後ろ方向(xlPrevious)か指定する。
MatchCase可能False大文字と小文字を区別するか。Trueの場合、区別する。Falseの場合、区別しない。
MatchByte可能日本語環境なら、ほとんどの場合、False全角・半角を区別するか。Trueの場合、区別する。Falseの場合、区別しない。
SearchFormat可能False検索の書式を指定する。Trueの場合、区別する。Falseの場合、区別しない。なお、事前にFindFormatで検索する書式を指定しないと、Trueにしても動作しない。

一部、Microsoft社のリファレンスを参照しています。
【Microsoft公式】 Range.Find メソッド (Excel)

FindメソッドとInStr関数との違いは??

Findメソッドと、InStr関数との違いは「検索対象」と「戻り値の値」にあります。
Findメソッドは、指定したセルの範囲から、検索したい文字列を探し、そのセルのオブジェクトを返します。
InStr関数は、指定した1つの文字列の中から、検索したい文字列が何文字目にあるかを数値で返します(見つからない場合は0を返します)

Findメソッドを使って、文字列があるセルを探す

『りんご』と記載されているセルがどのセルに存在するか、アドレスを表示します。

サンプルコード

Sub FindSample1()
    Dim rng As Range
    
    'アクティブなシートにある『りんご』のセルを探す
    Set rng = ActiveSheet.UsedRange.Find("りんご")
    
    '『りんご』がセルにない場合、Nothingを返す。
    If rng Is Nothing Then
        Debug.Print "文字列が見つかりませんでした"
    Else
        Debug.Print "見つかったセルのアドレス: " & rng.address
    End If
End Sub
【実行結果】

♦セルのどこかに「りんご」と入力されている場合♦
見つかったセルのアドレス:●●
 ※ ●●には、りんごと入力されているセルの位置が表示されます。

♦どのセルにも「りんご」と入力されていない場合♦
文字列が見つかりませんでした

複数のセルに検索文字がある場合

複数のセルに検索文字が含まれていて、それぞれに処理を行いたい場合は、Find メソッドに加えて FindNext メソッドを使用します。 挙動がややこしいため、まずはサンプルコードを動かして確認することをおすすめします。

準備は以下の変数を用意します。

  1. Range型の変数を2つ(検索対象範囲、検索結果)
  2. String型の変数を1つ(最初に見つかったセルのアドレス保持用)

検索は以下の流れになります。

  1. Range.Findで最初のセルを検索して、アドレスを「検索結果用のRange変数」に代入する。
  2. そのセルのアドレスを String型変数 に記録する。
  3. 以降の検索は、Range.FindNext(検索結果変数) を使う。
  4. FindNextは検索範囲を一周して最初のセルに戻る仕様のため、
    「最初に見つかったセルと同じか」を確認し、一致したらループを終了する。

「最初のセルに戻るチェック」処理を入れないと、無限ループになるため、注意が必要です。

サンプルコード

Sub FindSample2()
    Dim rngBase As Range
    Dim firstAddress As String
    Dim rngResult As Range
    Dim flag1 As Boolean
    Dim flag2 As Boolean
    
    Set rngBase = ActiveSheet.UsedRange
    Set rngResult = ActiveSheet.UsedRange.Find(What:="りんご")
    
    '検索した文字列があるか
    If Not rngResult Is Nothing Then
        '最初に検索したアドレスを保存(ループ終了の確認用)
        firstAddress = rngResult.address
        '検索が全て終わるまでループさせる
        Do
            '処理
            Debug.Print "見つかったセルのアドレス: " & rngResult.address
            
            '次の検索結果に進む。
            Set rngResult = rngBase.FindNext(rngResult)
            '処理中に検索文字列(りんご)が消された場合、検索結果が「Nothing」    
            flag1 = Not rngResult Is Nothing
            '検索が1周したか
            flag2 = rngResult.address <> firstAddress
        '検索文字列が消された か 検索が1周した 場合は終了
        Loop While flag1 And flag2
    Else
        Debug.Print "文字列が見つかりませんでした"
    End If
End Sub
【実行結果】

♦セルのどこかに「りんご」と入力されている場合♦
見つかったセルのアドレス:●●
見つかったセルのアドレス:●●
 ※ ●●には、りんごと入力されているセルの位置が表示されます。

♦どのセルにも「りんご」と入力されていない場合♦
文字列が見つかりませんでした

文字列があるセルのアドレスを返す関数を自作する

関数化して、使いまわす

文字列があるセルを全て検索する処理は手順が多かったり、Findメソッドの引数が前回使用した値を引き継ぐため、毎回設定したりなど、面倒なので、関数化しましょう。
文字列があるセルのアドレスを格納した配列を返す関数を作成します。なお、配列は「Variant型」で返す必要があるため注意が必要です。

サンプルコード

'----------------------------------------------------
' この関数を実行する
'----------------------------------------------------
Sub testMain()
    Dim arr As Variant
    Dim buf As Variant
    '「りんご」があるセルのアドレスを返す
    arr = FindString(ActiveSheet, "りんご")
    
    If arr(0) <> "-1" Then
        For Each buf In arr
            Debug.Print "見つかったセルのアドレス: " & buf
        Next buf
    Else
        Debug.Print "文字列が見つかりませんでした"
    End If
End Sub

'----------------------------------------------------
' 【自作関数】FindString関数
' 検索した文字列があるセルのアドレスを配列で返す
' 検索した文字列が無い場合、配列の要素0に"-1"を入れて返す
' 引数  ws        :検索対象のシート
'    strWhat   :検索する文字列
'    rngAddress:検索する範囲
'----------------------------------------------------
Function FindString(ByVal ws As Worksheet, ByVal strWhat As String, _
                        Optional rngAddress As String = "", _
                        Optional lookIn As Long = xlValues, _
                        Optional blSearchPart As Boolean = True, _
                        Optional blColumnOrder As Boolean = True, _
                        Optional blMatchCase As Boolean = True) As Variant
    Dim rng As Range
    Dim firstAddress As String
    Dim result As Range
    Dim num As Long
    Dim buf() As String
    
    '検索範囲を定める
    If rngAddress = "" Then
        Set rng = ws.UsedRange  'シート全て
    Else
        Set rng = ws.Range(rngAddress)  '特定の範囲
    End If
    
    Set result = rng.Find(What:=strWhat, lookIn:=lookIn, _
                    LookAt:=IIf(blSearchPart, xlPart, xlWhole), _
                    SearchOrder:=IIf(blColumnOrder, xlByColumns, xlByRows), _
                    MatchCase:=blMatchCase)
    
    num = -1
    
    '検索した文字列が1つ以上ある場合、真となる
    If Not result Is Nothing Then
        firstAddress = result.address
        Do
            num = num + 1
            ReDim Preserve buf(0 To num)
            buf(num) = result.address
            Set result = rng.FindNext(result)
        Loop While Not result Is Nothing And result.address <> firstAddress
    End If
    
    '検索した文字列が1つもない場合、その旨を示す配列を返す
    If num <> -1 Then
        FindString = buf
    Else
        ReDim Preserve buf(0)
        buf(0) = "-1"
        FindString = buf
    End If
End Function
【実行結果】

♦セルのどこかに「りんご」と入力されている場合♦
見つかったセルのアドレス:●●
見つかったセルのアドレス:●●
 ※ ●●には、りんごと入力されているセルの位置が表示されます。

♦どのセルにも「りんご」と入力されていない場合♦
文字列が見つかりませんでした

関連リンク

ページの先頭へ