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
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
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?
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?
Hi Daniel,
Any updates for Access 2016 please?
I haven’t looked into the matter myself, but it would just be the case of adding new case statements based on the build numbers found at https://support.office.com/en-us/article/Version-and-build-numbers-of-update-channel-releases-ae942449-1fca-4484-898b-a933ea23def7
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
Not sure what to say. I just tested in Access 2016 and it worked just fine for me.
How are you using it exactly?
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?
Have you tried it? It works just fine.
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.
sExePath is not declared in your code
Also, when I test ran it, the result it return was
False
??
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.
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”.
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/
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