2012年6月24日日曜日

[ExcelVBA] Collectionオブジェクト


Collectionオブジェクトといえば、配列のようにインデックス番号と値とをセットで記憶します。登録した数を確認したり、値を追加したり値を表示するだけならどちらでも同じことができますがそれ以外は全く違うのでそこらへんに気をつけてメモ書きしておきます。



■宣言
  1. Dim 変数名 As New Collection  
と、宣言すると下記メソッドが使えるようになります。



■要素数を調べる<.Count>
  1. Option Explicit  
  2.   
  3. Sub SampleCode()  
  4.     Dim foo As New Collection  
  5.     debug.print foo.Count '要素を追加していないので0を表示  
  6.     Set foo = Nothing  
  7. End Sub  
ここで補足。
Dim foo As Collection とした場合
Collectionオブジェクトを利用することができる変数の入れ物ができただけにすぎません。
Dim foo As New CollectionのようにNewを使うことで初めてCountが使えるようになります。

Dim foo As New Collectionと一行で表現しても

Dim foo As Collection 'この時点ではNothingの状態。
Set foo = New Collectionとニ行で表現しても一緒です。



■要素を追加する<.Add>
  1. Option Explicit  
  2.   
  3. Sub SampleCode()  
  4.     Dim foo As New Collection  
  5.   
  6.     foo.Add "a"  
  7.     foo.Add "b"  
  8.     foo.Add "c"  
  9.     foo.Add "d"  
  10.     foo.Add "e"  
  11.     Set foo = Nothing  
  12. End Sub  





■要素を表示する<.Item([番号])> ※番号は、1以上
  1. Option Explicit  
  2.   
  3. Sub SampleCode()  
  4.     Dim foo As New Collection  
  5.   
  6.     foo.Add "a"  
  7.     foo.Add "b"  
  8.     foo.Add "c"  
  9.     foo.Add "d"  
  10.     foo.Add "e"  
  11.   
  12.     'Foo文で表示  
  13.     Dim i As Integer  
  14.     For i = 1 To foo.Count  
  15.         Debug.Print foo.Item(i)  
  16.     Next  
  17.   
  18.   
  19.     'For Each文で表示  
  20.     Dim v As Variant  
  21.     For Each v In foo  
  22.         Debug.Print v  
  23.     Next  
  24.     Set foo = Nothing  
  25. End Sub  
.Itemメソッドで要素の番号を指定する時は、
最初の要素が1になるので1以上の数値ということになります。



■要素の削除<.Remove([要素番号])>
  1. Option Explicit  
  2.   
  3. Sub SampleCode()  
  4.     Dim foo As New Collection  
  5.       
  6.     foo.Add "a"  
  7.     foo.Add "b"  
  8.     foo.Add "c"  
  9.     foo.Add "d"  
  10.     foo.Add "e"  
  11.       
  12.     foo.Remove (3)  
  13.     Set foo = Nothing  
  14. End Sub  
Removeすると削除されたインデックス番号のところにそれ以降の要素が前へ一つずつ詰まることになります。

dが4番⇒3番
eが5番⇒4番へかわっています。
初期化ではなく、取り除かれることに注意ですね。

うっかり偶数番目のデータだけ省いてしまおうと思ってこんなコードを書くとエラーになりますね
  1. Option Explicit  
  2.   
  3. Sub SampleCode()  
  4.     Dim foo As New Collection  
  5.       
  6.     Dim i As Integer  
  7.     For i = 1 To 10  
  8.         foo.Add i  
  9.     Next  
  10.       
  11.       
  12.     For i = 1 To foo.Count   
  13.         If i / 2 = Int(i / 2) Then '偶数番目の値は削除する  
  14.             foo.Remove (i)  
  15.         End If  
  16.     Next  
  17.     Set foo = Nothing  
  18. End Sub  

For文は、iが1から10になっら終了します。

i=2 i=4 i=6
================================
Item1:1 Item1:1 Item1:1
Item2:3 Item2:3 Item2:3
Item3:4 Item3:4 Item3:4
Item4:5 Item4:6 Item4:6
Item5:6 Item5:7 Item5:7
Item6:7 Item6:8 Item6:9
Item7:8 Item7:9 Item7:10
Item8:9 Item8:10
Item9:10


i=8
Item8がないのでエラーとなる。

どうせやるなら、小さい番号から処理をするのでなく、大きい番号から処理すべきですね。
  1. Option Explicit  
  2.   
  3. Sub SampleCode()  
  4.     Dim foo As New Collection  
  5.       
  6.     Dim i As Integer  
  7.     For i = 1 To 10  
  8.         foo.Add i  
  9.     Next  
  10.       
  11.       
  12.     For i = foo.Count To 1 Step -1  
  13.         If i / 2 = Int(i / 2) Then  
  14.             foo.Remove (i)  
  15.         End If  
  16.     Next  
  17.   
  18. End Sub  

i=10 i=8 i=6 i=4 i=2
========================================================
Item1:1 Item1:1 Item1:1 Item1:1 Item1:1
Item2:2 Item2:2 Item2:2 Item2:2 Item2:3
Item3:3 Item3:3 Item3:3 Item3:3 Item3:5
Item4:4 Item4:4 Item4:4 Item4:5 Item4:7
Item5:5 Item5:5 Item5:5 Item5:7 Item5:9
Item6:6 Item6:6 Item6:7 Item6:9
Item7:7 Item7:7 Item7:9
Item8:8 Item8:9
Item9:9


0 件のコメント: