VBA - classes and structures videos | Excel VBA Part 37 - Custom Collections

Posted by Andrew Gould on 27 October 2014

Excel VBA is full of collections and you can even create your own custom collections using the Collection object. This video teaches you how to create a new custom collection, how to add items to it, how to reference those items individually and how to loop over all of the items in the collection. You'll also see how you can add items based on a custom class module to a collection.

You can increase the size of the video:

Full screen mode for YouTube

You can view the video in full screen mode as shown on the left, using the icon at the bottom right of the frame.

You can also increase the quality of the video:

Changing resolution

You can improve the resolution of the video using another icon at the bottom right of the frame. This will slow down the connection speed, but increase the display and sound quality. This icon only becomes visible when you start playing the video.

Finally, if nothing happens when you play the video, check that you're not using IE in compatibility view.

This page has 1 thread Add post
20 Sep 18 at 21:44

This code removes all rows if column E contains Oranges  

    Dim DataArray() As Variant
   
    DataArray() = Sheet1.Cells(1, 1).CurrentRegion.Value
   
    Dim DataArrayRows As Long
   
    DataArrayRows = UBound(DataArray(), 1)
   
    Dim DataArrayCols As Long
   
    DataArrayCols = UBound(DataArray(), 2)
   
    Dim SubArray() As Variant
   
    ReDim SubArray(1 To DataArrayRows, 1 To DataArrayCols) As Variant
   
    Dim I As Long, j As Long, k As Long
   
    j = 1
   
    k = 1
   
    For i = 2 To DataArrayRows
   
        If DataArray(i, 5) <> "Oranges" Then
       
            For j = 1 To DataArrayCols
       
                SubArray(k, j) = DataArray(i, j)
           
            Next j
           
            k = k + 1
           
        End If
   
    Next I
   
    Sheet3.Cells(2, 1).Resize(k - 1, DataArrayCols).Value = SubArray()

 

but I've had to declare a large SubArray, as big as the original array.

 

ReDim SubArray(1 To DataArrayRows, 1 To DataArrayCols) As Variant

 

Is it possible to use collections to "add-on-the-fly"?

 

Dim DataArray() As Variant
   
    DataArray() = Sheet1.Cells(1, 1).CurrentRegion.Value
   
    Dim DataArrayRows As Long
   
    DataArrayRows = UBound(DataArray(), 1)
   
    Dim DataArrayCols As Long
   
    DataArrayCols = UBound(DataArray(), 2)
   
    Dim SubArray() As Variant
   
    ReDim SubArray(1 To DataArrayRows, 1 To DataArrayCols) As Variant
   
    Dim I As Long, j As Long, k As Long
   
    j = 1
   
    k = 1
   
    Dim Coll1 As Collection
    Dim Coll2 As Collection
    Dim Coll3 As Collection
    Dim Coll4 As Collection
    Dim Coll5 As Collection
    Dim Coll6 As Collection
    Dim Coll7 As Collection
    Dim Coll8 As Collection
    Dim Coll9 As Collection
    Dim Coll10 As Collection
    Set Coll1 = New Collection
    Set Coll2 = New Collection
    Set Coll3 = New Collection
    Set Coll4 = New Collection
    Set Coll5 = New Collection
    Set Coll6 = New Collection
    Set Coll7 = New Collection
    Set Coll8 = New Collection
    Set Coll9 = New Collection
   
    Set Coll10 = New Collection
    For i = 2 To DataArrayCols
   
        If DataArray(i, 12) <> "RD" Then
       
            Coll1.Add DataArray(i, 1)
            Coll2.Add DataArray(i, 2)
            Coll3.Add DataArray(i, 3)
            Coll4.Add DataArray(i, 4)
            Coll5.Add DataArray(i, 5)
            Coll6.Add DataArray(i, 6)
            Coll7.Add DataArray(i, 7)
            Coll8.Add DataArray(i, 8)
            Coll9.Add DataArray(i, 9)
            Coll10.Add DataArray(i, 10)
       
            k = k + 1
           
        End If
   
    Next i
   
    Sheet3.Cells(2, 1).Resize(k - 1, DataArrayCols).Value = SubArray()

 

but it seems cumbersome.

 

How can I use a collection without having to declare it many times?

 

 

21 Sep 18 at 09:12

I don't think that a collection will help you here.  Regardless of how you populate it, you won't be able to write its contents into a range of cells in a single step in the same way you can with an array.  You would have to loop over the collection after you have populated it and write out its contents one-by-one.

For the sake of interest, you could use a single collection as shown below:

Sub PopulateCollection()

    Dim DataArray
    Dim DataArrayRows As Long
    Dim DataArrayCols As Long
    
    Dim i As Long, j As Long
    Dim Coll1 As Collection
    
    DataArray = Sheet1.Cells(1, 1).CurrentRegion
    DataArrayRows = UBound(DataArray, 1)
    DataArrayCols = UBound(DataArray, 2)
    
    Set Coll1 = New Collection
    
    'Loop through array and add matching values to collection
    For i = 2 To DataArrayRows
        If DataArray(i, 12) <> "RD" Then
            For j = 1 To DataArrayCols
            
                Coll1.Add Item:=DataArray(i, j)
                
            Next j
        End If
    Next i
    
    'Loop through collection and list its values
    Dim v As Variant
    
    For Each v In Coll1
        Debug.Print v
    Next v
    
End Sub

You may also be interested in this post which talks about ways to create a key for each item in the collection https://stackoverflow.com/questions/5702362/vba-collection-list-of-keys

I hope that helps!

22 Sep 18 at 07:14

Thanks, greatly appreciated.

 

 

Andrew G  
24 Sep 18 at 09:09

No problem!