2016-05-02 6 views
3

einen Aufzählungstyp:Wie konvertiere ich einen String in seinen Enum-Wert ähnlich wie Javas .valueOf?

Public Enum Options 
    optionA 
    optionB 
    optionC 
End Enum 

und einen String myString = "optionB" gibt es einen schnellen Weg, um die Zeichenfolge in dem entsprechenden ENUM-Wert zu konvertieren? (Options.optionB/1)

I.e. Ich bin auf der Suche nach der VBA-Entsprechung von Java .valueOf()

Ich bin mir bewusst, dass ich eine Select Case schreiben könnte, aber das ist wie das Schreiben der Definition der Enumeration wieder und schwer zu warten, sobald die enum Werte ändern.

+0

Nicht in VBA, müssen Sie Ihre eigene Funktion, um das zu tun. –

+0

Ich glaube nicht, dass es eine prägnantere Möglichkeit gibt, als eine eigene Funktion mit einem 'Select Case' zu ​​erstellen. Ich mache normalerweise zwei: 'OptionStringToEnum' und für die umgekehrte Operation' OptionEnumToString'. "* schwer zu warten, sobald sich die Enums-Werte ändern *" Sicher, aber Code wie '.valueOf (" OptionC ")' wird ebenso schwer zu pflegen sein, wenn sich OptionC ändert. Ich sehe den relativen Nutzen nicht. –

+0

@ Jean-FrançoisCorbett Du hast Recht, dass ** das Aufrechterhalten von ** '.valueOf()' schwierig wäre. Deshalb habe ich nach einer Möglichkeit gefragt, das '.valueOf()' zu codieren, ohne es zu behalten. Es ist in Java möglich, also dachte ich, dass es auch in VBA möglich sein könnte - aber es scheint, dass es nicht/verdammt schwierig ist. – Nijin22

Antwort

5

bearbeitet 2: added Lösung # 3, die

  • alle Vorteile der Lösung # 2 hat, dh

    • valueOf Funktion

    • einzige Enum-Deklaration (gut , Art von ...)

    • intellisense

  • hat nicht den Nachteil (wenn auch leicht) unterschiedliche Namen für die Klasse und Enum (in Lösung # 2, sie seien "OptionsC" und "Optionen") benötigen

  • noch Basen auf dem Objektmodell VBE -> ein paar vorbereitenden Schritte benötigen) (Schritt 2 sehen)


Lösung # 3

1) ein Klasse-Modul in Ihrem Projekt hinzufügen, nennt es "EnumClass" (oder was auch immer) und

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) tun, wie pro here vorläufige Einstellung in dem folgenden Code setzen (siehe ab "Um Um den Code auf dieser Seite in Ihren Projekten zu verwenden, müssen Sie zwei Einstellungen ändern."Auf" ACHTUNG "Klausel enthalten)

3) es in der Hauptunter ausnutzen wie folgt

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 

hier

# 2

1 vorherige Lösung folgt) in ein Modul in Ihrem Projekt, nennen Sie es "OptionsModule" (oder was auch immer) und legen Sie dort Ihre "Enum"

.210

2) ein Klasse-Modul in Ihrem Projekt hinzufügen, nennt es "EnumClass" (oder was auch immer) und

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) hinzufügen Referenz in dem folgenden Code setzte auf "Microsoft Visual Basic für Applikationen Extensibility Library"

4) fügen sie diese Funktion (in jedem Modul des Projekts)

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) ausbeuten sie alle in der Hauptunter wie

folgt
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 

folgt hier vorherige Lösung # 1

1) ein Klasse-Modul hinzufügen, nennt es "EnumClass" (oder was auch immer) und

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) dann in dem folgenden Code setzen in Ihrem Haupt-Sub-Exploit es wie folgt

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 
+0

Danke für diesen guten Vorschlag! Leider muss ich die Werte des Enums zweimal schreiben. Ich möchte diese Frage für ein bisschen mehr offen lassen, um zu sehen, ob es eine bessere Antwort gibt, aber ich wähle deine, wenn keine gefunden werden kann. – Nijin22

+0

Nur um darauf hinzuweisen, müssen Sie Enum-Werte nur einmal schreiben: Wenn Sie die Klasse "Enums" -Eigenschaft füllen – user3598756

+0

Müsste ich nicht auch zuerst schreiben, wenn Sie die tatsächliche Enum definieren? (Oder verpassen Sie einige Funktionen wie intellisense) – Nijin22

Verwandte Themen