OLE操作Excel发现一个问题

青蛙工作室 2020-07-21 03:27:23
用OLE法操作Excel,主要代码是这样的:

Variant Ex;
int swp, Err;
Ex =GetActiveOleObject(L"Excel.Application") ; //指向正在运行的Excel
swp = SetWindowPos( Ex.OlePropertyGet(L"hWnd"), 0, 0, 0, 0, 0, 0x43 ); //设置Excel为最前端窗口
//错误就在这里,swp返回0
if(swp==0) {
Err = GetLastError() ; //这里Err得到1400,查得解释是无效的句柄
Return ;
}
//别的一些代码,忽略



经追踪,发现 Ex.OlePropertyGet(L"hWnd")得到的值并不是Excel程序的句柄,因为在Excel用VBA取Excel的句柄,得到的是另一个值。把VBA得到的Excel句柄比如198656代入,SetWindowPos((void*)198656,0, 0, 0, 0, 0, 0x43 ); 能正确返回1而且Excel也确实被置到最前端。

问题就是,如何从OLE语句取得Excel的句柄?
...全文
102 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
就像(HWND__ *)这个类型转换暗示的那样,这个Varaint存储的是一个指向HWND的指针(引用),如果直接传参Ex.OlePropertyGet(L"hWnd"),会把这个指针作为HWND传入...
青蛙工作室 2020-07-23
  • 打赏
  • 举报
回复
引用 3 楼 早打大打打核战争 的回复:
Delphi中这样写是可以的,但是在CB中这些确实不行。原因在于CB中的Variant是用类模拟的,不像Delphi中是编译器直接支持的原生类型,有编译器魔术支持。在CB中这么写就可以了: SetWindowPos((HWND__ *)Ex.OlePropertyGet(L"hWnd").byref, 0, 0, 0, 0, 0, 0x43 );
加个.byref,得到正确的句柄了。我用的CB2009,不需要转换类型。 byref在VB是按址传递,在CB是什么个意思?为什么就能够得到句柄
  • 打赏
  • 举报
回复
Delphi中这样写是可以的,但是在CB中这些确实不行。原因在于CB中的Variant是用类模拟的,不像Delphi中是编译器直接支持的原生类型,有编译器魔术支持。在CB中这么写就可以了:
SetWindowPos((HWND__ *)Ex.OlePropertyGet(L"hWnd").byref, 0, 0, 0, 0, 0, 0x43 );
青蛙工作室 2020-07-21
  • 打赏
  • 举报
回复
引用 1 楼 早打大打打核战争 的回复:
Ex.hWnd难道不行
OLE不是这么写法的,再说,Ex是Variant类型,没有hWnd这种属性。 我用的OLE的写法在别的方面都能正常,比如Ex.OlePropertyGet(L"ActiveWorkbook")就能得到活动工作簿,OlePropertySet()则可以写入,参数是属性,可以参考VBA的写法来用。
  • 打赏
  • 举报
