What are they?
An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains a list of valid elements. Here’s an example:
Private Enum MyEnum ‘ May also be Public
FirstElement
SecondElement
ThirdElement
FourthElement
‘etc.
End Enum
You would place that code in the Declarations section (in other words at the top) of any type of form or module. Each value in the list is defined internally by VB as a Long Integer and by default the first element will be given a value of 0, the second a value of 1, and so on.
You might be saying to yourself that you could do that with constants like this
Private Const FirstElement = 0
Private Const SecondElement = 1
Private Const ThirdElement = 2
Private Const FourthElement = 3
and you'd be right, but there are several advantages to Enums that will become apparent as you read on. Two that I’ll mention now however are: they are faster and take up less memory than strings and Intellisense will be available when you use them as shown in this picture. If you’ve forgotten how to invoke Intellisense, you press Ctrl+Spacebar, and in this case it was done after the equal sign was entered.
You may not have realized it but you’ve probably run into Enums which are built into Visual Basic.
In that code if you chose vbFriday, MyDayNumber would be be given a value of 6. Another place you see Enums is in the property value choices that you see when for example you are setting the BorderStyle of a form.
Details
I mentioned above that FirstElement in the Enum would have the value of zero by default. You can however give the elements any numeric value you like including negatives or floating point values, which in the latter case VB will round to the nearest integer. The rule is that any elements not specifically given a value will take on the value of the previous element plus one. So given this Enum
Private Enum Cars
Ford = 1
Chevrolet
Chrysler
Honda = 10
Subaru
Toyota
Mazda = 20
BMW
Mercedes
Tesla = 100
End Enum
Chevrolet would be 2, Chrysler 3, Subaru 11 and I’m sure you can figure the rest out. You could also do something like
Subaru = Honda + 2
Which would give Subaru a value of 12. Like Consts however the values can only be changed in design mode and not by way of code.
If you want to you can use names that contain spaces by placing square brackets around the names like this
Private Enum Cars
Ford
Chevrolet
[Chrysler 300]
[Honda Civic]
Subaru
Toyota
Mazda
BMW
Mercedes
Tesla
End Enum
Enums in Use
The following code contains two functions and two Subs that illustrate a couple of ways the Enum can be used.
Option Explicit
Private Enum Cars
Ford
Chevrolet
[Chrysler 300]
[Honda Civic]
Subaru
Toyota
Mazda
BMW
Mercedes
Tesla
End Enum
Private Function isAmerican(aCar As Integer) As Boolean
If aCar = Ford Or aCar = Chevrolet Or aCar = [Chrysler 300] Then
isAmerican = True
End If
End Function
Private Function isMadeIn(aCar As Integer) As String
Select Case aCar
Case Ford To [Chrysler 300], Tesla
isMadeIn = "America"
Case [Honda Civic] To Mazda
isMadeIn = "Japan"
Case BMW, Mercedes
isMadeIn = "Germany"
Case Else
isMadeIn = "Unknown"
End Select
End Function
Private Sub Example1()
If isAmerican(Cars.Ford) Then ' Or just Ford instead of Cars.Ford
MsgBox "Ford is an american made car"
End If
End Sub
Private Sub Example2()
MsgBox "Mazda is made in " & isMadeIn(Mazda)
End Sub
Select all Open in new window
If the Enum values are sequential and you want to validate a potential use you can change the Enum to
Private Enum Cars
[_First] = 1
Ford = 1
Chevrolet
[Chrysler 300]
[Honda Civic]
Subaru
Toyota
Mazda
BMW
Mercedes
Tesla
[_Last] = 10 ' This value should equal the value for the last element
End Enum
and then do something like this.
Dim i As Long
Dim intCar As Integer
intCar = 5
For i = Cars.[_First] To Cars.[_Last]
If intCar = i Then
MsgBox "It's valid"
End If
Next
Select all Open in new window
Note that the special [_First] and [_Last] values won’t be shown by Intellisense and that the square brackets are needed to make them valid names. You should also note that you can assign any numeric value to a variable of Cars type even if that value is not in the Enum declaration, so intCar = 999 is valid but it would have no related Enum element.
The [_Last] value is handy if you are going to often add new elements to the Enum since all you need do is change the value of [_Last] and the validation shown above would still work.
My Favorite Use of an Enum (Does not apply to VBA)
One of the hallmarks of a well-written program is self-documentation or readability. Lets take an example of some code that in my opinion is
not well written. Assume that the program has a control array called txtName (thank goodness it's not called Text43) and it consists of three members. In that program the author writes this code.
Dim strName As String
If txtName(1).Text = "" Then
strName = txtName(2).Text & ", " & txtName(0).Text
Else
strName = txtName(2).Text & ", " & txtName(0).Text & " " & txtName(1).Text
End If
MsgBox strName
Select all Open in new window
A stranger to the program or even the author after a few months away from the program might have to take a minute or two to figure out what's going on there. How much easier and nicer it would be if the author had an Enum and code like this
Private Enum BuyerName
bnFirstName
bnMiddleInitial
bnLastName
End Enum
Dim strName As String
If txtName(bnMiddleInitial).Text = "" Then
strName = txtName(bnLastName).Text & ", " & txtName(bnFirstName).Text
Else
strName = txtName(bnLastName).Text & ", " & txtName(bnFirstName).Text & " " & txtName(bnMiddleInitial).Text
End If
MsgBox strName
Select all Open in new window
where it's immediately apparent that a last name, first name, middle initial string is being created. When the author wrote that code he'd also find that naming the Enum entries with a common prefix like that allows him to invoke Intellisense after typing in ‘bn’ to see and select the appropriate Enum element name.
I use Enums all the time and I think after you use one you'll find that you do too. Your future self and/or the people who maintain your code will appreciate that.
If you find that this article has been helpful, please click the “thumb’s up” button below. Doing so lets me know what is valuable for EE members and provides direction for future articles. It also provides me with positive feedback in the form of a few points. Thanks!
Comments (4)
Commented:
Commented:
Commented:
Great article about Enums, but I seem to have a problem using them.
I'm using VB6.
I define an enum in my global definition module as:
Open in new window
Then I use the enum as:Open in new window
Where I have a problem is that if I type out the selection "tnresponses", my definition (in the enum definition) changes to "tnresponses" from "tnResponses". I just discovered that is I use Intellisense with the typing that doesn't occur, however if I type out the name (without using Intellisense) that the case change does happen. Is there something (other than not always using Intellisense) that I's doing wrong?I know that case isn't important in VB, however it is to me - I have been writing code about as long as you have - started with an HP9815 and wrote some rather complex programs for it, had to migrate one program to Apple basic on an Apple II (before the IIe) - and went on from there. I have established some standards about how I write code:
1) I use explicit data types for ALL Dim and Global definitions
2) When defining a variable I use the first letter (lower case) to indicate the data type - iValue1 as Integer, lValue2 for long etc.
3) I only use variants were absolutely necessary
These were established as soon as I had a keyboard which has Upper and lower case letters!
There are others, but these are the main ones I use for readability.
I will say that you have been very helpful to me over the years - one thing I haven't done (early on especially) is to push myself beyond what I knew (programming wise). I'm trying to do that now and it is much more difficult!
Richard
Author
Commented: