VBA

Findメソッドで検索が見つからない場合に試すこと3選

このページでわかること

Findメソッドで検索が見つからない、失敗したときの対策を3つ紹介します。

覚えること
  1. 検索条件が適切に設定されていない。特にLookIn、LookAtを正確に使う。
  2. 前回の検索条件を引っ張っている。
    検索条件を省略せずに書く
    Find(what:=””, LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=False, MatchByte:=False, SearchFormat:=False)でリセット
  3. 検索するセル範囲が非表示になっている。
  4. エラーを回避するコツは
    If Not 〇〇 Is Nothing thenを使う。

こんにちは、hokkyokunです。
Findメソッドは便利なんですが、クセが強く、うまく検索してくれないってことがよくあります。
私が経験した原因をご紹介しますので、
もし検索できなくて困っていらっしゃいましたら参考にしてみてください。

Findメソッドがうまくいかない理由3選

検索条件が不適切

Findメソッドは

構文:レンジオブジェクト.Find(What , [After] , [LookIn] , [LookAt] , [SearchOrder] , [SearchDirection] , [MatchCase] , [MatchByte] , [SearchFormat])

となっています。

このうち、検索条件に関わってくるのは
What, LookIn, LookAt, MatchCase, MatchByte, SerchFormatです。

引数役割
What検索する値
LookIn検索の対象を
数式(xlFormula)
値(xlValues)
コメント(xlComments)
の中から選択
LookAt検索対象を
完全一致(xlWholes)
一部一致(xlPart)
から選択
MatchCaseブール型
大文字と小文字を区別する(True)
区別しない(False)
MatchByteブール型
半角と全角を区別する(True)
区別しない(False)
SearchFormatブール型
書式を検索する(True)
検索しない(False)

良くあるのが、LookInをxlValuesにして、計算式を検索したり、
LookAtをxlWholeにして、一部適合する検索を行っていたりと
やりたいことをうまく設定できていないパターンです。

前回の検査条件になっている

恐らくこれが原因の大半だと思います。
Findメソッドは What, LookIn, LookAt, MatchCase, MatchByte, SerchFormat の設定値が
前回の検索条件を反映する形になります。

これは連続で検索することを想定しての仕様ですが、
これが意図しない検索をしてしまう温床になっています。

  1. 対策は検索条件をしっかり指定してあげる。
  2. プログラムの処理の最後に検索条件をリセットする。

1は毎回設定するのは面倒ですが、
最低限LookInとLookAtは設定するようにしましょう。

2に関しては最後にコードを1行追加することで対応できます。

Find(what:="", LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=False, MatchByte:=False, SearchFormat:=False)

これを最後に入れるだけで検索条件がリセットされます。

検索するセル範囲が非表示になっている

あまり知られていませんが、非表示の部分に関してはFindメソッドは検索してくれません。

実験してみます。
この表からバナナを検索してみます。

Sub test()
Dim srcRng, fndRng As Range

'検索する範囲
Set srcRng = ActiveSheet.Columns("A")

'srcRngからバナナを検索
Set fndRng = srcRng.Find(what:="バナナ", LookIn:=xlValues, lookat:=xlWhole)

Debug.Print fndRng.Address

End Sub

うまく検索できました。

検索できました。

次にバナナの行(3行)を非表示にしてみます。

実行してみると。。

エラーが出ます。
Findメソッドで見つからなかったようです。

対策は再表示をさせることです。

Sub test()
Dim srcRng, fndRng As Range

'検索する範囲
Set srcRng = ActiveSheet.Columns("A")

'行全部非表示解除
Rows.Hidden = False

'srcRngからバナナを検索
Set fndRng = srcRng.Find(what:="バナナ", LookIn:=xlValues, lookat:=xlWhole)

'バナナの行だけ非表示
fndRng.Rows.Hidden = True


Debug.Print fndRng.Address

End Sub

Hiddenプロパティ

行や列を表示、非表示させるのに使用します。

行を非表示/再表示

単独:Rows(行番号).Hidden = True / False
rangeオブジェクト.Rows.Hidden = True / False
全行:Rows.Hidden = True / False

列を非表示/再表示

単独:Columns(列番号).Hidden = True / False
rangeオブジェクト.Columns.Hidden = True / False
前列:Columns.Hidden = True / False

マクロをとめないコツ(検索できないときの対応)

対策をしないと
検索がひっかからないたびに、マクロがストップしてしまいます。
スムーズに使うためには最低限の対策をしましょう。
If文を使い、検索できなかったとき(=Nothing)の処理を書いておくと、マクロが止まらなくて済みます。

Sub test()
Dim srcRng, fndRng As Range

'検索する範囲
Set srcRng = ActiveSheet.Columns("A")

'srcRngからバナナを検索
Set fndRng = srcRng.Find(what:="バナナ", LookIn:=xlValues, lookat:=xlWhole)

'fndRngがNothingでないならfndRngのアドレス表示、そうでないならメッセージだけ
If Not fndRng Is Nothing Then
    MsgBox ("fndRng:" & fndRng.Address)
Else
    MsgBox ("バナナは見つかりませんでした")
End If

End Sub

If Not~はよく使う手法です。

If Not ○○ Is Nothing then
  処理A
Else
  処理B
End If

○○でないなら処理Aそうでないなら処理Bという構文です。
ただし、処理Bを行ったときは何らかのリアクションを残しておかないと、何もやらないマクロができるだけなので注意してください。

まとめ

検索条件に関わる引数:
What, LookIn, LookAt, MatchCase, MatchByte, SerchFormatです。
特にLookInとLookAtの使い方に注意しましょう

検索条件は前回の設定を記憶しています。
検索条件を細かく指定するか、使用するたびにリセットしましょう。

非表示したセルは検索してくれません。
再表示して検索後、非表示に戻しましょう。

If Not ○○ Is Nothing then を使ってプログラムが止まらないように処理しましょう。
ただし、エラーがどこで起こったかは把握するようにしましょう。