非IT企業に勤める中年サラリーマンのIT日記

非IT企業でしかもITとは全く関係ない部署にいる中年エンジニア。唯一の趣味がプログラミングという”自称”プログラマー。

ExcelVBAで検索速度勝負!Findメソッド vs ワークシート関数利用

   

前回、Findメソッドを使った超高速検索方法について書きましたが、ワークシート関数利用版とどっちが速いか?という質問をもらったので速度勝負してみました。

ワークシート関数利用版というのはこっちの方です。

使ったデータは上記記事と同じく郵便局サイトの郵便番号ダウンロードページから全国データをもらって使いました。124,500行もの大量データの中から検索させます。

 

 

検索する郵便番号はランダムに40個選びました。(北海道は頭に0が入るのですがExcel上では数値として認識され0がなくなってしまうので検索ワードも先頭0なしでやりました。)

これを以下のようにzip配列変数に格納してループで順次検索させました。

Dim zip As Variant
zip = Array(420941, 981821, 9896801, 9998522, 3702461, 2700222, 2208121, 9591851, 9231269, 5030878, _
            4170844, 4430011, 6048004, 6128477, 6712132, 6392212, 7011527, 7911501, 8200067, 8720345, _
            660005, 891330, 101606, 9637858, 3702343, 3400024, 2520173, 9593444, 9203126, 5061317, _
            4380086, 4470866, 5290251, 5406019, 6530877, 6441142, 7390517, 7981354, 8595101, 8780146)
 

 

それでは速度勝負

Findメソッド版

まずFindメソッド版です。以下のようなコードでやりました。出力はセルだと速度ロスが起きるのでイミディエイトウィンドウに表示させます。

Dim i As Long
Dim d1, d2 As Double
Dim zip As Variant

d1 = Timer()
zip = Array(420941, 981821, 9896801, 9998522, 3702461, 2700222, 2208121, 9591851, 9231269, 5030878, _
            4170844, 4430011, 6048004, 6128477, 6712132, 6392212, 7011527, 7911501, 8200067, 8720345, _
            660005, 891330, 101606, 9637858, 3702343, 3400024, 2520173, 9593444, 9203126, 5061317, _
            4380086, 4470866, 5290251, 5406019, 6530877, 6441142, 7390517, 7981354, 8595101, 8780146)

Dim c As Range
For i = 0 To UBound(zip)
  Set c = Sheets("KEN_ALL").Range("C:C").Find(What:=zip(i), LookAt:=xlWhole)
  If Not c Is Nothing Then
    Debug.Print c(1, 5) & c(1, 6) & c(1, 7)
  Else
    Debug.Print "見つかりません"
  End If
Next
d2 = Timer()
Debug.Print (d2 - d1)
 

 

結果はご覧の通り。かかった時間は2.296875秒です。

 

ワークシート関数利用版

次にMatch関数利用版です。セルQ1に郵便番号を入力し、R1, S1, T1セルに、=INDIRECT(ADDESS(MATCH(Q1,C:C,0), 7)))という関数を仕込んでおきます。その結果を読んでイミディエイトウィンドウに出力させます。

Dim i As Long
Dim d1, d2 As Double

d1 = Timer()
For i = 0 To UBound(zip)
  Sheets("KEN_ALL").Range("Q1").Value = zip(i)
  Debug.Print Sheets("KEN_ALL").Range("R1").Value & Sheets("KEN_ALL").Range("S1").Value & Sheets("KEN_ALL").Range("T1").Value
Next

d2 = Timer()

Debug.Print (d2 - d1)
 

 

結果はこちら。なんと0.453125秒! めっちゃ速い!

 

ワークシート関数利用版の方がセルへの読み書きが発生するので絶対に遅いと思ったのですが結果は逆でした。まさかの5倍速。

 

スポンサーリンク

 - Excel, VBA