3

我在 MSScriptControl 上阅读的所有文档都说它可以响应添加到它的对象的事件。

脚本控件允许您编写在对象上发生事件时自动触发的脚本。 https://msdn.microsoft.com/en-us/library/ms974586.aspx

ScriptControl 将能够接收由使用 AddObject 方法添加的对象生成的事件。 http://flylib.com/books/en/1.492.1.154/1/

但我这样做没有成功。我假设这意味着 ScriptControl 内的代码将在添加的对象引发它的事件时触发。我无法让任何人工作。

寻找将任何对象添加到 ScriptControl 并处理由该控件触发的事件的示例代码。不要关心对象是自定义类、窗体、控件还是内置 Excel 对象(如 Worksheet)。

在 Win Server 2008 64 位上运行 Office 2010 32 位。

对替代方法持开放态度,例如 WSH,但 Tushar Mehta 在这里没有成功http://dailydoseofexcel.com/archives/2009/08/19/using-vbscript-to-monitor-office-eventsor-not/

我已成功将 Excel Application 对象添加到 ScriptControl,并在 Excel Application 对象上执行了代码:

这没问题:

Function TestProc()
          Dim oScriptCtl As New MSScriptControl.ScriptControl

          With oScriptCtl
                    ' init
                    .Language = "VBScript"
                    .AllowUI = True

                    ' add Excel application object
                    .AddObject "app", Application, True

                    ' add procedure
                    Dim sCode As String
                    sCode = "Sub TestProc : MsgBox ""hi"" : End Sub"
                    .AddCode sCode

                    ' run procedure. Msgbox displays. 
                    .Run "TestProc"
          End With

          ' cleanup
          Set oScriptCtl = Nothing
End Function

失败:

在这个测试中,m_oScriptCtl 是一个模块范围的变量。当我单击表单时没有任何反应:

Function TestForm()
          Set m_oScriptCtl = New MSScriptControl.ScriptControl

          With m_oScriptCtl
                    ' init
                    .Language = "VBScript"
                    .AllowUI = True

                    MyForm.Show False

                    .AddObject "app", Application, True
                    .AddObject "frm", MyForm, True
                    .State = Connected

                    Dim sCode As String
                    sCode = "Sub frm_Click():   MsgBox Chr(14):   End Sub"
                    .AddCode sCode
          End With
End Function

下一个在 .AddCode 上报告以下错误:

预期的 ')'

Function TestSheet()
          Set m_oScriptCtl = New MSScriptControl.ScriptControl

          With m_oScriptCtl
                    ' init
                    .Language = "VBScript"
                    .AllowUI = True

                    .AddObject "app", Application, True
                    .AddObject "sheet", Sheet2, True
                    .State = Connected

                    Dim sCode As String
                    sCode = "Private Sub sheet_Change(ByVal Target As Range): MsgBox Target: End Sub"
                    .AddCode sCode
          End With
End Function

在接下来的测试中,MyClass 被定义为:

Public Event MyEvent()

Public Sub TestEvent()
          RaiseEvent MyEvent
End Sub

但以下报告在 .Run 上“对象不支持属性或方法”。所以在这种情况下,失败的不是事件——我只是无法在类中运行方法。

Function TestClassEvent()
          Set oScriptCtl = New MSScriptControl.ScriptControl

          Dim oClass As New MyClass

          With oScriptCtl
                    ' init
                    .Language = "VBScript"
                    .AllowUI = True

                    ' add objects
                    .AddObject "app", Application, True
                    .AddObject "oClass", oClass, True
                    .State = Connected

                    ' add code
                    Dim sCode As String
                    sCode = "Sub oClass_MyEvent() : MsgBox vbNullString : End Sub"
                    .AddCode sCode

                    .Run "oClass.TestEvent"
          End With

          ' cleanup
          Set oScriptCtl = Nothing
End Function

线索:

有人发帖:

如果您完全无法接收事件,请尝试调用 'ScriptControl1.Modules("Global").CodeObject.Name_Of_Your_Event(ParameterList)' http://computer-programming-forum.com/59-vbscript/4b059f9f6eacfaf0.htm

