对于Excel VBA中的每个类属性

我有一些看起来像这样的代码:

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是一个集合,Clutch,Wiper等是列索引(从1开始)。 这目前的作品,但非常丑陋。 我正在寻找一种方法来做这样的事情…

 Do While i <= classProperty.count For each classProperty in pos classProperty = sh2.Cells(R + 1, i) Next classProperty Loop 

显然,这不会工作,但没有人有任何build议,如何做一个方法或集合内类将完成大致相同?

我不知道一个好方法。 丑陋的唯一原因是你还没有把它藏在课堂上。 采取这个程序

 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 

没有什么丑陋的。 现在,AddFromRange方法有点难看,但是当你写这个方法的时候,或者当数据发生了变化的时候,你只需要看一下。

 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 

更新:吃数组而不是范围的替代方法。

 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 

正如其他人所说,没有直接的方式来循环通过一个对象的属性。 我有一个电子表格,它存储了许多值,我需要在运行时读取,与您的类似。 我发现最好的方法是通过使用CallByName方法,它允许您设置或获取名称属性。

现在,有人可能会说最初的设置是过度的,但我经常添加和删除这些属性,所以如此做代码更麻烦。 所以这种方法的美是你可以经常修改你的属性数量,而不必改变这个代码。 你可以使用从这里使用CallByName的真棒函数: https : //stackoverflow.com/a/5707956/1733206

那么对于你的例子,我会做我的poss收集以下(注意这不会做任何错误检查等,你可能会喜欢做):

 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 

以下是工作簿中的示例: https : //dl.dropboxusercontent.com/u/13173101/VBAObject.xlsm

编辑:由于你会经常改变对象,我已经包含了另一个模块,这是非常方便的,并将根据您的工作表中的列标题实际上为您 pos类。 这意味着如果你添加另一列,它会将这些属性添加到对象! 它假定所有的属性都是string,但你可以修改以适应。

VBA类不允许定义构造函数。

在主要模块中,我将创build一个“创build者”:

  For R = R1 To R2 pos.Add NewPos(Range("A" & R & ":E" & R) Next R Function NewPos(R As Range) As classProperty Set NewPos = New ClassProperty NewPos.Init(R) Exit Function 

在课堂里:

 Sub Init(R As Range) Clutch = R.Cells(1, 1) Wiper = R.Cells(1, 2) ... End Sub 

可能能够使用这样的一些代码。 因为这是打印每一个程序和财产的想法:

 Function getPropCount(ClassName As String) As String Dim classes, Class Dim i As Integer Dim strClass As String Dim propCount As Integer For Each classes In Application.VBE.CodePanes If classes.CodeModule.Name = ClassName Then Set Class = classes End If Next For i = 1 To Class.CodeModule.CountOfLines If Class.CodeModule.ProcOfLine(i, 1) <> strClass Then strClass = Class.CodeModule.ProcOfLine(i, 1) Debug.Print strClass propCount = propCount + 1 End If Next getPropCount = propCount End Function 

祝你好运,LC