【问题标题】:How do I close a currently opened MsgBox using VBA?如何使用 VBA 关闭当前打开的 MsgBox?
【发布时间】:2009-07-16 17:57:38
【问题描述】:

是否有任何选项可以使用 VBA 访问表单应用程序中的任何代码关闭当前打开的 MsgBox?

【问题讨论】:

    标签: vba ms-access msgbox


    【解决方案1】:

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

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

    然后您将创建自己的 MsgBox 表单并构建一个计时器以在设定的时间段后关闭您的表单。他提供了链接来展示如何做到这一点。

    他还讨论了一种在需要时显式调用内置 MsgBox 函数的方法。

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

    【讨论】:

    • 只有在从您自己的代码中显示 MsgBox 时才有效。如果是 Access 原生 MsgBox,则需要另一种方法。
    • 您可以从您的应用中挂钩另一个应用的 msgbox 并关闭它。您将从上面的资源中找到有关 hooks 和 msgbox 的信息。我不得不这样做 1000 次,并在他的网站上住了几个星期。 :) 避免像瘟疫一样的发送键。对于系统上的用户,至少无法确定哪个应用程序最终会获得击键。
    【解决方案2】:

    MsgBoxes 不打算以编程方式关闭,这就是为什么很难这样做。如果您发现自己处于必须强制关闭 MsgBox 的设计中,您可能应该重新评估您的设计。

    【讨论】:

    • 基于 Win32.dll 的答案实际上确实包含下面的计时器功能。
    【解决方案3】:

    我可能错了,但 MsgBox 是一个创建模式表单的阻塞调用,所以我认为没有一种简单的方法可以做到这一点。你有这方面的具体用例吗?

    【讨论】:

    • 我不知道消息框在哪里弹出,我不想分析它来自哪里我想 KILLLLLL :-)
    • 如果您想知道消息框弹出的位置,只需按“Ctrl + Break”即可查看导致该消息的原因并评论该调用。如果是第三方 dll 弹出框,那么除非有一些属性使其“静音”,否则您可能无法做任何事情
    • 它也可能是由您所做的某事触发的 Access 原生 MsgBox。如果是这样,可能有另一种方法可以使 Access “静默”
    • 是的,你是对的:这是一个阻塞调用,没有简单的方法。当然,有一条艰难的路。
    • 有一个简单的基于 Win32 的答案。我发给你了。
    【解决方案4】:

    正如 MarkJ 指出的那样,这可能是 Access 生成的对话框(而不是在您自己的代码中调用的 VBA.MsgBox)吗?

    例如,当在 Access UI 中使用表的“数据视图”添加一行时,您会收到一条消息,“您将要追加 1 条记录...”(或类似内容)。这是你的意思吗?如果是这样,确实有办法压制它们……

    【讨论】:

      【解决方案5】:

      我曾经对此有一个简单的答案:使用 Windows Scripting Shell 对象,它有一个“弹出”函数 - 一个消息框,就像 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”参数并不能真正起作用天 - 雷德蒙德的某个人真的不喜欢一个线程关闭另一个线程的有用警告和对用户工作流程的重要中断的想法。

      但是,您可以使用 API Timer() 函数启动延迟的消息框“关闭”命令 - 不是完全“关闭当前打开的 MsgBox”,因为这需要提前警告您打算打开它 - 但它是我拥有的最接近的东西,它适合一个独立的 VBA 模块和I posted the code in an answer to a very similar StackOverflow question to yours

      我应该警告你,问题的答案是用大锤敲碎坚果,并附有冗长的解释。

      【讨论】:

        【解决方案6】:

        与其从头开始编写 Access MsgBox 的替代方案,不如考虑使用(或至少学习)Arvin Meyer 的 Custom MessageBox Creator(可在 this page 上下载)。

        【讨论】:

        • 基于 Win32 的答案相当容易实现。我将 dll 用于我的 dB 中的一些事情,例如查找要导入的文件。
        【解决方案7】:

        消息框旨在向用户描述一些信息。因此,以编程方式关闭不是一个好的设计,除非您没有自动化某些流程。

        您可以使用 sendkeys 或 win API。

        【讨论】:

        • 我在下面使用了一条快速弹出消息,让我知道数据库将在后台执行操作,并且可能会暂时无响应。
        【解决方案8】:

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

        【讨论】:

          【解决方案9】:

          一个易于使用的基于 Win32 的答案实际上对调用它很有用。使用下面的代码,您可以轻松地创建一个基于计时器的 PopUpBox。我喜欢 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 是什么?
          • Title = 消息框或标题栏的顶部,与 VBA 中的 msgbox 命令相同。我的代码使用 Windows 代码库 (Win32) 创建消息框,它确实有一个计时器选项。使用 Win32,您可以完全按照要求完成。
          【解决方案10】:

          我知道这是一篇旧帖子,看来有一种新的简单方法可以做到这一点:

              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://docs.microsoft.com/en-us/office/vba/excel/concepts/controls-dialogboxes-forms/automatically-dismiss-a-message-box

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-06-22
            • 1970-01-01
            • 2019-12-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-11-16
            相关资源
            最近更新 更多