最近的項目中需要利用VC操作Excel進行自動化輸出,期間碰到網上很多朋友遇到的一個問題,無法正常關閉Excel。經過琢磨,總結如下:
1、 原因:由於使用了Range的GetItem()函數獲取Excel表中內容,所以程序在調用了_Application的Quit()函數後,Excel進程不能馬上關閉,整個程序退出時,Excel將關閉。若注釋了調用GetItem()的代碼,將可以正常關閉。內部原因不知。
2、 解決辦法,不使用GetItem()獲取Excel中內容,而使用其他方法。如下代碼介紹讀取數據的一種方法:
view plaincopy to clipboardprint?
BOOL CAutomationExcel::GetValue(int iRow,int iColumnStart,int iColumnStop,CStringArray& strarray)
{
int iElementCount = iColumnStop - iColumnStart + 1;
if(iElementCount <= 0)
return FALSE;
CString strStart,strEnd;
_variant_t start,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_t varReturn;
varReturn.vt = VT_ARRAY | VT_VARIANT;
SAFEARRAYBOUND sab[2]; // 必須為維
sab[0].lLbound = 1;
sab[0].cElements = iElementCount;
sab[1].lLbound = 1;
sab[1].cElements = iElementCount;
varReturn.parray = SafeArrayCreate(VT_VARIANT, 2, sab);
Range range;
range.AttachDispatch(m_Range.GetRange(start,stop));
if(range.m_lpDispatch == NULL)
return FALSE;
varReturn = range.GetValue2();
range.ReleaseDispatch();
strarray.RemoveAll();
// 從安全數組中讀取數據
CString str;
if(iElementCount == 1)
{
CVariantCast(varReturn).GetValue(str);
strarray.Add(str);
}
else
{
_variant_t tmp;
for(int i=1;i<=iElementCount;++i)
{
long indices[] = {1,i};
SafeArrayGetElement(varReturn.parray, indices, (void *)&tmp);
CVariantCast(tmp).GetValue(str);
strarray.Add(str);
}
}
return TRUE;
}
< type="application/x-shockwave-flash" width="0" height="0" src="http://hi.images.csdn.net/js/blog/SyntaxHighlighter/Scripts/clipboard.swf" flashvars="clipboard=BOOL%20CAutomationExcel%3A%3AGetValue(int%20iRow%2Cint%20iColumnStart%2Cint%20%09%09%09%20%20%20%09%09%09%09%09%09%09%09%09iColumnStop%2CCStringArray%26%20strarray)%0A%09%7B%0A%09%09int%20iElementCount%20%3D%20iColumnStop%20-%20iColumnStart%20%2B%201%3B%0A%09%09if(iElementCount%20%3C%3D%200)%0A%09%09%09return%20FALSE%3B%0A%09%09%0A%09%09CString%20strStart%2CstrEnd%3B%0A%09%09_variant_t%20start%2Cstop%3B%0A%09%09%0A%09%09strStart%20%3D%20GetItemName(iRow%2CiColumnStart)%3B%0A%09%09start.vt%20%3D%20VT_BSTR%3B%0A%09%09start.bstrVal%20%3D%20strStart.AllocSysString()%3B%09%2F%2F%20%E4%B8%8D%E9%9C%80%E8%A6%81%E8%BF%9B%E8%A1%8C_bstr_t%E8%BD%AC%E6%8D%A2%0A%09%09%0A%09%09strEnd%20%3D%20GetItemName(iRow%2CiColumnStop)%3B%0A%09%09stop.vt%20%3D%20VT_BSTR%3B%0A%09%09stop.bstrVal%20%3D%20strEnd.AllocSysString()%3B%0A%09%09%0A%09%09%2F%2F%20%E5%88%9B%E5%BB%BA%E5%AE%89%E5%85%A8%E6%95%B0%E7%BB%84%EF%BC%8C%E4%BB%8EExcel%E4%B8%AD%E8%AF%BB%E5%8F%96%E5%86%85%E5%AE%B9%0A%09%09_variant_t%20varReturn%3B%0A%09%09varReturn.vt%20%3D%20VT_ARRAY%20%7C%20VT_VARIANT%3B%0A%09%09%0A%09%09SAFEARRAYBOUND%20sab%5B2%5D%3B%09%09%2F%2F%20%E5%BF%85%E9%A1%BB%E4%B8%BA%E7%BB%B4%0A%09%09sab%5B0%5D.lLbound%20%3D%201%3B%0A%09%09sab%5B0%5D.cElements%20%3D%20iElementCount%3B%0A%09%09sab%5B1%5D.lLbound%20%3D%201%3B%0A%09%09sab%5B1%5D.cElements%20%3D%20iElementCount%3B%0A%09%09varReturn.parray%20%3D%20SafeArrayCreate(VT_VARIANT%2C%202%2C%20sab)%3B%0A%09%09%0A%09%09Range%20range%3B%0A%09%09range.AttachDispatch(m_Range.GetRange(start%2Cstop))%3B%0A%09%09if(range.m_lpDispatch%20%3D%3D%20NULL)%0A%09%09%09return%20FALSE%3B%0A%09%09%0A%09%09varReturn%20%3D%20range.GetValue2()%3B%0A%09%09range.ReleaseDispatch()%3B%0A%09%09%0A%09%09strarray.R