エクセルVBA|FindメソッドやInStr関数で文字列を検索する

VBAで文字列やセルを検索するときには、FindメソッドやInStr関数を使うと便利です。これらは、Excelシート上のセルや文字列の中に指定したデータが含まれているかどうか、またその位置はどこかを調べることができるメソッドや関数です。

しかし、これらのメソッドや関数はそれぞれ特徴や使い方が異なります。適切に使い分けることで、効率的に検索処理を行うことができます。

そこで、この記事では、FindメソッドとInStr関数の基本的な使い方から応用的な使い方まで解説します。また、それぞれのメソッドや関数の違いと使い分けについても説明します。

この記事を読めば、VBAで文字列やセルを検索する際に役立つ知識が身につくでしょう。ぜひ参考にしてください。

独学でプログラミングをはじめてみたけど、このままの学習方法に不安を感じているのなら、
オンラインスクールで現役エンジニアのサポートがあるテックアカデミーがおすすめ。
スキマ時間に学べて仕事も保証。必ず副業、始められます。まずは無料でプログラミング体験

Findメソッドとは

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

Excelでは、シート上にあるデータを素早く見つけたり、置換したりするために、「検索と置換」の機能を利用ができます。この機能は、ホームタブの「編集」グループにある「検索と選択」から開くことができます。しかし、この機能は手動で操作する必要があります。

もし、VBAをつかったマクロで自動化したい場合に使用するのがFindメソッドです。Findメソッドは、Rangeオブジェクトのメソッドで、ワークシート操作の「検索と置換」 の 「検索」 の機能をVBAで実装するために使うものです。

Findメソッドの使い方

Findメソッドの基本的な使い方

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

構文

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

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

Findメソッドは引数で検索条件を指定する

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

引数 省略 定数 説明
What 不可 検索するデータを指定
After 検索を開始するセルを指定します。検索範囲内の1つのセルを指定します。
指定したセルの次のセルから検索を開始します。なお、Afterを指定しない場合は範囲内の左上から検索が開始されます。
LookIn xlFormulas -4123 検索対象を数式に指定
xlValues -4163 検索対象を値に指定
xlComents -4144 検索対象をコメント文に指定
LookAt xlPart 2 一部が一致するセルを検索
xlWhole 1 全部が一致するセルを検索
SearchOrder xlByRows 1 検索する方向を列で指定します。
範囲内の列を下方向に検索し、最下行までいくと次の列の検索を開始します。
xlByColumns 2 検索する方向を行で指定します。
範囲内の行を横方向に検索し、最右列までいくと次の行の検索を開始します。
SearchDirection xlNext 1 順方向で検索(デフォルトの設定)
xlPrevious 2 逆方向で検索
MatchCase True 大文字と小文字を区別
False 区別しない(デフォルトの設定)
MatchByte True 半角と全角を区別する
False 区別しない(デフォルトの設定)
SearchFormat True 範囲内のセルの書式(フォントスタイルやサイズ、背景色など)を区別します。
ただし、検索を実行するためには「FindFormatプロパティ」を別途指定しておく必要があります。
False 範囲内のセルの書式を区別しません。(デフォルトの設定)

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

Findメソッドのサンプルコード

Findメソッドをつかったサンプルコードを紹介します。以下の表から特定の文字列が入力されたセルを検索してみます。

エクセルワークシート上の表
Findメソッドをつかったサンプルコード(引数の指定を最小限にしたもの)
Option Explicit

Sub Findメソッド1()

    Dim 検索範囲 As Range '検索する範囲を代入する変数を宣言する
    Dim 結果 As Range '結果を代入する変数を宣言する
    Dim 検索文字列 As String '検索文字列を代入する変数を宣言する
    
    With Sheet1
        '検索範囲を変数に代入する
        Set 検索範囲 = .Range("A1:E11")
        
        '検索文字列を変数に代入する
        検索文字列 = Application.InputBox("検索文字列を入力してください。", "検索文字列を入力", "東京都")
        
        '検索結果を変数に代入する
        Set 結果 = 検索範囲.Find(検索文字列)
        
        '検索ヒットしたときとしなかったときで処理を分岐する
        If 結果 Is Nothing Then
            Debug.Print 検索文字列 & " が入力されたセルはありませんでした。"
        Else
            Debug.Print 結果.Address
        End If
    
    End With

End Sub

こちらのサンプルコードでは、インプットボックスを表示し、ユーザーから入力された文字列を検索します。検索するセルの範囲は、A1からE11セルです。検索の結果、見つからなかった場合は、検索文字列が入力されたセルはありませんでした。と表示し、見つかった場合は、見つかったセルのアドレス(座標)を表示します。

実行結果

‘インプットボックスに”北海道”を入力した場合
>$E$8

‘インプットボックスに”オレンジ”を入力した場合
>$A$4

