Enumeration through a collection in a custom class (1 Viewer)

mdlueck

Sr. Application Developer
Local time
Today, 06:16
Joined
Jun 23, 2011
Messages
2,631
Sure, and I have already said so in post #32.

Look at Galaxiom’s upload in post #25 because he has already set it up for you…

I have pulled down that example this morning. In it, I still find use of hidden Attribute LOC's as follows:

Code:
Function Coll() As Collection
[B][COLOR=Red]Attribute Coll.VB_UserMemId = 0[/COLOR][/B]

    Set Coll = Items

End Function

Property Get NewEnum() As IUnknown
[B][COLOR=Red]Attribute NewEnum.VB_UserMemId = -4[/COLOR][/B]

        Set NewEnum = Items.[_NewEnum]
        
End Property
ChrisO, I thought you were objecting to use of those under-the-cover Attribute capabilities. No?

It now appears I have two valid samples of making use of the hidden Attribute LOC's, and those other web pages I located and posted links to in #17.

So many examples to learn from. :rolleyes:
 

ChrisO

Registered User.
Local time
Today, 20:16
Joined
Apr 30, 2003
Messages
3,202
Yes but they are not being used.

Attached is a ‘clean’ one.

Chris.
 

Attachments

  • EnumerateCustomCollection.zip
    13.7 KB · Views: 126

mdlueck

Sr. Application Developer
Local time
Today, 06:16
Joined
Jun 23, 2011
Messages
2,631
Yes but they are not being used.

Attached is a ‘clean’ one.

Aaahhhh... So since an Ordered Collection was desirable, then using the alternate object enumeration syntax suggested in #27 prevented completely need to export / add Attribute LOCs / import?

If so, then this is starting to make sense.
 

mdlueck

Sr. Application Developer
Local time
Today, 06:16
Joined
Jun 23, 2011
Messages
2,631
What would be the correct thing to return on error in the Item method? Your code was:

Code:
Property Get Item(ByVal Index As String) As Variant

    If IsObject(Items(Index)) Then
        Set Item = Items(Index)
    Else
        Item = Items(Index)
    End If
 
End Property
My code is:
Code:
Function Item(ByVal strIndex As String) As Variant
On Error GoTo Err_Item

  If IsObject(m_PrivateCollection.Item(strIndex)) Then
    Set Item = m_PrivateCollection.Item(strIndex)
  Else
    Item = m_PrivateCollection.Item(strIndex)
  End If

Exit_Item:
  Exit Function

Err_Item:
  Call errorhandler_MsgBox("Class: " & TypeName(Me) & ", Function: Item()")
  Resume Exit_Item

End Function
I just realized that the Err_Item: is not returning anything... Oops! Since you suggested testing the stored item with IsObject() and depending on if it is an object or not you selectively use Set, what would be always correct in an error situation?
 

mdlueck

Sr. Application Developer
Local time
Today, 06:16
Joined
Jun 23, 2011
Messages
2,631
All right, one further question for when peers get to my questions...

A VBA.Collection appears to respond / look up the correct object out of the collection based on the string key value or the numeric ID assigned by the VBA.Collection object. Is this indeed the way VBA.Collection objects work? If so, I am thinking to switch my Item() method to accept a Variant so that it could support both the String Key or the Long Integer numeric arg being passed in to locate the correct object within the VBA.Collection object.

Thus, it is starting to actually work as intended... that I am getting to asking such detailed questions. Yeaaaa!!! ;)
 

MarkK

bit cruncher
Local time
Today, 03:16
Joined
Mar 17, 2004
Messages
8,186
But Chris, your custom collection wraps around a VBA.Collection and re-exposes exactly what a VBA.Collection exposes. In that case why bother? It's a good demo, but it only makes sense to me to make a custom collection class if you are going to customize the initialization step and/or expose a strongly typed object, otherwise what is gained?

Also, I suggest you don't create anything until you have to, so rather than Class_Initialize, consider this code...
Code:
Private m_items As VBA.Collection

Property Get Items as VBA.Collection
[COLOR="Green"]'   Don't create this object until a consumer specifically requests it.
'   This becomes more important if you actually create a strongly typed 
'   collection of custom objects, and if a parent class contains a few of those.
'   So my cCustomer class might have a custom cOrders collection, a
'   cPayments collection, a cEmployees collection, but don't build them
'   when created, wait until until a consumer actually demands one
[/COLOR]   if m_items is nothing then set m_items = GetCollection
   set Items = m_items

