スポンサーリンク

ExcelマクロのFind(FindNext)による文字列検索

Findを使って特定の文字列が入っているセルを見つけることができます。

Findで文字を見つけるコード

別のファイルから特定の項目を見つけて、さらに別のファイルにコピペする際に便利です。

Findで文字列を検索する

Findの使い方

以下のデータの中から、”測定値A”のセルの位置を取得しましょう。

測定値が入っているデータの例
Sub test()

target = Rows(1).Find("測定値A")
MsgBox target

End Sub

検索範囲を指定してから、Find(“検索文字”)と書きます。

Findで文字を見つけるコード

もし検索範囲内に指定の文字が存在すれば、変数targetに検索した文字が入ります。
実行してみて”測定値A”が表示されれば成功です。

行番号or列番号を取得する方法

Sub test()

r = Rows(1).Find("測定値A").Row
c = Rows(1).Find("測定値A").Column
MsgBox r
MsgBox c

End Sub

行番号が欲しければRow、列番号ならColumnをつけ足せば番号が手に入ります。

行と列を示した例

ただし、列の場合はアルファベットじゃなくて番号になるので注意しましょう。

検索範囲を広げる方法

Sub test()

r = Range(Rows(1), Rows(2)).Find("測定値A").Row
c = Range(Rows(1), Rows(2)).Find("測定値A").Column
MsgBox r
MsgBox c

End Sub

上記コードは1,2行目の中から”測定値A”を探します。
Range(Rows(), Rows())で複数行を対象に指定可能です。

1,2行を示した例

例えば3~5行を対象にしたいなら、Range(Rows(3), Rows(5))にしましょう。

また、Cellsを使えばシート全体を指定できます。

Sub test()

r = Cells.Find("測定値A").Row
MsgBox r

End Sub

ただし全体を検索範囲にすると、欲しくない位置を取得する可能性も高まります。

完全一致 or 部分一致にする方法

Sub test()

c = Rows(1).Find("測定値", LookAt:=xlPart).Column
MsgBox c

End Sub

引数LookAtを設定すると”完全一致”か”部分一致”かを選べます。

検索範囲.Find(検索文字, LookAt := xlWhole or xlPart)
・完全一致:xlWhole
・部分一致:xlPart

上記コードは部分一致にしているので”測定値”が含まれればヒットします。

xlWholeにすると完全一致ですが、今回は”測定値”という項目がありません。
そのため実行すると下図のようなエラーになります。

xlWholeでエラーになる例

複数のセルが条件に当てはまる場合

Sub test()

c = Rows(1).Find("測定値", LookAt:=xlPart).Column
MsgBox c

End Sub

複数のセルが条件に当てはまる場合は最も番号の若いセルがヒットします。
例えば上記コードの場合、”測定値”が含まれれば条件を満たします。

項目名に測定値が入っている図

つまり”測定値A,B,C”のどれでも当てはまります。

しかし実行すると2が表示されるはずです。
つまり、この方法では”測定値A”しかヒットしません。

すべての”測定値”が欲しい場合はFindNextを使いましょう。

FindNextで複数の文字を検索する

FindNextの使い方

Sub test()

target1 = Rows(1).Find("測定値", LookAt:=xlPart).Column
target2 = Rows(1).FindNext(Rows(1).Find("測定値", LookAt:=xlPart)).Column

MsgBox target1
MsgBox target2

End Sub

まず変数target1では、Findで1つ目の”測定値”を見つけます。
そしてFindNextの()に1行目で使ったFindをそのまま入れてください。

FindNextで2つまでデータを見つけるコード

実行するとtarget1は2をtarget2は3を表示するはずです。

FindNextで測定値ABを見つける図

このようにFindNextなら複数ヒットしたセルを順番に取り出すことができます。

Findを変数に格納する方法

Sub test()

Dim target As Range
Set target = Rows(1).Find("測定値", LookAt:=xlPart)

col1 = target.Column
col2 = Rows(1).FindNext(target).Column
MsgBox col1
MsgBox col2

End Sub

同じコードを何度も書き続けると面倒なので、Setを使ってまとめましょう。

FindNextでtargetを変数化した例

Dimで変数targetがセルの位置であることを定義します。
Setで変数targetが最初に見つけたセルであると決めましょう。
するとFindNextにはtargetと入れるだけで済みます。

3つ以上のセルをヒットさせる方法

項目名に測定値が入っている図

“測定値A” ~ “測定値C”の3つを取得してみましょう。

Sub test()

Dim target As Range
Set target = Rows(1).Find("測定値", LookAt:=xlPart)

col1 = target.Column

col2 = Rows(1).FindNext(target).Column
Set target = Rows(1).FindNext(target)

col3 = Rows(1).FindNext(target).Column

MsgBox col1
MsgBox col2
MsgBox col3

End Sub
FindNextで3つデータを見つけるコード

“測定値A” ~ “測定値Cの列番号を”col1” ~ “col3″として取得しました。
検索対象が見つかったら、それを変数targetとし、さらに次を探していきます。

ちなみに、下記コードのように更新を忘れると失敗します。

Sub test()

Dim target As Range
Set target = Rows(1).Find("測定値", LookAt:=xlPart)

col1 = target.Column
col2 = Rows(1).FindNext(target).Column
col3 = Rows(1).FindNext(target).Column
MsgBox col1
MsgBox col2
MsgBox col3

End Sub

targetは常に1個目のデータを指すので、col2もcol3も同じデータがヒットしているためです。

FindNextで3つ目のファイルを間違って見つけた例

なので、検索対象が見つかったら必ず更新するようにしましょう。

loopで複数のセルを検索する

Sub test()

Dim target As Range
Set target = Rows(1).Find("測定値", LookAt:=xlPart)

i = 1
Do While i < 4
    MsgBox target.Column
    Set target = Rows(1).FindNext(target)
    i = i + 1
Loop

End Sub

同じ処理を何度も書くのはめんどくさいので、loop文で繰り返しましょう。
Do~Loopまでの処理が繰り返されます。

LoopでFindNextの対象を更新する例

3回で終わりなので条件はWhile i < 4です。
loop文の中でtargetを更新しているので、実行されるたびに次の”測定値”を探してくれます。

FindNextの無限ループ

Sub test()

Dim target As Range
Set target = Rows(1).Find("測定値", LookAt:=xlPart)
Start = target.Address

Do
    MsgBox target.Column
    Set target = Rows(1).FindNext(target)
    If target.Address = Start Then
        Exit Do
    End If
Loop

End Sub

FindNextでは、一通りすべてのデータを見つけた後に1個目のデータに戻ってきます。
ここで、変数Startをつまり”測定値A”の位置として保存しましょう。
そして、loop文の中でもしtargetの位置がStartと同じなら、処理を終えるようにします。

LoopでFindNextを最後まで実行するコード

すると、1周処理が終わってStartに戻ってくるタイミングでループを終えてくれます。

まとめ

今回はFindとFindNextを解説しました。
1つだけ見つけたいならFindで、複数見つけたいならFindNextをループさせましょう。
コピペのプログラムと非常に相性が良いのでぜひ使ってみてください!

コメント

タイトルとURLをコピーしました