отредактирован 2: добавлено решение # 3, который
имеет все преимущества решения # 2, т.е.
не имеет недостаток, заключающийся в необходимости (даже если чуть-чуть) разные имена для класса и 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
Не в VBA вам нужно будет создать свою собственную функцию для этого. –
Я не думаю, что есть более сжатый способ, чем создание собственной функции, содержащей «Выбрать случай». Обычно я делаю два: «OptionStringToEnum» и для обратной операции «OptionEnumToString». «* трудно поддерживать, когда значения перечислений меняются *« Конечно, но код, подобный '.valueOf (« OptionC »), будет также трудно поддерживать, если OptionC изменится. Я не вижу относительной пользы. –
@ Jean-FrançoisCorbett Вы правы, что ** сохранение ** '.valueOf()' было бы затруднительным. Вот почему я попросил способ кодировать '.valueOf()' без его поддержки. Это возможно на Java, поэтому я подумал, что это возможно и в VBA, но, похоже, это сложно/сложно. – Nijin22