‘インプットボックスに”東京都”を入力した場合
>東京都 が入力されたセルはありませんでした。

このサンプルでのFindメソッドは、必須である”検索するデータ”のみを指定しており、省略できるものはなにも指定していません。つづいて一部の引数を指定してみましょう。サンプルコードのFindメソッドを以下のように書きかえてみます。

Findメソッドをつかったサンプルコード(一部の引数を指定したもの)
Option Explicit

Sub Findメソッド2()

    Dim 検索範囲 As Range '検索する範囲を代入する変数を宣言する
    Dim 結果 As Range '結果を代入する変数を宣言する
    Dim 検索文字列 As String '検索文字列を代入する変数を宣言する
    
    With Sheet1
        '検索範囲を変数に代入する
        Set 検索範囲 = .Range("A1:E11")
        
        '検索文字列を変数に代入する
        検索文字列 = Application.InputBox("検索文字列を入力してください。", "検索文字列を入力", "東京都")
        
        '検索結果を変数に代入する(引数で逆方向で検索、大文字と小文字を区別しない)
        Set 結果 = 検索範囲.Find(検索文字列, SearchDirection:=xlPrevious, MatchCase:=False)
        
        '検索ヒットしたときとしなかったときで処理を分岐する
        If 結果 Is Nothing Then
            Debug.Print 検索文字列 & " が入力されたセルはありませんでした。"
        Else
            Debug.Print 結果.Address
        End If
    
    End With

End Sub

変更したところは、Findメソッドの引数の部分だけです。
引数の”SearchDirection:=xlPrevious“で逆方向からの検索となり、”MatchCase:=False“を指定したことで大文字と小文字を区別しない。となっているはずです。

以下で実行結果をみてみましょう。

実行結果

‘インプットボックスに”北海道”を入力した場合
>$E$8

‘インプットボックスに”オレンジ”を入力した場合
>$C$11

‘インプットボックスに”東京都”を入力した場合
>東京都 が入力されたセルはありませんでした。

サンプル[Sub Findメソッド1]の実行結果と比べて、結果が異なる点は”オレンジ”を入力したときです。[Sub Findメソッド1]の実行結果は”$A$4“ですので、明らかにちがう結果となりました。[Sub Findメソッド2]では、引数 SearchDirection を指定したため、末尾から検索を開始して最初にみつかったセルのアドレスを実行結果として返しています。

条件に該当するものが複数あるときは、検索を開始する向きによって結果がかわってしまうね。

Findメソッドの戻り値

Findメソッドでは、検索範囲の先頭のセルを表すRangeオブジェクトが戻り値です。
サンプルコードにおいて”北海道”が入力されたセルは、全セル中に1つしかありませんので問題はありませんが、“オレンジ”を入力した場合は、検索で1番最初にみつかったセルのアドレスが戻ってきていることがわかります。

つまりFindメソッドでは、複数個一致した場合に対応ができません。複数セルが一致するような場面では、FindNextFindPreviousというメソッドを使います。これらのメソッドは、Findメソッドと組み合わせて使うことで、複数の一致するセルを順番に検索していくことができます。

FindNextメソッドは、Findメソッドで見つかった次の一致するセルを返します。引数はありません。FindPreviousメソッドは、Findメソッドで見つかった前の一致するセルを返します。引数はありません。

PCでスキルアップをしたい・Excelをしっかり学んで社内の評価を高めたい人は必見!
実務をプロから学べる「ユースフル」は講座の動画は永年見放題。安心のQ&A機能で分からないを解決。

FindNextメソッド

ExcelのVBAでセル範囲内の条件に一致するセルを検索する方法として、Findメソッドを紹介しましたが、Findメソッドは、最初に一致するセルを見つけるのに便利ですが、複数のセルを検索する場合は、「FindNextメソッド」や、このあと紹介する「FindPreviousメソッド」を使う必要があります。

FindNextメソッドは、Findメソッドによって開始された検索を継続して次の検索を実行します。ここでは、FindNextメソッドの使い方や注意点について解説します。

FindNextメソッドの基本的な使い方

構文

Object.FindNext (After)

FindNextメソッドを使う前に、必ずFindメソッドで最初の検索を行う必要があります。

引数の After は、指定したセルの下方 (行のときは右、列のときは下) のセルから検索を開始します。この引数を省略すると、前回の検索結果から続けての検索をします。

FindNextメソッドは、一致するセル (Rangeオブジェクト) を返します。一致するセルが見つからなかった場合はNothingを返します。

簡単に言えば、Findメソッドの次の検索をするものだね。

FindNextメソッドのサンプルコード

FindNextメソッドのサンプルコードを書いてみます。こちらのコードでもFindメソッドでつかったデータをつかって検索をしていきます。

エクセルワークシート上の表
FindNextメソッドのサンプルコード
Option Explicit

