生成每个可能的VBA引用GUID的列表

J. *_*Cal 1 excel vba excel-vba access-vba office365

我有一个我在Access 2016中创建的Access数据库.我有一些VBA代码需要Access 2016中的一些库.大多数其他用户具有不同的旧版Access.

例如,我需要运行代码的一个库是Microsoft Access 16.0 Object Library.许多用户正在运行Office 2013,而Microsoft Access 15.0 Object Library不是16.0.

我需要以编程方式在运行VBA代码时添加此版本的库.这需要我知道GUID,我无法在网上找到.我研究过的所有其他领域都告诉你如何获得你活跃的图书馆的GUID,但这对我不起作用,因为我不能使用或罚款15.0库.

如何找到此库的GUID,以及我没有活动或安装的其他库?

Mat*_*don 6

安装15.0时以编程方式添加16.0可能只会导致更多崩溃,并且无法解决您的问题.

早期绑定代码(即对类型库的项目引用)是特定于版本的,这意味着如果您的用户运行的是其他版本,则可能会出现问题.

后期绑定代码(即没有对类型库的项目引用)不是特定于版本的:如果您的用户运行的是其他版本,则后期绑定调用将在运行时解析为存在于您的用户运行的任何版本.如果它存在.

最后一点是关键:如果您的代码使用仅存在于16.0库中的功能,那么无论如何,您都可以预期运行时错误438"对象不支持此属性或方法".因此,编写代码以便它可以在最低的可用版本上运行.

如果您不知道版本之间存在哪些API差异,那么您唯一的希望是使用用户最早的版本进行开发.


用早期声明和调用编写代码; 通过这种方式,您可以获得IntelliSense和自动完成功能,并且可以浏览对象浏览器(F2)以探索可用的内容.

避免使用类型库中存在的枚举和常量:改为声明自己的,并复制基础值(对象浏览器非常适用于此).切换到后期绑定代码后,将不再定义这些枚举和常量,除非您自己定义它们.确保指定了Option Explicit,这样如果你碰巧忘了某个地方,你会得到一个编译时错误告诉它,而不是在运行时默默地传递一个错误的值并遇到奇怪的,难以调试的行为.

当你准备好部署时,注释掉所有Dim accApp As Access.Application和其他早期声明; 替换为Dim accApp As Object(Object是什么使得调用在运行时后期绑定/解析).

然后更换所有Set foo = New XYZ与任务CreateObject调用,例如Set accApp = New Access.Application会Set accApp = CreateObject("Access.Application").这是指示运行时命中注册表以确定该ProgID的类型库可能位于何处的内容.如果用户的计算机上不存在该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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您确实想要获取所有已注册类型库及其各自GUID的列表,则需要扫描Windows注册表的ClassesRoot节点并找到所有TypeLib子项.在VBA中实现这可能非常有趣,但IMO对于您正在尝试的操作并不是非常有用.