如何在Microsoft脚本控件中实现事件?

时间:2016-09-17 00:50:14

标签: excel vba vbscript scriptcontrol msscriptcontrol

我在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 64bit上运行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("全球&#34)CodeObject.Name_Of_Your_Event(参数列表)&#39。   http://computer-programming-forum.com/59-vbscript/4b059f9f6eacfaf0.htm

- 但是这个解决方法对我来说并不清楚:事件程序不应该被称为"#34;显然,他们应该只是开枪。以下几行都给出了"方法或数据成员未找到",在上面的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

1 个答案:

答案 0 :(得分:1)

使其工作的关键是 :在添加后,必须在侦听器类中设置event-firing-object脚本控制 - 而不是之前。意思是,这一行必须在SC内部执行:

Set oListener.EventFiringObject = oEventFiringObject

这是解决脚本控件中对象之间事件的触发和响应的工作示例。

在这个例子中:

  • 我演示了两种事件触发对象:自定义类和工作表。
  • 自定义类在将其添加到scriptcontrol之前进行实例化(" 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 clsSheetListener Changeandroid:theme="@android:style/Theme.Translucent.NoTitleBar" 时,您会看到library(data.table) library(lubridate) dt <- data.table(x) # date should not be factors dt[, Date.y := ymd(Date.y)] setorder(dt, Account.Name, -Date.y) dt[, col_index := 0:(.N-1L), by = Account.Name] dt_casted <- dcast(dt, Account.Name ~ col_index, value.var = "EI") 消息响应事件。

现在切换到Excel前端,并在Sheet2的单元格中输入一个值。您会看到NSString *encoded = [self.link stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:encoded]]; self.webView.delegate = self; [self.webView loadRequest:request]; 通过消息框回复from sympy import Symbol, Matrix, Function, simplify eta = Symbol('eta') xi = Symbol('xi') x = Matrix([[xi],[eta]]) h = [Function('h_'+str(i+1))(x[0],x[1]) for i in range(3)] z = [Symbol('z_'+str(i+1)) for i in range(3)] lamb = 0 for i in range(3): lamb += 1/(2*sigma**2)*(z[i]-h[i])**2 simplify(lamb) 事件。