2014-12-04 121 views
4

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

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

我之前试过功能AppActivate("Microsoft Excel")没有任何成功(How do I bring focus to a msgbox?)。由于Excel 2010将文档名称添加到窗口标题,因此应用程序名称实际上比此长。

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

+1

这不是说这是一个解决方案,但是Alt-Tab能帮助你吗? – peege 2014-12-04 18:52:58

+1

不,我也试过。 MsgBox不被视为Windows的窗口(这里是W7),所以我只能看到Excel 2010并关注Excel 2010。但是在Excel中,焦点仍然以某种方式位于Excel窗口后面的MsgBox中。我可以尝试用我的键盘按“Enter”键,但这是我唯一没有尝试的。 – dnLL 2014-12-04 18:54:23

+1

您是否使用多显示器显示?另外,你可以发布一些代码吗? – peege 2014-12-04 18:55:37

回答

1

我试过几乎所有的其他的答案:

  • ThisWorkbook.Activate
  • AppActivate()
  • Application.Wait()
  • Sleep

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

说到这里,我真正的解决方案(这不是真正的解决方案,最初的问题)没有使用MsgBox()。有几个解决方法确实存在,我发现Forms对我来说是最好的。因此,而不是在这个问题上浪费更多的时间,我抛出了非常简单的下面的代码来代替我原来MsgBox()

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

,我可以把我想要的任何文字标签在frmMsgBox,而且由于这是Excel中,我可以简单地通过使用隐藏的单元格传递参数。

感谢您的帮助。

3

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

Sleep API source

在过程

然后

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 

我建议设置Application.ScreenUpdating =假,然后重新打开它的过程完成之后,但它可能使事情更差。

更新

只要阅读,打字时我的回答中输入的意见。另一种选择,而不是讯息话题框将打开,其中已创建的所有 文件后的文件被保存在文件夹窗口(与保存位置替换ENVIRON $(“APPDATA”)):

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

OR PDF文件打开一个:

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

另一个选项

我不能把这个意见,因为有太多的代码,但是做一个API调用的MessageBox instea d,但不要将消息框的所有者(hWnd)设置为& H0或& O0。 vbSystemModal应该让它弹到顶端。我不知道这是否会允许你在用户点击后好选择Excel应用程序窗口:

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 
+1

如果没有其他工作,打开文件夹绝对是解决问题的好方法。谢谢,我会在星期一看看你的第一个解决方案和其他解决方案。 – dnLL 2014-12-04 20:38:42

+1

@dnLL听起来像是一个加重的问题,祝你好运。 – 2014-12-04 20:43:51

+1

所有解决方案都不起作用,所以我现在试图绕过它而不使用MsgBox。打开文件夹确实解决了这个问题并且工作正常。感谢那。唯一的问题是,即使使用vbMaximizedFocus,焦点也不会进入该文件夹,所以我必须查看任务栏才能知道它实际存在。我会试着用表格来看看它是否更好。 – dnLL 2014-12-08 15:56:22

3

我做了一些测试,发现一个潜在的解决办法给你。

我成立了这个简单的程序来测试您的情况:

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 

当我运行的过程。这一次,然后最小化所有窗口,而不是看到什么消息框弹出(但不是Excel窗口)。

我认为在你的MsgBox代码之前加上ThisWorkbook.Activate你可以在你的文件中发生同样的情况。

它并不完全让你在那里,但希望比你在哪里更好。

+1

我尝试了ThisWorkbook.Activate,但不幸的是它没有帮助。我不确定什么是错的,但我用另一台电脑尝试过,并且遇到同样的问题。但是我们公司的所有电脑在硬件和软件方面几乎完全相同。我可能会使用完全替代的解决方案,如打开文件夹而不是MsgBox。 – dnLL 2014-12-04 20:56:55

3

*哎呀没有看过你的问题的其余部分,我用则AppActivate和预期,并使用MS Office专业增强版林工作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 
+1

无论是否使用AppActive或ThisWorkbook.Activate都不起作用。 Application.Wait似乎没有帮助。请注意,当我单击Excel时,可以看到元素在工作簿中不断闪烁,等待对MsgBox的回复(隐藏在后台)。按Enter键似乎并不总是奏效,但通常是Ctrl + Break,Esc和Enter的组合。 – dnLL 2014-12-08 15:32:59

+1

这很奇怪,我运行这个,我可以让Excel全部最小化,然后弹出msgbox。 Dunno :( – mrbungle 2014-12-08 17:10:59

+1

这可能与Excel和Windows在我们的商业计算机上配置的方式有关,尽管它不能很好地解决问题,但我会根据Forms来寻求解决方法。 – dnLL 2014-12-08 17:46:26

1

这将在Excel工作无论哪个其他应用程序具有焦点:

之前的消息框或任何警示把下面的代码:

AppActivate Application.Caption 
DoEvents 

信任我在这,这个是惊人的!

+1

我需要给这个这个问题在一年前(!),是因为MsgBox会在后台显示,而用户不会注意到它,因为Excel/Access中的MsgBox没有创建任务Windows中,没有办法将焦点集中到MsgBox上,唯一的解决方法是在聚焦应用程序后(尽管MsgBox仍然存在,它通过主应用程序(Excel)以某种方式具有焦点)杀死应用程序或按Enter键。 – dnLL 2015-11-26 20:28:46

+1

如果excel和最近激活的应用程序在同一个显示器上,这个功能不起作用,我会更多地考虑它... – 2016-01-21 13:46:35

+0

@DougCoats你能解释一下吗?这是唯一的东西为我增加了对msgbox的注意力 – DeerSpotter 2016-02-04 23:52:16