It has been asked on Stack Overflow is there is an inbuilt way to convert a VBA enum to a string, i.e. to get a string representation of the value, like there is in C#. The answer is no. But one can write a helper function with the enum values stored in an array. (UPDATE: and in this follow-up post I give Python code to write it for you!)
In the code below I have four examples. In the first two the values are sequential, they differ only in that one is zero-based and the other isn't.
The third example is a binary flag based enumeration where the values are not mutually exclusive but instead building blocks for a composite indicator. This requires a helper function to convert the value to binary with modular division.
The fourth example is to catch all other cases because it uses a Switch statement to find the index of the correct string in the array and is less efficient.
However, all three examples require the enumeration definition to be synchronized to the array of strings. This might be considered a pain, I wonder if there is anything we can do to salve this pain?
Option Explicit
'* a sequential example zero based
Public Enum Cars
BMW
Ford
Lotus
End Enum
'* a sequential example non-zero based
Public Enum MyColor
Red = 1
Green
Blue
End Enum
'* a binary flag based
Public Enum ParamFlags
FIN = 1
FOUT = 2
FLCID = 4
FRETVAL = 8
FOPT = 16
FHASDEFAULT = 32
FHASCUSTDATA = 64
End Enum
'* non sequential, non binary flags
Public Enum PrimeNumbers
First = 2
Second = 3
Third = 5
Fourth = 7
Fifth = 11
End Enum
Public Function CarsEnumToString(e As Cars)
CarsEnumToString = Array("BMW", "Ford", "Lotus")(e)
End Function
Public Function MyColorEnumToString(e As MyColor)
MyColorEnumToString = Array("Red", "Green", "Blue")(e - 1)
End Function
Public Function ParamFlagsEnumToString(e As ParamFlags)
ParamFlagsEnumToString = ToBinary(e, Array("FIN", "FOUT", "FLCID", "FRETVAL", "FOPT", "FHASDEFAULT", "FHASCUSTDATA"))
End Function
Public Function PrimeNumbersEnumToString(e As PrimeNumbers) As String
PrimeNumbersEnumToString = Array("First", "Second", "Third", "Fourth", "Fifth")(Switch(e = 2, 0, e = 3, 1, e = 5, 2, e = 7, 3, e = 11, 4))
End Function
Function ToBinary(ByVal lFlags As Long, ByRef vNames As Variant)
Dim dic As Scripting.Dictionary
Set dic = New Scripting.Dictionary
Dim lIndex As Long
While lFlags > 0
If lFlags Mod 2 = 1 Then dic.Add dic.Count, vNames(lIndex)
lFlags = lFlags \ 2
lIndex = lIndex + 1
Wend
ToBinary = VBA.Join(dic.Items, " | ")
End Function
Sub Test()
Debug.Assert CarsEnumToString(BMW) = "BMW"
Debug.Assert CarsEnumToString(Ford) = "Ford"
Debug.Assert CarsEnumToString(Lotus) = "Lotus"
Debug.Assert MyColorEnumToString(Red) = "Red"
Debug.Assert MyColorEnumToString(Green) = "Green"
Debug.Assert MyColorEnumToString(Blue) = "Blue"
Dim e As ParamFlags
e = FIN + FOUT + FLCID + FOPT + FHASDEFAULT + FHASCUSTDATA
Debug.Assert ParamFlagsEnumToString(e) = "FIN | FOUT | FLCID | FOPT | FHASDEFAULT | FHASCUSTDATA"
Debug.Assert PrimeNumbersEnumToString(2) = "First"
Debug.Assert PrimeNumbersEnumToString(11) = "Fifth"
End Sub
No comments:
Post a Comment