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メソッドは引数で検索条件を指定します。引数が多いのでそれぞれの引数の説明を表にまとめました。
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メソッドをつかったサンプルコードを紹介します。以下の表から特定の文字列が入力されたセルを検索してみます。
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メソッドを以下のように書きかえてみます。
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メソッドでは、複数個一致した場合に対応ができません。複数セルが一致するような場面では、FindNextやFindPreviousというメソッドを使います。これらのメソッドは、Findメソッドと組み合わせて使うことで、複数の一致するセルを順番に検索していくことができます。
FindNextメソッドは、Findメソッドで見つかった次の一致するセルを返します。引数はありません。FindPreviousメソッドは、Findメソッドで見つかった前の一致するセルを返します。引数はありません。
なぜ、膨大な事務作業でも定時で退社できるのか。
実務をプロから学べる「ユースフル」の動画は永年見放題。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メソッドでつかったデータをつかって検索をしていきます。
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コードを紹介していきます。ここでは Do~Loop を使って繰り返しの条件を指定して、検索キーワードに一致するセルのアドレスをすべてを取り出します。
Do~Loop文は条件によって繰り返すかどうかを判断するものだよ。
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メソッドでつかったデータをつかって検索をしていきます。
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メソッドで複数のセルを検索するサンプルコード
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メソッドの検索の前の検索を実行します。
具体例を参考すると理解しやすいと思いますので、以下のサンプルコードで見てみましょう。
今回もこちらの表からキーワードである”オレンジ“が入力されたセルの検索してみます。
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 です。
引数Afterに指定したセルの次のセルから右下へ検索をしていくよ。
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]の順番で結果が返ってきます。
引数Afterに指定したセルの次のセルから左上へ検索をしていくよ。
InStr関数は、ある文字列の中から別の文字列を検索して、最初に見つかった位置を返す関数です。
例えば、InStr("ABCDE", "C")
は、”Excel”という文字列の中で”c”という文字列が最初に現れる位置を返します。
この場合、戻り値は3です。最初の位置を返すため、検索する文字列が重複していた場合であっても、InStr("COFFEE", "E")
では、3が返り、InStr("COFFEE", "F")
では、5を返します。
検索文字列が見つからない場合[InStr("COFFEE", "N")]
などでは、0を返します。
InStr関数
文字列に含まれる文字列の最初の位置を数値で返すよ。
InStr関数の実用例
- 文字列の中に特定の文字や記号が含まれているかどうかを判定する
- 文字列の中から括弧やコンマなどで区切られた部分を取り出す
- 文字列の中から特定の単語やフレーズを検索する
InStr関数の使い方
InStr関数は引数として指定した検索対象となる文字列から、検索値として指定した文字列の開始位置を返す関数です。ここではInStr関数の構文や引数についての説明と、簡単なサンプルコードの実行結果も含めてみていきましょう。
こちらで紹介するInStr関数は文字列をあつかう関数のひとつです。VBAにはこのほかにも文字列をあつかうことのできる関数が多くあります。文字列をあつかえる関数を紹介した記事もありますので、詳しく知りたい人は以下のリンクをクリックしてご覧になってください。
文字列操作に便利な関数をまとめた記事だよ。
\文字列操作ができる関数についてはコチラ/
InStr関数の基本的な使い方
InStr([ start ], string1, string2, [ compare ])
引数 | 必須/省略可 | 説明 |
---|---|---|
start | 省略可 | それぞれの検索の開始位置を指定する数値です。 省略すると、最初の文字位置から検索開始となる。 引数のcompareを指定する場合は、startも必須となります。 |
string1 | 必須 | 検索対象となる文字列です。 |
string2 | 必須 | 検索値となる(開始位置を特定したい)文字列です。 |
compare | 省略可 | 文字列比較の種類を指定します。 |
定数 | 値 | 説明 |
---|---|---|
vbUseCompareOption | -1 | 宣言セクションで宣言した比較方法で比較を実行します。 ※指定がない場合はバイナリ比較を実行します。 |
vbUseCompareOption | -1 | 宣言セクションで宣言した比較方法で比較を実行します。 ※指定がない場合はバイナリ比較を実行します。 |
vbBinaryCompare | 0 | バイナリ比較を実行します。 ※全角半角や大文字小文字を区別します。 |
vbTextCompare | 1 | テキスト比較を実行します。 |
vbDatabaseCompare | 2 | Microsoft Access のみで使用します。エクセルでは使いません。 |
引数の指定がない場合は、vbBinaryCompare(0)で検索となるよ。
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
なぜ、膨大な事務作業でも定時で退社できるのか。
実務をプロから学べる「ユースフル」の動画は永年見放題。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メソッドで紹介したように、以下の表から検索値“オレンジ”が入力されたセルのアドレスを検索して出力結果として返すマクロを作ってみます。
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メソッドのようなマクロをつくることもできます。
今回はここまで。
コダマのもりブログはにほんブログ村に登録しています。
ブログの記事が役に立ったと感じて頂けたら、フォローお願いいたします。
コメント