Home > front end >  Loop a collection made by VBA class
Loop a collection made by VBA class

Time:03-11

I'm new to coding class modules, but pretty decent in normal modules... Now I'm trying to loop a collection made by me with no success. I can expand and see "the elements" inside VBE but get the error: "Object doesn't support this property or method".

In a standard module I have

Public collItems As Collection

The collection is populated inside a userform module on initialization

collItems.add cItems

cItems is an object made from New clsItems, which is the class module.

The class module consists of many userform controls like this:

Private WithEvents frm As msforms.Frame
Private WithEvents lbl As msforms.Label
Private WithEvents cmd As msforms.CommandButton
Private WithEvents txt1 As msforms.TextBox
Private WithEvents txt2 As msforms.TextBox 
   

Not sure if Private is the way to go on this...

When the userform finish loading, a dynamic number of frames with all these textboxes inside each frame appears. It looks like a spreadsheet made from data inside MS Project. The command buttons job is to change a lot of the textbox's attributes/properties. So now I want to loop the collItems collection and write my code. But then I get an error...

I don't have any get or let in my class. Just a single set property. It might look stupid to add 10 unique textboxes inside the class, but that's how I made it work so far... All the form objects are given names that refer to row and column during creation and helps me identify them.

The failing code looks like this:

Sub changeBox(ByRef name As String)
For Each item in collItems.item(CLng(Replace(name, "cmd", "")))
     'blabla
Next item
End Sub

This test works and shows all the elements I want to loop but can't:

Set test = collItems.item(3) 'Meaning row 3 in userform

Any help on what I'm doing wrong or missing, in order to loop my specific textboxes and change their attributes would be much appreciated!

CodePudding user response:

So now I want to loop the collItems collection and write my code. But then I get an error...

The collection holds a sequence of objects of type cItems. Thus to loop the collection items, declare an object of this type to be used as the iterator.

Note, the class members must be publicly exposed in order to be accessible outside the cItems class. Not sure how you instantiate them, but they could be exposed through a public read-only property.

Public Property Get Form() As msforms.Frame
    Set Form = frm
End property

To loop:

Dim objCurrent As cItems, frm As msforms.Frame  

For Each objCurrent in collItems
     'here you can use the objCurrent to access the current item.
    Set frm = objCurrent.Form
    '...
Next objCurrent

To be able to get a control by name, create a dictionary in the cItems class to store the controls and use the key to retrieve the objects.

See an example below:

'dictionary
Private m_boxes As Object

Public Sub AddTextBox(ByVal Key As String, ByVal obj As msforms.TextBox)
    m_boxes.Add Key, obj
End Sub

Public Function GetTextBox(ByVal Key As String) As msforms.TextBox
    Set GetTextBox = m_boxes(Key)
End Function

Private Sub Class_Initialize()
    Set m_boxes = CreateObject("Scripting.Dictionary")
End Sub

Private Sub Class_Terminate()
    Set m_boxes = Nothing
End Sub

The to call it:

Dim txt As msforms.TextBox
Set txt = objCurrent.GetTextBox("txt1")
  • Related