2014-12-04 123 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