Collections

bulletCollection Class - hold references for a series of objects created from the same class.  The collection contains references to each of the actual objects, called members of the collection
bulletCollections are similar to arrays. A collection object has an Add method, a Remove method, an Item method, and a Count property.
bulletRefer to members either by an index number like an array ... the object's position in the collection.  Or, if the order of the objects might change, you give each object a string key that uniquely identifies the object (e.g. social security number, account number, ... something unique in each object).
bulletNaming Convention:  it's always the plural of the object in the collection.  So a collection of the objects of the CProdcuct class would be called CProducts
bulletCollections are built into VB.  Each project has a Forms collection.  Each form has a Controls collection.  You can refer to project's forms as Forms(0), Forms(1), ... rather than by their names.

dim anycontrol as control

for each anycontrol in frmdisplay.controls

 anycontrol.enabled = false

next

Creating a Collection

A Collection is another type of object.  You create a collection by writing a new class module and declaring an object variable.

First, modify the CProduct class to hold a unique key, which must be a string.  We'll generate consecutive numbers (with a function we'll write) to be unique keys to each each object added to the collection

Add to the CProduct class:

'****** add productcode to be the key ******
Private mstrProductCode As String

'***********************
' Add get and let for the new productcode property/key
'***********************
Public Property Get ProductCode() As String ' change variant to string
 ProductCode = mstrProductCode
 ' return mstrproductcode
End Property

Public Property Let ProductCode(ByVal vNewValue As String)
  mstrProductCode = vNewValue
End Property

'*************************************************

Create the CProducts Collection Class

Add a class module  - and here's the code for all the pieces:

'local variable to hold collection
Private mCol As Collection  'm=module Col=Collection

' Collection objects have an Add method.  If it's declared as public,
' anybody can add objects to the collection.  Good OOP means YOU control
' each object that is added.  So you write a wrapper method called Add -
' That way, your Add function is called, and you can then check things, and
' then call the Add method that comes with the collection.

'
Public Function Add(Description As String, Price As Currency,    _
             Quantity As Integer) As CProduct 
'return a CProduct object
 'create a new object
 Dim objNewMember As CProduct  
'define the "pointer" to the new object
 Set objNewMember = New CProduct 
' instantiate the new object


 'set the properties passed into the wrapper
 objNewMember.Description = Description
 objNewMember.Price = Price
 objNewMember.Quantity = Quantity
 objNewMember.productcode = NextProductCode()
 ' calls on our function (defined below) to generate unique keys

 ' call on Add from the collection to add the new object
 mCol.Add objNewMember, objNewMember.productcode 
'Add wants object,key


 'return the object created
 Set Add = objNewMember
 Set objNewMember = Nothing

End Function

' Our function that will generate sequential numbers
' that will be used as unique string keys

Private Function NextProductCode() As String
 Static intProductCode As Integer 
'static keeps it value from call to call
 intProductCode = intProductCode + 1
'generate next productcode

 ' convert to string and trim blanks off

 NextProductCode = Trim(Str(intProductCode))
End Function


'Get Item wrapper procedure for returning a specific object
Public Property Get Item(productcode As String) As CProduct
 'used when referencing an element in the collection
 'Syntax: Set foo = x.Item(xyz)

 Set Item = mCol(productcode)
End Property

'Get Count wrapper procedure for returning # of objects
'  in the collection using the read-only Count property

Public Property Get Count() As Long
 'used when retrieving the number of elements in the
 'collection. Syntax: Debug.Print x.Count

 Count = mCol.Count
End Property


' wrapper for Remove method that removes
' objects from the collection

Public Sub Remove(productcode As String)
 'used when removing an element from the collection
 'Syntax: x.Remove(xyz)

 mCol.Remove (productcode)
End Sub


' Small workaround to be able to use For Each
' for a user-defined collection
' _NewEnum is a hidden property that allows For Each (enumeration)

Public Property Get NewEnum() As IUnknown  
'Generated by the class wizard!
 'this property allows you to enumerate
 'this collection with the For...Each syntax

 Set NewEnum = mCol.[_NewEnum]
 
'must have brackets & the underscore indicates 'hidden'
End Property


' Construction for the collection object
Private Sub Class_Initialize()
 
'creates the collection when this class is created
 Set mCol = New Collection
End Sub


' Destructor for the collection object
Private Sub Class_Terminate()
 'destroys collection when this class is terminated
 Set mCol = Nothing
End Sub

Using the Collection in a Form

It's time to put all of this code together (the CProduct class and the CProducts collection) and make it all run.  Modify the form from the Classes example, so it looks like this:

Name the new buttons:
 - cmdAdd
 - cmdDisplay
 - cmdClear
   and name the picturebox picDisplay

Declare the Collection Object along with the CProduct Object (already there)

Private mProduct As CProduct
' define the new object of the
'  collection class in General Declarations too

Private mProducts As New CProducts

Code Each New Procedure that corresponds to the new buttons

'**********************************
' Code the Add procedure
'**********************************

Private Sub cmdAdd_Click()
 ' add the product to the collection
 If txtDescription.Text <> "" Then
   mProducts.Add txtDescription.Text, _
   Val(txtQuantity.Text), _
   Val(txtPrice.Text)
 End If
 cmdClear_Click
' clear out the form controls

End Sub


'**********************************

Private Sub cmdDisplay_Click()
 ' display each product from the collection
 Dim displayProduct As CProduct

 For Each displayProduct In mProducts
  picDisplay.Print displayProduct.Description
 Next
End Sub
'**********************************

'**********************************

Private Sub cmdClear_Click()
 ' clear form contents, and set focus to the Description textbox
 txtDescription.Text = ""
 txtPrice.Text = ""
 txtQuantity.Text = ""
 lblInventoryValue.Caption = ""
 picDisplay.Cls
 txtDescription.SetFocus
End Sub
'**********************************
 

If you're lucky, this will work!

If you're not, try downloading the pieces from here:

  CProduct Class Module
  CProducts Collection Module
  The Form
  The Project 

Created and last updated by Prof Domanski on Wednesday February 18, 2009