I have some code that looks like this:
pos.Clutch = sh2.Cells(R, Clutch)
pos.Wiper = sh2.Cells(R, Wiper)
pos.Alternator = sh2.Cells(R, Alternator)
pos.Compressor = sh2.Cells(R, Compressor)
...
pos.Telephone = sh2.Cells(R, Telephone)
poss.Add pos
poss is a collection, and Clutch, Wiper etc. are column indexes (starting from 1). This currently works but is very ugly. I'm looking for a way to do something like this...
Do While i <= classProperty.count
For each classProperty in pos
classProperty = sh2.Cells(R + 1, i)
Next classProperty
Loop
Obviously that wouldn't work but does anyone have any advice on how to make a method or collection within a class that would accomplish roughly the same?
A For Each loop is used to execute a statement or a group of statements for each element in an array or collection. A For Each loop is similar to For Loop; however, the loop is executed for each element in an array or group. Hence, the step counter won't exist in this type of loop.
A property is an attribute of an object that defines one of the object's characteristics, such as size, color, or screen location, or an aspect of its behavior, such as whether it is enabled or visible. To change the characteristics of an object, you change the values of its properties.
I don't know of a good way. The only reason it's ugly is because you haven't hidden it in a class yet. Take this procedure
Sub Main()
Dim clsPos As CPos
Dim clsPoses As CPoses
Set clsPoses = New CPoses
Set clsPos = New CPos
clsPos.AddFromRange Sheet1.Range("A10:E10")
clsPoses.Add clsPos
End Sub
Nothing ugly about that. Now the AddFromRange method is a little ugly, but you only have to look at that when you write it or when you're data changes.
Public Sub AddFromRange(ByRef rRng As Range)
Dim vaValues As Variant
vaValues = rRng.Rows(1).Value
Me.Clutch = vaValues(1, 1)
Me.Wiper = vaValues(1, 2)
Me.Alternator = vaValues(1, 3)
Me.Compressor = vaValues(1, 4)
Me.Telephone = vaValues(1, 5)
End Sub
Update: Alternative method for eating an array instead of a Range.
Public Sub AddFromArray(vaValues as Variant)
Me.Clutch = vaValues(1, 1)
Me.Wiper = vaValues(1, 2)
Me.Alternator = vaValues(1, 3)
Me.Compressor = vaValues(1, 4)
Me.Telephone = vaValues(1, 5)
End Sub
As others have stated there is no direct way to loop through an object properties. I have a spreadsheet which stores many values which I need to read in at run time, similar to yours. The best method I have found to do this is by using the CallByName
method which allows you set or get a property by name.
Now, some might say the initial set up is overkill, but I frequently add and remove these properties so doing likewise with code is even more hassle. So the beauty of this method is you can frequently modify your number of properties without having to change this code. You can use the awesome functions that make use of CallByName
from here: https://stackoverflow.com/a/5707956/1733206
Then for your example, I would do the following in my poss
collection (note this doesn't do any error checking etc which you may like to do):
Public Sub ReadInData()
Dim vInputs As Variant, ii As Integer, jj As Integer, cp As pos
Dim sPropertyName As String, vPropertyValue As Variant
'Raead in the data. I've set it from the activesheet, you can do it how you like
With ActiveSheet
vInputs = .Range(.Cells(1, 1), .Cells(.UsedRange.Rows.Count, .UsedRange.Columns.Count)).Value2
End With
'Look through the rows of data, one row per 'pos' object
For ii = LBound(vInputs, 1) + 1 To UBound(vInputs, 1)
'Set up your object
Set cp = New pos
'Loop through the columns of data eg Clutch, wiper, etc
For jj = LBound(vInputs, 2) To UBound(vInputs, 2)
'Put in seperate variables so its easy to see what's happening
sPropertyName = vInputs(1, jj)
vPropertyValue = vInputs(ii, jj)
'Use the callable method to set the property (from here: https://stackoverflow.com/a/5707956/1733206)
Call SetProperty(sPropertyName, vPropertyValue, cp)
Next jj
Me.Add cp
Set cp = Nothing
Next ii
End Sub
Here is an example in a workbook: https://dl.dropboxusercontent.com/u/13173101/VBAObject.xlsm
Edit: Since you will be changing the object often, I've included another module which is really handy and will actually write the pos
class for you based on the column headings in your worksheet. That means if you add another column it will add those properties to the object! It assumes that all properties are strings but you can modify to suit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With