生成每个可能的VBA引用GUID的列表
我有一个Access数据库,我在Access 2016中创build。我有一些VBA代码需要在Access 2016中的一些库。大多数其他用户有不同的老年版本的Access。
例如,我需要运行代码的一个库是Microsoft Access 16.0 Object Library
。 许多用户正在运行Office 2013,它具有Microsoft Access 15.0 Object Library
而不是16.0。
我需要以编程方式在运行VBA代码时添加此版本的库。 这将需要我知道我一直无法在网上find的GUID。 我研究过的所有其他领域告诉你如何得到你已经激活的库的GUID,但是这对我不起作用,因为我不能使用或罚款15.0库。
我怎样才能find这个库的GUID和其他库我没有活动或安装?
安装15.0时以编程方式添加16.0可能只会导致更多的崩溃,并不会解决您的问题。
早期绑定的代码(即带有对types库的项目引用)是特定于版本的,这意味着如果用户正在运行不同的版本,则可能会出现问题。
后期绑定的代码(即没有对types库的项目引用)不是特定于版本的:如果用户正在运行不同的版本,则后期绑定的调用将在运行时parsing为存在于无论你的用户运行什么版本。 如果存在 。
最后一点是关键:如果你的代码使用只存在于16.0库中的function,那么你可以期待运行时错误438“对象不支持这个属性或方法”抛在你的用户面上。 因此, 编写代码以便它可以在最低的可用版本上运行 。
如果您不知道版本之间有哪些API差异,那么您唯一的希望就是使用用户的最早版本进行开发 。
用早期的声明和调用写你的代码; 这样你可以获得智能感知和自动完成function,你可以浏览对象浏览器 (F2)来探索可用的function。
避免使用types库中存在的枚举和常量:声明自己的属性,并复制基础值( 对象浏览器非常适合)。 一旦你切换到后期绑定的代码,这些枚举和常量将不再被定义,除非你自己定义它们。 确保指定了Option Explicit ,这样如果你碰巧在某个地方忘记了某个地方,就会得到一个编译时错误,而不是在运行时静静地传递一个错误的值,并且遇到奇怪的,难以debugging的行为。
当您准备好部署时,注释掉所有Dim accApp As Access.Application
和其他早期的声明; 用Dim accApp As Object
( Object
是什么使得调用在运行时被延迟/parsing)。
然后使用CreateObject
调用replace所有Set foo = New XYZ
赋值,例如Set accApp = New Access.Application
将被Set accApp = CreateObject("Access.Application")
。 这是什么指示运行时去registry来找出该ProgID的types库可能在哪里。 如果用户的机器上没有ProgID,事情就会在运行时炸毁。
至于所问的问题, Ross Knudsen的Kavod.ComReflection GitHub存储库包含一些线索:
private static IEnumerable<ComTypeRegistryEntry> GetComTypeRegistryEntries() { using (var clsidRootKey = Registry.ClassesRoot.OpenSubKey("TypeLib")) { if (clsidRootKey == null) { yield break; } foreach (var typeLibKey in EnumerateSubKeys(clsidRootKey)) { var currentTypeLib = GetCurrentKeyName(typeLibKey); Guid clsid; if (!Guid.TryParseExact(currentTypeLib, "B", out clsid)) { Debug.WriteLine($"Couldn't parse CLSID = {currentTypeLib}"); continue; } foreach (var entry in EnumerateRegistryEntryVersions(typeLibKey, clsid)) yield return entry; } } }
如果您确实想获取所有注册types库及其各自的GUID列表,则需要扫描Windowsregistry的ClassesRoot
节点并find所有TypeLib
子项。 这在VBA中实现起来可能相当有趣,但IMO对于你所要做的事情不是很有用。
除非您的计算机上安装了Office 2013,否则您将无法访问Microsoft Access 15.0 Object Library
。 同样,除非您的用户安装了Office 2016,否则他们将无法访问Microsoft Access 16.0 Object Library
。 但是,如果您拥有Office 2016,则引用Microsoft Access 15.0 Object Library
vba
代码仍然可以工作。
所以正如我在评论中所说的,当涉及到Office时,您需要以最低的共同点开发您的vba
。 即如果你最早的Access版本是2010,那么你需要在2010年开发。
此外, 14.0 Object Library
将工作15.0 Object Library
将适用于16.0 Object Library
等,而不是反过来。 所以,如您所见,如果您在Office 2010中开发了某些function,则应该在2016年仍能正常工作。至less,您不应该有任何库参考问题。
警告编辑
只记得我试图debugging一些代码的时候真棒 。 如果您在Office 2013中开发并保存macros文档,然后使用Office 2016更改文档并保存,Office将自动select它认为Object Library
的正确版本为16.0
。 这将使macros文档对您的Office 2013用户无用 。
一个简单的解决scheme(但可能不是你正在寻找的),就是先像你一样开发它,然后在部署之前,将这些声明转换为CreateObject调用。
像这样的东西:
' Normal way Dim A As Excel.Worksheet ' With CreateObject Dim B As Object Set B = CreateObject("Excel.Worksheet")
对这样的代码进行故障排除是非常痛苦的,所以请保持旧的声明。