VS2010/MFC 利用OLE讀寫excel操作時,手動開啟其他excel文件程式崩掉的問題解決
問題點:
(1)我是利用excel儲存程式過程資料,300ms儲存一次。在程式執行過程中,如果手動開啟其他excel檔案,則程式建立的那個excel檔案也會被同時開啟。此時 如果把二者都關閉了,則程式崩潰。為了程式繼續執行,必須保持程式建立的那個excel開啟;
(2)如果在程式執行前,先開啟一個excel檔案然後關閉,再開啟程式則不會出現(1)的情況。
問題分析:
“出現上述問題的原因是,當程式新建一個Excel.Application物件時,實際上在程序中新建了一個系統已經安裝的Excel程式的例項(此時程序中會有一個EXCEL.EXE),這其實與手動啟動Excel程式(注意,是啟動Excel程式,不是開啟xls檔案)是沒有分別的。只不過在程式中可以將Excel 物件設定為不可見。
運行了一個EXCEL.EXE之後,就可以開啟xls檔案了。在程式中,可以使用xlApp.Workbooks.Open來指定使用哪一個Excel 物件來開啟xls檔案;而在手動開啟xls檔案時,系統總是自動查詢現有的EXCEL.EXE程序中最後建立的那個,並用它來開啟xls檔案。如果當前還沒有EXCEL.EXE程序執行,系統就會新建一個EXCEL.EXE程序,這就是我們一般雙擊開啟xls檔案時的情況。
這裡需要提到EXCEL.EXE程式的一個特性:一個EXCEL.EXE可以開啟多個xls檔案。(不信你可以手動開啟很多xls檔案,然後看看工作管理員裡是不是隻有一個EXCEL.EXE程序。)有意思的是,當一個EXCEL.EXE開啟多個xls檔案時,這些xls檔案會各自獨立出現在工作列,好像它們源自不同的程序似的,容易給人錯覺。”
解決方法:
BOOL OperationExcelFile::InitExcel() { CoUninitialize(); if(CoInitialize(NULL)==S_FALSE) { AfxMessageBox(_T("初始化COM支援庫失敗!")); return FALSE; } //建立偽裝EXCEL伺服器yu20160813 //防止程式使用過程中人為開啟其他excel造成程式崩潰 if (!excel_application_fake_.CreateDispatch(_T("Excel.Application"),NULL)) { AfxMessageBox(_T("建立偽裝Excel服務失敗,你可能沒有安裝EXCEL,請檢查!")); return FALSE; } excel_application_fake_.put_DisplayAlerts(FALSE); excel_books_fake_.AttachDispatch(excel_application_fake_.get_Workbooks(),true); //建立Excel 2000伺服器(啟動Excel) if (!excel_application_.CreateDispatch(_T("Excel.Application"),NULL)) { AfxMessageBox(_T("建立Excel服務失敗,你可能沒有安裝EXCEL,請檢查!")); return FALSE; } excel_application_.put_DisplayAlerts(FALSE); return TRUE; }
(2)在程式退出時,要檢視是否有其他excel開啟。因為這些excel檔案使用excel_application_fake_開啟的,如果直接關閉程式這些excel檔案也會退出。
void OperationExcelFile::ReleaseExcel()
{
excel_application_.Quit();
excel_application_.ReleaseDispatch();
excel_application_=NULL;
//偽裝excel服務退出
if( !excel_books_fake_.get_Count() )
{
excel_application_fake_.Quit();
excel_application_fake_.ReleaseDispatch();
excel_application_fake_=NULL;
}
}