Reputation: 103
I have created this class,
Interval.cls
public x as new collection
public y as new collection
public z as string
I wish to loop through the properties because I want the user to choose input x,y,z in the form so at my sub
sub test()
dim inter as new Intervals
inter.x.add "a"
inter.x.add "a"
inter.x.add "b"
inter.x.add "b"
inter.x.add "b"
userString1 = x
userString2 = a
' I want to make it dynamic so that whatever the user wants i can provide the results. 'i just want to make it possible to compare the userString to my properties
for each i in inter
'so i wish for i in this loop to be my properties x,y,z so i can make the if statement if ( i = userString1) then
end if
next i
end sub
I know i can maybe make a tweek in the class to make it iterable, i don't know how to do it
any help is appreciated
Upvotes: 1
Views: 5972
Reputation: 119
I know this is an old post, but I wanted to share a solution I came up with when I had a similar issue.
VBA doesn't seem to offer any abstraction that allows you to refer to class members without naming them directly. However, there is a way to loop through the members of a class in code. It’s kind of clunky, and it adds overhead, but makes it possible to address some or all of the members of your class from one or more loops without having to hard-code the property names every time. It might be useful if you have to step through the class from multiple places in your code. Say you have a class with three properties (string A, integer B and double C), defined as usual with Property Let/Get statements, and private backing fields. Now, add a function to your class definition that uses a named argument to return each of the values from the class itself.Public Function MyValue (MyName As String) As Variant
Select Case MyName
Case “ValueA”
MyValue = Me.A
Case “ValueB”
MyValue = Me.B
Case “ValueC”
MyValue = Me.C
End Select
End Function
From your main code, you can now just pass in the string argument to get the desired value from the class. By creating a variant array of the desired name arguments in your code, you can loop through the array and retrieve the values from any instance of your class.
Dim VarList as Variant
Dim IntCounter as Integer
VarList = Array(“ValueB”, “ValueC”, “ValueA”)
For IntCounter = 0 to UBound(VarList)
Debug.Print MyClassInstance.MyValue(Cstr(VarList(IntCounter)))
Debug.Print MySecondClassInstance.MyValue(Cstr(VarList(IntCounter)))
Next IntCounter
This allows you to loop through as many or as few of the values from your class as you need, in any order, by just changing the order of the arguments in the array. (You would need to create a similar class function if you wanted to assign incoming values to the instance fields.) As I said, it’s not perfect: it adds overhead, and unless all of the properties in your class happen to be the same type, it requires the function to return variant values, possibly forcing the caller to cast the returned values. But if you have to deal with numerous property values in multiple places in your code, it can be considerably less complicated than hard-coded direct assignments for each property name.
Upvotes: 0
Reputation: 1239
Is this the sort of thing you are after?
'in class
Public x As New Collection
Public y As New Collection
Public z As String
Public Property Get Item(i As Integer) As Variant
Select Case i
Case 1: Item = Me.x
Case 2: Item = Me.y
Case 3: Item = Me.z
End Select
End Property
Sub try()
Dim userString2 As String
Dim userString1 As String
Dim inter As Interval
Dim i As Integer
Set inter = New Interval
inter.x.Add "a"
inter.x.Add "a"
inter.x.Add "b"
inter.x.Add "b"
inter.x.Add "b"
userString2 = "aabbb"
For i = 1 To inter.x.Count
userString1 = userString1 & inter.x.Item(i)
Next i
If userString1 = userString2 Then
'<do whatever>
End If
End Sub
OK how about forgetting the class and just using an array? The array of strings can be of any length and you can dynamically control it's size by the calling procedure.
Sub tryWithArray(ByRef StringArray() As String)
Dim userString2 As String
Dim i As Integer
userString2 = "b"
For i = 1 To UBound(StringArray())
If userString2 = StringArray(i) Then
'do something
End If
Next i
End Sub
Upvotes: 0
Reputation: 450
'in class
Public Property Get Item(i As Integer) As Variant
Select Case ndx
Case 1: Item = Me.x
Case 2: Item = Me.y
Case 3: Item = Me.z
End Select
End Property
'in sub
Dim c as Collection
Dim s as String
For i = 1 to 3
if i < 3 then
set c = inter.Item(i)
'iterate through collection
else
s = inter.Item(i)
end if
next i
something like this is probably the easiest way to go, i didnt test it but hopefully it at least gets you started
Upvotes: 2