【发布时间】:2018-06-06 15:35:26
【问题描述】:
在将 Excel VBA 应用程序转换为 VB.NET 的过程中,我知道我不能在 DLL 中使用 End 语句,因为它只能由启动它的进程停止。相反,DLL 似乎必须引发要由 Excel 中的 VBA 代码处理的事件。
我认为除了应该检测到引发事件以立即停止执行的部分之外,它大部分都可以正常工作。到目前为止,这是我得到的:
VBA调用的DLL过程:
Public Class Class1
Sub DLLentry()
Dim ClStop As New ClassStop
AddHandler StopExecution, AddressOf ClStop.stopExec
DLLprocedure1()
End Sub
End Class
执行大部分操作的过程:
Module Module1
Public Event StopExecution()
Sub DLLprocedure1()
'Operations that in certain circumstances must stop the execution
RaiseEvent StopExecution()
End Sub
End Module
应该将引发的事件传递给 Excel 的类:
Imports System.Runtime.InteropServices
<ComVisible(True)>
<InterfaceType(ComInterfaceType.InterfaceIsIDispatch)>
<Guid("28C7DCE1-90EF-4a30-AF7F-4187F9FFFDEB")>
Public Interface ICoreEvents
<DispId(1)>
Sub StopExecutionCl()
End Interface
<ComVisible(True)>
<InterfaceType(ComInterfaceType.InterfaceIsDual)>
<Guid("86CE5E8D-777D-4cd5-8A7D-7F58737F1DB4")>
Public Interface ICore
Sub stopExec()
End Interface
<ComVisible(True)>
<ClassInterface(ClassInterfaceType.None)>
<ComDefaultInterface(GetType(ICore))>
<ComSourceInterfaces(GetType(ICoreEvents))>
<Guid("C58721B1-15B3-4eeb-9E1E-BCDA33D38EE6")>
Public Class ClassStop
Implements ICore
<ComVisible(False)>
Public Delegate Sub OnStopExecutionCl()
Public Event StopExecutionCl As OnStopExecutionCl
Sub stopExec() Implements ICore.stopExec
MsgBox("Checkpoint 1")
RaiseEvent StopExecutionCl()
End Sub
End Class
在 Excel 的 VBA 中,我在开始执行的过程中有一个模块:
Sub StartingProcedure()
Dim oMyApp1 As New Class1
Call oMyApp1.activateEvent
Dim oMyApp2 As New DLLname.Class1
Call oMyApp2.DLLentry
End Sub
还有一个应该捕获事件并停止执行的类模块:
Public WithEvents cls1 As DLLname.ClassStop
Private Sub cls1_StopExecutionCl()
MsgBox "Checkpoint 2"
End
End Sub
Public Sub activateEvent()
Set cls1 = New DLLname.ClassStop
End Sub
DLL“DLLname.dll”注册为 COM 并在 Excel 中引用。我知道 Excel 可以正确检测到 DLL 中的事件声明,因为我可以从类模块的下拉菜单中选择它。
问题是即使多次到达“检查点 1”(引发事件),也没有到达“检查点 2”。
我错过了什么?这是实现我想要的最佳方式吗?
附:我不确定,但我不能抑制 Guid 定义和 Interface ICore 吗?
【问题讨论】:
-
不确定我是否完全按照,因为我从来没有这样做过,但你的事件处理 VBA 类实例中的 DLL 对象实例
cls1与oMyApp2不同吗? /跨度> -
@TimWilliams 是的,它们指的是 DLL 中的不同类。我试图通过将过程
DLLentry移动到ClassStop使其成为一个类,从而消除Class1,但结果是一样的。 -
在DLL的不同instances中它们不是不同的类吗?
-
@TimWilliams 你是对的。我不太了解不同实例的概念。我替换为
Call oMyApp1.cls1.DLLentry,现在它可以工作了。谢谢!