Sub FindNextメソッド1()

    Dim 検索範囲 As Range '検索する範囲を代入する変数を宣言する
    Dim 結果 As Range '結果を代入する変数を宣言する
    Dim 検索文字列 As String '検索文字列を代入する変数を宣言する
    
    With Sheet1
        '検索範囲を変数に代入する
        Set 検索範囲 = .Range("A1:E11")
        
        '検索文字列を変数に代入する
        検索文字列 = Application.InputBox("検索文字列を入力してください。", "検索文字列を入力", "東京都")
        
        'Findメソッドで検索結果を変数に代入する
        Set 結果 = 検索範囲.Find(検索文字列, LookIn:=xlValues)
        
        '検索した文字列があるセルのアドレスを表示する
        Debug.Print 結果.Address
        
        'FindNextメソッドでFindメソッドの結果を引数に指定した戻り値を変数に代入する
        Set 結果 = 検索範囲.FindNext(結果)'Findメソッドの検索結果を引数に指定
        
        '検索した文字列があるセルのアドレスを表示する
        Debug.Print 結果.Address
        
        'FindNextメソッドでFindメソッドの結果を引数に指定した戻り値を変数に代入する
        Set 結果 = 検索範囲.FindNext(結果)'FindNextメソッドの結果を引数に指定
        
        '検索した文字列があるセルのアドレスを表示する
        Debug.Print 結果.Address
    
    End With

End Sub

FindNextメソッドはFindメソッドと組み合わせる必要がありますので、Findメソッドの結果をつかってFindNextメソッドの引数に指定しています。

FindNextメソッドの引数にFindメソッドの検索結果を代入した変数を指定し、その次のFindNextメソッドでは、その前のFindNextメソッドの検索結果を代入した変数を指定しています。

続いて実行結果を確認してみましょう。

実行結果

‘インプットボックスに”オレンジ”を入力した場合
>$A$4
>$C$4
>$C$11

Findメソッドで検索でセル[$A$4]の、次の検索で該当するセルのアドレス[$C$4]と[$C$11]返すことができました。

しかし、これでは検索キーワードに一致するセルの数だけ、FindNextメソッドの処理を繰り返し書いておく必要がります通常、なにかしらのキーワードで検索をするときに、条件に一致する数は未知数であると考えるため、このままのマクロでは使い勝手が良いとは言えないものとなってしまっています。

このままだと少し使いにくいマクロなので補足していくよ。

それでは、次に繰り返し文をつかって、検索キーワードに該当するセルのアドレスをすべて表示するサンプルVBAコードを紹介していきます。ここでは DoLoop を使って繰り返しの条件を指定して、検索キーワードに一致するセルのアドレスをすべてを取り出します。

Do~Loop文は条件によって繰り返すかどうかを判断するものだよ。

FindNextメソッドで複数のセルを検索するサンプルコード

FindNextメソッドのサンプルコード(全てを検索するマクロ)
Option Explicit

Sub FindNextメソッド2()

    Dim 検索範囲 As Range '検索する範囲を代入する変数を宣言する
    Dim 結果 As Range '結果を代入する変数を宣言する
    Dim 初回結果 As String
    Dim 検索文字列 As String '検索文字列を代入する変数を宣言する
    
    With Sheet1
        '検索範囲を変数に代入する
        Set 検索範囲 = .Range("A1:E11")
        
        '検索文字列を変数に代入する
        検索文字列 = Application.InputBox("検索文字列を入力してください。", "検索文字列を入力", "東京都")
        
        '検索結果を変数に代入する
        Set 結果 = 検索範囲.Find(検索文字列, LookIn:=xlValues)
        
        '検索ヒットしたときとしなかったときで処理を分岐する
        If 結果 Is Nothing Then '検索にヒットしない場合
            Debug.Print 検索文字列 & " が入力されたセルはありませんでした。"
        Else '検索にヒットした場合
            初回結果 = 結果.Address '最初にヒットしたセルのアドレスを変数に代入する
            Do
                Debug.Print 検索文字列 & " は" & 結果.Address & " です。" '結果を表示する
                Set 結果 = 検索範囲.FindNext(結果) 'FindNextメソッドによる次の検索
            Loop While 結果.Address <> 初回結果 '繰り返し条件:最初にヒットしたセルのアドレスと現在のセルアドレスが異なる間は繰り返す
        End If
    
    End With

End Sub

Set 結果 = 検索範囲.FindNext(結果)

FindNextメソッドをつかう上で注意しなければならない点として、Findメソッドと組み合わせる必要があるため、Findメソッドの戻り値をFindNextメソッドの引数(After)として指定しています。

初回結果 = 結果.Address

もう一点注意しなければならない点が繰り返しの条件の指定方法です。具体的には、FindNextメソッドに繰り返しを組み合わせたときに無限ループが発生しないようにする必要があります。そのためにFindNextメソッドで戻ってきたセルのアドレス(結果.Address)を、別の変数(初回結果)に代入しています。

