LoginSignup
3
6

More than 3 years have passed since last update.

VBAで重複のない配列(ユニーク,一意の配列)を作成する関数

Posted at

適当に探してみても見つからなかったので、練習がてら初投稿させていただきます。

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

データ数に対してほぼ比例した速度を保っている(と思う)

3
6
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
6