如何将String转换为类似于Java的.valueOf的Enum值?

时间:2016-05-02 14:03:10

标签: vba string-conversion

鉴于枚举:

Public Enum Options
    optionA
    optionB
    optionC
End Enum

和一个字符串myString = "optionB",有一种快速的方法将String转换为相应的枚举值吗? (Options.optionB / 1

即。我正在寻找VBA相当于Java的.valueOf()

我知道我可以写一个Select Case,但这就像再次编写枚举的定义,并且一旦枚举值发生变化就很难维持。

1 个答案:

答案 0 :(得分:6)

编辑2 :添加了解决方案#3

  • 具有解决方案#2的所有好处,即

    • valueOf功能

    • 单枚举声明(好吧,有点......)

    • 智能感知

  • 没有需要(即使稍微)Class和Enum的不同名称的缺点(在解决方案#2中它们是“OptionsC”和“Options”)

  • 仍然基于VBE对象模型 - >需要一些初步步骤(见步骤2))

解决方案#3

1)在项目中添加一个Class模块,称之为“EnumClass”(或其他),并输入以下代码

Option Explicit

Private Enums_ As Variant

Public optionA As String
Public optionB As String
Public optionC As String

Private Sub Class_Initialize()
    optionA = "optionA"
    optionB = "optionB"
    optionC = "optionC"
    Enums_ = GetEnums
End Sub

Public Property Get valueOf(enumText As String) As Long
    Dim i As Long
    valueOf = -1
    For i = LBound(Enums_) To UBound(Enums_)
        If enumText = Enums_(i) Then
            valueOf = i
            Exit For
        End If
    Next i
End Property

Private Function GetEnums() As Variant
    Dim VBProj As VBIDE.VBProject
    Dim CodeMod As VBIDE.CodeModule
    Dim lineCount As Long
    Dim strEnum As String

    Set CodeMod = ActiveWorkbook.VBProject.VBComponents("EnumClass").CodeModule

    lineCount = 9 'if you keep class code as this one, you'd need checking lines from line 9. otherwise set it to 1 as a general setting
    With CodeMod

        Do Until InStr(UCase(.Lines(lineCount, 1)), UCase("Class_Initialize")) > 0
            lineCount = lineCount + 1
        Loop

        lineCount = lineCount + 1
        Do Until InStr(.Lines(lineCount, 1), "Enums_ = GetEnums") > 0
            strEnum = strEnum & GetTextWithingQuotes(.Lines(lineCount, 1)) & ","
            lineCount = lineCount + 1
        Loop
    End With
    GetEnums = Split(Left(strEnum, Len(strEnum) - 1), ",")

End Function

Private Function GetTextWithingQuotes(strng As String) As String
    Dim i1 As Long, i2 As Long

    i1 = InStr(strng, "=")
    i1 = InStr(i1, strng, Chr(34))
    i2 = InStr(i1 + 1, strng, Chr(34))
    GetTextWithingQuotes = Mid(strng, i1 + 1, i2 - i1 - 1)

End Function

2)根据here进行初步设置(参见“为了在项目中使用此页面上的代码,您必须将两个设置更改。”改为“ 注意 “包含的条款”

3)在你的主要子目录中利用它,如下所示

Option Explicit

Sub main()
Dim Options As New EnumClass '<== declare a variable of the EnumClass (or whatever the name you chose) and set it to a new instance of it
Dim myString As String

myString = "optionB"
MsgBox "string value of 'Options.optionB' = " & Options.optionB 'exploit intellisense
MsgBox "long Value of 'OptionB' =" & Options.valueOf(myString) 'convert the string to corresponding "enum" value

End Sub

此处遵循先前的解决方案#2

1)在你的项目中添加一个模块,称之为“OptionsModule”(或其他),然后放置你的“Enum”

Public Enum Options
    optionA
    optionB
    optionC
End Enum

2)在项目中添加一个Class模块,称之为“EnumClass”(或其他),并输入以下代码

Option Explicit

Private Enums_ As Variant

Public Property Let Enums(enumArr As Variant)
  Enums_ = enumArr
End Property

Public Property Get valueOf(enumText As String) As Long
    Dim i As Long
    valueOf = -1
    For i = LBound(Enums_) To UBound(Enums_)
        If enumText = Enums_(i) Then
            valueOf = i
            Exit For
        End If
    Next i
End Property

3)添加对“Microsoft Visual Basic for Applications可扩展性库”的引用

4)添加此功能(在项目的任何模块中)

Function GetEnums() As Variant
    Dim VBProj As VBIDE.VBProject '<== this needs that reference to "Microsoft Visual Basic for Applications Extensibility Library"
    Dim CodeMod As VBIDE.CodeModule '<== this needs that reference to "Microsoft Visual Basic for Applications Extensibility Library"
    Dim lineCount As Long
    Dim strEnum As String

    Set CodeMod = ActiveWorkbook.VBProject.VBComponents("OptionsModule").CodeModule

    lineCount = 2
    With CodeMod
        Do Until InStr(UCase(.Lines(lineCount, 1)), UCase("End Enum")) > 0
            strEnum = strEnum & WorksheetFunction.Trim(.Lines(lineCount, 1)) & ","
            lineCount = lineCount + 1
        Loop
    End With
    GetEnums = Split(Left(strEnum, Len(strEnum) - 1), ",")

End Function

5)在你的主要子目录中利用它,如下所示

Sub main()
Dim OptionsC As New EnumClass '<== declare a variable of the EnumClass (or whatever the name you chose) and set it to a new instance of it
Dim myString As String

OptionsC.Enums = GetEnums() '<== fill your "Enum" class reading Module with enum

myString = "optionB"

MsgBox OptionsC.valueOf(myString) 'convert the string to corresponding "enum" value

End Sub

此处遵循先前的解决方案#1

1)添加一个Class模块,称之为“EnumClass”(或其他),并输入以下代码

Option Explicit

Private Enums_ As Variant

Public Property Let Enums(enumArr As Variant)
  Enums_ = enumArr
End Property

Public Property Get valueOf(enumText As String) As Long
    Dim i As Long
    valueOf = -1
    For i = LBound(Enums_) To UBound(Enums_)
        If enumText = Enums_(i) Then
            valueOf = i
            Exit For
        End If
    Next i
End Property

2)然后在你的主要子程序中利用它如下

Option Explicit

Sub main()
Dim Options As New EnumClass '<== declare a variable of the EnumClass (or whatever the name you chose) and set it to a new instance of it
Dim myString As String

Options.Enums = Array("optionA", "optionB", "optionC") '<== fill your "Enum" class with string values

myString = "optionB"

MsgBox Options.valueOf(myString) 'convert the string to corresponding "enum" value

End Sub