VBA入門
Findメソッド(Find,FindNext,FindPrevious)

ExcelマクロVBAの基本と応用、エクセルVBAの初級・初心者向け解説
最終更新日:2021-11-09

第98回.Findメソッド(Find,FindNext,FindPrevious)


Findメソッドは、マクロVBAでセル範囲内の条件に当てはまるセルを検索するものです。


Findメソッドは、Rangeオブジェクトのメソッドで、
ワークシート操作の「検索と置換」「検索」の機能をマクロVBAで使うものになります。

マクロ VBA Find

上の画像では「検索する文字列」だけしか指定できませんが、
「オプション」をクリックすると、

マクロ VBA Find

このように、いろいろな指定ができるようになります。
以下では、これらの検索を行う時のマクロVBAについて解説します。


Findメソッド

セル範囲内で特定の情報を検索します。

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

引数の説明
What 検索するデータです。
文字列などセル内のデータに該当する値を指定します。
After セル範囲内のセルの1つを指定します。
このセルの次のセルから検索が開始されます。
引数Afterで指定するセルは、コードからではなく、通常の画面上で検索を行う場合のアクティブセルに該当します。
このセルの次から検索が開始されるため、範囲内の他のセルがすべて検索され、このセルに戻るまで、このセル自体は検索されません。
この引数を省略すると、対象セル範囲の左上端のセルが検索の開始点になります。
LookIn 情報の種類を、XlFindLookIn列挙から指定します。
xlFormulas:数式
xlValues:値
xlComents:コメント文
以下は使えるバージョンに注意
xlCommentsThreaded:スレッドコメント(2016以降)
xlFormulas2:(スピル対応?詳細不明)
LookAt

xlPart:検索テキストの一部を検索します。
xlWhole:検索テキスト全体を検索します。

SearchOrder xlByColumns:列を下方向に検索してから、次の列に移動します。
xlByRows:行を横方向に検索してから、次の行に移動します。
SearchDirection

xlNext:一致する次の値を検索します。
xlPrevious:一致する前の値を検索します。

MatchCase 大文字と小文字を区別するには、Trueを指定します。
既定値はFalseです。
MatchByte この引数は、2バイト(全角)文字の言語サポートが選択またはインストールされている場合にだけ使用できます。
2バイト文字が2バイト文字とだけ一致するようにする場合は、Trueを指定します。
2バイト文字が2バイト文字だけではなく、対応する1バイト文字とも一致するようにする場合はFalseを指定します。
SearchFormat 検索の書式を指定します。

戻り値
検索範囲の先頭のセルを表すRangeオブジェクトが戻されます。
一致するデータが見つからなかった場合、このメソッドはNothingを返します。

Findメソッドでは、複雑なパターンと一致するセルを検索することはできません。
複雑な検索を行う場合は、
For...NextステートメントまたはDo...Loopステートメントを使い、順次IfステートメントとLike演算子等で判定するようにします。


引数が保存される注意点

引数LookIn、LookAt、SearchOrder、およびMatchByteの設定は、
このメソッドを使用するたびに保存されます。

次にこのメソッドを使用するときにこれらの引数の指定を省略すると、保存された設定が使用されます。
これらの引数の設定を変更すると、[検索と置換]ダイアログボックスに表示される設定が変わります。
また、[検索と置換]ダイアログボックスで設定を変更すると、保存されている値、つまり引数を省略した場合に使用される値が変わります。

このような設定の変更によって生じる問題を避けるには、
メソッドを使用するたびに、これらの引数を明示的に指定します。


Findメソッドの使用例

Set rngFind = Range("A1:B100").Find(What:="A", _
              LookIn:=xlValues, _
              LookAt:=xlPart, _
              SearchOrder:=xlByColumns, _
              SearchDirection:=xlNext, _
              MatchCase:=False, _
              MatchByte:=False)
If Not rngFind Is Nothing Then
  MsgBox "見つかった" & vbLf & rngFind.Address
End If

A1セル~A100セルの範囲内から、"A"を探して、
見つかったら、そのアドレスを表示しています。


Findメソッドの注意点