回复
Ex.hWnd难道不行
【前言】 工作或学习中可能需要实现基于VC读\写Excel文件的功能,本人最近也遇到了该问题。中间虽经波折,但是最终还是找到了解决问题的办法。 在此跟大家分享,希望对跟我同样迷茫过的同学们有所帮助。 1、程序功能 1)打开一个excel文件; 2)显示到CListCtrl上; 3)新建一个Excel文件。 以上均在对话框中实现。 2、平台 VC++2010 3、实现方法 常用的Excel打开方式有两种 1)通过数据库打开; 2)OLE方式打开。 由于方式1)操作繁琐,经常出现莫名的错误,这里选用方式2). 4、准备步骤 首先新建一个Dialog窗体程序,添加list control和两个按钮 1)将ExcelLib文件夹拷贝到程序目录下; 2)将Export2Excel.h,Export2Excel.cpp两个文件添加到项目; 3)包含头文件,#include "ExcelLib/Export2Excel.h" 通过以上步骤在程序中引入了可以读取Excle文件的CExport2Excel类; 5、打开excel文件 通过按钮点击打开 void CExcelTestDlg::OnBnClickedButtonOpenExcel() { //获取文件路径 CFileDialog* lpszOpenFile; CString szGetName; lpszOpenFile = new CFileDialog(TRUE,"","",OFN_FILEMUSTEXIST|OFN_HIDEREADONLY,"Excel File(*.xlsx;*.xls)|*.xls;*.xlsx",NULL); if (lpszOpenFile->DoModal()==IDOK) { szGetName = lpszOpenFile->GetPathName(); SetWindowText(szGetName); delete lpszOpenFile; } else return; //打开文件 //文件中包含多个sheet时,默认打开第一个sheet CExport2Excel Excel_example; Excel_example.OpenExcel(szGetName); //获取sheet个数 int iSheetNum = Excel_example.GetSheetsNumber(); //获取已使用表格行列数 int iRows = Excel_example.GetRowCount(); int iCols = Excel_example.GetColCount(); //获取单元格的内容 CString cs_temp = Excel_example.GetText(1,1); //AfxMessageBox(cs_temp); //List control上显示 //获取工作表列名(第一行) CStringArray m_HeadName; m_HeadName.Add(_T("ID")); for (int i=1;iGetItemCount()>0) { m_list.DeleteColumn(0); } //初始化ClistCtrl,加入列名 InitList(m_list,m_HeadName); //填入内容 //第一行是标题,所以从第2行开始 CString num; int pos; for (int row = 2;row<=iRows; row++) { pos = m_list.GetItemCount(); num.Format(_T("%d"),pos +1); m_list.InsertItem(pos,num); for (int colum=1;columDoModal()==IDOK) { szGetName = lpszOpenFile->GetPathName(); SetWindowText(szGetName); delete lpszOpenFile; } else return; //文件全名称 CString csFileName = szGetName; //需要添加的两个sheet的名称 CString csSheetName = "newSheet"; CString csSheetName2 = "newSheet2"; // 新建一个excel文件,自己写入文字 CExport2Excel Excel_example; //新建excel文件 Excel_example.CreateExcel(csFileName); //添加sheet,新加的sheet在前,也就是序号为1 Excel_example.CreateSheet(csSheetName); Excel_example.CreateSheet(csSheetName2); //操作最开始添加的sheet:(newSheet) Excel_example.SetSheet(2); //添加表头 Excel_example.WriteHeader(1,"第一列"); Excel_example.WriteHeader(2,"第二列"); //添加核心数据 Excel_example.WriteData(1,1,"数据1"); Excel_example.WriteData(1,2,"数据2"); //保存文件 Excel_example.Save(); //关闭文件 Excel_example.Close(); } 7、注意事项 1)一般单个Excel文件包含多个sheet,程序默认打开第一个; 2)指定操作sheet,使用Excel_example.SetSheet(2)函数; 3)打开文件时最左侧的sheet序号为1,新建excel时最新添加的sheet序号为1. 【后记】 本程序主要基于网络CSDN中---“Excel封装库V2.0”---完成,下载地址是:http://download.csdn.net/detail/yeah2000/3576494,在此表示感谢!同时, 1)在其基础上作了小改动,改正了几个小错误,添加了几个小接口; 2)添加了如何使用的例子,原程序是没有的; 3)详细的注释 发现不足之处,还请大家多多指教!
具体内容请参考我的BLOG:http://blog.csdn.net/smallwhiteyt/archive/2009/11/08/4784771.aspx 如果你耐心仔细看完本文,相信以后再遇到导出EXCLE操作的时候你会很顺手觉得SO EASY,主要给新手朋友们看的,老鸟可以直接飘过了,花了一晚上的时间写的很辛苦,如果觉得对你有帮助烦请留言支持一下,我会写更多基础的原创内容来回报大家。 C#导出数据到EXCEL表格是个老生常谈的问题了,写这篇文章主要是给和我一样的新手朋友提供两种导出EXCEL的方法并探讨一下导出的效率问题,本文中的代码直接就可用,其中部分代码参考其他的代码并做了修改,抛砖引玉,希望大家一起探讨,如有不对的地方还请大家多多包涵并指出来,我也是个新手,出错也是难免的。 首先先总结下自己知道的导出EXCEL表格的方法,大致有以下几种,有疏漏的请大家补充。 1.数据逐条逐条的写入EXCEL 2.通过OLEDB把EXCEL做为数据源来写 3.通过RANGE范围写入多行多列内存数据到EXCEL 4.利用系统剪贴板写入EXCEL 好了,我想这些方法已经足够完成我们要实现的功能了,方法不在多,在精,不是么?以上4中方法都可以实现导出EXCEL,方法1为最基础的方法,意思就是效率可能不是太高,当遇到数据量过大时所要付出的时间也是巨大的,后面3种方法都是第一种的衍生,在第一种方法效率低下的基础上改进的,这里主要就是一个效率问题了,当然如果你数据量都很小,我想4种方法就代码量和复杂程度来说第1种基本方法就可以了,或当你的硬件非常牛逼了,那再差的方法也可以高效的完成也没有探讨的实际意义了,呵呵说远了,本文主要是在不考虑硬件或同等硬件条件下单从软件角度出发探讨较好的解决方案。

13,826

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