Private Function GetCollection as VBA.Collection
[COLOR="Green"]'  Do this custom initialization INSIDE your custom collection . . .[/COLOR]
   Set GetCollection =  New VBA.Collection
   GetCollection.Add "A", "1"
   GetCollection.Add "B", "2"
End Function

Now you've automated your initialization of a custom collection class and given it a reason to exist beyond simply wrapping an existing class.
Or this code, which exposes strongly typed items in it's Item() property . . .
Code:
[SIZE="1"]Private m_items As VBA.Collection
Private m_sf As cSnapForm

Private Property Get Items() As VBA.Collection
    If m_items Is Nothing Then CreateCollection
    Set Items = m_items
End Property

Property Get Item(index) As cSnapSide
    Set Item = Items(index)
End Property

Property Get Count() As Long
    Count = Items.Count
End Property

Function Load(Form As cSnapForm) As cSnapSides
    Set m_sf = Form
    Set Load = Me
End Function

Private Sub CreateCollection()
    Dim css As cSnapSide
    Dim i As Byte
    
    Set m_items = New VBA.Collection
    For i = 1 To 4
        Set css = New cSnapSide
        css.Load m_sf, i
        m_items.Add css
    Next
End Sub[/SIZE]
. . . and I don't want there to be an Add() method. Access.Form.Controls and DAO.Recordset.Fields don't have, and don't need, Add() methods.

My 2c,
 

ChrisO

Registered User.
Local time
Today, 20:16
Joined
Apr 30, 2003
Messages
3,202
Michael.

Post #44.
>>What would be the correct thing to return on error in the Item method? Your code was:<<

No, that was Galaxiom’s code not mine. I’m not saying I disagree with it, just that it is not mine.

>>Since you suggested testing the stored item with IsObject() and depending on if it is an object or not you selectively use Set, what would be always correct in an error situation?<<

Again, that code is not mine and I try to avoid words like ‘always’.
Many times you will see it said on the www that all procedures should have error handling in them. That is not correct. Many people do not put error handling in Class modules but, rather, let the caller of the Class handle the error.

But this thread is about “Enumeration through a collection in a custom class” not about error handling. Error handling is a whole new bucket of bolts.


Post #45
>>A VBA.Collection appears to respond / look up the correct object out of the collection based on the string key value or the numeric ID assigned by the VBA.Collection object. Is this indeed the way VBA.Collection objects work?<<

That appears to be entirely accurate.



Chris.
 

ChrisO

Registered User.
Local time
Today, 20:16
Joined
Apr 30, 2003
Messages
3,202
Mark.

From post #46
>> But Chris, your custom collection wraps around a VBA.Collection and re-exposes exactly what a VBA.Collection exposes. In that case why bother?<<

Indeed, why bother? This thread is about “Enumeration through a collection in a custom class” and, as yet, we don’t even know what will be going into the Collection or how it will be used.

So why bother going to all the trouble of hiding information in the Class header and also requiring another reference?

It might be clever code but it might also be too clever under the circumstances, which we do not know.

Chris.
 

mdlueck

Sr. Application Developer
Local time
Today, 06:16
Joined
Jun 23, 2011
Messages
2,631
But this thread is about “Enumeration through a collection in a custom class” not about error handling. Error handling is a whole new bucket of bolts.

Indeed, why bother? This thread is about “Enumeration through a collection in a custom class” and, as yet, we don’t even know what will be going into the Collection or how it will be used.

To answer both of these at the same time, per my OP I referenced where I got the original design. Thus, per that example, this collection only holds one custom class type. So since the VBA.Collection is completely encapsulated (I decided against adding the Items() method which would return the raw VBA.Collection object), it can never have a non Object in it, so I will remove that IsObject() check, and thus have the Err_Item: return using the Set keyword.

Code:
Err_Item:
  Call errorhandler_Logger("Class: " & TypeName(Me) & ", Function: Item()")
  [B]Set Item = Nothing[/B]
  Resume Exit_Item
Post #45
>>A VBA.Collection appears to respond / look up the correct object out of the collection based on the string key value or the numeric ID assigned by the VBA.Collection object. Is this indeed the way VBA.Collection objects work?<<

That appears to be entirely accurate.

Thank you for confirming that detail. It was first I realized that Objects witin the VBA.Collection were accessible via two ways.
 
Last edited:

Users who are viewing this thread

Top Bottom