- 但我不清楚这种解决方法:事件过程不应该被明确地“调用”,它们应该只是触发。TestClassEvent在上面的示例中,以下几行都给出了“找不到方法或数据成员” :

m_oScriptCtl.Modules("Global").CodeObject.MyEvent
m_oScriptCtl.Modules("Global").CodeObject.TestEvent

我没有测试以下内容,因为我不太确定如何:

脚本控件无法处理来自与其在 https://diigo.com/08we68中托管的应用程序相同项目中的类的事件

不确定以下是否相关,不太明白: http: //www.programmersheaven.com/discussion/79452/me-activecontrol-and-events

4

1 回答 1

1

使其工作的关键是:您必须在将两者都添加到脚本控件之后在侦听器类中设置事件触发对象意思是,这一行必须在 SC 内部执行:

Set oListener.EventFiringObject = oEventFiringObject

这是一个触发和响应脚本控件内对象之间事件的工作示例。

在这个例子中:

  • 我演示了 2 种事件触发对象:自定义类和工作表。
  • 自定义类在添加到脚本控件(“sc”)之前被实例化。
  • 我在自定义 sc 对象中调用了一个方法。

设置演示

  • 开始一个新项目(即,在 Excel 中添加一个新工作簿)。
  • 在您的 VB IDE 中,添加对Microsoft Script Control 的引用。
  • 创建以下 VB 组件:

代码

clsSheetListener

Public WithEvents oSht As Worksheet

Private Sub oSht_Change(ByVal Target As Range)
  ' show  changed cell
  MsgBox "Sheet Listener" & vbCrLf & "Changed: " & Target.Address _
          & vbCrLf & Target.Cells(1).Value2
End Sub

clsEventClass

Public Event MyEvent(sCaller As String)

Public Sub Raise_MyEvent(sCaller As String)
  RaiseEvent MyEvent(sCaller)
End Sub

clsClassListener

Public WithEvents m_oEventClass As clsEventClass

Private Sub m_oEventClass_MyEvent(sCaller As String)
  ' show my execution-scope
  MsgBox "Class Listener, " & sCaller & " caller"
End Sub

模块Module1

Function Main()
  ' init scriptcontrol
  Set m_oScriptCtl = Nothing
  Set m_oScriptCtl = New MSScriptControl.ScriptControl
  With m_oScriptCtl
    .Language = "VBScript"
    .AllowUI = True

    ' add Excel application object, needed for all Excel methods in script-control
    .AddObject "sc_Application", Application, True


    ' add Sheet2 to the sc
    ' code executed in sc refers to objects by name, as defined in .AddObject
    .AddObject "sc_oSheet", Sheet2, True

    ' init sheet event-listener, and add to sc
    Dim oSheetListener As New clsSheetistener
    .AddObject "sc_oSheetListener", oSheetListener, True

    ' register the sheet-object with its listener in the scriptcontrol
    ' so the listener can hear the sheet's events
    .ExecuteStatement "Set sc_oSheetListener.oSht = sc_oSheet"


    ' init custom event-firing class object, and add to sc
    Dim oEventClass As New clsEventClass
    .AddObject "sc_oEventClass", oEventClass, True

    ' init class-event listener, and add to sc
    Dim oClassListener As New clsClassListener
    .AddObject "sc_oClassListener", oClassListener, True

    ' register event-firing object with its listener inside the Script Control
    ' so the listener can hear the object's events
    .ExecuteStatement "Set sc_oClassListener.m_oEventClass = sc_oEventClass"


    ' cause event to be raised. 
    ' Call from local context, then sc-context.
    ' it's the same object instance in both cases
    oEventClass.Raise_MyEvent "Local"
    .ExecuteStatement "sc_oEventClass.Raise_MyEvent ""SC"""

  End With
End Function

测试

一步通过Main()。您将看到何时Raise_MyEvent触发MyEvent,使用消息框响应事件clsEventClassclsClassListener

现在切换到 Excel 前端,并在 Sheet2 的单元格中输入一个值。您将看到使用消息框clsSheetListener响应事件。Change

于 2016-09-18T14:07:49.853 回答