MsgBox在Excel中的焦点

我在Excel中使用VBA计算大量数据,并在完成时显示MsgBox。 MsgBox实际上显示了计算所需的时间。

问题是用户在计算发生时决定做其他事情。 Excel继续计算,当它完成后,MsgBox会显示,但由于某种原因,Excel不会将焦点放到MsgBox。 Excel图标将在任务栏中闪烁,如果我们单击它,Excel会最大化,但MsgBox位于Excel窗口后面,我们永远不能单击它。 所以唯一的办法就是去taskkill excel.exe …不是很好。 Alt + Pause不起作用,因为代码将仅在当前代码行之后停止,这将在MsgBoxclosures时结束。

我之前试过AppActivate("Microsoft Excel")函数,没有任何成功( 我如何将焦点集中到一个msgbox? )。 由于Excel 2010将文档名称添加到窗口标题中,所以应用程序名称实际上比此长。

任何想法如何能解决这个恼人的问题?

我做了一些testing,发现了一个潜在的工作。

我设置了这个简单的程序来testing你的情况:

 Sub test() If Application.Wait(Now + TimeValue("0:00:10")) Then MsgBox "Time expired" End If End Sub 

我运行这个,然后最小化所有的窗口,当计时器启动时,没有任何反应。 如果我切换到Excel,我可以看到消息框,但没有其他的东西。

所以我试过这个:

 Sub test() If Application.Wait(Now + TimeValue("0:00:10")) Then ThisWorkbook.Activate MsgBox "Time expired" End If End Sub 

这一次,当我运行该过程,然后尽量减less所有的窗口,而不是没有看到消息框popup (而不是Excel窗口)。

我想通过在你的MsgBox代码之前添加ThisWorkbook.Activate你可以在你的文件中发生同样的事情。

这并不能让你一路顺风,但希望比你所在的位置更好。

*哎呀没有读你的问题的其余部分,我使用AppActivate和按预期工作,我使用MS Office Professional Plus 2010

我无法从guitarthrower的工作方法,但能够得到这个作为一个例子。 而不是ThisWorkbook.Activate尝试AppActivate ("Microsoft excel")然后您的MsgBox

 Sub test() If Application.Wait(Now + TimeValue("0:00:10")) Then AppActivate ("Microsoft excel") MsgBox "Time expired" End If End Sub 

听起来像macros观过程是使应用程序无响应。 不确定这是否会有所帮助,但是您是否考虑在长时间运行的进程中添加DoEvents或Sleep(API调用)以将控制权交还给操作系统? 睡眠是一个API调用,所以你需要在模块中声明它来使用它。 DoEvents防止应用程序被locking,但它确实使用更多的CPU,所以如果它在一个循环中,我会每隔一段时间访问它(30%或更less的迭代)。 如果它不是一个循环,并且您知道长时间运行过程中的瓶颈位置,则可以在每个长时间运行过程后调用DoEvents。

 #If VBA7 And Win64 Then ' 64 bit Excel Public Declare PtrSafe Sub Sleep Lib "kernel32" ( _ ByVal dwMilliseconds As LongLong) #Else ' 32 bit Excel Public Declare Sub Sleep Lib "kernel32" ( _ ByVal dwMilliseconds As Long) #End If 

睡眠API来源

然后在你的过程中

 Sub SomeLongProcessWithDoEventsExample() For i = 1 to 100000 'Some lengthy code If i Mod 333 = 0 Then DoEvents End If Next i End Sub Sub SomeLongProcessWithSleepExample() For i = 1 to 100000 'Some lengthy code If i Mod 333 = 0 Then Sleep 1 * 1000 'Millseconds End If Next i End Sub 

我build议设置Application.ScreenUpdating = False,然后在过程结束后重新打开它,但它可能会使情况变得更糟。

更新

只要阅读input我的答案时input的评论。 另一个选项,而不是messsage框将打开所有文件创build后保存文件的文件夹窗口(用保存位置replaceEnviron $(“APPDATA”)):

 Shell "explorer.exe" & " " & Environ$("APPDATA"), vbMaximizedFocus 

或打开其中一个PDF文件:

 Shell Environ$("COMSPEC") & " /c Start C:\SomeFile.pdf", vbMaximizedFocus 

另外一个select

我不能把它放在注释中,因为代码太多,而是调用MessageBox的API调用,而不是将消息框的所有者(hWnd)设置为&H0或&O0。 vbSystemModal应该使它popup到顶部。 我不知道是否允许您在用户点击好之后selectexcel应用程序窗口:

 MessageBox &O0, "My Message", "My Caption", vbOKOnly + vbSystemModal #If VBA7 And Win64 Then Public Declare PtrSafe Function MessageBox _ Lib "User32" Alias "MessageBoxA" _ (ByVal hWnd As LongLong, _ ByVal lpText As String, _ ByVal lpCaption As String, _ ByVal wType As LongLong) _ As Long #Else Public Declare Function MessageBox _ Lib "User32" Alias "MessageBoxA" _ (ByVal hWnd As Long, _ ByVal lpText As String, _ ByVal lpCaption As String, _ ByVal wType As Long) _ As Long #End If 

我尝试了大部分其他答案:

  • ThisWorkbook.Activate
  • AppActivate()
  • Application.Wait()
  • Sleep图书馆

无论出于何种原因,以上都不是。 我相信在我们的计算机环境中有一些非常具体的业务设置可能会造成问题。 正如其他人提到的,即使在双显示器设置中,上述所有解决scheme都可能适用于安装有任何Office 2010版本的任何全新格式化的Windows 7安装。 所以对所有这些答案+1。 另外,我注意到这个问题只发生在一些特定的工作簿中。 真的很奇怪的行为,这可能只是一个与我在工作簿中做的事情有关的Office 2010错误(无论是VBA还是简单的Excel)。

这就是说,我真正的解决scheme(这不是最初的问题的解决scheme)不使用MsgBox() 。 有一些解决方法确实存在,我发现窗体是最适合我的。 所以,而不是浪费更多的时间在这个问题上,我出来了真正简单的下面的代码来replace我原来的MsgBox()

 Application.ScreenUpdating = False frmMsgBox.Show Application.ScreenUpdating = True 

我可以把任何文本放在frmMsgBox的标签中,因为这是Excel,所以我可以通过使用隐藏的单元格来传递参数。

感谢所有的帮助。

这将在Excel中工作,而不pipe其他应用程序的重点:

在消息框或任何警告之前放置下面的代码:

 AppActivate Application.Caption DoEvents 

相信我,这太神奇了!