目次
はじめに
VBAでMatch関数を使うとき、WorksheetFunction.MatchとApplication.Matchの2つの書き方があります。どちらも同じように見えますが、エラーが発生したときの動作が大きく異なるため、使い分けが重要です。
WorksheetFunctionとApplicationの基本的な違い
WorksheetFunctionとApplicationは、どちらもExcelのワークシート関数をVBAから呼び出すための仕組みです。しかし、関数が失敗したときの振る舞いが異なります。
WorksheetFunction.Matchは、検索値が見つからないとVBAのエラー(実行時エラー1004)を発生させてプログラムが停止します。一方、Application.Matchは、見つからない場合にError型の値を返すだけで、プログラムは停止しません。
この違いは、Match関数に限らず、VLookupやIndexなど、値が見つからない可能性がある関数全般に当てはまります。
エラー処理の違いを実際に確認する
実際に動作を確認できるコードを用意しました。以下の手順で試してみてください。
- 新しいExcelブックを開く
- Alt + F11でVBエディタを開く
- 「挿入」→「標準モジュール」で新しいモジュールを追加
- 以下のコードを貼り付けて実行
Sub MatchTest()
Dim ws As Worksheet
Dim result As Variant
Set ws = ThisWorkbook.Worksheets("Sheet1")
' サンプルデータを準備
ws.Range("A1").Value = "リンゴ"
ws.Range("A2").Value = "バナナ"
ws.Range("A3").Value = "ミカン"
' Application.Matchの場合
result = Application.Match("存在しない値", ws.Range("A:A"), 0)
If IsError(result) Then
MsgBox "見つかりませんでした"
Else
MsgBox "見つかりました: " & result & "行目"
End If
End Sub
このコードは正常に動作し、「見つかりませんでした」というメッセージが表示されます。Application.MatchがErrorを返すため、IsError関数でチェックできます。
【WorksheetFunction.Matchでエラー処理を行う方法】
WorksheetFunction.Matchを使いたい場合は、On Errorステートメントでエラー処理を追加する必要があります。
Sub MatchTestWithErrorHandling()
Dim ws As Worksheet
Dim result As Long
Set ws = ThisWorkbook.Worksheets("Sheet1")
' サンプルデータを準備
ws.Range("A1").Value = "リンゴ"
ws.Range("A2").Value = "バナナ"
ws.Range("A3").Value = "ミカン"
On Error Resume Next
result = WorksheetFunction.Match("存在しない値", ws.Range("A:A"), 0)
If Err.Number <> 0 Then
MsgBox "見つかりませんでした"
Err.Clear
Else
MsgBox "見つかりました: " & result & "行目"
End If
On Error GoTo 0
End Sub
On Error Resume Nextを使うと、エラーが発生してもプログラムが停止せず、次の行に進みます。その後、Err.Numberでエラーが発生したかどうかを確認できます。
パフォーマンスの違い
WorksheetFunctionとApplicationでは、処理速度にも微妙な違いがあります。
一般的に、Application.Matchの方がわずかに高速です。これは、WorksheetFunctionがエラー発生時に例外処理(プログラムを一時停止してエラー情報を準備する仕組み)を行うオーバーヘッド(余計な処理時間)があるためです。
ただし、この差は数千回、数万回と繰り返し実行する場合に体感できる程度で、通常の使用では気にする必要はありません。大量のデータを処理する場合や、ループ内で何度もMatchを呼び出す場合は、Application.Matchを使うと少し速くなる可能性があります。
使い分けの判断基準
どちらを使うか迷ったときの判断基準をまとめます。
Application.Matchがおすすめなのは、検索値が見つからない可能性がある場合です。マスタデータの検索や、ユーザー入力値の照合など、値が存在しないケースが普通にあり得る状況では、IsErrorでシンプルにチェックできるApplication.Matchが便利です。
result = Application.Match(searchValue, searchRange, 0)
If IsError(result) Then
' 見つからなかった場合の処理
Else
' 見つかった場合の処理
End If
逆に、WorksheetFunction.Matchがおすすめなのは、値が必ず見つかるはずの場合です。プログラム内部で生成した固定のリストを検索する場合や、見つからないこと自体が異常事態である場合は、エラーで停止させることで問題を早期に発見できます。
また、On Error Resume Nextを既に使っている処理の中では、WorksheetFunction.Matchを使っても問題ありません。すでにエラー処理の枠組みがあるため、追加のコードが不要です。
WorksheetFunctionを使うかApplicationを使うかは、「エラーをどう扱いたいか」で決めるのがポイントです。見つからない可能性があるならApplication、必ず見つかるはずならWorksheetFunctionという基準で選ぶと、コードの意図も明確になります。
まとめ
Application.Matchは値が見つからないときにErrorを返し、WorksheetFunction.Matchは実行時エラーを発生させます。検索値が存在しない可能性がある場合はApplication.Matchを使うと、シンプルなエラー処理で対応できます。