Constructing Version Numbers

Every program needs a version number. But there's no need to overthink it. When versioning Access apps, less is more.

Constructing Version Numbers

I find having an easily visible version number in my Access applications to be a great help when troubleshooting problems.

Keep It Simple, Stupid

I follow the KISS principle.  I want my Access version numbers to perform the following functions:

  1. Always incrementing
  2. Dead simple to generate
  3. Convey whether a user is running the latest version of my application


The version format that fits these criteria is a simple one: YY.M.D.  For example, if I released a new version of an application today--January 8, 2021--it would have a version number of 21.1.8.

What if there are multiple releases on the same day?  It doesn't happen often, but it definitely happens.  In those cases, I start adding an incrementing letter for each subsequent release.  For example, if I released four versions of the same program today, they would have the following version numbers:

  1. Version 21.1.8
  2. Version 21.1.8a
  3. Version 21.1.8b
  4. Version 21.1.8c

Another option that I've used in place of the incrementing letter is a four-digit hour and minute section.  For example, "Version" for a release at 11:14 PM.  I shy away from that because the time portion of the version number is usually just noise.  This makes the version number unnecessarily long and more difficult to communicate than it needs to be.

Displaying the Version Number

Depending on the style of user interface the program uses, I display the version number on an "About" form that opens from a ribbon button or on a "Main Menu" form.  In either case, though, the version number itself is stored in a public function and displayed using a text box with a control source of ="Version " & PgmVersion().  

I used to display the version number inside of a form label.  I would just update the form label's caption with each release.  I stopped doing that because my error logging often did not have access to the version number.  If the error occurred at program startup before the Main Menu form loaded, then I couldn't log the version number.

By storing the version number inside of a function, it guarantees it will be available when I'm logging errors.  I don't bother assigning the version number to a global constant.  Since form controls don't have direct access to global constants, I would need to rely on a public function anyway.

Public Function PgmVersion() As String
    PgmVersion = "21.1.8"
End Function

Releasing Updates

Before releasing a new version of any application to my end users, I follow these steps:

  1. Update the version number
  2. Export to source and commit to version control
  3. Decompile
  4. Compact and repair

Steps 1 and 2 guarantee that I know exactly what code went out with each release.  When an error gets reported, it contains the application's version number.  Sometimes a bug gets fixed, but a user is running an old version of the application.  Rather than waste time tracking down a bug I already fixed, I know I just need to get the user an updated version of the program.

A Note About "Semantic Versioning"

When I'm writing libraries in other languages, such as C#, I try to follow the Semantic Versioning approach.  

Given a version number MAJOR.MINOR.PATCH, increment the:
  1. MAJOR version when you make incompatible API changes,
  2. MINOR version when you add functionality in a backwards compatible manner, and
  3. PATCH version when you make backwards compatible bug fixes.

This is a great approach for a project that will expose any kind of public API.  With semantic versioning, the version number itself conveys meaning about what kind of changes were made to the software.  

An Access application does not benefit from those features.  For Access applications, I prefer to keep it simple.

Image by Quang Nguyen vinh from Pixabay

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