Excel VBAで使える可変長なコレクションまとめ

# 概要
Excel VBAには、Collectionという可変長なコレクションが組み込まれています。
それに加えて.NET Frameworkのコレクションも使用できます。
それぞれで微妙に違っているので整理しました。

# 一覧
※ 一部でDebug.Printを使った例を示してます。

|  | Collection | Dictionary | ArrayList | SortedList |
|:--|:--|:--|:--|:--|
| 生成 | Dim c As Collection<br>Set c = New Collection | Dim dict<br>Set dict = CreateObject("Scripting.Dictionary") | Dim arrayList<br>Set arrayList = CreateObject("System.Collections.ArrayList") | Dim sortedList<br>Set sortedList = CreateObject("System.Collections.SortedList") |
| 追加 | Call c.Add("Value1", "Key1")  | ' 注意：Collectionと順番が違う<br>Call dict.Add("Key1", "Value1") | Call arrayList.Add("Value1") | ' 注意：Collectionと順番が違う<br>Call sortedList.Add("Key1", "Value1") |
| 参照(byインデックス) | ' 1スタート<br>c.Item(1) | ' 0スタート<br>dict.Items()(0) | ' 0スタート<br>arrayList.Item(0) | ' 0スタート<br>sortedList.GetByIndex(0) |
| 参照(byキー) | c.Item("Key1") | dict.Item("Key1") | 無し | sortedList.GetByIndex(sortedList.IndexOfKey("Key1")) |
| キーの参照 | 無し | ' 0スタート<br>dict.Keys()(0) | 無し | ' 0スタート<br>sortedList.GetKey(0) |
| 削除(byインデックス) | ' 1スタート<br>Call c.Remove(1)  | ' 0スタート<br>Call dict.Remove(dict.Keys()(0)) | ' 0スタート<br>Call arrayList.RemoveAt(0) | ' 0スタート<br>Call sortedList.RemoveAt(0) |
| 削除(byキー) | Call c.Remove("Key1")  | Call dict.Remove("Key1") | 無し | Call sortedList.Remove("Key1") |
| 要素数 | c.Count  | dict.Count | arrayList.Count | sortedList.Count |
| For(全Key)  | 無し | Dim tmpKey<br>For Each tmpKey In dict.Keys<br>&nbsp;&nbsp;&nbsp;&nbsp;Debug.Print tmpKey<br>Next | 無し | Dim i As Long<br>For i = 0 To sortedList.Count - 1<br>&nbsp;&nbsp;&nbsp;&nbsp;Debug.Print sortedList.GetKey(i)<br>Next |
| For(全Value)  | Dim tmp<br>For Each tmp in c<br>&nbsp;&nbsp;&nbsp;&nbsp;Debug.Print tmp<br>Next | Dim tmpValue<br>For Each tmpValue In dict.Items<br>&nbsp;&nbsp;&nbsp;&nbsp;Debug.Print tmpValue<br>Next | Dim tmp<br>For Each tmp In arrayList<br>&nbsp;&nbsp;&nbsp;&nbsp;Debug.Print tmp<br>Next | Dim i As Long<br>For i = 0 To sortedList.Count - 1<br>&nbsp;&nbsp;&nbsp;&nbsp;Debug.Print sortedList.GetByIndex(i)<br>Next |
| キーの存在チェック  | ' 無いけど欲しいので自作<br>Function ExistsCollection(ByRef c As Collection, ByRef key) As Boolean<br>&nbsp;&nbsp;&nbsp;&nbsp;On Error Resume Next<br>&nbsp;&nbsp;&nbsp;&nbsp;Call c.Item(key)<br>&nbsp;&nbsp;&nbsp;&nbsp;If Err.Number <> 0 Then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ExistsCollection = False<br>&nbsp;&nbsp;&nbsp;&nbsp;Else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ExistsCollection = True<br>&nbsp;&nbsp;&nbsp;&nbsp;End If<br>&nbsp;&nbsp;&nbsp;&nbsp;On Error GoTo 0<br>End Function<br><br>' 使い方<br>ExistsCollection(c, "Key1") | dict.Exists("Key1") | 無し | sortedList.ContainsKey("Key1") |
| 値の存在チェック | 無し | 無し | arrayList.Contains("Value1") | sortedList.ContainsValue("Value1") |
| 全削除  | ' 全削除は無いので新規作成する。<br>' 他で参照のコピーを持っている場合、そっちはクリアされない<br>Set c = New Collection | dict.RemoveAll | arrayList.Clear | sortedList.Clear |

# 備考
CreateObjectで
「実行時エラー '-2146232576(80131700)':オートメーションエラーです。」
のエラーが出る場合があります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178867/c4f32b9f-1d1f-66d5-c311-b4a82623acf3.png)

その場合は「Windowsの機能の有効化または無効化」から「.NET Framework 3.5 (.NET 2.0および3.0を含む)」を有効化してください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178867/746f71ac-322f-7db3-5e6d-2130981ce773.png)

# リンク
[Dictionary：https://msdn.microsoft.com/ja-jp/library/cc428065.aspx](https://msdn.microsoft.com/ja-jp/library/cc428065.aspx)
[ArrayList：https://docs.microsoft.com/ja-jp/dotnet/api/system.collections.arraylist?view=netframework-4.7.2](https://docs.microsoft.com/ja-jp/dotnet/api/system.collections.arraylist?view=netframework-4.7.2)
[SortedList：https://docs.microsoft.com/ja-jp/dotnet/api/system.collections.sortedlist](https://docs.microsoft.com/ja-jp/dotnet/api/system.collections.sortedlist)