部品_MATCH検索位置取得
GetMatchPosition
https://feelcodelab.com/vba_parts/getmatchposition/
・指定した範囲(1 列)から、検索値と一致する最初のセルの「位置」を返す(完全一致) ・位置は、範囲の最初の行を 1 とした番号(Excel の MATCH 関数と同じ)。見つからない場合は 0 を返す ※ この部品は、見つからない場合も、エラーでは止まらず、0 を返す(見つからないのは、異常ではなく、結果のひとつ)
土台
取得
範囲
・【最重要】検索する範囲(vSearchRng)は、呼び出し側が、範囲設定の部品で作って、変数に入れて渡す
→ 範囲は、1 列だけの範囲にする(複数列の場合は、エラーで止まる)
→ 最終行が可変の場合は、範囲設定_行可変で作る(見つからない場合は Nothing になるので、先に確認する)
・【最重要】戻り値は「位置」であり、シート上の行番号ではない
→ 範囲の最初の行を 1 とした番号。シート上の行番号は、次の式で求める
シート上の行番号 = vSearchRng.Row + 戻り値 - 1
・【最重要】戻り値が 0 の場合は「見つからなかった」ことを表す。呼び出し側で必ず確認してから使う
→ 0 のまま、シート上の行番号を計算すると、誤った行(範囲の 1 つ上)を指す
・検索は「完全一致」で、英字の大文字・小文字は区別する("a-001" と "A-001" は別の値)
※ Excel の MATCH 関数は区別しないが、この部品は、コードや ID の取り違えを防ぐため、区別する
・文字列の「1」と、数値の 1 は、一致しない(Excel の MATCH 関数と同じ)
数値と日付は、値が同じなら一致する。セルのエラー値(#N/A など)は、検索の対象外
・同じ値が複数ある場合は、最初に見つかった(最も上の)位置を返す
・検索値が空(Empty・空文字・Null・エラー値)の場合は、呼び出し側の誤りとして、エラーで止まる
・設定の誤りは、0 ではなく、原因を示すエラーで止まる(Err.Raise)
- 検索範囲(vSearchRng)が Nothing(vbObjectError + 1014)
- 検索範囲が、1 列でない(vbObjectError + 1017)
- 検索値が空(vbObjectError + 1016)
・Offset / Find / Resize / With は禁止(検索は、配列に取り込んで比較する)・他の部品を参照しない(土台) ・組み合わせ:範囲設定_固定(または範囲設定_行可変)→ MATCH検索位置取得 (呼び出し側が、範囲を作って変数に入れ、その変数を渡す) ・組み合わせ:MATCH検索位置取得 → 範囲設定_固定 など (見つけた行番号を使って、その行の範囲を作る)
・特定のシートや表の名前には、依存しない(呼び出し側が渡した範囲だけを使う) ・検索する範囲(vSearchRng)は、検索する値が縦に並んだ、1 列の範囲にする ・戻り値は、範囲の最初の行を 1 とした「位置」(シート上の行番号は、範囲の先頭行を使って、呼び出し側で求める)
vSearchRng : 検索する範囲(Range)。1 列だけの範囲。範囲設定の部品で作る vSearchValue : 検索値(Variant)。文字列・数値・日付
Long : 見つかった場合は、範囲の最初の行を 1 とした位置。見つからない場合は 0
Long
Function 部品_MATCH検索位置取得( _
ByVal vSearchRng As Range, _
ByVal vSearchValue As Variant) As Long
部品_MATCH検索位置取得 = f_GetMatchPosition(vSearchRng, vSearchValue)
End Function
Function f_GetMatchPosition( _
ByVal vSearchRng As Range, _
ByVal vSearchValue As Variant) As Long
Dim arr As Variant
Dim cellValue As Variant
Dim rowCount As Long
Dim i As Long
Dim isSearchText As Boolean
f_GetMatchPosition = 0
If vSearchRng Is Nothing Then
Err.Raise vbObjectError + 1014, "f_GetMatchPosition", _
"検索範囲(vSearchRng)が設定されていません(Nothing)。"
End If
If vSearchRng.Columns.Count <> 1 Then
Err.Raise vbObjectError + 1017, "f_GetMatchPosition", _
"検索範囲(vSearchRng)は、1 列だけの範囲にしてください(現在は " & _
vSearchRng.Columns.Count & " 列)。"
End If
If IsError(vSearchValue) Then
Err.Raise vbObjectError + 1016, "f_GetMatchPosition", _
"検索値(vSearchValue)が、エラー値です。"
End If
If IsNull(vSearchValue) Or IsEmpty(vSearchValue) Then
Err.Raise vbObjectError + 1016, "f_GetMatchPosition", _
"検索値(vSearchValue)が空です(Empty または Null)。"
End If
If VarType(vSearchValue) = vbString Then
If Len(vSearchValue) = 0 Then
Err.Raise vbObjectError + 1016, "f_GetMatchPosition", _
"検索値(vSearchValue)が空です(空文字)。"
End If
End If
rowCount = vSearchRng.Rows.Count
If rowCount = 1 Then
ReDim arr(1 To 1, 1 To 1)
arr(1, 1) = vSearchRng.Value
Else
arr = vSearchRng.Value
End If
isSearchText = (VarType(vSearchValue) = vbString)
For i = 1 To rowCount
cellValue = arr(i, 1)
If IsError(cellValue) = False Then
If VarType(cellValue) = vbString Then
If isSearchText Then
If StrComp(cellValue, vSearchValue, vbBinaryCompare) = 0 Then
f_GetMatchPosition = i
Exit Function
End If
End If
ElseIf IsEmpty(cellValue) = False Then
If isSearchText = False Then
If cellValue = vSearchValue Then
f_GetMatchPosition = i
Exit Function
End If
End If
End If
End If
Next i
End Function◆例1:1 列目で検索し、見つかった行の 3 列目の値を取得する◆
Dim lastRow As Long
Dim rng As Range
Dim pos As Long
Dim dataRow As Long
lastRow = 部品_最終行取得(ThisWorkbook, "顧客表", 1) '1列目の最終行
Set rng = 部品_範囲設定_固定(ThisWorkbook, "顧客表", 2, 1, lastRow, 1) '2行目~最終行の、1列目
pos = 部品_MATCH検索位置取得(rng, "A-001")
If pos = 0 Then
MsgBox "A-001 は、見つかりませんでした"
Exit Sub
End If
dataRow = rng.Row + pos - 1 'シート上の行番号 = 範囲の開始行 + 位置 - 1
MsgBox ThisWorkbook.Worksheets("顧客表").Cells(dataRow, 3).Value
※ 設定の誤り(Nothing、複数列、検索値が空)の場合は、0 ではなく、
原因を示すエラーで止まる(起点で On Error で受けて、Err.Description を表示する) 1.0
2026-10-29