哪个 SUB 正在调用这个 SUB

Posted

技术标签:

【中文标题】哪个 SUB 正在调用这个 SUB【英文标题】:Which SUB is calling this SUB 【发布时间】:2013-06-11 07:45:05 【问题描述】:

有没有人知道如何在access-vba 中进行堆栈跟踪。我正在尝试做类似的事情:

Public Sub a()   
    Call c    
End Sub    

Public Sub b()    
    Call c    
End Sub

Public Sub c()    
    Debug.Print "Which sub has called me ?"    
End Sub

我想在Sub c 中做的是显示Sub aSub b 是否已在不传递任何参数的情况下调用它。在c 中,我会简单地显示堆栈,但我不知道这在 VBA 中是否可行 - 有什么想法吗?

【问题讨论】:

你能解释一下为什么你需要这个...? 我有一些调用函数的形式的代码。在函数开始时,我写入日志文件以说明该函数已启动。从我的一个用户那里,我可以看到这个函数在它已经运行的时候被调用了。我想看看是不是真的是这种情况,或者日志记录不起作用。 在 SUB a、b 和 c 中进行登录 ... 我有,但它没有解释为什么一个函数在 Access 2007 / 2010 上被调用两次,但在 Access 2003 上它只被调用一次。这仅在您关闭数据库时发生 我建议使用 F8 一次通过您的代码一行。它会在运行之前突出显示每一行代码,因此您可以准确地看到它何时跳转到 c()。 【参考方案1】:

你可以在运行时在菜单View->Call Stack下访问调用栈

您也可以在运行时使用键盘快捷键 CTRL+L

【讨论】:

没发现。这对我如何在代码中进行堆栈调用有帮助吗?【参考方案2】:

您可以使用 Mztools 插件,它有一个选项来查看过程调用者。 Download Mztools

【讨论】:

我不确定这个实用程序是否能解决 OP 的问题,但这是我从你的回答中发现的一个了不起的工具。 @hungryhippo 实际上是的,它是我最喜欢的 VBA 插件,【参考方案3】:

你能知道的唯一方法是从堆栈中获取调用子例程的返回地址指针。 VBA 不会直接这样做,您必须编写自己的库或从需要了解这些内容的其他人那里获得库。如果调用例程来自您无法更新的程序,这可能是值得的,但是如果这只是来自您自己的代码,则重写代码以识别调用者要容易得多。

【讨论】:

【参考方案4】:

我这样做的方法是在我拥有的每个 VBA 例程的开头和结尾调用 ProcedureEnter 和 ProcedureExit。 ProcedureEnter 例程有一个 Sub/Function 名称的参数,该参数存储在全局调用堆栈集合中。 ProcedureExit 只是从堆栈中弹出最后一个条目。

因此,要获取调用者例程名称,您只需获取堆栈集合中的项目 .count - 1

我个人使用 MZTools 设置了一个默认的 VBA 例程页眉/页脚,所以我只需键入

Function fnname(arg as whatever) as boolean
End Function

然后单击 MZTools 中的添加错误处理程序按钮,它会为我添加 ProcedureEnter 和 ProcedureExit 调用。这使得添加堆栈跟踪代码变得不那么麻烦。

【讨论】:

以上是关于哪个 SUB 正在调用这个 SUB的主要内容,如果未能解决你的问题,请参考以下文章

从 Google Pub/Sub 调用 Google App Engine 端点

从 vba 中的 sub 调用函数

未调用 Sub-ViewController 上的 TouchesBegan

如何在不传递预期参数但使用它已有的参数的情况下调用 sub?

从同一个线程多次调用 sub

子调用第一个子但不调用第二个子