Determine Access Version Build Number and Service Pack Level

It is normally essential to always ensure that Office/Access is up-to-date when troubleshooting problems.  Sadly, over the course of the past new releases of MS Office, Microsoft has made finding the version, service pack level of each application difficult to locate, if possible at all.  Yet looking back at 2003, 2000 it was available at the click of a button!

Microsoft solution is to tell you to use the Program and Features dialog from the Control Panel to get the build number of MS Office.  Now this is not great for a number of reasons, of which:

  • Not all users can access the control panel due to security restrictions
  • Even if they can, it normally isn’t a good idea to let users go play around in the Control Panel
  • Even if they do retrieve this beautiful build number, such as 12.0.6423.0, it means nothing and finding a cross-reference table is next to impossible (unless you are on my site!)

So at the end of the day, what do we do when all we want to know is what version of Access are we dealing with.

Below is a function, which I cannot take credit for and I believe (I could be wrong) that the original author was fellow MVP Tom van Stiphout and that I found a number of years ago while trying to solve this dilemma for myself.  All I have done was update it with values for Access 2007 SP 2 and SP3, 2010 & 2013.

 

Function GetAccessEXEVersion() As String
'Valid for us with Access 2000 or later.
'Original author: Tom van Stiphout (I believe)
'New version information added by Daniel Pineault
 
'SysCmd(715) -> 6606
'Application.Version OR SysCmd(acSysCmdAccessVer) -> 12.0
    On Error Resume Next
    Dim sAccessVerNoNo As String
'    sAccessVerNo = fGetProductVersion(Application.SysCmd(acSysCmdAccessDir) & "msaccess.exe")
    sAccessVerNo = SysCmd(acSysCmdAccessVer) & "." & SysCmd(715)
    Select Case sAccessVerNo
        'Access 2000
        Case "9.0.0.0000" To "9.0.0.2999": GetAccessEXEVersion = "Microsoft Access 2000 - Build:" & sAccessVerNo
        Case "9.0.0.3000" To "9.0.0.3999": GetAccessEXEVersion = "Microsoft Access 2000 SP1 - Build:" & sAccessVerNo
        Case "9.0.0.4000" To "9.0.0.4999": GetAccessEXEVersion = "Microsoft Access 2000 SP2 - Build:" & sAccessVerNo
        Case "9.0.0.6000" To "9.0.0.6999": GetAccessEXEVersion = "Microsoft Access 2000 SP3 - Build:" & sAccessVerNo
        'Access 2002
        Case "10.0.2000.0" To "10.0.2999.9": GetAccessEXEVersion = "Microsoft Access 2002 - Build:" & sAccessVerNo
        Case "10.0.3000.0" To "10.0.3999.9": GetAccessEXEVersion = "Microsoft Access 2002 SP1 - Build:" & sAccessVerNo
        Case "10.0.4000.0" To "10.0.4999.9": GetAccessEXEVersion = "Microsoft Access 2002 SP2 - Build:" & sAccessVerNo
        'Access 2003
        Case "11.0.0000.0" To "11.0.5999.9999": GetAccessEXEVersion = "Microsoft Access 2003 - Build:" & sAccessVerNo
        Case "11.0.6000.0" To "11.0.6999.9999": GetAccessEXEVersion = "Microsoft Access 2003 SP1 - Build:" & sAccessVerNo
        Case "11.0.7000.0" To "11.0.7999.9999": GetAccessEXEVersion = "Microsoft Access 2003 SP2 - Build:" & sAccessVerNo
        Case "11.0.8000.0" To "11.0.8999.9999": GetAccessEXEVersion = "Microsoft Access 2003 SP3 - Build:" & sAccessVerNo
        'Access 2007
        Case "12.0.0000.0" To "12.0.5999.9999": GetAccessEXEVersion = "Microsoft Access 2007 - Build:" & sAccessVerNo
        Case "12.0.6000.0" To "12.0.6422.9999": GetAccessEXEVersion = "Microsoft Access 2007 SP1 - Build:" & sAccessVerNo
        Case "12.0.6423.0" To "12.0.5999.9999": GetAccessEXEVersion = "Microsoft Access 2007 SP2 - Build:" & sAccessVerNo
        'Unable to locate specific build versioning for SP3 - to be validated at a later date.
        '  Hopefully MS will eventually post the info on their website?!
        Case "12.0.6000.0" To "12.0.9999.9999": GetAccessEXEVersion = "Microsoft Access 2007 SP3 - Build:" & sAccessVerNo
        'Access 2010
        Case "14.0.0000.0000" To "14.0.6022.1000": GetAccessEXEVersion = "Microsoft Access 2010 - Build:" & sAccessVerNo
        Case "14.0.6023.1000" To "14.0.7014.9999": GetAccessEXEVersion = "Microsoft Access 2010 SP1 - Build:" & sAccessVerNo
        Case "14.0.7015.1000" To "14.0.9999.9999": GetAccessEXEVersion = "Microsoft Access 2010 SP2 - Build:" & sAccessVerNo
        'Access 2013
        Case "15.0.0000.0000" To "15.0.4569.1505": GetAccessEXEVersion = "Microsoft Access 2013 - Build:" & sAccessVerNo
        Case "15.0.4569.1506" To "15.0.9999.9999": GetAccessEXEVersion = "Microsoft Access 2013 SP1 - Build:" & sAccessVerNo
        'Access 2016
        '   See: https://support.office.com/en-us/article/Version-and-build-numbers-of-update-channel-releases-ae942449-1fca-4484-898b-a933ea23def7#bkmk_byversion
        '   To build a proper sequence for all the 2016 versions!
        Case "16.0.0000.0000" To "16.0.9999.9999": GetAccessEXEVersion = "Microsoft Access 2016 - Build:" & sAccessVerNo
        Case Else: GetAccessEXEVersion = "Unknown Version"
    End Select
    If SysCmd(acSysCmdRuntime) Then GetAccessEXEVersion = GetAccessEXEVersion & " Run-time"
