Cri*_*use 14 vba interface implements
对于较大的 VBA 项目(40,000 多行代码),我无法正确使用接口,因为应用程序(我主要使用 Excel)会经常崩溃。显然,这是因为代码不能保持编译状态(根据我的理解,VBA 代码被编译为 P 代码,稍后解释)。当 VBA 项目受密码保护时,我主要会得到这种行为。
该文章描述了同样的情况。转至第 2.3 节
例如:
IClass接口:
Option Explicit
Public Property Get SomeProperty() As Double
End Property
Run Code Online (Sandbox Code Playgroud)
Class1:
Option Explicit
Implements IClass
Private Property Get IClass_SomeProperty() As Double
IClass_SomeProperty = 0
End Property
Run Code Online (Sandbox Code Playgroud)
标准模块中的代码:
Option Explicit
Sub TestInterface()
Dim obj As IClass
Set obj = New Class1
Debug.Print obj.SomeProperty 'Crashes here on large projects only
End Sub
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,Debug.Print obj.SomeProperty如果项目很小,该行可以正常工作并在“立即”窗口中打印 0。但是,在大型项目中,调用此行时应用程序会崩溃。在IClass_SomeProperty没有达到(记录到文件阐明了这一点)。
正如上面提到的文章,有一些方法可以暂时避免这个问题:
Implementsstatements in the entire project using the Find/Replace window, then compiling and then reactivating the statements back. 同样,这可以工作几个小时或几天,但不可避免地会在不久的将来发生崩溃由于 VBA 项目受密码保护,并且许多人都在使用这些支持 VBA 的文档(在我的例子中是工作簿),应用临时修复程序根本没有帮助。
我发现避免崩溃并仍然获得接口好处的唯一方法是使用条件编译。基本上,我只将接口用于开发,然后切换到后期绑定用于生产。显然,这会带来很多麻烦。
上面的例子变成
Class1::
Option Explicit
#Const USE_INTERFACES = True
#If USE_INTERFACES Then
Implements IClass
#End If
Private Property Get IClass_SomeProperty() As Double
IClass_SomeProperty = Me.SomeProperty
End Property
Public Property Get SomeProperty() As Double
SomeProperty = 0
End Property
Run Code Online (Sandbox Code Playgroud)
请注意,所有接口方法都必须复制并公开,以便后期绑定成为一种选择。
标准模块中的代码:
Option Explicit
#Const USE_INTERFACES = True
Sub TestInterface()
#If USE_INTERFACES Then
Dim obj As IClass
#Else
Dim obj As Object
#End If
Set obj = New Class1
Debug.Print obj.SomeProperty
End Sub
Run Code Online (Sandbox Code Playgroud)
在开发新功能时,我遵循以下步骤:
#Const USE_INTERFACES = True使用查找所有出现/替换#Const USE_INTERFACES = False以便代码在后期绑定时运行并且不会崩溃我已经遇到这个错误至少 3 年了。如果可以的话,我显然会避免条件编译解决方法。
有没有办法在不访问VBA 项目对象模型的情况下保持 VBA 项目的编译(假设在打开文档时运行一个过程)?我不能选择打开对VBA 项目对象模型的信任访问。
我很欣赏这个错误不容易重新创建,除非您手头有一个大型 VBA 项目。
编辑 1
@PEH 在评论中提出了一个很好的观点:这个问题适用于xlsm和xlsb文件(Excel)。
我也开始使用接口(几年前),因为我认为它们是正确的 COM(而且它们确实是),但我也遇到了问题。所以,我停止使用它们。
除此之外,如果双击具有普通代码的方法,您会跳转到代码实现,但如果使用接口,您会跳转到一个空方法(这是不令人满意的)。
如果您确实有一个类 Foo,它表达了足以分解为单独接口 IBar 的不同行为,那么为什么不将 IBar 分解为实际的单独类 Bar,然后将 Bar 的实例设置为 Foo 的公共属性呢?
这只是一个建议。据我所知,没有其他 VBA 修复程序,而且 Microsoft 现在也不太可能修复此问题。
如果您想保留类/接口设计,您始终可以将代码迁移到 VisualBasic.Net。
如果有人真正解决这个问题,我会很高兴。
| 归档时间: |
|
| 查看次数: |
321 次 |
| 最近记录: |