如何使用VBA关闭当前打开的MsgBox?

3
有没有任何选项可以使用VBA访问表单应用程序中的任何代码关闭当前打开的MsgBox?
10个回答

6

请查看Randy Birch在microsoft.public.vb.general.discussion线程中的this回复。

他建议在.bas文件中创建一个名为MsgBox的函数。这样做将导致VB调用您的函数而不是内置函数。

然后,您将创建自己的MsgBox表单,并在其中设置定时器以在一定时间后关闭您的表单。他提供了显示如何执行此操作的链接。

他还讨论了一种显式调用内置MsgBox函数的方法,以防需要执行此操作。

注意:我从未这样做过,但我发现Randy Birch是一个知识渊博的资源。


1
只有当 MsgBox 是从您自己的代码中显示时,此方法才有效。如果它是 Access 原生的 MsgBox,则需要另一种方法。 - MarkJ
你可以从你的应用程序中挂钩另一个应用程序的消息框并关闭它。你可以从上面的资源中了解有关挂钩和消息框的信息。我已经做了1000次,并在他的网站上花费了几个星期的时间。 :) 避免像瘟疫一样使用sendkeys。对于系统上的用户来说,无法确定哪个应用程序最终会获得按键。 - Praesagus

3

MsgBox不能被编程关闭,因此关闭起来比较困难。如果你发现自己的设计必须强制关闭一个MsgBox,那么你应该重新评估你的设计。


基于Win32.dll的答案,实际上包括下面的计时器函数。 - Crazyd

1

我曾经有一个简单的答案:使用Windows脚本外壳对象,它具有“Popup”函数 - 一个消息框,就像VBA MsgBox()函数一样,具有“SecondsToWait”参数,可以提供你所需的超时时间。

With CreateObject("Scripting.WsShell")
    .Popup "Watch me disappear in 5 seconds", 5, Application.Name & ": test", vbInformation + vbOkCancel
End With

如果您包含一个“取消”按钮,它可能仍然有效:可用的参数是vbOkCancel、vbYesNoCancel和vbRetryCancel。
如果您试图关闭一个您没有使用自己的msgBox()函数调用启动的对话框框,那是不太有用的:而且,正如我上面暗示的,'SecondsToWait'参数现在并不真正起作用——Redmond中的某个人真的不喜欢一个线程关闭另一个线程的有用警告和重要中断用户工作流的想法。
但是,您可以使用API Timer()函数启动延迟的消息框“关闭”命令——不完全是“关闭当前打开的MsgBox”,因为这需要提前警告您打算打开它——但这是我拥有的最接近的东西,它适合于一个自包含的VBA模块,并且我已经在回答类似于您的StackOverflow问题时发布了代码
我应该警告您,问题中的答案是用大锤砸核桃,并附有冗长的解释。

1

我可能错了,但是MsgBox是一个阻塞调用,创建了一个模态窗体,所以我不认为有一种简单的方法来实现这个选项。你有具体的使用案例吗?


我不知道消息框从哪里弹出来,我不想分析它来自哪里,相反我想要杀掉它 :-) - Jaison
4
如果您想知道消息框从哪里弹出,请按“Ctrl + Break”查看原因并注释该调用。如果是第三方dll弹出框,则除非有某个属性使其“静默”,否则您可能无法做任何事情。 - Sébastien Nussbaumer
1
这也可能是由你触发的Access本地MsgBox。如果是这样的话,可能有另一种方法让Access“静音”。 - MarkJ
是的,你说得对:这是一个阻塞调用,并且没有简单的方法。当然,有一种困难的方法。 - Nigel Heffernan
有一个基于Win32的简单答案。我已经为您发布了它。 - Crazyd

1
正如MarkJ所指出的那样,这可能是由Access生成的对话框(而不是在您自己的代码中调用的VBA.MsgBox)?
例如,在使用表格的“数据视图”在Access UI中添加行时,您会收到一条消息:“您即将追加1条记录…”(或类似消息)。这是您所说的那种消息吗?如果是,确实有方法可以抑制它们...

