Vit*_*ata 3 reflection enums vba
有没有办法在VBA中获取枚举?像C#的这个例子,但对于VBA?
using System;
class EnumsExampleZ
{
private enum SiteNames
{
SomeSample = 1,
SomeOtherSample = 2,
SomeThirdSample = 3
}
static void Main()
{
Type enumType = typeof(SiteNames);
string[] enumName = enumType.GetEnumNames();
for (int i = 0; i < enumName.Length; i++)
{
Console.WriteLine(enumName[i]);
}
}
}
Run Code Online (Sandbox Code Playgroud)
可以说我们有以下内容:
Enum FruitType
Apple = 1
Orange = 2
Plum = 3
End Enum
Run Code Online (Sandbox Code Playgroud)
我们如何在即时窗口中显示这些:
Apple
Orange
Plum
Run Code Online (Sandbox Code Playgroud)
没有内置功能,虽然它很容易在具体的情况下滚动你自己:
Enum FruitType
Apple = 1
Orange = 2
Plum = 3
End Enum
Function EnumName(i As Long) As String
EnumName = Array("Apple","Orange","Plum")(i-1)
End Function
Run Code Online (Sandbox Code Playgroud)
如果您有多个不同的枚举,则可以添加一个参数,该参数是枚举的字符串名称并Select Case在其上.
说完这一切之后,可以用VBA编辑器编写脚本来做一些事情,虽然它不太值得(恕我直言).
自己用 VBIDE 扩展性库解析 VBA 代码一开始会看起来很好很简单,然后你会遇到边缘情况,很快就会意识到你需要实际实现 VBA 规范的那部分,以便正确和成功解析在 VBA 中定义枚举的所有可能方式。
我会选择简单的解决方案。
这就是说,Rubberduck 几乎就是这样做的,并公开了一个实验性的COM API,允许您枚举VBE 中的所有声明(及其引用),有效地为您的 VBA 代码赋予类似反射的功能;从 2.0.11(最新版本)开始,代码如下所示:
Public Enum TestEnum
Foo
Bar
End Enum
Public Sub ListEnums()
With New Rubberduck.ParserState
.Initialize Application.VBE
.Parse
Dim item As Variant
For Each item In .UserDeclarations
Dim decl As Rubberduck.Declaration
Set decl = item
If decl.DeclarationType = DeclarationType_EnumerationMember Then
Debug.Print decl.ParentDeclaration.Name & "." & decl.Name
End If
Next
End With
End Sub
Run Code Online (Sandbox Code Playgroud)
而在理论上将输出这样的:
TestEnum.Foo
TestEnum.Bar
Run Code Online (Sandbox Code Playgroud)
然而,我们(好吧,我做了)在 2.0.9 版本周围破坏了一些东西,所以如果你在 2.0.11 中尝试,你会得到一个运行时错误,抱怨无效的强制转换:

这应该 是一个简单的修复,我们将在 2.0.12 之前修补,但请注意,此时 API 仍处于实验阶段,并且很可能会发生变化(欢迎功能请求!),所以我不建议使用它适用于玩具项目以外的任何事情。
如果您正在寻找枚举名称的原因是因为您打算在用户界面中使用它们,请知道即使在 C# 中这也是不好的做法;在 .net 中,您可以使用 a[DisplayAttribute]来指定 UI 友好的显示字符串,但即便如此,这也不是本地化友好的。
在excel-vba 中,您可以使用 Excel 本身从代码中删除数据,方法是将其输入到一个表中,该表可以存在于一个隐藏的工作表中,该工作表实际上可以充当资源文件:

然后你可以有一个实用函数来获取标题,给定一个枚举值:
Public Enum SupportedLanguage
Lang_EN = 2
Lang_FR = 3
Lang_DE = 4
End Enum
Public Function GetFruitTypeName(ByVal value As FruitType, Optional ByVal langId As SupportedLanguage = Lang_EN) As String
Dim table As ListObject
Set table = MyHiddenResourceSheet.ListObjects("FruitTypeNames")
On Error Resume Next
GetFruitTypeName = Application.WorksheetFunction.Vlookup(value, table.Range, langId, False)
If Err.Number <> 0 Then GetFruitTypeName = "(unknown)"
Err.Clear
On Error GoTo 0
End Function
Run Code Online (Sandbox Code Playgroud)
或者类似的东西。这样你就可以用代码保存代码,用数据保存数据。你也可以很容易地扩展它。