皆様こんにちは、ノグチです。
何度かに分けてDictionaryオブジェクトを使った、リストの重複を排除する方法をご紹介しています。
前回の記事では、複数のループを使ったコードとDictionaryオブジェクトを使ったコードでは、どちらが重複排除処理が速いのかを比較しました。
これまでご紹介してきたコードでは、リストの値がDictionaryに存在するか否かをチェックして、存在していなければDictonaryオブジェクトにキーと要素を追加し、読込んだセルのデータをそのままシートに出力していました。
今回は、Dictionaryオブジェクトに格納したキーと要素を、直接シートに出力する方法をご紹介します!
Dictionaryに値が存在しているかどうかをチェックする方法については、下記記事をご覧ください。
Dictionaryに格納されたキーと要素を取得する
キーを取得するKeysメソッド
今回は、Dictionaryオブジェクトに格納されたキーと要素を、格納された順に出力していきます。
まず、Dictionaryに格納されているキーを取得するには、Keysメソッドを使います。
Keysメソッドは、引数にDictionaryの何番目にあるキーを出力するかを指定すれば、引数に指定した数字をIndexに持つキーを取得することができます。
記述方法はこちら。
要素を取得するItemsメソッド
Dictionaryに格納されたキーが取得できたら、お次は要素の取得方法です。
要素の取得は、Itemsメソッドを使います。
ItemsメソッドもKeysメソッド同様、Dictionaryの何番目に格納されているのか?を引数に指定することで、引数に指定した数字をIndexに持つキーの要素を取得できます。
記述方法はこちら。
Dictionaryに格納されているレコードの数を取得する
Countプロパティ
Dictionaryに格納したキーと要素を出力するために、For ~ Nextを使います。
その際、何回ループをするのか、指定してあげなければいけませんね。
単純に考えて、Dictionaryに格納してあるレコードの件数分ループすればOKです。
Dictionaryに格納されているレコードの数を取得するには、DictionaryオブジェクトのCountプロパティを使います。
これで、Dictionaryオブジェクトのキーと要素をリスト出力するために何回ループすればよいのか?が取得できます。
コード例
出力データ
上でご紹介したメソッドやプロパティを使って、前回記事でも出てきたこちらのリストをDictionaryに格納して、右側のリストに出力するコードにしてみます。
For ~ NextでDictionaryの内容を出力するコード
上でお見せした左側のリストをDictionaryに格納して、キーと要素を出力するコードがこちら。
Sub OutputDictionary() Dim i As Long Dim j As Long Dim maxRow As Long Dim strMat As Variant Dim lngNum As Variant Dim dic As Dictionary Set dic = New Dictionary 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) = False Then dic.Add strMat, lngNum Else dic.Item(strMat) = dic.Item(strMat) + lngNum End If Next i For j = 0 To dic.Count - 1 .Cells(j + 2, 6).Value = dic.Keys(j) .Cells(j + 2, 7).Value = dic.Items(j) Next j End With End Sub
ミソは、For j = 0 To dic.Count – 1です。
なぜdic.Countから-1しているのかというと、このjはDictionaryオブジェクトのインデックスを示しています。
Dictionaryオブジェクトも中身は配列なので、キーと要素に対して数値のインデックスが自動的に振られるのですが、このインデックスは0を先頭に順に振られていくので、Dictionaryには5件のレコードがあったとしたら、インデックスは0から始まって4までの5件に対してIndexが振られることになります。
よって、0からスタートして、Dictionaryに格納されているレコードの件数-1回ループすればよいのです。
出力結果
上のコードを実行した結果がコチラ。
右側のリストに、左側リストの重複排除しつつ値が表示されていますね。
For~Each文を使ってDictionaryの内容を出力するコード
For~Each文を使って、Dictionaryの内容を出力することもできます。
その場合のコードはこんな感じ。
For Each varDic In dic .Cells(j, 6).Value = varDic .Cells(j, 7).Value = dic.Item(varDic) j = j + 1 Next
上のコードのDictinaryの内容を出力している、For~Nextの部分を置きかえればOKです。
最後に
今回は、Dictionaryオブジェクトに格納したキーと要素を、直接シートに出力する方法をご紹介しました。
この方法を使えば、処理速度の向上だけでなく、コードの簡潔化も期待できそうですね。
それでは、最後までお読みいただきありがとうございました!
連載目次:エクセルVBAのDictionaryオブジェクトでリストの重複を排除する
エクセルVBAでリストの重複を排除する方法として、Dictionaryオブジェクトを使った重複排除の方法をご紹介しています。