導入
実務でマクロを組む際、「特定のデータがリストの何行目にあるか知りたい」という場面は非常に多いです。VBAだけでループ処理(For Eachなど)を書いて探すことも可能ですが、コードが長くなり、実行速度も遅くなりがちです。そこで活用したいのがExcelの「MATCH関数」です。VBAからワークシート関数を呼び出すことで、効率的かつ簡潔に検索処理を実装できます。
基礎知識
MATCH関数は、指定された範囲内で特定の値を検索し、その値が範囲内の何番目にあるかを「数値」で返す関数です。
VBAからこの関数を使うには、Application.WorksheetFunctionオブジェクトを使用します。
基本構文は「Application.WorksheetFunction.Match(検索値, 範囲, 照合の型)」となります。
照合の型に「0」を指定することで、完全一致での検索が可能になります。また、検索値が見つからない場合はVBA側でエラー(実行時エラー1004)が発生するため、エラーハンドリングを組み合わせるのが実務上の定石です。
実装/解決策
実務では、単にエラーを出すだけでなく、検索に失敗した場合に「処理を中断する」のか「新規追加する」のかといった分岐が必要です。On Error GoTo文を使用し、エラーが発生した際の挙動を制御することで、堅牢なプログラムを作成します。
サンプルプログラム
以下のコードは、B列のリストからA1セルの値を検索し、その位置(行番号)を取得する実用的な例です。
Sub FindValuePosition()
‘ 検索結果を格納する変数(エラー値も入る可能性があるためVariant型を推奨)
Dim ret As Variant
Dim searchRange As Range
‘ 検索対象の範囲を設定
Set searchRange = Range(“B1:B5”)
‘ エラーが発生した場合はErr_Trapラベルへ飛ぶ設定
On Error GoTo Err_Trap
‘ MATCH関数を実行
‘ 検索値が見つかれば、範囲内での相対的な位置が返る
ret = Application.WorksheetFunction.Match(Range(“A1”).Value, searchRange, 0)
‘ 結果を表示(相対位置のため、開始行を考慮して実アドレスを計算することも可能)
MsgBox “検索値は範囲内の” & ret & “番目にあります。”
Exit Sub
Err_Trap:
‘ 検索値が見つからない場合のエラー処理
If Err.Number = 1004 Then
MsgBox “指定された値は見つかりませんでした。”
Else
MsgBox “予期せぬエラーが発生しました:” & Err.Description
End If
End Sub
応用・注意点
1. 行番号のオフセット: MATCH関数が返すのは「検索範囲内の何番目か」という数値です。例えばB10からB20を検索範囲にした場合、結果が「1」ならB10セルを指します。実際の行番号を知りたい場合は、開始行を足すなどの調整が必要です。
2. Matchメソッドの活用: WorksheetFunctionを使用するとエラー時にコードが停止しますが、Application.Match(WorksheetFunctionを省略)と記述すると、エラーを発生させずに「エラー値(Error 2042)」を戻り値として受け取れます。IsError関数で判定したい場合は、こちらの方がスマートな場合があります。
3. 大文字・小文字の区別: MATCH関数は、基本的にアルファベットの大文字・小文字を区別しません。厳密に区別したい場合は、VBAのStrComp関数などと組み合わせる別のロジックが必要になります。
