Enabling the use of For Each Next syntax in collection classes authored in Visual Basic 6

by VT Software

 

Summary

Your collection class should implement an ICollection interface.  This enables an ObjectEnumerator class to access the members of your collection.  ObjectEnumerator supports the IEnumVARIANT interface (it's a hidden member of the stdole library).  This is the interface that Visual Basic uses to enumerate through a collection.

You should also add a NewEnum procedure to your collection class with a procedure ID of -4.  The NewEnum procedure should return a new instance of the ObjectEnumerator class which in turn is set with a reference to the ICollection interface of your collection.

When a user uses For Each Next syntax with your collection, Visual Basic calls the procedure in your class with an ID of -4 at the beginning of the enumeration to obtain an enumerator object.  It then calls the methods in the IEnumVARIANT interface of this object to enumerate through your collection.

Is is hard to write an enumerator class in Visual Basic because IEnumVARIANT uses a data type not supported by Visual Basic.  As a consequence, VT Software provides ObjectEnumerator and ICollection in a DLL which you can download free of charge.  The hard work has been done for you.

It sounds difficult, but by using the DLL it is not:

Step by step

1    Download the file VTEnum.dll to your Windows\System folder (or wherever you like).  VTEnum.dll is under 50 KB and is itself written in Visual Basic 6 (with a few tricks).

2    Register VTEnum.dll.  An easy way to register a DLL is to copy Regsvr32.exe to your Windows\SendTo folder.  Then right click on your copy of VTEnum.dll in MyComputer/Windows Explorer, choose Send To and then Regsvr32.exe.

3    Tick VT Enumeration in the References dialog (Project menu of the VB IDE) for your project.

4    Copy and paste the following code into your collection class:

Implements ICollection

Public Function NewEnum() As IEnumVARIANT
'The ProcedureID in the Procedure Attributes dialog (Tools
'menu of the VB IDE) must be set to -4 for this procedure

    Set NewEnum = NewObjectEnumerator(Me)
End Function

Private Property Get ICollection_Count() As Long
    ICollection_Count = Me.Count
End Property

Private Property Get ICollection_Item(ByVal Index As Long) As Object
    Set ICollection_Item = Me.Item(Index)
End Property

Private Property Get ICollection_IsMemberInvalid(ByVal Object As Object) As Boolean
'There is no need to respond to this procedure if the objects
'in your collection cannot be deleted, or if you cannot
'very quickly determine if they have been deleted (ie NOT
'by searching through your collection). This procedure
'is only significant if an item not yet enumerated is
'deleted during an enumeration. This is a rare occurrence.


End Property

5    Set the ProcedureID of the NewEnum function to -4.  This is done in the Procedure Attributes dialog (Tools menu of the VB IDE or via the Object Browser).  Click the Advanced button in the dialog.  -4 is not one of the options listed, you have to type -4 instead.  Click here for a screen shot of the dialog.

That's it.  Have fun!  Viel Spass!  If you find our ideas useful, send us an email.

Further comments
The above code uses an ObjectEnumerator object from the VTEnum library to carry out the enumeration.  As soon as enumeration starts ObjectEnumerator reads all the objects from your collection.  This means that objects can be re-positioned or deleted during enumeration without upsetting the enumeration.

This technique may not always be satisfactory.  Perhaps your collection contains a data type other than an object.  Perhaps your collection is based on a linked list and does not have Count and Item properties.  Perhaps your collection contains a very large number of 'just-in-time' objects, and instantiating all these objects at once would consume too many resources.

The VTEnum library contains an alternative enumerator and interface (GenericEnumerator and IEnumerable) which may be more useful in these circumstance.  The comments in the object browser for VTEnum should provide sufficient information to use GenericEnumeratorGenericEnumerator is slightly more difficult to use, and it is your responsibility to determine what happens if objects are re-positioned or deleted during an enumeration.

The downloads and code referred to on this site are provided free of charge by VT Software Limited.  No responsibility is accepted for any problems or loss arising from their use.  Support cannot be provided.

 

Hit Counter