Community Pick: Many members of our community have endorsed this article.

Using Enums in VB6 and VBA

Martin LissKeep everyone healthy; Get Vaccinated
CERTIFIED EXPERT
Almost 50 years of programming experience. Click '+ More' in my "Full Biography" to see links to some articles I've written.
Published:
Updated:
Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.

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.

Using Intellisense to show Enum values
You may not have realized it but you’ve probably run into Enums which are built into Visual Basic.

The built-in days of the week EnumIn 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!
15
37,714 Views
Martin LissKeep everyone healthy; Get Vaccinated
CERTIFIED EXPERT
Almost 50 years of programming experience. Click '+ More' in my "Full Biography" to see links to some articles I've written.

Comments (4)

Thanks i have some code to use this
EsotManager

Commented:
Good clarification, thanks

Commented:
Hi Martin,
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:
Public Enum Tables
    tnResponses
    tnAnswers
    tnQuestions
    tnPASSalongs
End Enum

Open in new window

Then I use the enum as:
        Dim myTable As Long        
        myTable = tnresponses

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
Martin LissKeep everyone healthy; Get Vaccinated
CERTIFIED EXPERT
Most Valuable Expert 2017
Distinguished Expert 2023

Author

Commented:
I've experienced the same thing in other situations and I really think it's a bug in, or at least a failing of, vb6. To fix it I've found that doing a mass-change using ctrl+h to change tnresponses to tnResponses usually works. Please send me a message if you want to discuss this further.

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.