【Excel VBA入門】Collectionとは?サイズ変更に強いリストの作り方

【Excel VBA入門】Collectionとは?サイズ変更に強いリストの作り方

Collectionとは?サイズ変更に強いリストの作り方

ITを使った業務効率化の相談ができるコミュニティ「業務自動化推進ラボ」を公開しました。

こんにちは、業務自動化ツール開発担当の吉池(@valmore_myoshi)です。

前回の配列に引き続き、データをまとめて管理する方法の第二弾としてCollectionオブジェクトを取り上げます。配列よりも簡単にリストを管理できるのが大きな特徴です。

本記事では、Collectionオブジェクトの使い方はもちろん、配列との違い、連想配列の作り方についても解説します。VBAプログラムでデータを管理するときにお役立てください。

Collectionオブジェクトとは

Collectionオブジェクトを使うとデータをまとめて扱えます。New演算子でCollectionを指定し、初期化します。配列のようにサイズ(=要素数)を宣言する必要はなく、最初から動的に扱えるのが特徴です。

  1. Dim コレクション名 as New Collection
Dim コレクション名 as New Collection

要素を追加するにはAddメソッド

要素を追加するにはAddメソッドを使います。配列は同じ種類のデータしか追加できませんが、Collectionオブジェクトは種類を問いません

  1. コレクション名.Add 追加する値
コレクション名.Add 追加する値

例えば、文字列を追加してみます。値を追加した順に1から始まるインデックス番号が振られます

  1. Dim foodList As New collection
  2. foodList.Add "りんご"
  3. foodList.Add "みかん"
  4. foodList.Add "桃"
  5. foodList.Add "メロン"
  6. ‘ インデックス番号は1から振られる
  7. Debug.Print "インデックス番号1", foodList(1)
  8. Debug.Print "インデックス番号2", foodList(2)
  9. Debug.Print "インデックス番号3", foodList(3)
  10. Debug.Print "インデックス番号4", foodList(4)
Dim foodList As New collection

foodList.Add "りんご"
foodList.Add "みかん"
foodList.Add "桃"
foodList.Add "メロン"

‘ インデックス番号は1から振られる
Debug.Print "インデックス番号1", foodList(1)
Debug.Print "インデックス番号2", foodList(2)
Debug.Print "インデックス番号3", foodList(3)
Debug.Print "インデックス番号4", foodList(4)
実行結果

キーと値を連想配列で管理する

Collectionオブジェクトはさらに「キー」と「」をペアで管理できます。キーは重複することのない一意の文字列のことで、インデックス番号の代わりになります。

コレクションのイメージ

書き方も簡単で、追加したい値のあとにキー名を書くだけです。

  1. コレクション名.Add 追加する値, キー名
コレクション名.Add 追加する値, キー名

例えば、上記画像のように姓、名、性別、年齢の4つをキーにコレクションを作ると以下のように書けます。値を取得するときはキー名を指定すればOK!

  1. Dim foodList As New collection
  2. foodList.Add "山田", "姓"
  3. foodList.Add "太郎", "名"
  4. foodList.Add "男", "性別"
  5. foodList.Add 20, "年齢"
  6. ‘ 指定するときはキー名を使う
  7. Debug.Print "姓", foodList("姓")
  8. Debug.Print "名", foodList("名")
  9. Debug.Print "性別", foodList("性別")
  10. Debug.Print "年齢", foodList("年齢")
Dim foodList As New collection

foodList.Add "山田", "姓"
foodList.Add "太郎", "名"
foodList.Add "男", "性別"
foodList.Add 20, "年齢"

‘ 指定するときはキー名を使う
Debug.Print "姓", foodList("姓")
Debug.Print "名", foodList("名")
Debug.Print "性別", foodList("性別")
Debug.Print "年齢", foodList("年齢")
実行結果

2019/5/20追記
連想配列を使うならDictionaryオブジェクトも要チェック!Collectionオブジェクトよりも連想配列を簡単に操作できます。

【Excel VBA入門】Dictionaryとは?データ管理が楽になる連想配列の作り方

要素を削除するにはRemoveメソッド

コレクションの要素を削除するときはRemoveメソッドを使います。インデックス番号で指定してもよし、キーを設定していればキー名を指定しても削除できます。

  1. コレクション名.Remove(インデックス番号あるいはキー名)
コレクション名.Remove(インデックス番号あるいはキー名)

For Eachで要素一覧を取得する

コレクションの要素を取得する方法は「インデックス番号を指定する」あるいは「キー名を指定する」といった2つの方法がありますが、全要素を取得するのであればFor Eachを使う手もあります。

コレクションの各要素が変数に一つずつ格納され、全要素ループし終えたら処理が完了します。変数にはVariant型あるいは特定のオブジェクト型しか指定できないことに要注意です。

  1. For Each 変数 In コレクション名
  2. 変数を使った処理
  3. Next
For Each 変数 In コレクション名
    変数を使った処理
Next

例えば、姓、名、性別、年齢を追加したコレクションの全要素を取得するときは下記のように書けます。

  1. Dim foodList As New collection
  2. Dim value As Variant
  3. Dim i As Integer
  4. foodList.Add "山田", "姓"
  5. foodList.Add "太郎", "名"
  6. foodList.Add "男", "性別"
  7. foodList.Add 20, "年齢"
  8. For Each value In foodList
  9. i = i + 1
  10. Debug.Print CStr(i) & ": " & value
  11. Next
Dim foodList As New collection
Dim value As Variant
Dim i As Integer

foodList.Add "山田", "姓"
foodList.Add "太郎", "名"
foodList.Add "男", "性別"
foodList.Add 20, "年齢"

For Each value In foodList
    i = i + 1
    Debug.Print CStr(i) & ": " & value