0

与其从头开始编写替代Access MsgBox的代码,您可以考虑使用(或至少学习)Arvin Meyer的自定义消息框创建器(可在this page上下载)。


基于Win32的答案相当容易实现。我在我的数据库中使用dll来定位一些文件以进行导入。 - Crazyd

0

我曾经遇到过类似的问题;理论上你可以使用“SendKeys”函数(参见http://msdn.microsoft.com/en-us/library/8c6yea83%28VS.85%29.aspx)。然而,MsgBox会阻塞运行,因此您无法使用该命令。如果您知道它何时弹出,您可以从脚本中运行外部whshell等待一段时间,然后使用SendKeys。但是,如果您知道如何做到这一点,请告诉我(在这里)。另一个类似的可能性是为其打开不同的线程/进程,这将不会被阻止,但我不知道在VBA中是否可能。


0

消息框旨在向用户展示一些信息。因此,从程序上关闭它并不是一个好的设计,除非您没有自动化某个过程。

您可以使用sendkeys或win APIs。


我使用了以下代码来快速弹出提示信息,让我知道数据库将在后台执行操作,并可能会在一段时间内无响应。 - Crazyd

0

我知道这是一篇旧文章,但似乎现在有一个新的简单方法来做到这一点:

    Sub MessageBoxTimer()
    Dim AckTime As Integer, InfoBox As Object
    Set InfoBox = CreateObject("WScript.Shell")
    'Set the message box to close after 10 seconds
    AckTime = 10
    Select Case InfoBox.Popup("Click OK (this window closes automatically after 10 seconds).", _
    AckTime, "This is your Message Box", 0)
        Case 1, -1
            Exit Sub
    End Select
End Sub

代码示例提供者:Tom Urtis

https://learn.microsoft.com/en-us/office/vba/excel/concepts/controls-dialogboxes-forms/automatically-dismiss-a-message-box


0

一个易于使用的基于Win32的答案,实际上是有用的。使用下面的代码,您可以轻松地进行基于计时器的弹出框。我喜欢1/2秒计时器控制,所以2=1秒。在查找此线程的答案时发现了这个答案。以上答案似乎不起作用。当我想要显示快速消息或快速答案时,我想使用它,默认情况下通常是正确的,也可以用于更多。

函数代码通常在模块中:

Declare Function MessageBoxTimeout Lib "user32.dll" Alias "MessageBoxTimeoutA" ( _
    ByVal hwnd As Long, _
    ByVal lpText As String, _
    ByVal lpCaption As String, _
    ByVal uType As Long, _
    ByVal wLanguageID As Long, _
    ByVal lngMilliseconds As Long) As Long

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" ( _
    ByVal lpClassName As String, _
    ByVal lpWindowName As String) As Long

Public Function PopUpBox(Optional stMessage As String _
        = "Yes or No? leaving this window for 1 min is the same as clicking Yes.", _
        Optional stTitle As String = "PopUp Window", _
        Optional HalfSecTimer As Long = 120, Optional lgVBmsgType As Long = vbYesNo) As Long

    Dim RetVal As Long

    HalfSecTimer = HalfSecTimer * 500
    RetVal = MessageBoxTimeout(FindWindow(vbNullString, Title), stMessage, stTitle, lgVBmsgType, _ 
        0, HalfSecTimer)

    PopUpBox = RetVal
End Function

调用函数代码
示例:来自我的数据库的实际代码

PopUpBox "Re-Linking and Closing dB", "Closing dB", 3, vbOKOnly
intAnswer = PopUpBox("Software Lock Down Active?", "Security", 10, vbYesNo)

这会阻止调用函数吗?Title是什么? - Andre
标题 = VBA中的消息框或标题栏与msgbox命令相同。我的代码使用Windows代码库(Win32)创建消息框,并且它确实具有计时器选项。使用Win32,您可以完全实现所要求的内容。 - Crazyd

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