Do ~ Loop While 結果.Address <> 初回結果

変数(初回結果)に代入されたアドレスとFindNextメソッドで返ってくる結果のアドレスが異なっている間は繰り返す。といった条件を指定しています。

繰り返し処理の詳しい解説は、こちらの記事をあわせて参考にしてください。

実行結果

‘インプットボックスに”オレンジ”を入力した場合
>オレンジ は$A$4 です。
>オレンジ は$C$4 です。
>オレンジ は$C$11 です。

Findメソッドによる検索の結果は[$A$4]を変数の初回結果に代入しているため、FindNextメソッドで[$A$4]が返ってくると繰り返しから抜け出しています。これで検索キーワードが含まれているセルのアドレスをすべて抽出することができました。

検索キーワード”オレンジ”があるのは3つのセルだね。

独学の学習効率でお悩みの人必見!
<動画学習見放題サービス>

初心者にやさしいチューターなら今すぐにはじめられる

オンラインで学習したい
プログラミングで副業をはじめたい
パソコン・エクセルの学習をしたい

FindPreviousメソッド

FindNextメソッドと同じようなものとして、FindPreviousメソッドも存在します。VBA FindPreviousメソッドは、Findメソッドで開始された検索を続行します。つまり、FindPreviousメソッドもまたFindメソッドと組み合わせて使わなければならないメソッドです。

FindPreviousメソッドは、一致するセル (Rangeオブジェクト) を返します。一致するセルが見つからなかった場合はNothingを返します。

FindPreviousメソッドの基本的な使い方

構文

Object.FindPrevious (Before)

FindPreviousメソッドを使う前に、必ずFindメソッドで最初の検索を行う必要があります。

引数 Before に指定したセルの上方 (行のときは左、列のときは上) のセルから検索を開始します。 この引数を省略すると、前回の検索結果から続きで検索します。

メソッドがこのセルに折り返されるまで、指定したセルは検索されません。 引数が指定されていない場合、検索は範囲内の左上のセルの前に開始されます。

簡単に言えば、Findメソッドの前の検索をするものだね。

FindPreviousメソッドのサンプルコード

FindPreviousメソッドのサンプルコードを書いてみます。こちらのコードでもFindメソッドでつかったデータをつかって検索をしていきます。

エクセルワークシート上の表
FindPreviousメソッドのサンプルコード
Option Explicit

Sub FindPreviousメソッド1()

    Dim 検索範囲 As Range '検索する範囲を代入する変数を宣言する
    Dim 結果 As Range '結果を代入する変数を宣言する

    Dim 検索文字列 As String '検索文字列を代入する変数を宣言する
    
    With Sheet1
        '検索範囲を変数に代入する
        Set 検索範囲 = .Range("A1:E11")
        
        '検索文字列を変数に代入する
        検索文字列 = Application.InputBox("検索文字列を入力してください。", "検索文字列を入力", "東京都")
        
        'Findメソッドで検索結果を変数に代入する
        Set 結果 = 検索範囲.Find(検索文字列, LookIn:=xlValues)
        
        If 結果 Is Nothing Then '検索にヒットしない場合
            Debug.Print 検索文字列 & " が入力されたセルはありませんでした。"
            Exit Sub
        Else
            '検索した文字列があるセルのアドレスを表示する
            Debug.Print 結果.Address
        
            'FindPreviousメソッドでFindメソッドの結果を引数に指定した戻り値を変数に代入する
            Set 結果 = 検索範囲.FindPrevious(結果)
        
            '検索した文字列があるセルのアドレスを表示する
            Debug.Print 結果.Address
        
            'FindPreviousメソッドでFindメソッドの結果を引数に指定した戻り値を変数に代入する
            Set 結果 = 検索範囲.FindPrevious(結果)
        
            '検索した文字列があるセルのアドレスを表示する
            Debug.Print 結果.Address
            
        End If
    End With

End Sub

FindPreviousメソッドはFindメソッドと組み合わせる必要がありますので、Findメソッドの結果をつかってFindPreviousメソッドの引数に指定しています。

FindPreviousメソッドの引数にFindメソッドの検索結果を代入した変数を指定し、その次のFindPreviousメソッドでは、その前のFindPreviousメソッドの検索結果を代入した変数を指定しています。

続いて実行結果を確認してみましょう。

実行結果

‘インプットボックスに”オレンジ”を入力した場合
>$A$4
>$C$11
>$C$4

Findメソッドで検索でセル[$A$4]の、次の検索で該当するセルのアドレス[$C$11]と[$C$4]返すことができました。FindNextメソッドのサンプルコード(Sub FindNextメソッド1)の実行結果と異なっている点は、結果で表示されたアドレスを表示する順番です。

