With Microsoft's latest forced update to Office 365 that broke so many Access databases using tables ODBC links to server databases, I've been trying to find a way to pull the Office build info while in MS-Access and display that info in a Main form for troubleshooting.
There's many solutions out there that use Application.Version in VBA but that doesn't seem to show the offending update version. I'm looking for a solution that maybe can find it using Registry, DLL or a VBA Object property.
In Access - under File | Account I can see the offending version under
Product Information in Office Click-To-Run
or,
About Access in Apps For Business
From VBA I can get the following
Debug.Print Application.Version & "." & Application.Build & vbcrlf & Application.ProductCode
16.0.8326
{90160000-000F-0000-0000-0000000FF1CE}
Looking at the properties of MSAccess.exe only shows the same app versions
EDIT
No luck with registry setting either
Looking at
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\ClickToRun\Configuration only shows
CurrentVersionToReport=16.0.8326.2096
This is, unfortunately, not a trivial task, but Colin made a serious attempt:
Access / Office 365 / Windows Version Check
Version 2.55. Updated 26/11/2021
Attached is a utility for checking the following: a) Access version &
bitness b) Whether Office 365 is installed c) Windows version &
bitness (32/64-bit)
Several functions are available for obtaining the Access version in
varying degrees of detail.
GetAccessVersion e.g. 16.0 (for Access 2016/2019/2021/365)
GetAccessBuildVersion e.g. 16.0.14701 (for Access 365)
GetAccessEXEVersion e.g. Access 365 - Build 16.0.14701.20226
These are combined with another function IsOfficex64 which returns the value 32-bit or 64-bit
The full Windows version is obtained using a GetWindowsVersion
function which returns e.g. Windows 10 Pro Version 21H2 - Build
10.0.19044.1348 64-bit
Too much code to post here.
You can map the build to the version. They're the same thing.
You've already figured out how to get the build number, Application.Build.
You can map that using the table provided on Microsoft Docs: https://learn.microsoft.com/en-us/officeupdates/update-history-microsoft365-apps-by-date.
The version is just a shorter code, and thus more easy to memorize and communicate (and minor changes can result in different build numbers but identical version numbers).
For info, the old link to my Access/Office/Windows version checker provided by Gustav is no longer being maintained and will eventually disappear. The current link is https://www.isladogs.co.uk/access-office365-win-check/index.html
Having made a determined effort last year to find the 365 monthly version (currently 2205) by various methods using VBA / from the registry / database properties etc, I agree that the version number can only be obtained by creating a lookup table.
Perhaps Office 'phones home' at startup to retrieve the version number? We now know that Access does this to determine whether certain features should be 'switched on' or not - a feature that is often used to roll back issues such as the hyperlink subaddress & #DELETED bugs that were triggered by version 2205
Office applications don't provide the version numbers in the format listed on the About window. You need to find the Application.Version in the list of all builds with a corresponding human-readable versions listed in MSDN.
Related
I am attempting to migrate my entire Word VBA project to a back up laptop.
Years ago I had great difficulty finding a number active X dlls that are used for various objects that my my project currently uses. They are all installed and working correctly after performing a lot of research.
When browsing the currently checked references (Tools--References) I see that some of the checked references (that I need and use) show only the top part of the path. I know that many of these checked references will not exist anywhere on my back up laptop (Both Win7, Office 2003)
If I can see the full path, I can go to it, copy it and install it on the back up laptop.
Is there anyway to get the full path??
I really dont want to do what I originally did on my original laptop, run the project, note the complaint that a dll is missing, try to figure out what reference that this dll belongs to, ad nauseum.
Not any help out there on Google for Word, lots of info for Access and excell that dont apply to Word.
Maybe these references are stored in the registry??
Thanks
Note, this project is very extensive, more than 3000 lines of code, integration with AutoIt, SQLite, Home Inspection software. Saves me tons of work.
From: https://www.tek-tips.com/viewthread.cfm?qid=1563159
After referencing 'Microsoft Visual Basic for Applications Extensibility 5.3' you can:
Function ListAllRefs()
Dim my_ref As VBIDE.Reference
For Each my_ref In ThisWorkbook.VBProject.References
With my_ref
Debug.Print .Name, .Description, .FullPath, .IsBroken
Debug.Print
End With
Next
End Function
Finding information on Add-In development for Microsoft Access is like getting all of your teeth pulled! Yes I've found the couple Managed Add-In Articles written... but could find next to nothing for Un-Managed Add-Ins. I did find one great article which is very old in creating basically an unmanaged .mda project... which I've followed and created a add-in. Now I would like an automated way to deploy this add-in.
I've seen it done from VBA with such tools as Rick Fisher's Find and Replace add-in tool... but can not find a way to do this programatically in Access. I have found lot's and lot's of articles on Excel Add-In's and even Excel Add-In Installation. One such method uses VBA like so:
Sub InstallAddIn()
Dim AI As Excel.AddIn
Set AI = Application.AddIns.Add(Filename:="C:\MyAddIn.xla")
AI.Installed = True
End Sub
Unfortunately Access does not use the same method. If anyone could point me in the right direction I would greatly appreciate it. AND if anyone knows of any books or references that goes more in-depth to developing Add-Ins for Microsoft Access that would be greatly appreciated as well as most of the picking seem slim.
This is just a bad idea. To be honest, I'm not sure where it's even located in the current version of Windows/Office. I have found Word and Excel at the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office, but I have Access installed and I don't see an Access folder there. At one point, Access add-ins were accessible through this registry key:
HKEY_CURRENT_USER\Software\Classes\VirtualStore\MACHINE\SOFTWARE\Microsoft\Office\11.0\Access\Menu Add-Ins
This worked for Office 2003 on Win Vista. But it changes every time Microsoft updates Office/Windows, so trying to do it programmatically would be moot because you would have to update and roll out a database change every time you updated Office or Windows.
If you target the main registry hive there is logic that will put the key in the correct location for you. For example, you never hard code Wow6432Node because that location is automatically managed by 64-bit windows when a 32-bit application tries to use the registry. Likewise, in modern C2R versions of office the registry location is in a really strange place. You don't have to worry about it. If you target the main key from Access, the key will end up in the correct location magically.
If you want to install per user I recommend using the following locations.
Put the file here:
Private Function GetAddinFileName() As String
GetAddinFileName = Environ$("AppData") & "\Microsoft\AddIns\" & CodeProject.Name
End Function
Use this registry location:
Private Function GetAddinRegPath() As String
GetAddinRegPath = "HKCU\SOFTWARE\Microsoft\Office\" & _
Application.Version & "\Access\Menu Add-Ins\"
End Function
I have an Microsoft Access 2010 database application with split front end and backend which has started to behave oddly, and I've exhausted all the options I know for investigating and resolving the problem.
32-bit Access 2010 running on Windows 8.1... I have both Access 2010 and Access 2013 installed, but the problem also manifests itself on a Windows 8.1 system with a completely fresh install of Access 2010 and no Office 2013 present. The issue also exists if the application is run using Access 2010 Runtime. The front-end is running on my hard disk, not in a Dropbox or similar environment. The back-end is in Dropbox.
There are a couple of third-party elements in the application -- references are as shown -- example 1 on the system with both Access 2010 and 2013 present, example 2 on the system with just Access 2010 present.
There hasn't been a software update to the Treeview control since December 2013. I've checked that the versions of the third-party controls I'm using are compatible with Windows 8.1.
Symptoms:
The application (an unreleased development version) initially works perfectly, but if closed and reopened, one specific operation (right-click on a third party treeview ActiveX control on the main form) misbehaves -- the right-click event is triggered multiple times instead of just once (the number of times is unpredictable). There are two treeviews on the main form with identical settings (populated dynamically with different data sets). One treeview behaves, one doesn't. Even if I remove all code from the right-click event, it fires twice.
This main form configuration and code hasn't been changed in over one year, not has the treeview config or code. I don't use Compact on Close. The application isn't logging any errors.
What I've tried:
If I restore a previous version of the application, it works... and when reopened, doesn't work. (I've tried this with several previous versions of the database.)
I've tried importing a copy of the main form from an old working version of the database -- same problem.
I've tried deleting the malfunctioning treeview and creating a new one (copying the one that is working) -- same problem.
I've tried creating a new blank database and importing all the objects from the old one. Once I've restored the references manually, the same problem.
I've reviewed all the possibilities mentioned in Can't eliminate Access corruption -- one commonality I have with this question is that I've (last three months) started using the VBA Implements keyword, but I hadn't made any changes to this code immediately before the problem showed up, and neither the main form nor the treeview control utilise it.
I've emailed the support team for the treeview control, but they haven't anything to suggest that I haven't already tried.
I've repaired the installation of both Access 2010 and Office 365 in case the references were somehow messed up.
I've un-installed Office 365 and Access 2010, rebooted the machine and reinstalled Access 2010. The references are all Office 14 references and the problem still exists (in a compiled accde). As soon as I reinstall Office 365, the references become mixed 14 and 15. (This is also true for the working version which is two years old).
What I haven't tried yet:
Rolling back a two months' worth of Windows updates to see if it's a Windows issue (this system has only been in use since early September, so this wouldn't be hugely onerous to try).
Rolling back to a version of the app from December 2012 (the last production release) which doesn't seem to have suffered the corruption and manually reapply almost two years worth of development changes. This would be a mega undertaking....
Are there any other options for investigation or resolution that I can try?
Edited to add: What finally worked
I created a new empty database, imported everything from the old database except the main form, which I recreated from scratch to look identical and have the same code as the old one... And the problem has gone away. It not very satisfactory as a resolution, but it seems to confirm that there was a corruption somewhere.
One of the best ways to remove corruption in an Access database is to save the forms and reports to text using the undocumented SaveAsText function, delete the form and report objects, close the database, use the undocumented /decompile switch to decompile the database, compact/repair the database, then re-import all the objects using the undocumented LoadFromText function.
Usually the Access databases corruptions affect the VBA modules, less likely the table data. So hopefully you should be able to copy the data to a blank database, get the VBA code from a older backup (since the last source code update) and merging the two together. It should work!
It won't stay fixed unless you disable updates. And you can't disable updates because you will be compromising security.
I am programmatically generating Office Documents (in my case Word or Excel 2007) using automation in VBA (in this example MS Access 2007, but that should not change much) under Windows 7. This works fine.
Since the documents are automatically generated I don't want them to show up in the recent lists. For recent list in Word I can just add "AddToRecentFiles:=False" when saving the document (see example) or I could delete the entries afterwards through "Application.RecentFiles ..."
My code
Set objWord = CreateObject("Word.Application")
Set curDocument = objWord.Documents.Add
curDocument.SaveAs FileName:=Folder + "text.doc", FileFormat:=wdFormatDocument,
AddToRecentFiles:=False
curDocument.Close
Problem is I could not find a way to disable the recent lists from Windows 7 (i.e. jump list with recent items in the taskbar for Word or last used folders in Explorer and recent list for Word in Start menu).
I am aware these lists are stored under %APPDATA%\Microsoft\Windows\Recent\AutomaticDestinations and I have found out that to manipulate Jumplist there is the "WindowsAPICodePack" (that I can not use from VBA, right?).
To add an item the the recent list I can use the old API SHAddToRecentDocs from the "shell32.dll" library but deleting with this API function does not work anymore as it only seems to affect the entries in the old "/recent" folder (and even deletes everything what is not my intention). Presentations on the Windows 7 Taskbar API too only seem to mention how to add items but not how to avoid doing so or to delete specific entries.
Am I missing something or is there no -- easy and ideally usable from within VBA -- way to manipulate (or temporerally disable) the recording Windows 7 does?
Kind regards
Andreas
I have encountered a similar problem when programmatically dealing with Word and other office documents with Sharepoint.
You can access the JumpList object via the PresentationFramework library (.Net 4) or the WindowsAPICodePack for 3.5 (and possibly earlier) however there does not appear to be a way to programmatically delete JumpListItems.
I found a post which suggests that you can disable Word from adding items to the JumpList via registry key. http://www.add-in-express.com/forum/read.php?PAGEN_1=2&FID=5&TID=8124#nav_start This shouldn't be too hard to do programmatically (if you have admin rights on the machine generating the documents).
I haven't had a chance to try out whether this works yet. If you find a more elegant solution please let me know!
Update: In my solution I ended up regenerating the jumplist based on the Word Recent files list (I looped backwards through the internal Word recent files list and called JumpList.AddToRecent method for each file).
How to detect OS of Win7 Home Premium, Win7 Professional, Win7 Enterprise or Win7 ultimate?
Determine Windows Version and Edition
Check this post Detect OS version and see if it helps. This is for XP but it should help you little bit.
Check this one too http://andrewensley.com/2009/06/c-detect-windows-os-part-1/ and this one is for Vista.
I'm using the key "Edition" under HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion to determine windows version, I don't know if it's unique? Thanks.
EditionID = ultimate
EditionID = Enterprise
EditionID = Professional
EditionID = Premium
He tagged the question with win32 api.
GetVersionEx() et al. is what you need. See this code sample for a more in depth example.
In Delphi I would use this method for Windows XP and above, it seems to be the most straight forward and this registry key should always exist
var
Reg : TRegistry
begin
Reg := TRegistry.Create();
Reg.RootKey := HKEY_LOCAL_MACHINE;
Reg.OpenKey('Software\Microsoft\Windows NT\CurrentVersion', false);
Caption := Reg.ReadString('ProductName');
Reg.Free;
end
You will need to include Registry as a unit in your app
Try WMI: host localhost, namespace root\cimv2 (these are the defaults) SELECT Caption FROM Win32_OperatingSystem
Using approach like checking the version number is incorrect in my opinion. I was reading an article about best practices (lost the link) and it clearly said never use these version numbers which microsoft may change in future updates to detect windows version.
Windows Vista is version 6.0 and Windows 7 is 6.1 which ideally should have been 7. This is not a reliable at all.
A better way is to check the existance of features which are particular to each version of windows. For ex, in windows vista/7 home basic you would not find aero experience. Same way ultimate edition comes with bitlocker etc and home premium doesnt.
MSDN will detail what features are available in each version and how to query if its available. Based on this you can decide what is the base version of windows. Also you can use to query version info from the system dlls to detect exact windows build date etc.
With windows 7 new DLLs have been added in the system32 as compared to vista. So when you search for particular dlls you would know if its windows 7 system or old versions like xp/vista.
You can use GetVersionEx to determine the core OS version, but this method gets messy faced with multiple products which use a common core, and I don't think you can programatically decode this information down to the level of a particular SKU. The best you could get away with is finding a string and letting the user see that. Some simple OSVERSIONINFOEX mappings are shown in the remarks section of the docs here
Read this Microsoft blog posting for current thinking on this topic. Basically it comes down to using GetProcAddress to look for the API you're trying to use and degrading gracefully.
I came here looking for the same thing but for powershell and found this as the easiest:
(gwmi -class Win32_OperatingSystem).name
Which returns a line like:
Microsoft Windows 7 Enterprise |C:\Windows|\Device\Harddisk0\Partition2
if you want version numbers etc., use a verbose form like
gwmi -class Win32_OperatingSystem | FL *
and pick out what you need