【エクセルVBA】重複排除処理が速いのはどっち?Dictionaryオブジェクト vs 複数ループ


dictionaryVSLoop,eyecatch

皆様こんにちは、ノグチです。

前回までは、Dictionaryオブジェクトを使って、複数ループで書かれた重複排除の処理を

置き換えていく方法をご紹介してきました。

今回は、置き換え前の複数ループ文で書かれたコードと、Dictionaryに置き換えられたコード、どちらが処理速度が速いのか?を試してみたいと思います!

前回記事は、下記リンクをご覧ください。

【エクセルVBA】Dictionaryオブジェクトを使ったリストの重複排除プログラム
複数のループ文で書かれた重複排除処理のコードを、これまで複数回にわけでご紹介してきた、Dictionaryオブジェクトと各メソッド、プロパティを使ったコードに置き換えていきます。これなら複数ループでネストが深くなってしまったり、ゴチャゴチャしてしまうコードともオサラバ!...かも?

追記:前回の記事に、「複数ループ側のコード内は、Dictionaryを使ったコードよりもシートアクセス回数が多いので、その分処理時間が長くなっているのでは」というコメントをいただきました。

コメントに沿ってコードを見直し、記事を修正しています。

スポンサーリンク

処理時間比較用のリストとコード

検証用のリストデータ

まず、速度の検証に使うデータはこちらです。vba,dictionary,検証用データ

このリストは前回までの記事で何度か登場してきましたが、今回はこの左側リストのレコード件数を10万件に増やして、各コードの処理時間を計測してみたいと思います!

複数ループを使った重複排除処理のコード

まず、ループを複数使って書かれた重複排除処理のコードがこちら。

先にお見せしたリストの、左側のリストにある品目の値が右側の出力リストにあるかどうかをループで探し、対象の品目が右側のリストにあった場合は在庫数を加算する、という動作のコードです。

Sub TestList()
Dim i As Long
Dim j As Long
Dim flgFind As Long
Dim maxRow  As Long
Dim maxRow_l As Long
Dim strMat, lngNum
Dim Start, Finish

Application.ScreenUpdating = False
Start = Time

With ActiveSheet
    maxRow = .Cells(Rows.Count, 2).End(xlUp).Row
    maxRow_l = 1
    
    For i = 2 To maxRow
        flgFind = 0
        For j = 1 To maxRow_l
            strMat = .Cells(i, 2).Value
            lngNum = .Cells(i, 3).Value
        
            If strMat = .Cells(j, 6).Value Then
                .Cells(j, 7).Value = .Cells(j, 7).Value + lngNum
                flgFind = 1
                Exit For
            End If
        Next j
        
        If flgFind = 0 Then
            .Cells(j, 6).Value = strMat
            .Cells(j, 7).Value = lngNum
            maxRow_l = maxRow_l + 1
        End If
    Next i
    
End With

Finish = Time

Application.ScreenUpdating = True
MsgBox "処理時間は" & Format(Finish - Start, "nn分ss秒") & "です"
End Sub

コードは前回の記事のものと全く同じですが、今回は処理時間の計測ということで、処理完了時にメッセージボックスで処理時間を表示するようにしました。

ついでに、画面の更新処理を非表示にするApplication.ScreenUpdating = Falseも加えてあります。

処理時間を計測する方法については、下記記事をご覧くださいね。

遅い…重い…そんなエクセルVBAプログラムの処理速度を劇的に改善する方法
エクセルVBAの実行速度が遅い・重いって時ありませんか?そんな時にエクセルVBAのプログラムの処理速度を速くするテクニックを紹介します。プログラムの実行時間を測定する方法も合わせてお伝えします。

Dictionaryを使った重複排除処理のコード

そして、Dictionaryオブジェクトを使った重複排除のコードです。

こちらも、前回出てきたコードに処理時間を計測して、メッセージボックスで表示するコードと、画面更新非表示のコードを追加してあります。

Sub ListWithDictionary()
Dim i As Long
Dim j As Long
Dim maxRow As Long
Dim dic As Dictionary
Dim strMat, lngNum
Dim Start As Variant
Dim Finish As Variant

