【Excel VBA】Findで検索結果が見つからない場合の対処法|Nothing・LookAt・LookInの注意点

みなさんこんにちは。

Excel VBAでセルを検索するときに、Range.Findを使用したことがある方も多いかと思います。

Findは簡単に目的のセルを取得できる便利な機能ですが、検索結果が見つからなかった場合にNothingが返されるため、そのまま.Addressや.Rowを参照するとエラーになってしまいます。

また、「シート上には確実に値があるのにFindで見つからない」といった場合には、LookAtやLookInの設定が原因になっていることもあります。

今回は、Excel VBAのRange.Findで検索結果が見つからない場合の対処法と、Nothing・LookAt・LookInの注意点についてご紹介したいと思います。

この記事はこんな人におすすめ

  • Range.Findで検索結果が見つからず困っている人
  • Findの結果がNothingになる場合の判定方法を知りたい人
  • 「オブジェクト変数またはWithブロック変数が設定されていません」と表示される人
  • LookAtの完全一致・部分一致の違いを知りたい人
  • LookInのxlValues・xlFormulasの違いを知りたい人

Range.Findの基本的な使い方

まずは、Range.Findの基本的な使い方を確認してみます。

例えば、Sheet1のA2:A10から「大阪」という文字を検索する場合は、次のように記述します。

Sub FindSample()

    Dim ws As Worksheet
    Dim foundCell As Range

    '========================================
    ' 検索対象となるワークシートを取得する
    '========================================
    Set ws = ThisWorkbook.Worksheets("Sheet1")

    '========================================
    ' A2:A10から「大阪」を検索する
    '========================================
    Set foundCell = ws.Range("A2:A10").Find( _
                        What:="大阪", _
                        LookIn:=xlValues, _
                        LookAt:=xlWhole)

    '========================================
    ' 検索結果のセル番地を表示する
    '========================================
    MsgBox foundCell.Address

End Sub

「大阪」が見つかれば、foundCellには該当するRangeオブジェクトが格納されます。

しかし、検索対象が存在しない場合は注意が必要となります。

Findで検索結果が見つからない場合

検索結果がない場合はNothingが返る

Range.Findは、条件に一致するセルが見つからなかった場合にNothingを返します。

例えば先ほどのコードで「広島」を検索し、A2:A10に「広島」が存在しなかった場合、foundCellはNothingになります。

この状態で次の処理を実行すると、エラーになります。

'検索結果がNothingの状態でAddressを参照するとエラーになる
MsgBox foundCell.Address

このような処理を実行すると、実行時エラー91の「オブジェクト変数またはWithブロック変数が設定されていません。」が表示されます。

Excel VBAのFindで検索結果が見つからず実行時エラー91が発生した画面

Is Nothingで検索結果を判定する

Findを使用する場合は、検索結果を使用する前にIs Nothingで判定しておくと安全です。

Sub FindWithNothingCheck()

    Dim ws As Worksheet
    Dim foundCell As Range
    Dim searchWord As String

    '========================================
    ' 検索条件を設定する
    '========================================
    Set ws = ThisWorkbook.Worksheets("Sheet1")
    searchWord = "広島"

    '========================================
    ' A2:A10から検索文字を検索する
    '========================================
    Set foundCell = ws.Range("A2:A10").Find( _
                        What:=searchWord, _
                        LookIn:=xlValues, _
                        LookAt:=xlWhole, _
                        SearchOrder:=xlByRows, _
                        SearchDirection:=xlNext, _
                        MatchCase:=False)

    '========================================
    ' 検索結果が見つかったか判定する
    '========================================
    If foundCell Is Nothing Then

        '検索結果が見つからなかった場合
        MsgBox "「" & searchWord & "」は見つかりませんでした。", vbExclamation

        '以降の処理を実行せず終了する
        Exit Sub

    End If

    '========================================
    ' 検索結果が見つかった場合の処理
    '========================================
    MsgBox "検索結果:" & foundCell.Address, vbInformation

End Sub

このように、先にfoundCell Is Nothingを確認しておけば、検索結果がない状態で.Addressなどを参照することを防ぐことができます。

Excel VBAのFindでNothingを判定し検索結果が見つからないことを表示した画面

あるはずの値がFindで見つからない原因

検索結果がNothingになる原因は、単純に値が存在しない場合だけではありません。

特に確認したいのが、LookAtとLookInの設定です。

LookAt|完全一致と部分一致の違い

LookAtでは、検索文字とセルの内容をどのように比較するかを指定します。

  • xlWhole:セル全体が一致する場合だけ検索
  • xlPart:セルの一部が一致すれば検索

例えばセルに「東京都」と入力されていて、「東京」を検索する場合を考えてみます。

'完全一致で検索する
Set foundCell = ws.Range("A2:A10").Find( _
                    What:="東京", _
                    LookIn:=xlValues, _
                    LookAt:=xlWhole)

xlWholeでは「東京」と「東京都」は完全には一致しないため、検索結果はNothingになります。

一方で、次のようにxlPartを指定すると部分一致で検索できます。

'部分一致で検索する
Set foundCell = ws.Range("A2:A10").Find( _
                    What:="東京", _
                    LookIn:=xlValues, _
                    LookAt:=xlPart)

「東京都」の中に「東京」が含まれているため、この場合は検索結果を取得できます。

xcel VBAのFindでLookAtの完全一致と部分一致を比較した結果

LookIn|値と数式の違い

LookInでは、セルのどの情報を検索するかを指定します。

  • xlValues:セルに表示されている値を検索
  • xlFormulas:セルに入力されている数式を検索

例えばA2セルに=B2&C2という数式が入力され、B2が「東京」、C2が「本社」で、A2に「東京本社」と表示されている場合を考えてみます。

表示結果の「東京本社」を検索したいのであればxlValuesを使用します。

'セルに表示されている値から検索する
Set foundCell = ws.Range("A2:A10").Find( _
                    What:="東京本社", _
                    LookIn:=xlValues, _
                    LookAt:=xlWhole)

反対に、セルへ入力されている数式そのものを対象に検索したい場合はxlFormulasを使用します。

「値を検索したいのにxlFormulasになっている」といった場合にも、あるはずのデータが見つからない原因となります。

Findでは検索条件を明示する

Findを使用するときにもう一つ注意したいのが、検索条件の引数です。

LookIn、LookAt、SearchOrderなどの設定は保存されるため、引数を省略すると以前の設定が利用される場合があります。

Excelの検索画面で設定を変更したあとにVBAを実行すると、想定していない検索条件が利用される可能性もあります。

そのため実務では、必要な検索条件を省略せず明示しておく方が安全です。

Set foundCell = ws.Range("A2:A10").Find( _
                    What:=searchWord, _
                    LookIn:=xlValues, _
                    LookAt:=xlWhole, _
                    SearchOrder:=xlByRows, _
                    SearchDirection:=xlNext, _
                    MatchCase:=False)

コードが少し長くなりますが、処理内容が明確になり、Excel側の検索設定に影響されにくくなります。

実務で使えるFindのサンプルコード

最後に、Findを実務で使用するときの基本形をまとめておきます。

Sub SearchCustomer()

    Dim ws As Worksheet
    Dim searchRange As Range
    Dim foundCell As Range
    Dim searchWord As String

    '========================================
    ' 検索対象を設定する
    '========================================
    Set ws = ThisWorkbook.Worksheets("Sheet1")
    Set searchRange = ws.Range("A2:A100")

    '検索したい文字列を取得する
    searchWord = ws.Range("C2").Value

    '検索文字が空欄の場合は処理を終了する
    If searchWord = "" Then
        MsgBox "検索文字を入力してください。", vbExclamation
        Exit Sub
    End If

    '========================================
    ' 指定した範囲から完全一致で検索する
    '========================================
    Set foundCell = searchRange.Find( _
                        What:=searchWord, _
                        LookIn:=xlValues, _
                        LookAt:=xlWhole, _
                        SearchOrder:=xlByRows, _
                        SearchDirection:=xlNext, _
                        MatchCase:=False)

    '========================================
    ' 検索結果を確認する
    '========================================
    If foundCell Is Nothing Then

        '見つからなかった場合
        MsgBox "「" & searchWord & "」は見つかりませんでした。", vbExclamation

    Else

        '見つかった場合はセル番地と行番号を表示する
        MsgBox "検索結果:" & foundCell.Address & vbCrLf & _
               "行番号:" & foundCell.Row, vbInformation

    End If

End Sub

Findを使用するときは、検索処理そのものよりも、「見つからなかった場合を想定して処理を書く」ことが大切となります。

過去の記事のご紹介

VBAではFind以外にも、想定していないエラーが発生した場合の処理をあらかじめ用意しておくことが大切です。

On Error GoToを使用したエラー処理については、以下の記事でも詳しくご紹介しています。

最後に

いかがでしたでしょうか。

今回は、Excel VBAのRange.Findで検索結果が見つからない場合の対処法についてご紹介しました。

Findでは検索結果がない場合にNothingが返るため、検索結果を利用する前にIs Nothingで判定しておくことが大切です。

また、「あるはずなのに見つからない」という場合には、LookAtの完全一致・部分一致や、LookInの検索対象を確認してみてください。

検索条件を明示し、見つからなかった場合まで考慮しておくことで、より安全なVBAコードになるかと思います。

少しでも参考になれば幸いです。

開発依頼について

ココナラでWebスクレイピング開発サービスを出品しております。

自分で開発をしようと思ったけど、VBAでのネット記事が少なく困っている方も多いかと思います。

そんな方はいつでもお気軽にご相談ください。

また、本ブログからご依頼いただいた方については割引特典がございますので、

ご不明点と合わせてメッセージをいただけると幸いです。

Excelにてブラウザ操作自動化ツールを作成します その作業、webスクレイピングを使って自動化しましょう!

Webスクレイピング以外にもWebアプリの開発サービスも出品しております。

こちらについても、本ブログからご依頼いただいた方については割引特典がございますので、

お気軽にご相談ください。

スモールスケールのWebアプリ開発します 先ずはスモールスケールのWebアプリから始めませんか?

ご興味がある方はこちら!!

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

CAPTCHA