【发布时间】:2009-07-16 17:57:38
【问题描述】:
是否有任何选项可以使用 VBA 访问表单应用程序中的任何代码关闭当前打开的 MsgBox?
【问题讨论】:
是否有任何选项可以使用 VBA 访问表单应用程序中的任何代码关闭当前打开的 MsgBox?
【问题讨论】:
查看 Randy Birch 对 microsoft.public.vb.general.discussion 中 this 线程的回复
他建议在名为 MsgBox 的 .bas 文件中创建一个函数。这样做会导致 VB 调用您的函数而不是内置函数。
然后您将创建自己的 MsgBox 表单并构建一个计时器以在设定的时间段后关闭您的表单。他提供了链接来展示如何做到这一点。
他还讨论了一种在需要时显式调用内置 MsgBox 函数的方法。
注意:我从未这样做过,但我发现 Randy Birch 是一个知识渊博的资源。
【讨论】:
MsgBoxes 不打算以编程方式关闭,这就是为什么很难这样做。如果您发现自己处于必须强制关闭 MsgBox 的设计中,您可能应该重新评估您的设计。
【讨论】:
我可能错了,但 MsgBox 是一个创建模式表单的阻塞调用,所以我认为没有一种简单的方法可以做到这一点。你有这方面的具体用例吗?
【讨论】:
正如 MarkJ 指出的那样,这可能是 Access 生成的对话框(而不是在您自己的代码中调用的 VBA.MsgBox)吗?
例如,当在 Access UI 中使用表的“数据视图”添加一行时,您会收到一条消息,“您将要追加 1 条记录...”(或类似内容)。这是你的意思吗?如果是这样,确实有办法压制它们……
【讨论】:
我曾经对此有一个简单的答案:使用 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。
我应该警告你,问题的答案是用大锤敲碎坚果,并附有冗长的解释。
【讨论】:
与其从头开始编写 Access MsgBox 的替代方案,不如考虑使用(或至少学习)Arvin Meyer 的 Custom MessageBox Creator(可在 this page 上下载)。
【讨论】:
消息框旨在向用户描述一些信息。因此,以编程方式关闭不是一个好的设计,除非您没有自动化某些流程。
您可以使用 sendkeys 或 win API。
【讨论】:
我也遇到过类似的问题;理论上你可以使用“SendKeys”功能(见http://msdn.microsoft.com/en-us/library/8c6yea83%28VS.85%29.aspx)。但是,MsgBox 会阻止运行,因此您无法使用该命令。如果您知道它何时会弹出,您可以(从脚本)运行外部 whshell,等待一段时间,然后使用 SendKeys。但如果你知道怎么做,请告诉我(这里)。其他类似的可能性是为其打开不会被阻塞的不同线程/进程,但我不知道在VBA中是否可能。
【讨论】:
一个易于使用的基于 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 是什么?
我知道这是一篇旧帖子,看来有一种新的简单方法可以做到这一点:
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 提供
【讨论】: