条件に当てはまるセルを検索する(Find/FindNext/FindPreviousメソッド) |Excel VBA |
セル範囲の中から指定した条件に当てはまるセルを検索します。条件に当てはまるセルが複数ある場合に、見つかったセルの次のセルを検索するのにFindNextメソッドとFindPreviousメソッドを使用します。
引数がたくさんありますが、[検索と置換]ダイアログボックスでセルを検索するときに指定する内容とほぼ同じです。なお、条件に当てはまるセルが存在しない場合には、Nothingを返します。
構文 Object.Find(What, After, LookIn, LookAt, SearchOrder, SearchDirection, MatchCase, MatchByte, SearchFormat) Object.FindNext(After) Object.FindPrevious(After)
設定項目 | 内容 |
---|---|
Object | Rangeオブジェクト |
What | 検索するデータを指定 [省略不可] |
After | 単一のセルを指定。この引数に指定したセルの次のセルから検索を開始する。省略するとObjectで指定したセル範囲の左上端セルの次のセルから検索する [省略可能] |
LookIn | 検索の対象を指定 数式(xlFormulas)、値(xlValues)、コメント(xlComments) [省略可能] |
LookAt | 完全に同一なセルだけを検索(xlWhole)、一部分でも一致するセルの検索(xlPart) [省略可能] |
SearchOrder | 検索方向を指定する。列方向に検索する(xlByColumns)、行方向に検索する(xlByRows) [省略可能] |
SearchDirection | 前方に検索(xlNext:既定値)、後方に検索(xlPrevious)[省略可能] |
MatchCase | 大文字と小文字を区別する(True)、区別しない(False) [省略可能] |
MatchByte | 半角と全角を区別する(True)、区別しない(False) [省略可能] |
SearchFormat | 書式を検索する (True)、検索しない(False) [省略可能](※) |
(※)引数SearchFormatは、Excel 2002以降で使用可
■ セルが見つかったかどうかを判定する
次のサンプル1はワークシート上に「モーグ」と入力されたセルを検索して文字を太字にします。
Sub Sample()
Cells.Find(What:="モーグ", LookIn:=xlValues, _
LookAt:=xlWhole).Font.Bold = True
End Sub
一見問題なさそうですが、このサンプルでは「モーグ」と入力したセルが見つからなかったときにエラーが発生します。
Findメソッドは条件を満たすセルがあった場合、そのセルを表すRangeオブジェクト返し、なかった場合はNothingを返します。NothingはRangeオブジェクトではないので、Nothingに対して.Font.Bold=Trueを実行しようとしてエラーとなるのです。
そこで、Findメソッドで検索したセルに対して処理を行うときは、必ずセルが見つかったかどうかを判定します。なお、Nothingかどうかを判定するには、=演算子でなくIs演算子を使用することに注意してください。
Sub Sample2()
Dim Rng As Range
Set Rng = Cells.Find(What:="モーグ", LookIn:=xlValues, LookAt:=xlWhole)
If Not Rng Is Nothing Then
Rng.Font.Bold = True
End If
End Sub
■ 条件を満たすすべてのセルを検索する
次のサンプル3は、LookAt:=xlPartと指定することであいまい検索(部分一致検索)を行い、指定したキーワードを含むレコードをデータベースから検索して、その結果をアクティブシートに転記するものです。
Sub Sample3()
Dim c As Range
Dim firstAddress As String
With Worksheets("DB").UsedRange.Columns(1)
Set c = .Find(What:=Range("B1").Value, _
LookIn:=xlValues, LookAt:=xlPart) '---(1)
'条件に当てはまるセルがあるかどうかを判定
If Not c Is Nothing Then
'最初のセルのアドレスを覚える
firstAddress = c.Address
'繰返し検索し、条件を満たすすべてのセルを検索する
Do
c.Resize(1, 3).Copy Destination:= _
Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
Set c = .FindNext(c) '----------------------(2)
If c Is Nothing Then Exit Do
Loop Until c.Address = firstAddress
End If
End With
End Sub
このサンプルではDBシートの1列目を検索します。
(1)のFindメソッドで「アクティブシートのセルB1と同じ値を一部でも含むセル」を検索し、条件を満たすセルがあったかどうかをIfステートメントでチェックします。条件を満たすセルがあった場合、最初に見つかったセルのアドレスを保存しておき、Do...Loopで2回目以降の検索を行います。
Do... Loopの中では、見つかったセルの1行分のデータ(ここでは3列分)をアクティブシートの表の末尾に追加し、FindNextメソッドで次の検索を行います。
FindNextメソッドは、Findメソッドの検索条件を引き継いで検索します。引数Afterを指定すると、そのセルの次のセルから下または右に向かって検索します。省略すると検索範囲の先頭に戻って次のセルから検索します。(2)では引数Afterにcを指定し、今見つけたセルの次から検索します。
また、FindNextメソッドは、検索範囲の最後に達すると、検索範囲の最初に戻って検索するため、見つかったセルのアドレスが、最初に見つかったセルのアドレスfirstAddressと等しければ、検索が一巡したことになります。
このようにFindメソッド、FindNextメソッド、Do...Loopステートメントを使い、条件を満たすセルを全て見つけた時点で検索処理を終了させることが、検索を繰り返すコードを書く際のポイントです。
なお、あいまい検索の方法として、引数Whatに「*」や「 ?」といったワイルドカードを使用することも可能です。
●補足●
2回目以降の検索を、Findメソッドで行うこともできます。ただし、Findメソッドの引数Whatは省略できないので、(2)をFindメソッドで行う場合は次のように記述します。
Set c = .Find(What:=Range("B1").Value, After:=c)
FindメソッドはFindNextメソッドと同様に、引数Afterで指定したセルの次のセルから検索します。省略すると、検索範囲の先頭セルが指定されたのと同じになり、2つめのセルから検索が開始されます。
ループを使って条件を満たすすべてのセルを検索する場合、引数Afterを省略すると先頭のセルは最後に検索されることになるので注意してください。
A |
|
1 | 田中 |
2 | 山田 |
3 | 鈴木 |
4 | 太田 |
5 | 高橋 |
シートに上のようなデータがあるとき、サンプル4を実行すると
セルA2(山田)→セルA4(太田)→セルA1(田中)の順に検索されます。
先頭のセルA1(田中)から順に検索するには、引数Afterに検索範囲の最後のセルA5を指定します。
Sub Sample4()
Dim c As Range
Dim firstAddress As String
With Range("A1:A5")
Set c = .Find("田", LookIn:=xlValues, LookAt:=xlPart)
If Not c Is Nothing Then
firstAddress = c.Address
Do
MsgBox c.Address & " : " & c.Value
Set c = .FindNext(c)
If c Is Nothing Then Exit Do
Loop Until c.Address = firstAddress
End If
End With
End Sub
●注意●
Findメソッドの引数のうち、LookIn、LookAt、SearchOrder、MatchCase、MatchByteは、指定を省略した場合には前回処理で使用された値を使用します。つまり、マクロ実行前に行われた検索処理の条件を引き継いでしまうので、省略時の既定値が保証されていないことになります。
前回の検索処理には、[検索と置換]ダイアログボックスを使って手動作で検索した場合も含まれます。また、これらの引数を指定すると、[検索と置換]ダイアログボックスの条件にも引き継がれます。
引数で指定する条件によって検索結果が異なることが懸念される場合には、引数は省略せずに指定するようにしてください。