何再朗 張梅
摘要:Excel是常見的Office應用之一,編程實踐中經常需要對其進行互操作。但在使用C#操作Excel時,經常出現無法關閉進程、無法保存文件和用戶無法同時使用Excel等問題,筆者經過摸索研究,得到了針對以上問題的行之有效的解決方案。
關鍵詞:Excel;互操作;C#
中圖分類號:TP311? ? ? 文獻標識碼:A
文章編號:1009-3044(2019)26-0080-02
開放科學(資源服務)標識碼(OSID):
在Office編程實踐中,經常需要將存放在Excel中的初始數據導入到軟件中,有時又需要將軟件解算得到的數據導出回Excel予以保存,所以利用C#對Excel進行操作的情形時有發生。
利用C#操作Excel,首先需要導入Excel類庫,然后通過互操作調用Excel類庫的類函數。這些基礎性內容在許多地方都有較為詳細的介紹,最詳細的介紹在MSDN,在此不再贅述。本文重點介紹幾個疑難問題的解決方案。
1 無法關閉Excel進程
利用C#操作Excel,經常出現軟件結束退出,但是Excel進程卻沒有被關閉的現象,在任務管理器中可以看到殘留的Excel僵尸進程。這雖然不影響軟件的使用,但是嚴格深究起來屬于內存泄漏,并且軟件運行時間長了或者次數多了,會消耗掉大量系統內存,同時也會帶來不小的安全隱患。關于解決方案,有人建議用kill進程,但是kill進程屬于黑盒操作,存在著不確定性;還有一些人建議用GC回收,但是似乎時靈時不靈,實踐效果也不理想。
這其中的訣竅是,從excelApp中生成、獲取的對象一定要按照它們對應的順序,反序調用Close函數予以關閉,并將變量值統一置為null。當操作系統發現excelApp所有的衍生對象的引用計數均為0,就會自動徹底地關閉Excel進程了。需要注意的是,如果有一個衍生對象沒有被置值為null,從而導致其引用計數不為0,操作系統就會誤認為該對象仍然處在使用狀態,導致Excel進程關閉的失敗。
2 無法保存Excel文件
利用C#操作Excel,有時會出現無法保存Excel文件,軟件報錯退出的情況。基于信息保密和運行效率的考慮,我們的軟件一般會采取靜默模式,即隱藏Excel應用的界面,使其在后臺運行。Excel應用在保存文件時往往會彈出對話框,要求用戶對一些操作(如覆蓋同名文件等)予以確認,但是由于應用界面被隱藏,用戶無法操作,軟件在經過長時間的等待后,得不到響應最終報錯退出。找到了原因,問題解決起來就簡單了,需要將Excel應用的DisplayAlerts屬性置為false關閉提示對話框。
打開Excel應用的代碼修改如下。
3 無法同時使用Excel應用
至此,大部分的問題都已得到妥善的解決,剩下的唯一難題是軟件在操作Excel時,用戶無法同時手工使用Excel。但是軟件在運行時,如果用戶雙擊了一個Excel文件,原本被軟件隱藏的Excel應用就會被顯示出來,其中的數據和操作一覽無余。更糟糕的是,如果此時Excel應用彈出了一個對話框用戶卻不及時操作的話,又會出現上一節所討論的情況,軟件在經過長時間等待后,得不到響應不得不報錯退出。而如果用戶手工操作關閉了軟件運行所需的Excel文件甚或是關閉了Excel應用本身,后果就更為嚴重了,軟件輕則報錯,重則崩潰,還會導致數據的丟失。
筆者經過反復試驗,終于找到問題的成因。Excel應用是一個典型的Windows自動化容器,即便它在隱藏運行時也被要求隨時響應用戶的操作,例如雙擊一個Excel文件等。解決方案是提供“雙應用”備份,即軟件在運行時同時建立兩個Excel應用,其中第一個是緩沖應用,用來響應用戶可能的雙擊操作,第二個則是真實應用,用來向軟件提供數據存取和查詢等服務。需要注意的是,緩沖應用一定要位于真實應用之前,因為操作系統會將檢索到的第一個Excel應用于響應用戶的操作。相關的代碼如下。
進一步說,利用C#在操作Office其他應用(Word、PowerPoint等)時有許多類似的場景,所以C#操作Excel的許多經驗都可以移植借鑒。
以上我們分享了利用C#操作Excel時幾個疑難問題的行之有效的解決方案,目的在于拋磚引玉,供大家參考和討論。
【通聯編輯:李雅琪】