Next
実行結果

Collectionオブジェクトの使いどころ

データをまとめて扱う方法は複数ありますが、あえてCollectionオブジェクトを使う理由は「要素の管理が簡単」の一言に尽きます。

配列よりもリストの管理が簡単

冒頭にも述べましたが、Collectionオブジェクトはリストのサイズを指定する必要がなく、動的に要素を追加できます。一方、配列ではサイズを宣言し、要素数を増やすにも再度Redimを使って宣言する必要があります。

  1. Dim foodArray() As String
  2. Dim foodList As New collection
  3. ' 配列の場合、要素数を増やしたいときは再宣言が必要
  4. ReDim foodArray(2)
  5. foodArray(0) = "りんご"
  6. foodArray(1) = "みかん"
  7. foodArray(2) = "桃"
  8. ReDim Preserve foodArray(3)
  9. foodArray(3) = "メロン"
  10. ' Collectionオブジェクトの場合、Addメソッドで要素を追加できる
  11. With foodList
  12. .Add "山田", "姓"
  13. .Add "太郎", "名"
  14. .Add "男", "性別"
  15. .Add 20, "年齢"
  16. End With
Dim foodArray() As String
Dim foodList As New collection

' 配列の場合、要素数を増やしたいときは再宣言が必要
ReDim foodArray(2)

foodArray(0) = "りんご"
foodArray(1) = "みかん"
foodArray(2) = "桃"

ReDim Preserve foodArray(3)
foodArray(3) = "メロン"

' Collectionオブジェクトの場合、Addメソッドで要素を追加できる
With foodList
    .Add "山田", "姓"
    .Add "太郎", "名"
    .Add "男", "性別"
    .Add 20, "年齢"
End With

キーを使った指定方法が便利

Collectionオブジェクトはインデックス番号の代わりにキー名を利用できるのも便利です。特定のキー名を指定したほうがプログラム内で何をしているかわかりやすいですよね。

  1. Dim foodArray(1) As String
  2. Dim foodList As New collection
  3. foodArray(0) = "りんご"
  4. foodArray(1) = "みかん"
  5. With foodList
  6. .Add "山田", "姓"
  7. .Add "太郎", "名"
  8. End With
  9. ' 配列の場合、何を指定しているのかわからない
  10. Debug.Print "配列インデックス番号(0): " & foodArray(0)
  11. Debug.Print "配列インデックス番号(1): " & foodArray(1)
  12. ' Collectionオブジェクトの場合、どんな値を指定したかわかる
  13. Debug.Print "Collectionキー名(姓): " & foodList("姓")
  14. Debug.Print "Collectionキー名(名): " & foodList("名")
Dim foodArray(1) As String
Dim foodList As New collection

foodArray(0) = "りんご"
foodArray(1) = "みかん"

With foodList
    .Add "山田", "姓"
    .Add "太郎", "名"
End With

' 配列の場合、何を指定しているのかわからない
Debug.Print "配列インデックス番号(0): " & foodArray(0)
Debug.Print "配列インデックス番号(1): " & foodArray(1)

' Collectionオブジェクトの場合、どんな値を指定したかわかる
Debug.Print "Collectionキー名(姓): " & foodList("姓")
Debug.Print "Collectionキー名(名): " & foodList("名")
実行結果

ただし、連想配列を使う場合はDictionaryオブジェクトもオススメです。こちらは連想配列に特化したオブジェクトで、連想配列を便利に扱えるメソッドが用意されています。

【Excel VBA入門】Dictionaryとは?データ管理が楽になる連想配列の作り方

値をまとめて取得、書き込むときは配列を使う

Collectionオブジェクトは配列よりもリストの管理が簡単ですが、それでも配列を使ったほうが良い場面があります。それが、Excelとデータをやり取りする場面です。

例えば、下記画像のように複数のデータをまとめてセルに書き込む場合を考えてみましょう。

二次元データサンプル

配列では、二次元配列を使うことで高速にセルに書き込むことができます。

  1. Dim foodArray(1, 3) As String
  2. foodArray(0, 0) = "りんご"
  3. foodArray(0, 1) = "みかん"
  4. foodArray(0, 2) = "桃"
  5. foodArray(0, 3) = "メロン"
  6. foodArray(1, 0) = "バナナ"
  7. foodArray(1, 1) = "すいか"
  8. foodArray(1, 2) = "キウイ"
  9. foodArray(1, 3) = "ぶどう"
  10. ' 二次元配列と同じセル範囲を用意し、一度に書き込み
  11. Range("A1:D2").value = foodArray
Dim foodArray(1, 3) As String

foodArray(0, 0) = "りんご"
foodArray(0, 1) = "みかん"
foodArray(0, 2) = "桃"
foodArray(0, 3) = "メロン"
foodArray(1, 0) = "バナナ"
foodArray(1, 1) = "すいか"
foodArray(1, 2) = "キウイ"
foodArray(1, 3) = "ぶどう"

' 二次元配列と同じセル範囲を用意し、一度に書き込み
Range("A1:D2").value = foodArray

複数のデータをExcelとやり取りする場合は配列」、「VBA内でまとまったデータを管理するときはCollectionオブジェクト」を使うとよいでしょう。

配列について詳しく知りたい方はこちらの記事をご覧ください。
【Excel VBA入門】配列とは?二次元配列を使った高速化手法も解説

まとめ

Collectionオブジェクトはデータをまとめて扱うときに便利です。データの種類は問わず、サイズも動的なため、配列よりも扱いが簡単です。

キーと値をペアで格納できる連想配列も使えるので、要素の取得も楽々!本記事で紹介したCollectionオブジェクトの使い方をマスターして、VBAを使いこなしましょう。