End Function

This function will return a string like:

Microsoft Access 2007 SP3 – Build:12.0.6606

I personally incorporate this within my About form, so the user can pull up such useful information at the click of a button without needing to know anything technical or even exiting the active database. IMHO, the way it should be with ALL MS products, but is no longer!

Software should be simple! Why MS has hidden such important information, which used to be so easily accessible, I will never understand! Oh well, at least we can come up with a solution.

Getting the Full Version Information

As pointed out by Andrew Reed (in the comments below) the above does not return the full application version number. So I quickly put together the following to get the full version information for any application registered in the registry. So all Office Application, and more. So if you truly need those last 4 digits, this should do the trick.

'---------------------------------------------------------------------------------------
' Procedure : GetVerInfo
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Get the FULL file version of an application (Access, Excel, Word, ...)
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: Uses Late Binding, so none required
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sExe      : The EXE file to check
'               Accesss -> msaccess.exe
'               Excel -> excel.exe
'               Word -> Winword.exe
'
' Usage:
' ~~~~~~
' MsgBox GetVerInfo("excel.exe")
'   Returns: 15.0.5007.1000
' sVer = GetVerInfo("msaccess.exe")
'   Returns: 15.0.4963.1000
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2018-02-13              Initial Release
'---------------------------------------------------------------------------------------
Function GetVerInfo(sExe As String)
    On Error GoTo Error_Handler
    Dim oWSHShell             As Object
    Dim oFSO                  As Object     'Scripting.FileSystemObject
    Dim sExePath              As String

    Set oWSHShell = CreateObject("WScript.Shell")
    sExePath = oWSHShell.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\" & sExe & "\")
    Set oFSO = CreateObject("Scripting.FileSystemObject")
    GetVerInfo = oFSO.GetFileVersion(sExePath)

Error_Handler_Exit:
    On Error Resume Next
    If Not oFSO Is Nothing Then Set oFSO = Nothing
    If Not oWSHShell Is Nothing Then Set oWSHShell = Nothing
    Exit Function

Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: GetVerInfo" & vbCrLf & _
           "Error Description: " & Err.Description & _
           Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
           , vbOKOnly + vbCritical, "An Error has Occurred!"
    Resume Error_Handler_Exit
End Function

