2010-05-01 176 views
2

我已經花了3小時在網上搜索無效的答案,所以我希望你能幫助我。我正在編寫一個使Excel自動運行的應用程序。應用程序可以選擇「顯示/隱藏Excel表格」,以便查看它,進行最終更改等等。檢測Excel文件是否已關閉

關閉應用程序自然會關閉Excel的實例,但是,有人可能會直接退出Excel,而無需考慮。這打破了我的應用程序,我似乎無法找到「檢查相同的工作簿是否仍然打開,如果不是,重新打開它」,在保存之前

我試過各種各樣的東西:檢查Excel應用程序是否爲空(當它爲!= null時,它將正確保存,但是當它爲「null」(或至少,除!以外的內容= null時,它甚至不會觸及斷點,因此我完全丟失:(

請幫助

編輯:感謝所有答覆到目前爲止,我會盡快給予回覆他們

AJ問我來編輯我到的問題提供更多信息:我使用C#應用程序中的COM Interop自動運行Excel。該應用程序允許用戶輸入某些統計數據,然後在Excel中進行更新。有一個按鈕允許Excel顯示/隱藏,以防有人想要檢查工作表中的任何其他信息如果有人直接退出Excel,那麼仍然可以使用顯示/隱藏按鈕(它顯示的Excel應用程序沒有工作簿加載)和相同的Excel實例仍顯示在任務管理器,但當我點擊「保存」按鈕。

我稍有不同的地方,最後一次加一個try/catch(未捕獲任何錯誤最後一次,現在它捕獲了兩個錯誤:

從HRESULT異常:0x800401A8

調用的對象已經與其客戶端斷開(異常來自HRESULT:0x80010108(RPC_E_DISCONNECTED))。

所以基本上看來我需要重新「重新連接」兩個,雖然與n在網絡上四處尋找新聞錯誤消息似乎並不表明它可能是一個問題。

我想知道是否最好將所有值存儲在字符串中(也許在應用程序失敗的情況下寫入臨時文件),然後在應用程序關閉時最終將它們推送到Excel中?

+0

您是否獲得未處理的異常,但此錯誤:0x800A01A8? – jcolebrand 2010-05-01 01:09:34

+1

「有人很可能會直接退出Excel,而不會想到」這種情況在95%的時間內會發生。 – Jay 2010-05-01 03:27:45

+0

@Charlie - 你可以編輯你的問題,提供更多關於你如何「自動化」Excel的上下文 - 它是通過C#應用程序的COM Interop還是其他一些方法? – 2010-05-01 03:48:04

回答

2

I've tried all sorts of things: checking if the Excel Application is null (when it's !=null it will save correctly, but when it "is" null (or at least, something other than !=null it won't even hit the breakpoint so I'm completely lost :(

測試可以做,像這樣:

if (excelApp == null) { 
    ; //set breakpoint here during execution to see if it IS null 
} 

編輯:

Type wheresExcel = typeof(excelApp); //this is going to execute if the object has not been GC'd 

/編輯:

所以,代碼如下:

if (excelApp != null) { 
    doSomething(); 
} 

那麼,爲什麼不這樣做:

if (excelApp == null) { 
    startExcel(); 
    addWorksheetToExcelInstance(); 
} 
doSomething(); 
+0

我已經嘗試過,斷點從來沒有打由於Excel關閉,工作簿已經與我的應用程序「斷開連接」。 – Charlie 2010-05-01 13:14:52

+0

你在Excel工作簿或應用程序上試過這個嗎?我在我的程序中保留了對這兩個參考的引用,所以我知道該實例是否消失了,而不僅僅是工作簿。而且,如果它沒有達到該斷點,則該對象不會消失。你需要一個不同的測試。也許定義一個新的類型設置爲該工作簿的類型。我將編輯並添加一個新的測試。 – jcolebrand 2010-05-01 23:14:27

+0

這似乎已經奏效了,我將它與try下面的Jay建議的try/catch塊結合使用,現在它實際上運行正常,並且在工作簿關閉時重新加載工作簿! 謝謝大家! – Charlie 2010-05-02 12:40:27

0

如何使用FindWindow API來查看應用是否仍然可見?

+0

不完全確定,但我認爲如果實際應用程序被隱藏起來,這將不起作用嗎?我從來沒有在僅用作COM服務器的應用程序上嘗試過它。 – jcolebrand 2010-05-01 01:10:37

+1

只要應用程序已加載,該窗口將可用 - 但如果用戶已關閉應用程序應該是完全內存不足(因此不可用)。 – 2010-05-01 01:15:05

+0

很高興知道,謝謝。 – jcolebrand 2010-05-01 01:15:51

0

沒有方式(讀:可靠+穩健),但有人想出了a reasonable workaround here在MSDN社交網站可能爲你做的伎倆。

這篇文章討論瞭如何使用子類來關閉窗口。它還引用了一個article on the microsoft support site,它更一般地討論了C#和.Net的子類化。

我採用的唯一另一種替代方法是非常俗氣的解決方法 - 我將允許Excel可見,但是我將自己的頂層窗體放在標題欄+按鈕上(不推薦)。

編輯:

以防萬一,目前尚不清楚 - 我不建議你創建一個加載項,但與子類相似的方法可能是可行的影響Excel的行爲而被自動。我假設你正在使用interop來「自動化excel」。

+0

難道這實際上不會阻止用戶通過顯示所述消息框來退出Excel EVERYTIME嗎?這不完全是@Charlie想要做的嗎? – jcolebrand 2010-05-01 01:21:07

+0

如果您調整代碼以防止關閉,直到您的應用準備就緒,您可以向用戶顯示一條消息(如果您選擇)並阻止關閉 - 這是可以接受的嗎? – 2010-05-01 01:25:13

+0

但是,如果它是一個Excel加載項,它不會影響所有的Excel實例嗎?用戶是否需要使用此程序始終退出Excel?這聽起來像是一個等待發生的潛在辦公室病毒。 「從不讓你退出辦公應用而不重啓」病毒。 – jcolebrand 2010-05-01 01:29:32

0

爲什麼在保存之前需要重新打開工作簿?

將保存包裝在try...catch區塊中 - 如果它有效,則表示良好,如果不存在,則可以在catch區塊中以任何方式處理。

6

Microsoft.Office.Interop.Excel.Application實際上有一個事件,您可以在工作簿關閉之前使用它。即使其他人在Excel中關閉工作簿,也會被解僱。該事件被稱爲WorkbookBeforeClose()。

m_app = new Microsoft.Office.Interop.Excel.Application() { Visible = false }; 
m_app.WorkbookBeforeClose += new AppEvents_WorkbookBeforeCloseEventHandler(m_app_WorkbookBeforeClose); 
m_workbook = m_app.Workbooks.Open(); // removing all arguements here for simplicity 

// event handler code 
void m_app_WorkbookBeforeClose(Workbook Wb, ref bool Cancel) 
{ 
    // making sure it is the same file that I opened 
    if (Wb.FullName == m_workbook.FullName) 
    { 
    m_workbook = null; 
    } 
} 

// when your app is closing 
public void Close() 
{ 
    if (m_workbook != null) 
    { 
    m_workbook.Close(Type.Missing, Type.Missing, Type.Missing); 
    } 
    m_app.Quit();   
} 
0

夜已深,但這個發生在我身上,每次我不小心發佈應用程序之前,我釋放的實際工作簿,所以只要鬆開工作簿第一

1

我剛剛經歷並修復了這個問題,雖然爲時已晚,在這個線程,我只是想在這裏添加我的修復,這可能對某人有幫助。

問題:我在關閉Excel Worksheet/Workbook之前關閉了Excel應用程序對象。因此,它將Excel工作表/工作簿對象從Excel應用程序對象中分離出來。

解決方案:關閉Excel工作表/工作簿,然後再關閉Excel應用程序對象或按照從工作表到工作簿到Excel應用程序的順序。

例子:xlwks.Close(); xlwks = null; xlwbk = null; xlapp = null;