Findメソッドで検索で見つかったセルのアドレスが[$A$4]であり、この結果を引数としてFindPreviousメソッドを実行すると[$C$11]が先に検索結果として返ってきています。

そして、FindNextメソッドと同じくFindPreviousメソッドも繰り返し処理と組み合わせて使うことでその真価を発揮します。

FindPreviousメソッドも、繰り返し処理と合わせて使ってみるよ。

FindPreviousメソッドで複数のセルを検索するサンプルコード

FindPreviousメソッドのサンプルコード(全てを検索するマクロ)
Option Explicit

Sub FindPreviousメソッド2()

    Dim 検索範囲 As Range '検索する範囲を代入する変数を宣言する
    Dim 結果 As Range '結果を代入する変数を宣言する
    Dim 初回結果 As String
    Dim 検索文字列 As String '検索文字列を代入する変数を宣言する
    
    With Sheet1
        '検索範囲を変数に代入する
        Set 検索範囲 = .Range("A1:E11")
        
        '検索文字列を変数に代入する
        検索文字列 = Application.InputBox("検索文字列を入力してください。", "検索文字列を入力", "東京都")
        
        '検索結果を変数に代入する
        Set 結果 = 検索範囲.Find(検索文字列, LookIn:=xlValues)
        
        '検索ヒットしたときとしなかったときで処理を分岐する
        If 結果 Is Nothing Then '検索にヒットしない場合
            Debug.Print 検索文字列 & " が入力されたセルはありませんでした。"
        Else '検索にヒットした場合
            初回結果 = 結果.Address '最初にヒットしたセルのアドレスを変数に代入する
            Do
                Debug.Print 検索文字列 & " は" & 結果.Address & " です。" '結果を表示する
                Set 結果 = 検索範囲.FindPrevious(結果) 'FindPreviousメソッドによる次の検索
            Loop While 結果.Address <> 初回結果 '繰り返し条件:最初にヒットしたセルのアドレスと現在のセルアドレスが異なる間は繰り返す
        End If
    
    End With

End Sub

Set 結果 = 検索範囲.FindPrevious(結果)

FindPreviousメソッドをつかう上で注意しなければならない点として、Findメソッドと組み合わせる必要があるため、Findメソッドの戻り値をFindPreviousメソッドの引数(Before)として指定しています。

初回結果 = 結果.Address

もう一点注意しなければならない点が繰り返しの条件の指定方法です。具体的には、FindPreviousメソッドに繰り返しを組み合わせたときに無限ループが発生しないようにする必要があります。そのためにFindPreviousメソッドで戻ってきたセルのアドレス(結果.Address)を、別の変数(初回結果)に代入しています。

Do ~ Loop While 結果.Address <> 初回結果

変数(初回結果)に代入されたアドレスとFindPreviousメソッドで返ってくる結果のアドレスが異なっている間は繰り返す。といった条件を指定しています。

繰り返し処理の詳しい解説は、こちらの記事をあわせて参考にしてください。

実行結果

‘インプットボックスに”オレンジ”を入力した場合
オレンジ は$A$4 です。
オレンジ は$C$11 です。
オレンジ は$C$4 です。

Findメソッドによる検索の結果は[$A$4]を変数の初回結果に代入しているため、FindPreviousメソッドで[$A$4]が返ってくると繰り返しから抜け出しています。これで検索キーワードが含まれているセルのアドレスをすべて抽出することができました。

FindPreviousメソッドを使っても”オレンジ”があるのは3つのセルだね。

独学でプログラミングをはじめてみたけど、このままの学習方法に不安を感じているのなら、
オンラインスクールで現役エンジニアのサポートがあるテックアカデミーがおすすめ。
スキマ時間に学べて仕事も保証。必ず副業、始められます。まずは無料でプログラミング体験

FindNextとFindPreviousメソッドの違い

本記事では、これまでFindメソッドとFindNextメソッド・FindPreviousの使い方やサンプルコードの解説をしました。FindNextメソッドとFindPreviousメソッドは、どちらもFindメソッドと組み合わせてつかう必要がありました。

さらに、複数のセルを検索する場合は、繰り返し処理を組み合わせてつかう必要がありました。
ここまで記事を読み進められた人であれば、すでにお分かりかもしれませんが、FindNextメソッドとFindPreviousメソッドの違いについて最後に紹介します。

FindNextメソッドとFindPreviousメソッドでは検索する方向が異なる

FindNextメソッドとFindPreviousメソッドの違いとしては、Findメソッドで得た検索結果から、次の検索をするか、前の検索をするかです。FindNextメソッドでは、Findメソッドの検索の次の検索を実行し、逆にFindPreviousメソッドでは、Findメソッドの検索の前の検索を実行します。

具体例を参考すると理解しやすいと思いますので、以下のサンプルコードで見てみましょう。
今回もこちらの表からキーワードである”オレンジ“が入力されたセルの検索してみます。

