如何判断是否从即时窗口调用Sub

时间:2017-05-22 08:49:51

标签: vba excel-vba immediate-window excel

有些潜艇我只想从即时窗口运行,就像这个风险稍大的那个:

Public Sub clear()

Application.SendKeys "^a", True
Application.SendKeys "{delete}", True

End Sub

万一你无法解决问题;它将 ctrl + a Del 发送到应用程序,并具有清除当前光标周围的任何内容的效果。

我通过键入clear在即时窗口中使用它,并删除了即时窗口中的所有内容。

正如你可能知道的那样,这个Sub非常危险并且不小心打电话。因此,当从立即窗口调用时,我希望它只运行

  • 不是来自另一个Sub
  • 不是来自表单控件
  • 不是来自ActiveX(虽然那实际上只是一个子)
  • 不是来自用户电话(通过开发人员/宏标签)

而且不是来自任何其他来源(我已经列出了所有这些,因为我认为即使你不能直接告诉它是由直接窗口调用的,你也许可以通过排除其他来间接告诉选项)

这可以以编程方式进行吗?理想情况下,我只想在我的clear() sub的开头进行简单的布尔检查,告诉它除了立即窗口调用之外什么都不做。

N.B。

一条路线可能是通过使用调用堆栈 ctrl + L 打开对话框),因为我立即注意到调用不会在堆栈中留下任何痕迹,而列出调用clear()的子列表,因此可以排除。但我不确定如何通过VBA访问它

3 个答案:

答案 0 :(得分:1)

一个简单的解决方案是添加一个参数

Public Sub clear(sCaller As String)

If sCaller = "Immediate" Then
    Application.SendKeys "^a", True
    Application.SendKeys "{delete}", True
End If

End Sub

这可能也不是你想要的,但显然会降低风险

答案 1 :(得分:0)

我知道这不是你问题的答案,但是如果你想“清除”你的直接窗口,这就是我的用法:

Sub clear()
For i = 0 To 100
    Debug.Print ""
Next i
End Sub

答案 2 :(得分:0)

我找到了一种结合了一些想法的方法:

Public Sub clear(Optional s As Variant)

If TypeName(Application.Caller) = "Error" And IsMissing(s) = False Then
'Do code
End If

End Sub

如果从一个范围(仅限函数)或一个按钮调用一个子,那么TypeName测试会捕获这个子,因为这些将返回Range和{{1} } 分别。错误选项是即时窗口,Sub或用户调用。用户无法提供额外的参数,因此排除了这一点。最后,我们希望子调用不包含参数。

Strings,因此您可以在即时窗口中输入Variant,而不必将clear whatever放入watever(表示文字)

显然可以通过适当的论证使其更安全。显然它并不理想,因为 hope 这个词的意思是显示出来!当然,它也没有真正回答这个问题。