哪个子程序调用了这个子程序?

10

有没有人知道如何在 中进行堆栈跟踪。我想做类似于:

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调用,而不传递任何参数。在中,我只需显示堆栈,但我不知道在VBA中是否可能 - 有何想法?


你能解释一下为什么你需要这个吗? - Mitch Wheat
我有一些代码以调用函数的形式存在。在函数开始时,我会写入日志文件以表明函数已经启动。从我的某个用户那里,我可以看到这个函数在运行时被调用。我想要确定的是,这是否真的是情况,或者日志记录不起作用。 - Richard Spencer
将日志记录放置在 SUB a、b 和 c 中... - Mitch Wheat
1
我有这个,但它并没有解释为什么在Access 2007/2010上一个函数会被调用两次,而在Access 2003上只调用一次。这只发生在关闭数据库时。 - Richard Spencer
我建议使用F8一行一行地调试您的代码。它将在运行之前突出显示每行代码,因此您可以准确地看到它何时跳转到c()函数。 - PowerUser
使用调试并没有帮助,因为问题并没有发生在我们的任何开发或测试机器上,只是两台用户机器有此问题,而它们与其他10台机器的设置完全相同。我想要做的就是将堆栈转储到SQL Server的日志表中。 - Richard Spencer
4个回答

14

您可以在运行时通过菜单 View -> Call Stack 访问调用堆栈。

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

输入图像描述


1
没注意到这个。这很有帮助,但你有什么想法如何在代码中调用堆栈? - Richard Spencer

3
你可以使用 Mztools 插件,这个插件有一个查看过程调用者的选项。 下载 Mztools enter image description here

1
我不确定这个工具是否能解决OP的问题,但这是一个很棒的工具,我从你的答案中发现了它。 - hungry hippo
@hungryhippo 是的,实际上这是我最喜欢的 VBA 插件。 - Santosh

0
我实现这个的方法是在每个VBA例程的开头和结尾都调用ProcedureEnter和ProcedureExit。ProcedureEnter例程有一个参数用于Sub/Function名称,该名称将存储在全局调用堆栈集合中。ProcedureExit只需从堆栈中弹出最后一个条目即可。
因此,要获取调用程序的名称,您只需获取Stack Collection.count - 1处的项。
我个人使用MZTools设置默认的VBA例程头/尾,这样我只需键入即可。
Function fnname(arg as whatever) as boolean
End Function

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


0
唯一的方法是从堆栈中获取调用子程序的返回地址指针。 VBA 不能直接执行此操作,您必须编写自己的库或使用其他需要知道这些信息的人提供的库。如果调用例程来自无法更新的程序,则这可能是值得的,但是如果这仅来自您自己的代码,则重新编写代码以识别调用方要容易得多。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接