Collectionオブジェクトを使い倒す!

最終更新日

Excelマクロで使用するVBAを用いたデータ処理で、欠かせないのが配列ですが、VBAの各種オブジェクトでも多く使用されているコレクション(Collection)オブジェクトの使い方を勉強していきます!

■複雑な操作

今回は、配列に対して複雑な操作が可能な以下のオブジェクトについて勉強してくわけですが・・

広告

配列や複雑な操作については、前回記載した内容を確認してください

※手は抜いていません!有効利用ですw

■Collectionオブジェクト

今回は、記事のタイトルでも書いた通り、今回はCollectionオブジェクトを勉強します!(Dictionaryオブジェクトも後日勉強しますw)

参考サイト:「Collection オブジェクト | Microsoft Docs

Collectionオブジェクトは参照設定が不要ですので、ダイレクトにCollectionオブジェクトを記載できます

参照設定は不要
参照設定は不要

説明するよりもサンプルを見てもらった方が早いかも知れません

・いきなりサンプル

CollectionオブジェクトにString型の値をAddして、For~EachステートメントでVariant型の変数に取り出すサンプルです

Collectionオブジェクトのメリットと言えば、Addメソッドで配列を動的に確保していけるので、ReDimステートメントを使用して、予め配列を確保する必要がありません

・Keyを用いたサンプル

あまり知られていない(?)かも知れませんが、CollectionオブジェクトにはKeyを使用して、Addする方法があります

実際に、MicrosoftのAddメソッドのサンプルは、Keyを使ったサンプルが公開されているのです!

Worksheetsオブジェクトでシート名をキーにして、Worksheetオブジェクトを取得できるのと同じように扱うことができます

– 注意点

インデックスで取り出す場合、ReDimステートメントが「0」からなのに対して、Collectionオブジェクトは「1」から開始することに注意が必要です

Keyを指定した場合には、更に以下の注意点があります

  • 重複するKeyはAddできない
  • Keyに指定できるのは文字列

ちなみに、重複するKeyをAddしようとすると、以下のエラーが発生します

重複Keyのエラー
重複Keyのエラー

※なお、Keyを指定せずにAddする場合は、このエラーは発生しません

Keyに数字を指定した場合は、以下のエラーが発生します

Keyに数字を指定
Keyに数字を指定

– デメリット

ただ、Keyを用いた場合、Itemへのアクセスは一意な名称で可能になるので、便利なのですが、以下のようなデメリットがあります

  • Keyの重複をチェックできるメソッドがない
  • Keyを取り出す方法がない
  • Addメソッドのエラーでしか判断できない

CollectionオブジェクトはKeyを用いたAddが可能ですが、Keyが既にコレクションに含まれていることを調べるメソッドが用意されていません

更に、Keyを取り出す方法もないため、Keyが既に含まれていることを調べることもできない

つまり、Addしてエラーになったら重複Keyがあるなど、あまり宜しくない対応が必要になります

・クラスを用いたサンプル(推奨)

そこで推奨したい実装としては、クラスをCollectionオブジェクトにAddする方法です

Weekクラスを定義して、WeeksのCollectionオブジェクトにクラスをAddするサンプルです

For~Eachステートメントで取り出す場合もWeekクラスで取り出すことができます

(WorksheetクラスのコレクションであるWorksheetsオブジェクトと同じイメージです)

クラスをCollectionオブジェクトのItemとする場合、重複したクラスデータを取り込むことが可能になります

一意性を保つために、クラスに一意な「No」をメンバに持たせて、これをCollectionオブジェクトのKeyに設定することで、一意性を維持して、Itemへのアクセスを簡単にすることが可能になります

これは一覧表などに「No」列を持たせて、一意性を保つのと同じ考えです

イメージ
イメージ

– Weekクラス

メンバしかいないシンプルなクラスを作ってみますw

メンバだけなら構造体でもいいんですけどねー

汎用的なことを考慮して、クラスにしています

そしてシレっとString型のみのメンバ構成にしています

ExcelからTextプロパティで値を取得するので、String型で扱うのが癖になったというだけのことですが、気になる方は、「No」をInteger型やLong型にしても良いかと思います

クラスにクラスそのものを返すゲッターを作成して、CollectionにAddするというのもよく使用します

広告

■メソッド

・Addメソッド

サンプルの中で使用しているので、使い方は概ねわかっていただけているかと思いますが、紹介していないオプションがあるので、それだけ説明します

– Before

AddメソッドでBeforeを指定することで、Collectionオブジェクトに含まれている既存の要素の前にItemを挿入することができます

インデックス番号を指定するサンプルを記載します

– After

Before同様に、AddメソッドでAfterを指定することで、Collectionオブジェクトに含まれている既存の要素の後にItemを挿入することができます

Keyの文字列を指定するサンプルを記載します

・Itemメソッド

あまり使いませんけど、Collectionオブジェクトの規定メンバなので、紹介しておきます

Sample6の20行目と出力結果を見て頂ければわかるように、以下の書き方で得られる情報は同じです

  • obj.Item(idx)
  • obj(idx)

なので、あまりItemメソッドは使いませんが、Itemメソッドでも引数にKeyの文字列を指定することは可能です

・Removeメソッド

Addメソッドの逆で、Collectionオブジェクトから要素を削除する場合に使用します

これはReDimステートメントで作成する配列にはない便利なメソッドです

残念なところは、他のメソッドと違って、Keyでは削除できないというところですね

■プロパティ

・Countプロパティ

Collectionオブジェクトのメンバで、Collectionオブジェクト内の要素数を返してくれるプロパティです

オブジェクトブラウザで見ると、メソッドに割り当たってるんですけどね!?

オブジェクトブラウザ
オブジェクトブラウザ

使い方は、Sample2でシレっと使っていますので、そちらをご覧くださいw

指定するインデックスの上限として、Forステートメントを使ってループする場合に使用します

■最後に

大量のデータを扱う上では、CollectionオブジェクトはAddやRemoveができるので非常に便利な配列として重宝されます

この便利さでも十分なのですが、より便利な配列用のオブジェクトとして、Dictionary オブジェクトが用意されています

次回は、このDictionary オブジェクトについて学びたいと思います

ではでは

シェア
広告

やもす ʕ•͡-•ʔ

のんびり!のほほん!がモットーです!w 蕎麦食いたい ライブ行きたい 暑いの嫌い