大体でIT

-ちょっと使えるネタを紹介-

大体でIT

Excel VBAで、VLookup関数を高速化する方法についてご紹介します。VLookup関数を高速でかつ、シンプルに使う方法は「埋め込み数式」を使う方法です。さらに高速化を目指したい場合は「Dictionary」を検討してみましょう。

はじめに

この記事では、VBAでVLookup関数を高速化する方法について、ご紹介します。

次の4つの方法でVLookup関数の機能を、実測してみました。

  • WorksheetFunctionでVLookup関数を使う
  • ForとIfを組み合わせて値を取得する
  • 埋め込み数式でVLookup関数を使う ←シンプルでかなり高速
  • Dictionaryで値を取得する ←ややこしいけど一番高速

「埋め込み数式」でVLookup関数を使うと、かなり高速でVBAコードもシンプルです。

十分に実務で使えるレベルですね。

どうしてもさらに高速にしたい場合は、「Dictionary」を使う方法を検討してみましょう。

では、VBAでVLookup関数を高速化する方法について、解説していきます。

この記事で紹介すること

  • VBAでVLookup関数を高速化する方法

目次から見たい項目へ移動すると便利ですよ。

目次

VLookup関数の機能を高速化したい

やりたいことは、VLookup関数の機能を高速化したい、ということです。

やりたいこと

やりたいことは、大量データから高速で値を検索するということで、次のようなイメージです。

大量データから高速で値を検索したい

「50,000行」のデータから、「10,000行」分を検索するという感じです。

実務では検索データが増えてきて、実行するのに時間がかかってしまう場合もあります。

そこまで頻度が高くなければいんですけど、頻度が高い場合は一回当たりの時間が短ければ短いほどいいですよね。

なので、VLookup関数の機能を一番高速化できてかつシンプルな方法というを確認してみます。

比較する方法

比較する方法は、次の4つでやってみます。

  • WorksheetFunctionでVLookup関数を使う
  • ForとIfを組み合わせて値を取得する
  • 埋め込み数式でVLookup関数を使う
  • Dictionaryで値を取得する

という感じです。

では、やっていきます。

大量データから条件一致のデータを取得してみる

大量データから条件一致のデータを取得してみます。

WorksheetFunctionでVLookup関数を使う

まずは、「WorksheetFunction」でVLookup関数を使ってみます。

結論から言うとこの方法は、ちょっと遅いです。

Sub TEST1()
    
    t = Timer
    
    Dim A
    A = Range("A2:B10001") '検索値を取得
    
    '検索値をループする
    For i = 1 To UBound(A, 1)
        'WorksheetFunctionでVLookup関数を使って値を取得
        A(i, 2) = WorksheetFunction.VLookup(A(i, 1), Range("D2:E50001"), 2, False)
    Next
    
    'セルに結果を入力
    Range("A2").Resize(UBound(A, 1), UBound(A, 2)) = A
    
    Debug.Print Timer - t & " 秒"
    
End Sub

大量データを用意しておきます。

大量データを用意

大量データを用意

では、VBAコードを実行してみます。

「WorksheetFunction」でVLookup関数を使う

「WorksheetFunction」でVLookup関数を使う

「WorksheetFunction」でVLookup関数を使って検索できました。

かかった時間

かかった時間は、「27.71 秒」となりました。

まぁちょっと遅いかなという感じです。

ForとIfを組み合わせて値を取得

「ForとIfを組み合わせて」値を検索して取得してみます。

力技でやるという感じです。

Sub TEST2()
    
    t = Timer
    
    Dim A, B
    A = Range("A2:B10001") '検索値を取得
    B = Range("D2:E50001") 'データベースを取得
    
    '検索値をループ
    For i = 1 To UBound(A, 1)
        'データベースをループ
        For j = 1 To UBound(B, 1)
            '値が一致した場合
            If A(i, 1) = B(j, 1) Then
                A(i, 2) = B(j, 2) '検索結果を取得
                Exit For 'ループを終了
            End If
        Next
    Next
    
    'セルに結果を入力
    Range("A2").Resize(UBound(A, 1), UBound(A, 2)) = A
        
    Debug.Print Timer - t & " 秒"
    
End Sub

大量データを用意しておきます。

大量データを用意

大量データを用意

では、VBAコードを実行してみます。

「ForとIfを組み合わせて」値を取得

「ForとIfを組み合わせて」値を取得

「ForとIfを組み合わせて」値を取得できました。

かかった時間

かかった時間は、「62.10 秒」です。

力技は一番やっちゃいけないですね。

埋め込み数式でVLookup関数を使う

「埋め込み数式」でVLookup関数を使ってみます。

この「埋め込み数式」がかなり高速で、かつVBAコードもシンプルです。

実務ではこの方法を使った方がいいですね。

