適当に探してみても見つからなかったので、練習がてら初投稿させていただきます。
Scripting.Dictionaryを使用して重複を削除する方法です。
これはデータ数が極端に増えてもそれなりの速度で処理可能です。
Office製品はExcelしか使ったこと有りませんがおそらくVBA/VB6系では共通で使えるのかなと
(使えなくても責任は負いません)
以下の関数をモジュール等にコピペして使用してください。
Function Distinct(args As Variant) As Variant
Dim dictionary As Object
Set dictionary = CreateObject("scripting.dictionary")
'microsoft scripting runtimeが参照設定されている場合は以下のほうが良い(補完が効く上に多少速い)
'Dim dictionary As Dictionary
'set dictionary = new Dictionary
Dim arg As Variant
For Each arg In args
If Not dictionary.Exists(arg) Then
dictionary.Add arg, 0
End If
Next arg
Distinct = dictionary.Keys
End Function
※ユーザー定義関数となるのでExcelワークシート上でも関数として使えますが
結果が配列として帰ってくるため余程トリッキーに使うのでもなければ使い所はないと思います。
また、この関数は2次元配列を引数に入れた場合も1次元配列となって帰ってきます。
使い方
以下は既存のhogeArrayから重複のない配列をuniqueArrayに代入します。
'hogeArrayにはあらかじめデータが入っているものとする。
dim uniqueArray
uniqueArray = Distinct(hogeArray)
また、Rangeオブジェクトは.valueプロパティで値を取得してくることでVariant配列を返すため、Excelでは以下の様な使い方もできます。
uniqueArrayには引数に入力した範囲の値を重複内配列として受け取ります。
dim uniqueArray
uniqueArray = Distinct(Range("a1:a100").value)
#速度測定
テスト1:A1-A1,000,000のセルに1-100の整数(乱数)が入っている。
テスト2:A1-A1,000,000のセルに1-100,000の整数(乱数)が入っている。
それぞれ、セルの値を取得して新しい配列に代入するまでの時間を測定
Sub DistinctTest()
Dim startDate As Date
Dim buf As Variant
Dim i As Long: i = 100
Do
startDate = timer
buf = Distinct(Range(Cells(1, 1), Cells(i, 1)).Value)
Debug.Print Format(timer - startDate, "0.000") & "sec データ数:" & i
i = i * 10
Loop Until i >= Rows.Count
End Sub
結果
テスト1(1-100までの数)
0.000sec データ数:100
0.000sec データ数:1000
0.008sec データ数:10000
0.109sec データ数:100000
0.867sec データ数:1000000
テスト2(1-100000までの数)
0.000sec データ数:100
0.000sec データ数:1000
0.023sec データ数:10000
0.258sec データ数:100000
2.141sec データ数:1000000
データ数に対してほぼ比例した速度を保っている(と思う)