エクセルワークシート上の表
FindNextメソッドのサンプルコード
Option Explicit

Sub difference_Next_Previous()

    Dim 検索範囲 As Range '検索する範囲を代入する変数を宣言する
    Dim 結果 As Range '結果を代入する変数を宣言する
    Dim 初回結果 As String
    Dim 検索文字列 As String '検索文字列を代入する変数を宣言する
    
    With Sheet1
        '検索範囲を変数に代入する
        Set 検索範囲 = .Range("A1:E11")
        
        '検索文字列を変数に代入する
        検索文字列 = "オレンジ"
        
        '検索結果を変数に代入する
        Set 結果 = 検索範囲.Find(検索文字列, After:=Range("$A$4"), LookIn:=xlValues)
        
        '検索ヒットしたときとしなかったときで処理を分岐する
        If 結果 Is Nothing Then '検索にヒットしない場合
            Debug.Print 検索文字列 & " が入力されたセルはありませんでした。"
        Else '検索にヒットした場合
            初回結果 = 結果.Address '最初にヒットしたセルのアドレスを変数に代入する
            Do
                Debug.Print 検索文字列 & " は" & 結果.Address & " です。" '結果を表示する
                Set 結果 = 検索範囲.FindNext(結果) 'FindNextメソッドによる次の検索
            Loop While 結果.Address <> 初回結果 '繰り返し条件:最初にヒットしたセルのアドレスと現在のセルアドレスが異なる間は繰り返す
        End If
    
    End With

End Sub

上記サンプルコードのポイントは黄色でラインでにある、Find関数で引数のAfterに[$A$4]を指定しているところです。指定した理由は、FindNextメソッドとFindPreviousメソッドの実行結果の違いをわかりやすくするためですが、Find関数のAfter引数の指定により、Find関数は[$A$4]の次のセルから検索を開始し、実行結果としては以下のとおりです。

実行結果(イミディエイトウィンドウ)

オレンジ は$C$4 です。
オレンジ は$C$11 です。
オレンジ は$A$4 です。

実行結果から検索のながれのイメージ図
エクセルワークシート上の表におけるFindメソッドのAfter引数の指定とFindNextメソッドの検索のながれ

引数Afterに指定したセルの次のセルから右下へ検索をしていくよ。

FindPreviousメソッドのサンプルコード
Option Explicit

Sub difference_Next_Previous2()

    Dim 検索範囲 As Range '検索する範囲を代入する変数を宣言する
    Dim 結果 As Range '結果を代入する変数を宣言する
    Dim 初回結果 As String
    Dim 検索文字列 As String '検索文字列を代入する変数を宣言する
    
    With Sheet1
        '検索範囲を変数に代入する
        Set 検索範囲 = .Range("A1:E11")
        
        '検索文字列を変数に代入する
        検索文字列 = "オレンジ"
        
        '検索結果を変数に代入する
        Set 結果 = 検索範囲.Find(検索文字列, After:=Range("$A$4"), LookIn:=xlValues)
        
        '検索ヒットしたときとしなかったときで処理を分岐する
        If 結果 Is Nothing Then '検索にヒットしない場合
            Debug.Print 検索文字列 & " が入力されたセルはありませんでした。"
        Else '検索にヒットした場合
            初回結果 = 結果.Address '最初にヒットしたセルのアドレスを変数に代入する
            Do
                Debug.Print 検索文字列 & " は" & 結果.Address & " です。" '結果を表示する
                Set 結果 = 検索範囲.FindPrevious(結果) 'FindPreviousメソッドによる前の検索
            Loop While 結果.Address <> 初回結果 '繰り返し条件:最初にヒットしたセルのアドレスと現在のセルアドレスが異なる間は繰り返す
        End If
    
    End With

End Sub

上記サンプルコードは、FindNextメソッドのものとほとんどが同じで、変更点はFindPreviousメソッドを使っている点です。FindメソッドのAfter引数の指定により、Findメソッドは[$A$4]の次のセルから検索し、実行結果としては以下のとおりです。

実行結果(イミディエイトウィンドウ)

オレンジ は$C$4 です。
オレンジ は$A$4 です。
オレンジ は$C$11 です。

[$A$4]の次のセルから検索するため、はじめにFindメソッドの検索で見つかるアドレスは[$C$4]です。その後のFindPreviousメソッドでは、[$A$4]→[$C$11]の順番で結果が返ってきます。

実行結果から検索のながれのイメージ図
エクセルワークシート上の表におけるFindメソッドのAfter引数の指定とFindPreviousメソッドの検索のながれ

引数Afterに指定したセルの次のセルから左上へ検索をしていくよ。