注意点1.
先の使用例のVBAの場合、
A1セルに"A"があったとしても、これで検索されるのは、それ以降に出現する最初のセルになります。
これは、ワークシートの操作でも同じです。
引数、Afterの説明にもあるように、このセルの次のセルから検索が開始されるからです。

注意点2.
引数 LookIn、LookAt、SearchOrder、MatchByte の設定は、このメソッドを使用するたびに保存されます。
つまり、[検索と置換]ダイアログボックスに表示される設定が変わります。
次にこのメソッドを使用するときにこれらの引数の指定を省略すると、保存された設定が使用されます。
このような設定の変更によって生じる問題を避けるには、メソッドを使用するたびに、引数を明示的に指定します。

注意3.
xlValues:値で検索した場合、この機能は表示形式に依存した検索となります。
数値や日付の場合は、表示形式の違いで検索されない場合がでてきます。
数値や日付の場合は、xlFormulas:数式 で検索するようにしてください。

ただし、数式で入っているセルを検索する場合は、xlFormulas:数式 で検索しても表示形式に依存する為検索できないものがでてきます。
この場合はxlValues:値 で表示形式に合わせた検索が必要になります。

注意4.
「ふりがな」も検索対象となります。
xlWhole:全体 の場合は問題になることはあまり無いと思いますが、
xlPart:一部 で「ひらがな」「カタカナ」の短い単語を検索する場合は注意が必要です。


FindNext メソッド

Find メソッドによって開始された検索を継続して次の検索を実行します。
前回の検索条件に一致するセルを、下方向 (行のときは左から右、列のときは上から下) に検索し、
見つかったセル (Range オブジェクト) を返します。
これは、ワークシートの操作「検索と置換」で、「次を検索」に相当します。

Range.FindNext(After)

引数の説明
After 指定したセルの下方 (行のときは右、列のときは下) のセルから検索を開始します。
ワークシート上で検索を行う場合のアクティブ セルに相当します。
引数Afterには、対象セル範囲内の単一セルを指定する必要があります。
検索は指定したセルの次のセルから始まるので、指定したセル自体は、範囲全体が一度検索されるまで検索されません。
この引数を省略すると、セル範囲の左上隅のセルが指定されたものと見なされます。

Findメソッドとの組み合わせで使用されます。
検索は指定された範囲の最後に達すると、範囲の最初に戻って検索を繰り返します

同じ範囲を繰り返して検索しないようにするには、
最初に検索内容が見つかったセルの位置を保存しておき、次のセルが見つかるたびに、そのセルの位置と保存しておいたセルの位置を比較するようにします。

FindNextメソッドの使用例は、下の実践例を参照してください。


FindPrevioust メソッド

Find メソッドによって開始された検索を継続します。
前回の検索条件に一致するセルを、上方向 (行のときは右から左、列のときは下から上) に検索し、見つかったセル (Range オブジェクト) を返します。

Range.FindPrevious(After)

引数の説明
After 指定したセルの上方 (行のときは左、列のときは上) のセルから検索を開始します。
ワークシート上で検索を行う場合のアクティブ セルに相当します。引数 After には、対象セル範囲内の単一セルを指定する必要があります。
検索は指定したセルの前のセルから始まるので、指定したセル自体は、範囲全体が一度検索されるまで検索されません。
この引数を省略すると、セル範囲の左上隅のセルが指定されたものと見なされます。

このFindPreviousは、実際に使う機会は少ないと思います。


Application.FindFormatメソッド

[検索と置換] ダイアログの右上の「書式」をクリックすると、

