设置对枚举的引用

时间:2015-06-24 03:35:02

标签: vba excel-vba excel

我有一个由多个工作表组成的应用程序,每个工作表在网格布局中包含类似的数据。

Sheet1

Enum eSht1
    FName = 1
    LName = 2
    Data1 = 3
    Data2 = 4
End Enum

问题是在行/列的交叉点提取数据。为了获得该列,宏在第1行搜索对应于所需项目的所需数字。例如,对于LName,宏将搜索2并返回列B

这些数字可能会有所变化,包括价值和价值。位置 - 我无法控制这个,客户端是“接口”设计器,我的工作是让VBA代码工作。因此,为了便于任何更改,这些数字包含在枚举中。因此,在此示例中,宏将搜索eSht1.LName

这在过去运作良好,每个工作簿有一个数据表,但现在我们将所有这些工作表都滚动到一个工作簿中。由于所有这些表都有类似的数据,因此最好始终使用相同的程序。

enter image description here

Enum eSht2
    Index = 10
    FName = 20
    LName = 30
    Data2 = 40
End Enum

问题是从单个宏引用各种枚举。因此,例如,要从sheet1中提取LName,宏将使用eSht1.LName进行搜索。要从sheet2获取LName,相同的宏将使用eSht2.LName进行搜索。

这是一个愚蠢的例子,有20多张表,并且在整个项目中散布了大量参考这些枚举的宏。 这是可能的,还是我需要为每张纸都有单独的宏?或尝试完全不同的方法?

1 个答案:

答案 0 :(得分:1)

Siddharth Rout在评论中提出了有效的观点,你可能最好只坚持使用名字,而不是跟踪两个不同的值。

然而,如果您有冒险精神,可以创建一个Class Module来帮助处理这些价值对。如果目标是能够在CallByName上使用与Enum类似的内容,这将非常有用。

因此,您可以采取以下措施:

eSht1.Properties("FName") ' Returns 1

这比编写eSht1.FName更好吗?使用类,您可以使用变量访问值。这使得迭代多个属性或对象变得非常简单。

例如,请考虑从this answer修改以下CEnum类模块:

Option Explicit

Private pProperties As Object

Public Property Get Properties() As Object
  Set Properties = pProperties
End Property

Public Property Let Properties(p As Object)
  Set pProperties = p
End Property

Sub Class_Initialize()
  Set pProperties = CreateObject("Scripting.Dictionary")

  'Add/instantiate your properties here
  pProperties("Index") = 0
  pProperties("FName") = 0
  pProperties("LName") = 0
  pProperties("Data1") = 0
  pProperties("Data2") = 0
End Sub

通过这个类,我们可以很容易地从任何或所有CEnum个对象获取属性。

Option Explicit

Sub TestCEnums()

  ' You can set a CEnum to a variable and instantiate the "properties"
  Dim e1 As New CEnum
  With e1
    .Properties("Index") = 1
    .Properties("Data1") = 10
  End With

  ' If you'd prefer to have all of the CEnums in a collection, it might be
  ' better to add them via a function
  Dim enums As New Collection
  AddEnum "e2", enums, 11, 12, 13, 14, 15
  AddEnum "e3", enums, 22, 23, 24, 25, 26
  AddEnum "e4", enums, 99, 88, 77, 66, 55

  ' Having everything under the dictionary object makes it trivial to get all
  ' properties from any (or every) CEnum object
  Debug.Print "All properties from e1:"
  Dim p As Variant
  For Each p In e1.Properties.Keys()
    Debug.Print p, e1.Properties(p)
  Next

  enums.Add e1, "e1", "e2" ' Add e1 to the collection

  ' You can also get only a specific property from all CEnums in a collection
  Debug.Print vbCrLf & "The Index property from all CEnums:"
  Dim e As CEnum
  For Each e In enums
    Debug.Print e.Properties("Index")
  Next

End Sub

这会产生以下输出:

All properties from e1:
Index          1 
FName          0 
LName          0 
Data1          10 
Data2          0 

The Index property from all CEnums:
 1 
 11 
 22 
 99 

以下是此示例的AddEnum函数:

' Adds a new CEnum to a collection
Private Function AddEnum( _
                          key As String, _
                          enums As Collection, _
                          myIndex As Long, _
                          myFName As Long, _
                          myLName As Long, _
                          myData1 As Long, _
                          myData2 As Long _
                        )

  Dim tempEnum As New CEnum
  With tempEnum
    .Properties("Index") = myIndex
    .Properties("FName") = myFName
    .Properties("LName") = myLName
    .Properties("Data1") = myData1
    .Properties("Data2") = myData2
  End With

  enums.Add tempEnum, key
  Set tempEnum = Nothing

End Function

修改

您不仅限于在实际的Properties属性对象中使用hack“属性”。 (一点也不困惑!)例如,如果每个CEnum都链接到特定工作表,则可以添加Sheet属性及其GetLet阻止。这将允许您向循环添加条件检查。

  ' SNIP
  For Each e In enums
    If e.Sheet = someSheet Then
      ' Do something
    End If
  Next