15 responses on “Determine Access Version Build Number and Service Pack Level

  1. Siem Eikelenboom

    Thanks for this code! Here’s an slightly updated version. I added Version 2002 SP3 and the build to Unknown Version output.

    Public Function GetAccessEXEVersion() As String
    ‘Valid for us with Access 2000 or later. Modified by Daniel Pineault and Siem Eikelenboom
    ‘Original version may be from Tom van Stiphout, not sure?
    ‘SysCmd(715) -> 6606
    ‘Application.Version OR SysCmd(acSysCmdAccessVer) -> 12.0
    On Error Resume Next
    Dim sAccessVerNo As String
    ‘ sAccessVerNo = fGetProductVersion(Application.SysCmd(acSysCmdAccessDir) & “msaccess.exe”)
    sAccessVerNo = SysCmd(acSysCmdAccessVer) & “.” & SysCmd(715)
    Select Case sAccessVerNo
    ‘Access 2000
    Case “9.0.0.0000” To “9.0.0.2999”: GetAccessEXEVersion = “Microsoft Access 2000 – Build:” & sAccessVerNo
    Case “9.0.0.3000” To “9.0.0.3999”: GetAccessEXEVersion = “Microsoft Access 2000 SP1 – Build:” & sAccessVerNo
    Case “9.0.0.4000” To “9.0.0.4999”: GetAccessEXEVersion = “Microsoft Access 2000 SP2 – Build:” & sAccessVerNo
    Case “9.0.0.6000” To “9.0.0.6999”: GetAccessEXEVersion = “Microsoft Access 2000 SP3 – Build:” & sAccessVerNo
    ‘Access 2002
    Case “10.0.2000.0” To “10.0.2999.9”: GetAccessEXEVersion = “Microsoft Access 2002 – Build:” & sAccessVerNo
    Case “10.0.3000.0” To “10.0.3999.9”: GetAccessEXEVersion = “Microsoft Access 2002 SP1 – Build:” & sAccessVerNo
    Case “10.0.4000.0” To “10.0.4999.9”: GetAccessEXEVersion = “Microsoft Access 2002 SP2 – Build:” & sAccessVerNo
    Case “10.0.6000.0” To “10.0.6999.9”: GetAccessEXEVersion = “Microsoft Access 2002 SP3 – Build:” & sAccessVerNo
    ‘Access 2003
    Case “11.0.0000.0” To “11.0.5999.9999”: GetAccessEXEVersion = “Microsoft Access 2003 – Build:” & sAccessVerNo
    Case “11.0.6000.0” To “11.0.6999.9999”: GetAccessEXEVersion = “Microsoft Access 2003 SP1 – Build:” & sAccessVerNo
    Case “11.0.7000.0” To “11.0.7999.9999”: GetAccessEXEVersion = “Microsoft Access 2003 SP2 – Build:” & sAccessVerNo
    Case “11.0.8000.0” To “11.0.8999.9999”: GetAccessEXEVersion = “Microsoft Access 2003 SP3 – Build:” & sAccessVerNo
    ‘Access 2007
    Case “12.0.0000.0” To “12.0.5999.9999”: GetAccessEXEVersion = “Microsoft Access 2007 – Build:” & sAccessVerNo
    Case “12.0.6000.0” To “12.0.6422.9999”: GetAccessEXEVersion = “Microsoft Access 2007 SP1 – Build:” & sAccessVerNo
    Case “12.0.6423.0” To “12.0.5999.9999”: GetAccessEXEVersion = “Microsoft Access 2007 SP2 – Build:” & sAccessVerNo
    ‘Unable to locate specific build versioning for SP3 – to be validated at a later date.
    ‘ Hopefully MS will eventually post the info on their website?!
    Case “12.0.6000.0” To “12.0.9999.9999”: GetAccessEXEVersion = “Microsoft Access 2007 SP3 – Build:” & sAccessVerNo
    ‘Access 2010
    Case “14.0.0000.0000” To “14.0.6022.1000”: GetAccessEXEVersion = “Microsoft Access 2010 – Build:” & sAccessVerNo
    Case “14.0.6023.1000” To “14.0.7014.9999”: GetAccessEXEVersion = “Microsoft Access 2010 SP1 – Build:” & sAccessVerNo
    Case “14.0.7015.1000” To “14.0.9999.9999”: GetAccessEXEVersion = “Microsoft Access 2010 SP2 – Build:” & sAccessVerNo
    ‘Access 2013
    Case “15.0.0000.0000” To “15.0.4569.1505”: GetAccessEXEVersion = “Microsoft Access 2013 – Build:” & sAccessVerNo
    Case “15.0.4569.1506” To “15.0.9999.9999”: GetAccessEXEVersion = “Microsoft Access 2013 SP1 – Build:” & sAccessVerNo
    Case Else: GetAccessEXEVersion = “Microsoft Access Unknown Version – Build:” & sAccessVerNo
    End Select
    If SysCmd(acSysCmdRuntime) Then GetAccessEXEVersion = GetAccessEXEVersion & ” Run-time”
    End Function

  2. Andrew Reed

    There is a flaw in your logic in the Case statement.
    Since sAccessVerNo does not contain the last part of the Build No (e.g. it only contains 15.0.4569 not 15.0.4569.1506), it would not be able to distinguish between 15.0.4569.1505 and 15.0.4569.1506 which is the branch in your Case statement.
    Therefore, if the build no is 15.0.4569.1506 (to 15.0.4569.9999), it would assume it was in the range 15.0.0000.000 to 15.0.4569.1505 and therefore not SP1.
    Not sure which SysCmd gives the full build no?

    1. Daniel Pineault Post author

      I have been using this code for years and haven’t yet encountered a case where it returned incorrect version information. Do you have a concrete real-life example where it failed?

  3. Claude Larocque

    Thanks Daniel for this code, however, I have encountered an error using your original code, nothing happens…
    When I debugged it, I have a variable not defined on sAccessVerNo…
    I tried with as string, as integer and no changes…
    Can you help
    oups I just found that on your code above: Dim ssAccessVerNoNo…???
    I changed it to sAccessVerNo as string.. nothing happens
    Claude from Quebec

  4. Andrew Reed

    The SysCmd(715) returns the Build number but not the sub-Build number
    i.e. for Access Version 16.0.9001.2080 it will return 9001 but not 9001.2080
    So Daniel’s Case statements won’t recognize the last (.2080) part of the Build number and so won’t work properly in my view.
    Does anyone know how to obtain that sub-Build number?

      1. Daniel Pineault Post author

        I updated the post to include a new function I created that returns the FULL version information. Feel free to use it instead, but in this case, the original code works fine.

        1. Brian Battles

          sExePath is not declared in your code

          Also, when I test ran it, the result it return was

          False

          ??

          1. Daniel Pineault Post author

            I’ve updated the code, thank you for pointing that out.

            I’m not sure what to say regarding the code returning False. I just tested at my end using Access 2013 & 2016 and it worked fine for both.

  5. Matthias Kläy

    Hi Daniel

    Do you know of a way to distinguish between Access 2016 and 2019? For both versions – installed on two different machines – SysCmd(acSysCmdAccessVer) returns “16.0”, your GetVerInfo function for MSACCESS.EXE returns “16.0.11727.2040” (this is the newest version available), and SysCmd(acSysCmdAccessDir) returns “C:\Program Files (x86)\Microsoft Office\Root\Office16\”.
    In fact, the two files MSACCESS.EXE are binary identical!

    Also, dow you know of a way to distinguish between an Office 365 installation and a “permanent” installation?
    And lastly, how can I check from within Access if it is the 32-bit or the 64-bit version?

    Kind regards, Matthias Kläy

    P.S. I think there is a typo in GetAccessEXEVersion: It should be “Dim sAccessVerNo As String” instead of “Dim sAccessVerNoNo As String”.

    1. Daniel Pineault Post author

      No, I haven’t gotten into that yet. We’ve had some discussions on the subject and it is a nightmare! Because Microsoft didn’t index the version number as they always previously did, there is no easy way to determine this. It all comes down to having to review the registry…

      Sadly, Microsoft has made this whole aspect of development much, much, much harder on us that it should be. Between versions, installation types, bitness, … it’s hours of fun to code all the possible variations.

      As for the Office bitness, you can easily determine that by using a function such as http://www.devhut.net/2018/08/24/vba-determine-ms-office-application-bitness/

  6. Mark Burns

    Regarding telling Office 2019 and 2016 Access apart…
    We have an imperfect solution (but it sure beats nothing):
    If Application.Version >= 16 And Application.Build >= 13929 Then ‘13929 is OUR earliest-deployed 2019 version…Others’ mileage may well vary!
    ‘Office 2019…
    ‘ To Compress & Repair DB: “WshShell.SendKeys “”%y1c”””
    Else
    ‘ Office 2016
    ‘ To Compress & Repair DB: “WshShell.SendKeys “”%yc”””
    End If