2016-05-02 6 views
3

Учитывая перечисление:Как преобразовать значение String в значение Enum, аналогичное значениям .valueOf в Java?

Public Enum Options 
    optionA 
    optionB 
    optionC 
End Enum 

и строку myString = "optionB", есть быстрый способ, чтобы преобразовать строку в соответствующих перечислениях стоимости? (Options.optionB)

I.e. Я ищу эквивалент VBA Java .valueOf()

Я знаю, что я мог бы написать Select Case, но это похоже на то, чтобы снова написать определение переименования и выполнить его с сохранением после изменения значений перечисления.

+0

Не в VBA вам нужно будет создать свою собственную функцию для этого. –

+0

Я не думаю, что есть более сжатый способ, чем создание собственной функции, содержащей «Выбрать случай». Обычно я делаю два: «OptionStringToEnum» и для обратной операции «OptionEnumToString». «* трудно поддерживать, когда значения перечислений меняются *« Конечно, но код, подобный '.valueOf (« OptionC »), будет также трудно поддерживать, если OptionC изменится. Я не вижу относительной пользы. –

+0

@ Jean-FrançoisCorbett Вы правы, что ** сохранение ** '.valueOf()' было бы затруднительным. Вот почему я попросил способ кодировать '.valueOf()' без его поддержки. Это возможно на Java, поэтому я подумал, что это возможно и в VBA, но, похоже, это сложно/сложно. – Nijin22

ответ

5

отредактирован 2: добавлено решение # 3, который

  • имеет все преимущества решения # 2, т.е.

    • valueOf особенность

    • одного перечисления декларации (хорошо , вид ...)

    • IntelliSense

  • не имеет недостаток, заключающийся в необходимости (даже если чуть-чуть) разные имена для класса и Enum (в растворе № 2 они были "OptionsC" и "Опции")

  • еще базируется на объектной модели VBE -> нужно несколько предварительных шагов (см шаг 2))


решение # 3

1) добавить модуль класса в проекте, называют его «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) добавить модуль класса в проекте, называют его «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 для приложений расширяемости библиотеки»

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) добавить модуль класса, называют его "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 
+0

Спасибо за это хорошее предложение! К сожалению, это все еще требует, чтобы я дважды записывал значения перечисления. Я хотел бы оставить этот вопрос открытым для немного больше, чтобы узнать, есть ли лучший ответ, но выберет ваш, если его не найти. – Nijin22

+0

Чтобы указать, что вы должны писать значения перечисления только один раз: когда вы заполняете свойство класса «Перечисления» – user3598756

+0

Не было бы также мне сначала писать их при определении фактического Enum? (Или пропустите некоторые функции, такие как intellisense) – Nijin22

 Смежные вопросы

  • Нет связанных вопросов^_^