Excel自动化时无法正常关闭Excel的解决方案
2011-06-01 23:56
225 查看
最近的项目中需要利用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;
}
其中CVariantCast为一个自己实现的转换类,使用的代码如下:
view plaincopy to clipboardprint?
inline void CVariantCast::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;
}
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;
}
其中CVariantCast为一个自己实现的转换类,使用的代码如下:
view plaincopy to clipboardprint?
inline void CVariantCast::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;
}
相关文章推荐
- Excel自动化时无法正常关闭Excel的解决方案
- 应用程序无法正常启动(0xc000007b)。请单击“确定”关闭应用程序。解决方案
- 关于tomcat7下shutdown无法正常关闭服务的解决方案
- PHPWAMP出现“应用程序无法正常启动(0xc0000135)。请单击“确定”关闭应用程序”的解决方案
- 应用程序无法正常启动(0xc000007b)。请单击“确定”关闭应用程序。解决方案
- 【Hadoop】关于hadoop正常启动而无法正常关闭
- [转]Win7、Windows Server 2008下无法在Windows Service中打开一个已经存在的Excel 2007文件问题的解决方案
- 【小技巧】firefox无法正常启动的解决方案
- Win7下用Framework 4.0开发的程序,发布时找不到Framework 4.0的问题,导致系统无法正常访问的解决方案
- Windows 下 SVN 图标无法正常显示的解决方案
- nginx rewrite(301)重定向之后无法正常请求的解决方案
- Excel导入,数字+文本,文本无法识别的解决方案
- Linux下Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’ mysql service 无法正常启动和关闭
- IIS无法启动,应用程序池自动关闭,应用程序池XXXX将被自动禁用 解决方案之一
- 应用程序无法正常启动(0xc000007b)。请单击“确定”关闭应用程序 解决
- MacPro无法正常识别电池解决方案
- Excel 帮助无法正常工作的解决方法
- 解决 无法引用Microsoft.Office.Interop.Excel的解决方案 的方法
- 应用程序无法正常启动0xc0150002 解决方案
- 应用程序无法正常启动(0xc000007b)。请单击确定关闭应用程序