最近的项目中需要利用VC操作Excel进行自动化输出,期间碰到网上很多朋友遇到的一个问题,无法正常关闭Excel。经过琢磨,总结如下:
1、原因:由于使用了Range的GetItem()函数获取Excel表中内容,所以程序在调用了_Application的Quit()函数后,Excel进程不能马上关闭,整个程序退出时,Excel将关闭。若注释了调用GetItem()的代码,将可以正常关闭。内部原因不知。
2、解决办法,不使用GetItem()获取Excel中内容,而使用其他方法。如下代码介绍读取数据的一种方法:
- BOOLCAutomationExcel::GetValue(intiRow,intiColumnStart,intiColumnStop,CStringArray&strarray)
- {
- intiElementCount=iColumnStop-iColumnStart+1;
- if(iElementCount<=0)
- returnFALSE;
- CStringstrStart,strEnd;
- _variant_tstart,stop;
- strStart=GetItemName(iRow,iColumnStart);
- start.vt=VT_BSTR;
- start.bstrVal=strStart.AllocSysString();//不需要进行_bstr_t转换
- strEnd=GetItemName(iRow,iColumnStop);
- stop.vt=VT_BSTR;
- stop.bstrVal=strEnd.AllocSysString();
- //创建安全数组,从Excel中读取内容
- _variant_tvarReturn;
- varReturn.vt=VT_ARRAY|VT_VARIANT;
- SAFEARRAYBOUNDsab[2];//必须为维
- sab[0].lLbound=1;
- sab[0].cElements=iElementCount;
- sab[1].lLbound=1;
- sab[1].cElements=iElementCount;
- varReturn.parray=SafeArrayCreate(VT_VARIANT,2,sab);
- Rangerange;
- range.AttachDispatch(m_Range.GetRange(start,stop));
- if(range.m_lpDispatch==NULL)
- returnFALSE;
- varReturn=range.GetValue2();
- range.ReleaseDispatch();
- strarray.RemoveAll();
- //从安全数组中读取数据
- CStringstr;
- if(iElementCount==1)
- {
- CVariantCast(varReturn).GetValue(str);
- strarray.Add(str);
- }
- else
- {
- _variant_ttmp;
- for(inti=1;i<=iElementCount;++i)
- {
- longindices[]={1,i};
- SafeArrayGetElement(varReturn.parray,indices,(void*)&tmp);
- CVariantCast(tmp).GetValue(str);
- strarray.Add(str);
- }
- }
- returnTRUE;
- }
其中CVariantCast为一个自己实现的转换类,使用的代码如下:
- inlinevoidCVariantCast::GetValue(CString&strValue)
- {
- strValue.Empty();
- if(m_variant.vt==VT_EMPTY||m_variant.vt==VT_NULL)
- return;
- if(m_variant.vt==VT_BOOL)
- {
- if(m_variant.boolVal)
- strValue=_T("TRUE");
- else
- strValue=_T("FALSE");
- return;
- }
- m_variant.ChangeType(VT_BSTR);
- strValue=m_variant.bstrVal;
- }