Enum Type Naming Convention

The combination of "IntelliSense overload" and "global identifier case changes" convinced me I needed a different approach.

Enum Type Naming Convention

Naming conventions are very much a personal preference.  The key with any convention is consistency.  If you already have a naming convention that you're happy with, you should stick with it.  If you don't have one or you're not satisfied with the one you have, maybe my approach will inspire you.

Early attempts at a naming convention

I struggled for a long time trying to settle on a naming convention for Enum types.  At first, I went with the Microsoft style, which is camel casing.  For example, vbGreen, vbKeyReturn, and acTextBox are all examples of Microsoft enumerators built into VBA or Microsoft Access.  

There were a couple of problems I ran into with that approach.

First, I had trouble settling on a prefix.  I went with a few different ones:

  • Organization-wide prefix: gb for Grandjean & Braverman, Inc.
    • a single prefix for every custom enum in our standard code library
  • Project-wide prefix: ap for Accounts Payable, gl for General Ledger
    • a single prefix for the custom enums that were specific to one project
    • analogous to vb for VBA and ac for Access
  • Enum-specific prefix: dl for Debug Level, bt for Batch Type
    • a different prefix for each enum type that was directly related to that type

Problems with the early attempts

I never really liked any of these approaches.  The first two suffered from "IntelliSense overload."  Since enums in VBA are only glorified Long types, IntelliSense will often default to showing every single available enum (and variable and constant and procedure) within the current scope.  Contrast this approach with other languages that have stronger enum typing.  IntelliSense in those languages often show only the enum members for the appropriate enum type.  I'm a strong believer in using IntelliSense to speed up the code-writing process, so this was a big deal for me.

The other problem for me was the VBA IDE's global "re-casing" feature.  VBA is case insensitive.  But in an effort to enforce a foolish consistency, the IDE will change the case of every identifier (variable name, function name, etc.) across the entire project whenever any declaration line with that identifier is changed.  To make things even worse, the changes affect identifiers outside the scope of the changed identifier.  

This may not seem like a big deal, but when your version control system is case sensitive then these innocuous changes can have severe ripple effects.  Suddenly, changing a procedure-level variable name in a private function can cause version control to see changes in dozens of other code modules.  That creates lots of noise in your version control, and noise is not good.

As bad as this state of affairs is, it's somehow even worse for Enum types and members.  That's because changing the case of an enum member anywhere in your code causes that identifier to change case throughout the entire project.  In other words, the forced change is not restricted to declaration lines only the way it is for every other type of identifier.

As I created more Enum types, I kept increasing the odds that I would choose an enum type or member identifier that overlapped with one of my other identifiers (variable, constant, procedure name, etc.)  When I did, it was only a matter of time before I inadvertantly changed the casing of that identifier across my entire project.

Neither of these drawbacks was a dealbreaker on its own.  But the combination of "IntelliSense overload" and "global identifier case changes" convinced me I needed a different approach.

A solution I love

I decided to use a two-letter prefix with two underscores for the type identifier and one underscore for the enum members.  For example, here's a custom enum type that I use in my ProgressMeters interface.  The interface supports dual progress meters: a major meter and a minor meter.  In my typical implementation, I use a horizontal bar for the major meter and a vertical bar for the minor meter.

Public Enum mt__MeterType
    mt_Major
    mt_Minor
End Enum

What I love about this solution is how nice the IntelliSense is.  I just went into the Immediate Window, typed mt_ and then pressed [Ctl] + [Spacebar].  My enum type shows up at the top of the IntelliSense dropdown thanks to the double underscores.  Directly underneath the enum type name is the list of enum members that belong to that type.  For someone as anal-retentive as me, this is a thing of beauty.

IntelliSense so beautiful it makes me want to cry

The other advantage of this approach is that I never use underscores with any of my other identifiers.  Thus, I never end up with accidental identifier collisions that cascade throughout the rest of my project wrecking my version control.

Here's one more example of the technique in action so that you can get a better sense for how this works:

Public Enum env__Environment
    env_UNSET
    env_Development
    env_Test
    env_Production
End Enum

Image by PublicDomainPictures from Pixabay

All original code samples by Mike Wolfe are licensed under CC BY 4.0