InStr関数は、ある文字列の中から別の文字列を検索して、最初に見つかった位置を返す関数です。
例えば、InStr("ABCDE", "C")は、”Excel”という文字列の中で”c”という文字列が最初に現れる位置を返します。
この場合、戻り値は3です。最初の位置を返すため、検索する文字列が重複していた場合であっても、InStr("COFFEE", "E")では、3が返りInStr("COFFEE", "F")では、5を返します。

検索文字列が見つからない場合[InStr("COFFEE", "N")]などでは、0を返します。

InStr関数

文字列に含まれる文字列の最初の位置を数値で返すよ。

InStr関数の実用例

  • 文字列の中に特定の文字や記号が含まれているかどうかを判定する
  • 文字列の中から括弧やコンマなどで区切られた部分を取り出す
  • 文字列の中から特定の単語やフレーズを検索する
独学だと中々スキルが身についた実感が湧かない。学習環境を見直してみませんか?

エクセルで繰り返しや転記作業で苦しい思いをした経験はありませんか?
今まで苦労してきたその作業を簡単なプログラムをおぼえるだけで解決できる可能性があります。
なるべくお金や時間をかけずにエクセルマクロVBAを習得したい人にはこちらの「1日速習講座」がおすすめです。

InStr関数の使い方

InStr関数は引数として指定した検索対象となる文字列から、検索値として指定した文字列の開始位置を返す関数です。ここではInStr関数の構文や引数についての説明と、簡単なサンプルコードの実行結果も含めてみていきましょう。

InStr関数の基本的な使い方

構文

InStr([ start ], string1, string2, [ compare ])

引数について
引数compareの設定値について

引数の指定がない場合は、vbBinaryCompare(0)で検索となるよ。

InStr関数のサンプルコード

InStr関数をつかったサンプルコードを紹介します。

InStr関数のサンプルコード
Option Explicit

Sub InStr関数()

    '文字列[ABCDE]のCは3番目
    Debug.Print InStr("ABCDE", "C")
    
    '文字列[COFFEE]で"F"は3番目
    Debug.Print InStr("COFFEE", "F")
    
    '文字列[COFFEE]で"E"は5番目
    Debug.Print InStr("COFFEE", "E")
    
    '文字列[COFFEE]で"N"は検索されないので0
    Debug.Print InStr("COFFEE", "N")

    '文字列[COFFEE]の検索値を指定しない場合は開始位置を返すため1
    Debug.Print InStr("COFFEE", "")
    
    '文字列[COFFEE]の検索値をしない場合は開始位置を返すため3
    Debug.Print InStr(3, "COFFEE", "")

   '文字列[COFFEE]の文字数を越えた開始位置7を指定したときは0
    Debug.Print InStr(7, "COFFEE", "O")

    '文字列[あかあおきいろ]の"あお"を開始位置3から検索する場合3
    Debug.Print InStr(3, "あかあおきいろ", "あお", vbTextCompare) 'テキスト比較を定数で指定

    '文字列[あかあおきいろ]の"あお"を開始位置4から検索する場合0
    Debug.Print InStr(4, "あかあおきいろ", "あお", 1) 'テキスト比較を値で指定

End Sub

引数である start を指定した場合、string2 の検索を開始する位置は指定値に応じますが、返ってくる値は start からの位置ではなく、あくまで string1 の最初に見つかった位置を返します。

Debug.Print InStr(“COFFEE”, “F”) を Debug.Print InStr(3,”COFFEE”, “F”)に書きかえて実行した場合であっても、検索を開始する位置に関わらず、”COFFEE”の最初から数えた位置の3が返ってきます。

検索開始位置に関係なく、検索元の文字列から何番目かが返ってくるんだね。

実行結果(イミディエイトウィンドウの出力結果)

3
3
3
5
0
1
3
0
3
0

画像によるInStr関数のイメージ
instr関数のサンプルコードのイメージ図
PCでスキルアップをしたい・Excelをしっかり学んで社内の評価を高めたい人は必見!
実務をプロから学べる「ユースフル」は講座の動画は永年見放題。安心のQ&A機能で分からないを解決。

FindメソッドとInStr関数の違いと使い分け

FindメソッドとInStr関数の違いと使い分けについて、以下のように説明できます。

Findメソッドは、Rangeオブジェクトのメソッドで、ワークシート上のセル範囲内の条件に当てはまるセルを検索するものです。Findメソッドは、ワークシート操作の「検索と置換」の「検索」の機能をVBAで使う場合に利用するものです。
Findメソッドは、見つかったセルのRangeオブジェクトを返します。

一方、InStr関数は、VBAの組み込み関数で、文字列の中から指定した文字列を検索して、最初に見つかった文字位置を返すものです。InStr関数は、文字列操作や判定に使われる関数です。InStr関数は、見つかった文字位置の数値を返します。

使い分けとしては、以下のような基準があります。

  • ワークシート上のセルの値や書式を検索したい場合は、Findメソッドを使います。
  • 文字列変数やセルの値などの文字列から部分文字列を検索したい場合は、InStr関数を使います。

検索したい文字列のセルを検索をするときはFindメソッド。文字列から一部の文字列を検索するときは、InStr関数を使うイメージだよ。

InStr関数をつかったFindメソッドのようなマクロ

InStr関数は特定の文字列の開始位置を返し、指定した文字列が含まれていなければ0が返ってくる。この仕様を利用するば、InStr関数を使ってFindメソッドのようなマクロをつくることもできます。

Findメソッドで紹介したように、以下の表から検索値“オレンジ”が入力されたセルのアドレスを検索して出力結果として返すマクロを作ってみます。

エクセルワークシート上の表
InStr関数を使ってFindメソッドのような動作をするサンプルコード
Option Explicit

Sub InStr関数でFindメソッド()

    
    Dim 結果フラグ As Long 'InStr関数の開始位置を代入する変数
    Dim 検索結果リスト() As String '検索結果のアドレスを代入する配列
    Dim 検索範囲 As Range '検索するセル範囲を代入する変数
    Dim 検索セル As Variant '繰り返し処理用のセルを代入する変数(Variant型)
    Dim i As Long 'カウンタ変数
    
    With Sheet1
        '検索範囲を変数に代入する
        Set 検索範囲 = .Range("A1:E11")
        
        'すべての検索対象の範囲すべてを検索する
        For Each 検索セル In 検索範囲
            結果フラグ = InStr(検索セル, "オレンジ") '検索値のオレンジの開始位置を変数(結果フラグ)に代入
            If 結果フラグ >= 1 Then '開始が1以上であれば実行する
                ReDim Preserve 検索結果リスト(i) As String '配列検索結果リストを再定義する
                検索結果リスト(i) = 検索セル.Address '検索セルのアドレスを検索結果リストに代入する
                i = i + 1 '配列インデックスカウンタの変数に1を足す
            End If
        Next 検索セル
        
        For i = 0 To UBound(検索結果リスト) '正順検索
            Debug.Print 検索結果リスト(i) '配列に代入された値をすべて表示する
        Next i
    
'        For i = UBound(検索結果リスト) To 0 Step -1 '逆順検索
'            Debug.Print 検索結果リスト(i)’配列に代入された値をすべて表示する
'        Next i
    
    End With

End Sub

サンプルコード(InStr関数でFindメソッド)のポイント

For Each 検索セル In 検索範囲

検索範囲に代入したセルの範囲すべてを検索するための繰り返し処理です。

If 結果フラグ >= 1 Then

InStr(検索セル, “オレンジ”)の戻り値が1以上であったら、動作する処理をIf文をつかって条件分岐しています。

ReDim Preserve 検索結果リスト(i) As String

“オレンジ”と入力されたセルが見つかったら、配列(検索結果リスト)の大きさを再定義しています。このとき、Preserveキーワードをつけることを忘れないことに注意が必要です。

今回のサンプルでは動的配列をつかっています。配列の詳しい解説については、他の記事でまとめていますので配列について知りたい人は以下の記事もぜひご覧ください。

検索結果リスト(i) = 検索セル.Address

配列(検索結果リスト)のインデックスを指定して、”オレンジ”が入力されたセルのアドレスを代入していきます。

実行結果(正順)

オレンジは $A$4 に入力されています。
オレンジは $C$4 に入力されています。
オレンジは $C$11 に入力されています。

実行結果(逆順)

オレンジは $C$11 に入力されています。
オレンジは $C$4 に入力されています。
オレンジは $A$4 に入力されています。

InStr関数を使ったマクロでも、オレンジが入力されたセルのアドレスを表示できたね。

まとめ

今回はエクセルVBAにおける検索に着目し、FindメソッドInStr関数を使って指定の検索値をさがす処理をするマクロについて紹介しました。

Findメソッドは、検索値とする文字列がどのセルに入力されているかを調べることに便利に使用できます。ただし、Findメソッドの戻り値は検索によって最初にみつかったセルのRangeオブジェクトを返します。すべてのセルを検索するためには工夫が必要です。

一方で、InStr関数はセル内の文字列の一部に指定の文字列が含まれてるか、含まれているのであれば、開始位置がどこであるかを調べるときに便利で、戻り値は開始位置を数値で返します。

Findメソッドだけでは、セル範囲を網羅的に検索することはできない点には注意が必要です。網羅的な検索をするためには、繰り返し処理や「FindNextメソッド」や「FindPreviousメソッド」と組み合わせることで実現ができます。

InStr関数は文字列の開始位置を数値で返しますが、返ってくる結果の利用のしかた次第では、Findメソッドのようなマクロをつくることもできます。

今回はここまで。

コダマのもりブログはにほんブログ村に登録しています。
ブログの記事が役に立ったと感じて頂けたら、フォローお願いいたします。

コメント

タイトルとURLをコピーしました