首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >以编程方式确定OnClick事件的事件处理程序

以编程方式确定OnClick事件的事件处理程序
EN

Stack Overflow用户
提问于 2017-09-21 01:59:55
回答 2查看 1.8K关注 0票数 1

我正在开发一个在MS Access VBA中跟踪执行路径的应用程序。然而,我遇到了一个问题。似乎您可以动态分配处理程序来控制OnClick和其他类似的事件,但我看不到从这些控件中读取事件的方法。例如:

代码语言:javascript
代码运行次数:0
运行
复制
With Forms("Order Entry").Controls("OK") 
 If .OnClick = "" Then 
 .OnClick = "fnProcessOrder" 
 End If 
End With 

这会动态地将函数"fnProcessOrder“分配给"OK”按钮。但是,如果您尝试获取该按钮的值,则会得到以下结果:

代码语言:javascript
代码运行次数:0
运行
复制
With Forms("Order Entry").Controls("OK") 
  Debug.Print "My Handler -->" + .OnClick
EndWith

结果如下:

代码语言:javascript
代码运行次数:0
运行
复制
--> [Event Procedure]

没有更多细节。这似乎是微软在这里陈述的行为:https://msdn.microsoft.com/en-us/vba/access-vba/articles/commandbutton-onclick-property-access

但我想知道有没有比这更进一步的方法。

我本以为这些信息会出现在MSysObjects和MSysQueries表中,但我没有看到。我已经尝试使用database Documenter提取我的测试数据库,我也从生成的文档中获得该值。

有没有办法找到分配给控件的VBA函数?

EN

回答 2

Stack Overflow用户

发布于 2017-09-21 03:03:41

实际上,代码在我看来并不正确。如果要将VBA函数赋给事件过程,则必须使用类似以下语法:.OnClick = "=fnProcess()"请注意文字=() --它们是使Access识别您要调用的函数所必需的。

作为额外的考虑,您可以有一个类模块(让我们称它为Observer),它的代码类似于:

代码语言:javascript
代码运行次数:0
运行
复制
Private WithEvents ctlInterest As Access.Textbox

Public Sub Init(TargetControl As Access.Control)
  Set ctlInterest = TargetControl
  With ctlInterst
    If .OnClick = "" Then
      .OnClick = "[Event Procedure]"
    End If
  End With
End Sub

Private ctlInterest_OnClick()
  fnProcess()
End Sub

然后您可以像这样以这样的形式部署类。

代码语言:javascript
代码运行次数:0
运行
复制
Private objObserver As Observer

Private Sub Form_Load()
  Set objObserver = New Observer
  objObserver.Init(Me.txtInterest)
End Sub   

这将产生相同的结果,并最终得到多个事件处理程序。

有关更多信息,this可能会有所帮助。

由于函数表达式是可能的,并且可以在任何时候动态赋值,因此通常需要代码路径分析来确定所有事件处理程序的可能入口点。这意味着你需要Rubberduck的解析器,注意静态代码路径分析已经计划好了,但还没有实现,AIUI。

此外,我希望确保--如果您的意图是构建用于错误处理的调用堆栈跟踪,则可能需要查看第三方插件。例如,商业产品vbWatchDog可以在VBA语言中提供这些信息。

票数 1
EN

Stack Overflow用户

发布于 2017-09-21 03:48:13

这将返回事件的完整代码。如果你只在事件中使用一个sub,它应该可以工作。

代码语言:javascript
代码运行次数:0
运行
复制
Public Sub TestModulePrinter()
    Dim subName As String
    With Forms("Order Entry").Controls("OK")
      subName = "Private Sub " & .Name & "_OnClick()"
    End With
    Dim i As Long
    Dim IsPrinting As Boolean
    With Forms("Order Entry").Module
        For i = 1 To .CountOfLines
            If Not IsPrinting Then
                If Trim(.Lines(i, 1)) = subName Then
                    IsPrinting = True
                End If
            Else
                If Trim(.Lines(i, 1)) = "End Sub" Then
                    IsPrinting = False
                Else
                    Debug.Print .Lines(i, 1)
                End If
            End If
        Next i
    End With
End Sub
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46328853

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档