繁体   English   中英

动态引用对象属性

[英]Refer to object properties dynamically

我有一个类ClsFruit的示例,其中ClsFruit以下成员变量:

在此处输入图片说明

我还有一个带有数据的excel表,如下所示:

在此处输入图片说明

我不觉得像使用直接引用填充对象

Fruit.Name = FruitSheet.Cells(1,2).Value
Fruit.Color = FruitSheet.Cells(2,2).Value
Fruit.Price = FruitSheet.Cells(3,2).Value

是要走的路,因为工作表上的大量重复代码和项目位置将来可能会发生变化。 所以我想遍历 excel Name-Color-Price的第一列并动态填充对象,如下所示:

Dim rg As Excel.Range
Set rg = FruitSheet.Range("A1", "A3")
Dim Cell As Variant

For Each Cell In rg
    Fruit(Cell.Value) = Cell.Offset(0, 1).Value
Next Cell

但是这个Fruit(Cell.Value)构造不起作用,我得到“对象不支持这个属性或方法”错误。 有办法解决吗?

你可能需要做这样的事情

For Each Cell In rg
    Select Case Cell.Value
        Case "Name"
            fruit.Name = Cell.Offset(0, 1).Value
        Case "Color"
            fruit.Color = Cell.Offset(0, 1).Value
        Case "Price"
            fruit.Price = Cell.Offset(0, 1).Value
    End Select
Next Cell

另一种方法是在您的班级中拥有相应的属性。 然后你可以使用CallByName

For Each Cell In rg
    CallByName fruit, cell.value, VbLet, Cell.Offset(0, 1).Value
Next Cell

更新:课程必须像那样改变

    Option Explicit

    Public mName As String
    Public mColor As String
    Public mPrice As Long

    Property Let name(nValue As String)
        mName = nValue
    End Property
    Property Get name() As String
        name = mName
    End Property

   ' continue with similar properties for the other member variables

更新 2 :正如评论中所指出的,没有必要拥有 Let/Get 等。可以坚持使用公共成员变量,而 CallByName 就可以正常工作。 从长远来看,这只是恕我直言更清洁的方法,请参见此处

我认为,使用工作表代理可以满足您的需求。 这将返回您的对象的集合:

WorksheetProxy class
Option Explicit

Private Property Get Table() As ListObject
    Set Table = Sheet1.ListObjects(1)
End Property

Private Property Get NameColumnIndex() As Long
    NameColumnIndex= Table.ListColumns("Name").Index
End Property

Private Property Get ColorColumnIndex() As Long
    ColorColumnIndex= Table.ListColumns("Color").Index
End Property

Private Property Get PriceColumnIndex() As Long
    PriceColumnIndex= Table.ListColumns("Price").Index
End Property

Private Property Get Data() As Collection

    Dim result As Collection
    Set result = New Collection

    Dim currentRow As ListRow
    For Each currentRow In Table.ListRows

        Dim currentItem As ClsFruit
        Set currentItem = New ClsFruit

        currentItem.Name= currentRow.Range(ColumnIndex:=NameColumnIndex).value
        currentItem.Color= currentRow.Range(ColumnIndex:=ColorColumnIndex).value
        currentItem.Price= currentRow.Range(ColumnIndex:=PriceColumnIndex).value

        result.Add currentItem

    Next

    Set Data = result

End Property

Mathieu Guindon 在这里讨论了这种方法: https ://rubberduckvba.wordpress.com/2017/12/08/there-is-no-worksheet/

在评论部分是他的示例工作簿的链接。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM