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



有些子我只想从直接窗口运行,比如这个有点风险的:

Public Sub clear()
Application.SendKeys "^a", True
Application.SendKeys "{delete}", True
End Sub

如果你无法解决它;它将ctrl+aDel发送到应用程序,并具有清除光标周围的任何内容的效果。

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

正如你可能知道的那样,这个潜艇非常危险,而且相对容易意外调用。因此,我希望仅在从即时窗口调用时才运行它

  • 不是来自另一个子
  • 不是来自窗体控件
  • 不是来自ActiveX(尽管这实际上只是一个子)
  • 不是来自用户调用(通过"开发人员/宏"选项卡)

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

这可以通过编程方式完成吗?理想情况下,我只想在clear()子的开头进行一个简单的布尔检查,告诉它除非被即时窗口调用,否则什么都不做。

<小时 />

注意

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

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

Public Sub clear(sCaller As String)
If sCaller = "Immediate" Then
Application.SendKeys "^a", True
Application.SendKeys "{delete}", True
End If
End Sub

这可能也不是您想要的,但显然可以将风险降至最低

我知道这不是您问题的答案,但是如果您想"清除"您的直接窗口,这就是我使用的:

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

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

Public Sub clear(Optional s As Variant)
If TypeName(Application.Caller) = "Error" And IsMissing(s) = False Then
'Do code
End If
End Sub

正在发生的事情是,如果从范围(仅函数)或按钮调用 sub,那么这会被TypeName测试捕获,因为它们将分别返回RangeString。错误选项包括即时窗口、Sub 或用户调用。用户无法给出额外的参数,因此排除了这种可能性。最后,我们希望子调用不会包含参数。

sVariant,以便您可以在即时窗口中键入clear whatever,而不必将watever放在"中(表示文本)。

显然,通过适当的论证可以变得更加安全。显然,这并不理想,因为希望这个词旨在显示!当然,它也没有真正回答这个问题。

最新更新