マクロ VBA Find[

このように、「書式の検索」ダイアログが表示されます。
ここで書式を指定すると、元の[検索と置換] ダイアログのプレビューに表示され、
この書式のセルを検索することができます。

手動では行う事があるかと思いますが、さすがにマクロVBAで使う機会はかなり稀だと思います。
必要となった時には、「マクロの記録」でVBAコードを確認するのが簡単だと思います。
以下は、塗りつぶし黄色で検索した場合の、自動記録のマクロVBAコードになります。

Sub Macro1()
  With Application.FindFormat.Interior
    .PatternColorIndex = xlAutomatic
    .Color = 65535
    .TintAndShade = 0
    .PatternTintAndShade = 0
  End With
  Cells.Find(What:="", After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
    xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
    , SearchFormat:=True).Activate
  Range("K14").Select
End Sub

Fontで検索する場合は、
FindFormat.InteriorこれをFindFormat.Fontとして、検索するFontの情報を設定すれば良い事になります。


FindメソッドとFindNextメソッドの実戦例

With Worksheets(1).Range("a1:a500")

  Dim c As Range
  Dim firstAddress As String
  Set c = .Find(2, lookin:=xlValues)
  If Not c Is Nothing Then
    firstAddress = c.Address
    Do
      c.Value = 5
      Set c = .FindNext(c)
    Loop While Not c Is Nothing And c.Address <> firstAddress
  End If
End With


次の使用例は、シート 1 のセル範囲 A1:A500 で、値に 2 が含まれているセルを検索し、その値を 5 に変更します。
これは、Excel2010までのヘルプの使用例です。
これは、実行してみれば解りますが、全てを置換後にエラーになってしまいます。
Set c = .FindNext(c)
これで、検索値が存在しない場合は、cはNothingとなりますが、
Not c Is Nothing And c.Address <> firstAddress
この判定では、cがNothingのときでも、c.Address <> firstAddressを評価する為、エラーとなります。
以下のようにすれば良いでしょう。

With Worksheets(1).Range("a1:a500")
  Dim c As Range
  Dim firstAddress As String
  Set c = .Find(2, LookIn:=xlValues)
  If Not c Is Nothing Then
    firstAddress = c.Address
    Do
      c.Value = 5
      Set c = .FindNext(c)
      If c Is Nothing Then
        Exit Do
      End If
      If c.Address = firstAddress Then
        Exit Do
      End If
    Loop
  End If
End With


If c Is Nothing Then
  Exit Do
End If
If c.Address = firstAddress Then
  Exit Do
End If

この部分は、理解しやすいように、だいぶ野暮ったく書きました。
このヘルプの使用例は、ANDの判定で初心者が、間違えやすい代表になっています。
もしかしたら、わざと、そうしたのでしょうか・・・


以下も是非お読みください。
Findメソッドを私があまり使わない理由を説明しています。
VBAのFindメソッドの使い方には注意が必要です

・1.処理速度が遅い ・2.指定オプションがシート操作とリンクしている ・「値」で検索した場合は、表示形式に依存した検索になる ・最後に




同じテーマ「マクロVBA入門」の記事

第97回.図形オートシェイプ(Shape)
第136回.フォームコントロール
第137回.ActiveXコントロール
第98回.Findメソッド(Find,FindNext,FindPrevious)
第99回.Replaceメソッド(置換)
第132回.その他のExcel機能(グループ化、重複の削除、オートフィル等)
第135回.ジャンプの選択オプション(SpecialCells)
第141回.行・列の表示・非表示・列幅・行高
第105回.Callステートメント
第106回.Functionプロシージャー
第107回.プロシージャーの引数


新着記事NEW ・・・新着記事一覧を見る

抜けている数値を探せ|エクセル雑感(2022-07-01)
.Net FrameworkのSystem.Collectionsを利用|VBA技術解説(2022-06-29)
迷路ネコが影分身の術を体得したら…|エクセル雑感(2022-06-27)
迷路にネコが挑戦したら、どうなるかな…|エクセル雑感(2022-06-26)
サロゲートペアに対応した自作関数(Len,Left,Mid,Right)|エクセル雑感(2022-06-24)
「マクロの登録」で登録できないプロシージャーは?|エクセル雑感(2022-06-23)
オブジェクトのByRef、ByVal、Variant|エクセル雑感(2022-06-22)
コメントから特定形式の年月を取り出す|エクセル雑感(2022-06-19)
4,9を使わない連番作成|エクセル雑感(2022-06-17)
連番を折り返して出力|エクセル雑感(2022-06-16)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
6.Excelショートカットキー一覧|Excelリファレンス
7.マクロって何?VBAって何?|VBA入門
8.並べ替え(Sort)|VBA入門
9.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
10.エクセルVBAでのシート指定方法|VBA技術解説




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。



このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