我有一个由多个工作表组成的应用程序,每个工作表在网格布局中包含类似的数据。
Enum eSht1
FName = 1
LName = 2
Data1 = 3
Data2 = 4
End Enum
问题是在行/列的交叉点提取数据。为了获得该列,宏在第1行搜索对应于所需项目的所需数字。例如,对于LName,宏将搜索2
并返回列B
。
这些数字可能会有所变化,包括价值和价值。位置 - 我无法控制这个,客户端是“接口”设计器,我的工作是让VBA代码工作。因此,为了便于任何更改,这些数字包含在枚举中。因此,在此示例中,宏将搜索eSht1.LName
。
这在过去运作良好,每个工作簿有一个数据表,但现在我们将所有这些工作表都滚动到一个工作簿中。由于所有这些表都有类似的数据,因此最好始终使用相同的程序。
Enum eSht2
Index = 10
FName = 20
LName = 30
Data2 = 40
End Enum
问题是从单个宏引用各种枚举。因此,例如,要从sheet1中提取LName,宏将使用eSht1.LName
进行搜索。要从sheet2获取LName,相同的宏将使用eSht2.LName
进行搜索。
这是一个愚蠢的例子,有20多张表,并且在整个项目中散布了大量参考这些枚举的宏。 这是可能的,还是我需要为每张纸都有单独的宏?或尝试完全不同的方法?
答案 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
属性及其Get
和Let
阻止。这将允许您向循环添加条件检查。
' SNIP
For Each e In enums
If e.Sheet = someSheet Then
' Do something
End If
Next