VS2010/MFC 利用OLE读写excel操作时,手动打开其他excel文档程序崩掉的问题解决

来源:互联网 发布:模板算量软件 编辑:程序博客网 时间:2024/05/04 08:31

//  利用OLE读写excel文件,可以参考   VS2010通过OLE操作Excel2010

 问题点:

(1)我是利用excel存储程序过程数据,300ms存储一次。在程序运行过程中,如果手动打开其他excel文件,则程序创建的那个excel文件也会被同时打开。此时 如果把二者都关闭了,则程序崩溃。为了程序继续运行,必须保持程序创建的那个excel打开;

(2)如果在程序运行前,先打开一个excel文件然后关闭,再打开程序则不会出现(1)的情况。


问题分析:

 //  这个问题的分析请参考  VC 操作XLS文件

   “出现上述问题的原因是,当程序新建一个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文件会各自独立出现在任务栏,好像它们源自不同的进程似的,容易给人错觉。”


解决方法:

         (1)在创建程序使用的excel之前,先调用EXCEL.EXE创建一个供打开其他excel文件的excel_application_fake_,然后再调用EXCEL.EXE创建一个供程序使用的excel_application_。

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;}}





1 0
原创粉丝点击