Application.ScreenUpdating = False
Start = Time
Set dic = New Dictionary

j = 2 'リスト書き出し開始行

With ActiveSheet

    maxRow = .Cells(Rows.Count, 2).End(xlUp).Row
    
    For i = 2 To maxRow
        strMat = .Cells(i, 2).Value
        lngNum = .Cells(i, 3).Value
        
        If dic.Exists(strMat) Then
            .Cells(dic.Item(strMat), 7).Value = .Cells(dic.Item(strMat), 7).Value + lngNum
        Else
            dic.Add (.Cells(i, 2).Value), j
            .Cells(j, 6).Value = strMat
            .Cells(j, 7).Value = lngNum
            j = j + 1
        End If
    Next i
    
End With

Finish = Time
Application.ScreenUpdating = True
MsgBox "処理時間は" & Format(Finish - Start, "nn分ss秒") & "です"

End Sub

計測方法

前述2種類のコードを、冒頭にお見せした10万件のデータを使って実行時間を計測してみましょう。

計測時間の比較は、単純に各コードを3回ずつ実行して、平均した値で行っていきます。

実行結果

では早速、複数ループのコードから実行してみましょう!
1回目
2回目
3回目

3回の平均は約11.3秒でした。

お次はDictionaryオブジェクトのコードを実行してみます。

1回目
2回目
3回目
3回の平均約5.7秒

平均を出すまでもなく結果が見えている気がしますが、先のコードの実行時間と比較すると若干スピードアップです。

各コードの処理時間を表にまとめてみました。

処理時間(秒) 複数ループ Dictionary
1回目 12 6
2回目 11 5
3回目 11 6

結果は、表のとおりDictionaryオブジェクトのコードが複数ループ文におよそ2倍ほどの差をつけて勝利でした。

Dictionaryオブジェクトを使ったコードの方が、ループが少ない分シートへのアクセス数が減って、処理時間が短くなっていそうです。

今回は処理対象の項目が2項目のみと少ないのでこの結果になっていますが、項目や処理の種類が増えるほど処理時間の差が開きそうですね。

最後に

今回は、Dictionaryオブジェクトを使って書かれたコードと、複数ループを使って書かれたコードの処理時間を比較してみました。

結果で見られた通り、Dictionaryオブジェクトを使ったコードならば高速化が見込めそうですね。

もし皆様のお手元にあるVBAコードの処理時間が長い、と悩んでおられるなら、Dictionaryオブジェクトでコードを書き換えてみてはいかがでしょうか。

次回は、Dictionaryオブジェクトに格納したキーと要素を、Dictionaryオブジェクトから直接ワークシートへ書き出す方法をご紹介します。

【エクセルVBA】Dictionaryに格納したキーと要素をリストに書き出す方法
エクセルVBAの、Dictionaryオブジェクトに格納されたキーと要素を、エクセルシートに出力する方法をご紹介しています。Dictionaryオブジェクトを使えば、コードが簡潔になる、VBAコードの作り方によって処理速度の短縮が見込めるといったイイコトがある!かも…?

それでは、最後までお読みいただきありがとうございました!

連載目次:エクセルVBAのDictionaryオブジェクトでリストの重複を排除する

エクセルVBAでリストの重複を排除する方法として、Dictionaryオブジェクトを使った重複排除の方法をご紹介しています。

  1. 【エクセルVBA】リスト処理に便利!Dictionaryオブジェクトをコードで使うための準備
  2. 【エクセルVBA】AddメソッドでDictionaryオブジェクトにキーと要素を追加する方法
  3. 【エクセルVBA】DictionaryオブジェクトのExistsメソッドで重複があるかを確認する方法
  4. 【エクセルVBA】Dictionaryオブジェクトを使ったリストの重複排除プログラム
  5. 【エクセルVBA】重複排除処理が速いのはどっち?Dictionaryオブジェクト vs 複数ループ
  6. 【エクセルVBA】Dictionaryに格納したキーと要素をリストに書き出す方法

タイトルとURLをコピーしました