Sub TEST3()
    
    t = Timer
    
    '埋め込み数式でVLookup関数を使う
    Range("B2:B10001") = "=VLOOKUP(A2,$D$2:$E$50001,2,FALSE)"
    Range("B2:B10001").Value = Range("B2:B10001").Value '値に変換
    
    Debug.Print Timer - t & " 秒"
    
End Sub

という感じで、VBAコードがシンプルです。

一括で入力するところがポイントです。

大量データを用意しておきます。

大量データを用意

大量データを用意

では、VBAコードを実行してみます。

「埋め込み数式」でVLookup関数を使う

「埋め込み数式」でVLookup関数を使う

「埋め込み数式」でVLookup関数を使って、値を取得できました。

かかった時間

かかった時間は、「0.47 秒」です。

「WorksheetFunction」を使う方法で、「27 秒」ぐらいでしたので、かなり高速に値を検索できます。

「VLookup関数」かなり高速化しています。

ちなみにVLookup関数が高速化したのが「Excel2016」からなので、このバージョン以降の場合は「埋め込み数式」を使うのがベストです。

Dictionaryで値を取得

先ほどの埋め込み数式よりさらに高速化したい場合は、Dictionaryを使う方法があります。

Dictionaryで値を取得する

Dictonaryで値を取得する手順は、このようになります。

  • データベースを配列に入力して「Dictionary」に登録
  • 検索値を配列に入力する
  • 検索値で「Dictionary」を検索して「アイテム」を取得
  • 結果をセルに入力

という感じです。

Dictionaryで値を取得するVBAコードはこんな感じになります。

Sub TEST4()

    '辞書を作成
    Dim A
    Set A = CreateObject("Scripting.Dictionary")
    
    'データベースを取得
    Dim B
    B = Range("D2:E10")
    
    'データベースを辞書に登録する
    For i = 1 To UBound(B, 1)
        A.Add B(i, 1), B(i, 2)
    Next
    
    '検索値を取得
    Dim C
    C = Range("A2:B4")
    
    '辞書を検索して価格を取得
    For i = 1 To UBound(C, 1)
        C(i, 2) = A(C(i, 1))
    Next
    
    'セルに結果を入力
    Range("A2").Resize(UBound(C, 1), UBound(C, 2)) = C
    
End Sub

Dictionaryはちょっとややこしいので簡単な表を使って、実行手順をみてみます。

簡単な表を用意します。

簡単な表を用意します

データベースを配列に入力して「Dictionary」に登録します。

データベースを配列に入力して辞書に登録します

検索値を配列に入力します。

検索値を配列に入力します

検索値を「Dictionary」から検索してアイテムを取得していきます。

検索値を辞書から検索してアイテムを取得します

配列をセルに入力します。

配列をセルに入力します

これで、Dictionaryを使って値を取得できます。

Dictionaryで値を取得できました

Dictionaryで値を取得できました。

大量データで測定してみる

大量データで測定してみます。

Sub TEST5()
    
    t = Timer
    
    '辞書を作成
    Dim A
    Set A = CreateObject("Scripting.Dictionary")
    
    'データベースを取得
    Dim B
    B = Range("D2:E50001")
    
    'データベースを辞書に登録する
    For i = 1 To UBound(B, 1)
        A.Add B(i, 1), B(i, 2)
    Next
    
    '検索値を取得
    Dim C
    C = Range("A2:B10001")
    
    '辞書を検索して価格を取得
    For i = 1 To UBound(C, 1)
        C(i, 2) = A(C(i, 1))
    Next
    
    'セルに結果を入力
    Range("A2").Resize(UBound(C, 1), UBound(C, 2)) = C
    
    Debug.Print Timer - t & " 秒"
    
End Sub

大量データを用意します。

大量データを用意します

では、VBAコードを実行してみます。

Dictionaryで値を取得できました

Dictionaryで値を取得できました。

かかった時間

かかった時間は、「0.23 秒」です。

先ほどの「埋め込み数式」が「0.4 秒ぐらい」でしたので、2倍ぐらい速くなっています。

ただ、0.2秒も0.4秒もあまりかわらないので、大量データを検索したい場合は「埋め込み数式」がベストです。

おわりに

この記事では、VBAでVLookup関数を高速化する方法について、ご紹介しました。

次の4つの方法でVLookup関数の機能を、実測してみました。

  • WorksheetFunctionでVLookup関数を使う
  • ForとIfを組み合わせて値を取得する
  • 埋め込み数式でVLookup関数を使う ←シンプルでかなり高速
  • Dictionaryで値を取得する ←ややこしいけど一番高速

「埋め込み数式」でVLookup関数を使うと、かなり高速でVBAコードもシンプルです。

十分に実務で使えるレベルですね。

どうしてもさらに高速にしたい場合は、「Dictionary」を使う方法を検討してみましょう。

参考になればと思います。最後までご覧くださいまして、ありがとうございました。

関連する記事から探す

カテゴリから探す

カテゴリから見たい項目を探すと便利ですよ。

サイト内を検索する

↓キーワードを入力する

アーカイブから探す