3

我喜欢在我的 VBA 项目中使用早期绑定,因为我喜欢在开发过程中自动完成方法名称等。我也喜欢知道如果我拼错了方法名,编译器会警告我的信心。

但是,要使用早期绑定,我需要添加对相关库的引用(例如,“Microsoft Scripting Runtime”)。这对于像这样的“标准”库来说很好,但有时我想使用用户机器上可能存在或不存在的库。

理想情况下,如果库不存在,我想显示一条有用的消息(例如“此计算机上未安装 xyz,因此无法使用此功能”)。如果我只使用后期绑定,那么我可以这样做:

Dim o As Object
Set o = CreateObject("foo", "bar")

If o Is Nothing Then
    MsgBox "nope"
End If

但是,如果我添加了对该库的引用以使用早期绑定,那么如果该库不存在,则在加载 VBA 项目时会出现编译错误。因此,没有代码运行(包括检测库不存在的代码)。

这个catch-22有什么办法吗?

4

2 回答 2

6

您可以创建一个类模块作为对象库的代理 --- 包装您的其他过程所需的所有方法、属性和常量。

所有这些过程都将以相同的方式使用代理类,因此您无需修改​​这些过程即可在早期绑定和后期绑定之间切换。Intellisense 会向您展示您使用代理类公开的所有内容。

该类将是在早期绑定和后期绑定之间切换的单点控制。您提到 Excel 作为一个例子:

#Const DevStatus = "PROD"
#If DevStatus = "DEV" Then
    Private objApp As Excel.Application
    Private objBook As Excel.Workbook
    Private objSheet As Excel.Worksheet
#Else 'assume PROD
    Private objApp As Object
    Private objBook As Object
    Private objSheet As Object
#End If

如果 Excel 可能未安装在任何用户的计算机上,您可以在类初始化期间检查其可用性。

Dim blnExcelAvailable As Boolean

Private Sub Class_Initialize()
    blnExcelAvailable = IsExcelAvailable()
End Sub

Private Function IsExcelAvailable() As Boolean
    Dim blnReturn As Boolean
    Dim objTest As Object

On Error GoTo ErrorHandler

    Set objTest = CreateObject("Excel.Application")
    blnReturn = True

ExitHere:
    On Error GoTo 0
    Set objTest = Nothing
    IsExcelAvailable = blnReturn
    Exit Function

ErrorHandler:
    blnReturn = False
    GoTo ExitHere
End Function

然后使用代理类的程序可以检查属性以查看 Excel 是否可用。

Public Property Get ExcelAvailable() As Boolean
    ExcelAvailable = blnExcelAvailable
End Property

我认为这种方法是可能的,并且满足您对 AFAICT 的要求。但是,我不确定这是否合理。回到 Excel 的示例,您可以对其对象模型的可管理子集执行类似的操作。但是,如果您需要它的全部或大部分方法、属性和常量,代理类将是一项艰巨的任务。

我个人不会使用这种方法。像 mwolfe02 和 JP 一样管理早期/晚期绑定对我来说工作量较小。描述。但是我的印象是,这在您的情况下更加繁重,因此也许您愿意比我在这样的事情上投入更多的精力。

于 2012-01-19T05:58:29.103 回答
3

并不真地。

但是,我在开发中处理此问题的一种方法是有两个单独的声明行。我根据我是在做开发工作还是发布到生产环境来评论一个或另一个。您可以不理会其他所有内容(包括该CreateObject行),然后您只需要记住切换注释行并添加/删除引用本身。

例如:

Dim o As foo.bar   'Comment out for production'
'Dim o As Object    ''Comment out for dev work'
Set o = CreateObject("foo", "bar")

If o Is Nothing Then
    MsgBox "nope"
End If
于 2012-01-18T14:38:23.240 回答