5

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

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

显然这是行不通的,但是有人对如何在一个类中创建一个大致相同的方法或集合有任何建议吗?

4

4 回答 4

4

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

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

更新:吃数组而不是 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
于 2013-06-18T21:32:48.643 回答
4

正如其他人所说,没有直接的方法来循环对象属性。我有一个电子表格,其中存储了许多我需要在运行时读取的值,类似于你的。我发现做到这一点的最佳方法是使用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这意味着如果您添加另一列,它会将这些属性添加到对象中!它假定所有属性都是字符串,但您可以修改以适应。

于 2013-06-18T22:46:04.217 回答
0

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

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

  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
于 2013-06-18T21:29:04.747 回答
0

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

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

于 2013-06-19T01:09:08.347 回答