Excel VBA 逆引き集 | XLOOKUP相当

Excel VBA
スポンサーリンク

XLOOKUP相当

XLOOKUPの強みは「検索列と戻り列を自由に指定」「見つからないときの値を簡単に設定」「縦横どちらも対応」。VBAでも同じ発想で、最短の呼び出しから辞書・Find・自作関数まで用途別に使い分けられます。


前提と選び方

  • 環境の前提:
    • XLOOKUPをそのまま呼ぶ: Excel 365 / 2021 以降。
    • それ以前のExcel: 辞書・Find・Evaluate(INDEX/MATCH)で代替。
  • 使い分けの目安:
    • 最短で書きたい: WorksheetFunction.XLookup。
    • 大量データで爆速+柔軟: Dictionary(O(1)検索)。
    • 部分一致や複雑な条件: Range.Find。
    • 数式で一括生成→値化: EvaluateでINDEX/MATCH。

最短テンプレ:WorksheetFunction.XLookup

Sub XLookup_Basic()
    Dim key As Variant, lookArray As Range, returnArray As Range, result As Variant
    key = Range("A2").Value
    Set lookArray = Range("D2:D1000")    '検索対象の列(1列でOK)
    Set returnArray = Range("F2:F1000")  '戻り値列(同じ行数)

    result = Application.WorksheetFunction.XLookup(key, lookArray, returnArray, "") '未一致は空文字
    Range("B2").Value = result
End Sub
VB
  • ポイント:
    • 検索列と戻り列を別々に指定できる。
    • 未一致時の値(第4引数)を与えれば、エラー処理不要。
    • 複数列返しも可能(戻り範囲を複数列にすると配列返却)。セルへ出すときは範囲に一括代入。
Sub XLookup_MultiReturn()
    Dim res As Variant
    res = Application.WorksheetFunction.XLookup( _
            Range("A2").Value, Range("D2:D1000"), Range("F2:G1000"), Array("", ""), False)
    Range("B2:C2").Value = res  '2列分を一気に貼り付け
End Sub
VB

大量データ定番:DictionaryでXLOOKUP相当

Sub XLookup_Dictionary()
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    Application.EnableEvents = False

    'キー列→戻り列(複数可)を辞書化
    Dim map As Object: Set map = CreateObject("Scripting.Dictionary")
    Dim m As Range: Set m = Worksheets("Master").Range("A2:C500000") 'A:キー B,C:戻り
    Dim data As Variant: data = m.Value
    Dim i As Long, k As String
    For i = 1 To UBound(data, 1)
        k = CStr(data(i, 1))
        '戻り複数を配列で保持
        map(k) = Array(data(i, 2), data(i, 3))
    Next

    '明細側で照合(A:キー → B,Cを埋める)
    Dim last As Long: last = Cells(Rows.Count, "A").End(xlUp).Row
    Dim out As Range: Set out = Range("A2:C" & last)
    Dim v As Variant: v = out.Value
    For i = 1 To UBound(v, 1)
        k = CStr(v(i, 1))
        If map.Exists(k) Then
            v(i, 2) = map(k)(0)
            v(i, 3) = map(k)(1)
        Else
            v(i, 2) = "": v(i, 3) = ""
        End If
    Next
    out.Value = v

    Application.EnableEvents = True
    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True
End Sub
VB
  • メリット:
    • 高速: 10万〜数百万行でも安定。
    • 柔軟: キー・戻り列の位置に制約なし。複数列返却も簡単。
  • コツ:
    • キー型の統一: CStrで文字列化して登録・照合。
    • 配列一括: 読み込み・書き戻しは範囲の配列で。

条件が自由:Range.FindでXLOOKUP相当

Sub XLookup_Find()
    Dim key As String: key = Range("A2").Value
    Dim col As Range: Set col = Range("D2:D100000")  '検索対象
    Dim f As Range
    Set f = col.Find(What:=key, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, MatchCase:=False)
    If Not f Is Nothing Then
        Range("B2").Value = f.Offset(0, 2).Value  'D→Fへ(+2列)
    Else
        Range("B2").Value = ""
    End If
End Sub
VB
  • メリット:
    • 部分一致(xlPart)や大文字小文字、検索方向など柔軟。
  • 注意:
    • 一件ずつの検索は大量処理に不向き。大量は辞書で。

数式一括生成:EvaluateでINDEX/MATCH(互換性重視)

Sub XLookup_Like_IndexMatch()
    Dim last As Long: last = Cells(Rows.Count, "A").End(xlUp).Row
    With Range("B2:B" & last)
        .Formula = "=IFERROR(INDEX($F$2:$F$100000, MATCH(A2, $D$2:$D$100000, 0)), """")"
        .Value = .Value  '値化して再計算負荷ゼロに
    End With
End Sub
VB
  • メリット:
    • 古いExcelでも動く。 XLOOKUPが使えない環境の安定策。
  • コツ:
    • 計算モードを手動にして最後に1回再計算すると体感が軽い。

自作関数:XLOOKUP風UDF(学習用・互換用)

Function XLOOKUP_VBA(ByVal key As Variant, look As Range, ret As Range, Optional notFound As Variant = "")
    Dim i As Long, n As Long
    n = look.Rows.Count
    If ret.Rows.Count <> n Then
        XLOOKUP_VBA = CVErr(xlErrRef)
        Exit Function
    End If
    For i = 1 To n
        If key = look.Cells(i, 1).Value Then
            XLOOKUP_VBA = ret.Cells(i, 1).Value
            Exit Function
        End If
    Next
    XLOOKUP_VBA = notFound
End Function
VB
  • 使い方例:
    • シートで =XLOOKUP_VBA(A2, D2:D1000, F2:F1000, "")
  • 注意:
    • 基本は「完全一致・単一列返し」。部分一致や複数列返しは拡張が必要。
    • 速度は辞書>UDF。業務では辞書の方が安定。

まとめの使い分け

  • Excel 365/2021: WorksheetFunction.XLookupを最短で。未一致の第4引数を活用。
  • 旧環境・大量データ: 辞書+配列一括が鉄板。
  • 柔軟検索: Findでピンポイント。複数候補はFindNextで列挙。
  • 式で一括+値化: INDEX/MATCHをEvaluateで埋めて最後に値化。

落とし穴と対策

  • ラベル:キー型の不一致
    • 数値と文字列の「00123/123」問題。キーは CStr で統一。
  • ラベル:検索範囲と戻り範囲の長さ不一致
    • XLOOKUPも辞書も「同じ行数」が前提。UDFではRefエラー返すなど検知。
  • ラベル:大量データのセル個別アクセス
    • 遅い。必ず配列で処理して一括書き戻し。
  • ラベル:再計算やイベントの暴発
    • 処理前に ScreenUpdating/EnableEvents/Calculation を一時停止→最後に復帰。
タイトルとURLをコピーしました