使用Excel COM组件导出数据后释放 Excel进程不能正常结束

简介: 分析一下自己的错误: 首先用Range的GetItem取到的是一个VARIANT,内含IDispatch接口,我一直以为内含的是一个BSTR,所以我已一开始直接用 _bstr_t   bs(rg.

分析一下自己的错误:

首先用Range的GetItem取到的是一个VARIANT,内含IDispatch接口,我一直以为内含的是一个BSTR,所以我已一开始直接用
_bstr_t   bs(rg.GetItem(_variant_t((short)1),_variant_t((short)2)));
来获取字符串(主要是的确能获得字符串),根据lop5712(LOP)的提醒,发现返回的VARIANT是接口并不是BSTR;

看来_bstr_t这个类可以把IDispatch接口直接转换为字符串。

跟踪代码发现,在给一个_bstr_t或COleVariant赋值VARIANT类型的时候,如果VARIANT不是VT_BSTR,这时候_bstr_t会调用OLE函数VariantChangeType进行类型转换,根据MSDN说明,如果转换是从一个IDispatch到BSTR,这时VariantChangeType会尝试接口的Value属性,而rg.GetItem返回的接口的确存在Value属性,因而_bstr_t和COleVariant能取到值。

根据上述原因,我们应该释放VARIANT所含的接口,但我用#import   指令导入Excel库的时候,却没有碰到这个问题,看来两种方式的代码是有区别的。

首先谈一下#import导入的情况:

Range   的GetItem声明为:
inline   _variant_t   Excel::Range::GetItem   (   const   _variant_t   &   RowIndex,   const   _variant_t   &   ColumnIndex   )   {
        VARIANT   _result;
        _com_dispatch_method(this,   0xaa,   DISPATCH_PROPERTYGET,   VT_VARIANT,   (void*)&_result,  
                L "/x000c/x080c ",   &RowIndex,   &ColumnIndex);
        return   _variant_t(_result,   false);
}

这种情况下返回的是_variant_t(_result,   false);
也就是说已经对返回的VARIANT用_variant_t包装了,而且重要的是第二个参数,第二个参数false告诉_variant_t包装VARIANT时仅仅把内容完整的复制过来,如果不含这个false(默认为true),_variant_t将采用OLE函数VariantCopy,根据MSDN,VariantCopy在碰到BSTR时会再分配一个空间,碰到接口类型时将对接口添加一个引用,所以_variant_t(_result,   false)直接把返回值存起来,并在析构的时候自动释放内含的IDispatch。

再来看一下用MFC导入的情况:
声明如下:
VARIANT   Range::GetItem(const   VARIANT&   RowIndex,   const   VARIANT&   ColumnIndex)
这时候返回的是未经过包装的VARIANT,不会自动释放,需要手动完成。

如果用_bstr_t   bs(rg.GetItem(_variant_t((short)1),_variant_t((short)2)));
将丢失返回的VARIANT,这就是我发生的错误。
我看到有的网站上的例子是这样的:
_variant_t   vt(rg.GetItem(_variant_t((short)1),_variant_t((short)2)));

_variant_t   vt=rg.GetItem(_variant_t((short)1),_variant_t((short)2));
这样做其实也是有问题的,虽然取到了VARIANT的值,但是不带false的_variant_t会添加一个引用,析构_variant_t只会Release一次,仍然造成对象释放不完全。

 

解决办法:每次VARIANT中的内容取出来后,调用VariantClear() 将VARIANT清除就好了

目录
相关文章
vue3 导出数据为Excel表格
vue3 导出数据为Excel表格
270 0
Echarts实战案例代码(19):利用visualMap视觉映射组件制作五色玫瑰工作进程图
Echarts实战案例代码(19):利用visualMap视觉映射组件制作五色玫瑰工作进程图
259 0
VS2005(excel2007)利用Automation(OLD Automation)方法。将Excel当成组件服务器的编译错误 我的系统盘和office都装在d盘。 自动生成的import有问题
VS2005(excel2007)利用Automation(OLD Automation)方法。将Excel当成组件服务器的编译错误 我的系统盘和office都装在d盘。 自动生成的import有问题
|
前端开发 C#
C# 基于NPOI+Office COM组件 实现20行代码在线预览文档(word,excel,pdf,txt,png)
C# 基于NPOI+Office COM组件 实现20行代码在线预览文档(word,excel,pdf,txt,png)
|
2月前
|
SQL 关系型数据库 MySQL
定时任务频繁插入数据导致锁表问题 -> 查询mysql进程
定时任务频繁插入数据导致锁表问题 -> 查询mysql进程
65 1
|
8月前
|
前端开发 Java
基于Java爬取微博数据(二) 正文长文本+导出数据Excel
【5月更文挑战第12天】基于Java爬取微博数据,正文长文本+导出数据Excel
|
6月前
|
Web App开发 前端开发 安全
2024年新一代WebOffice内嵌网页组件,Web网页在线编辑Word/Excel/PPT
WebOffice控件面临兼容性、用户体验和维护难题。随着浏览器更新,依赖插件的技术不再适用,如Chrome不再支持NPAPI和PPAPI。产品普遍不支持多版本Office并存,定制能力弱,升级复杂。猿大师办公助手提供了解决方案,它兼容多种浏览器,包括最新版和国产浏览器,不依赖插件,支持文档对比,具有丰富的功能和接口,兼容多种Office版本,允许源码级定制,提供终身技术支持,并实现静默在线升级。适用于多种行业和操作系统。
376 15
|
6月前
|
存储 对象存储 Python
`openpyxl`是一个用于读写Excel 2010 xlsx/xlsm/xltx/xltm文件的Python库。它不需要Microsoft Excel,也不需要.NET或COM组件。
`openpyxl`是一个用于读写Excel 2010 xlsx/xlsm/xltx/xltm文件的Python库。它不需要Microsoft Excel,也不需要.NET或COM组件。
|
6月前
|
Python
在Python中,`multiprocessing`模块提供了一种在多个进程之间共享数据和同步的机制。
在Python中,`multiprocessing`模块提供了一种在多个进程之间共享数据和同步的机制。
后端登录接口使用postman,无法接收返回数据,怎样解决,认真比较与原项目的代码,看看有没有写的不一样的,问题就能解决,不要多少写,根据postman的提示先找到错误的进程,看错误进程出现在那个进程
后端登录接口使用postman,无法接收返回数据,怎样解决,认真比较与原项目的代码,看看有没有写的不一样的,问题就能解决,不要多少写,根据postman的提示先找到错误的进程,看错误进程出现在那个进程

热门文章

最新文章

相关实验场景

更多