控件方式与OLE方式同时存在时报错了

蒙飞鸿 2012-11-26 03:39:11
用BCB操作EXCEL,网上都介绍两种方法,一是使用EXCEL控件,二是使用OLE。我需要做MDB转EXCEL,用的EXCEL控件方式能够把数据都转过来了,但是图片没能对齐,于是用OLE方式实现了图片对齐。

结果这两套代码能在一起通过编译,但运行了就报错,除非注释掉一套中的修改、写入EXCEL的代码。

怎么解决这个问题?
代码如下:
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Variant vExcelApp, vPic, vSheet, vShapeRange;

vExcelApp = Variant::CreateObject("Excel.Application");

// 使其可视
vExcelApp.OlePropertySet("Visible", true);
// 打开一个Excel文档
vExcelApp.OlePropertyGet("workbooks").OleFunction("open", "d:\\2.xls");
// 获取图像总数
int nPicsCount = vExcelApp.OlePropertyGet("ActiveSheet")
.OlePropertyGet("Pictures").OlePropertyGet("Count");
vSheet = vExcelApp.OlePropertyGet("ActiveSheet");
// 下面遍历当前ActiveSheet中的图像,不要直接运行
// 请自己修改后再执行,代码已测试过
for(int i=0; i<nPicsCount; i++)
{
vPic = vSheet.OlePropertyGet("Pictures").OlePropertyGet("Item", i+1);

String strPicID = String("Picture ") + String(i+1);
vSheet.OlePropertyGet("Shapes")
.OleFunction("Item", strPicID.c_str())
.OleProcedure("Select");

vSheet.OlePropertyGet("Shapes")
.OleFunction("Item", strPicID.c_str())
.OleProcedure("Select");
vShapeRange = vExcelApp.OlePropertyGet("Selection").OlePropertyGet("ShapeRange");

vShapeRange.OleProcedure("IncrementLeft",2);
vShapeRange.OleProcedure("IncrementTop",2);
// 调整图像大小结束
}
vExcelApp.OleFunction("Quit");

}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ExcelApplication1->Connect();
ExcelApplication1->set_Visible(0, true);
ExcelApplication1->set_DisplayAlerts(0,false);
ExcelWorkbook1->ConnectTo(ExcelApplication1->Workbooks->Open((WideString)"d:\\2.xls",
TNP, TNP, TNP, TNP,
TNP, TNP, TNP, TNP,
TNP, TNP, TNP, TNP, 0));
ExcelWorksheet1->ConnectTo(ExcelWorkbook1->Worksheets->get_Item(V(1)));

String ConnStr;
RangePtr R;
String SQL;
ExcelWorksheet1->Activate();
ADOConnection1->ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=e:\\111.mdb;Persist Security Info=False";
//ConnStr="ODBC;DSN=mm;UID='';PWD=''";
ConnStr="OLEDB;"+ADOConnection1->ConnectionString;
SQL="select * from steel";
R=ExcelWorksheet1->get_Range(V("a1"), V("a1"));

ExcelQueryTable1->ConnectTo(ExcelWorksheet1->QueryTables->Add(V(ConnStr), R, V(SQL)));
ExcelQueryTable1->Refresh();
ExcelWorksheet1->Rows->set_RowHeight(V(30));

ADOQuery1->SQL->Text="select * from steel";
ADOQuery1->Open();
int i,j,k;
String Col="a";
String newCol;
for(i=0;i<ADOQuery1->FieldCount;i++)
{
if(ADOQuery1->Fields->Fields[i]->FieldName == "图形")
{
newCol = Col+IntToStr(1);
R = ExcelWorksheet1->get_Range(V(newCol),V(newCol));
R = R->get_EntireColumn();
R->Insert(V(0));
R = ExcelWorksheet1->get_Range(V(newCol),V(newCol));
R->set_Value(V("图形"));
R->set_ColumnWidth(V(40));
break;
}
Col=GetNextColName(Col);
}

unsigned int DataHandle;
HPALETTE APalette;
unsigned short MyFormat;
Graphics::TBitmap *bmp=new Graphics::TBitmap();
RangePtr r;

Excel_2k::ShapesPtr ss;
Excel_2k::ShapePtr s;


ADOQuery1->First();
for(i = 0; i < ADOQuery1->RecordCount; i++)
{
Image1->Picture->Assign(ADOQuery1->FieldByName("图形"));//将字段内容转为图片
String strPos=Col+IntToStr(i+1);
r=ExcelWorksheet1->get_Range(V(strPos),V(strPos));

if(ADOQuery1->FieldByName("图形")->IsNull)
{
ADOQuery1->Next();
continue;
}
bmp->Width=Image1->Width;
bmp->Height=Image1->Height;
bmp->Canvas->StretchDraw(Rect(0,0,bmp->Width,bmp->Height),
Image1->Picture->Graphic);

bmp->SaveToClipboardFormat(MyFormat,DataHandle,APalette);

Clipboard()->SetAsHandle(MyFormat,DataHandle);
ExcelWorksheet1->Paste(V(LPDISPATCH(r)), TNP, 0);

ADOQuery1->Next();
}

delete bmp;
ADOQuery1->Close();

ExcelWorkbook1->Disconnect();
ExcelWorksheet1->SaveAs((WideString)"d:\\2.xls",
TNP, TNP, TNP, TNP,
TNP, TNP, TNP, TNP,
0 );
ExcelWorksheet1->Disconnect();
ExcelApplication1->Quit();
ExcelApplication1->Disconnect();

}
...全文
255 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
ccrun.com 2012-11-27
  • 打赏
  • 举报
回复
同意楼上意见。
蒙飞鸿 2012-11-27
  • 打赏
  • 举报
回复
顺便总结一下,BCB操作EXCEL,如果比较复杂,最好还是用OLE,通过宏分析,应该能解决所有问题,而用BCB控件,资料少,支持不足,搞到后面发现有些动作不能实现,那叫一个憋屈。同理应该可推到其他BCB编程上。
蒙飞鸿 2012-11-27
  • 打赏
  • 举报
回复
啊哈,最简化代码找到问题了,vBook=...的这句放的位置靠前了,在....("Add")后, ....("SaveAs",ExcelName.c_str());成功了。 不过我记得之前我并没有使用vBook,而是直接vExcelApp.PG("workbooks").FN("SaveAs",ExcelName.c_str())的,当时报错了,现在试了应该是用vExcelApp.PG("ActiveWorkBook").FN("SaveAs",ExcelName.c_str()); 问题解决了,结帐。。
蒙飞鸿 2012-11-27
  • 打赏
  • 举报
回复
现在最简化代码了:
我是在虚拟机里的环境,BCB6,系统是MS纯净原版XP,OFFICE2003虽然也是下来的但好象问题应该都不在这些环境上吧?
如图下的断点,进入该句后再也不能回到代码领空就报错了,错误如前
ccrun.com 2012-11-27
  • 打赏
  • 举报
回复
你确认是SaveAs这一句代码引起的错误?
蒙飞鸿 2012-11-27
  • 打赏
  • 举报
回复
void TForm1::DBToExcel(String DBName,String ExcelName) { ... vBook.OleFunction("SaveAs",WideString(ExcelName)); //不行 //vBook.OleFunction("SaveAs",Variant(ExcelName)); 也不行 ... } DBToExcel("e:\\111.mdb","e:\\111.xls");
蒙飞鸿 2012-11-27
  • 打赏
  • 举报
回复

还是不行
ccrun.com 2012-11-27
  • 打赏
  • 举报
回复
另外,判断文件是否存在,不能用DirectoryExists函数,要用FileExists函数。
ccrun.com 2012-11-27
  • 打赏
  • 举报
回复
vBook.OleFunction("SaveAs", WideString(ExcelName));
蒙飞鸿 2012-11-27
  • 打赏
  • 举报
回复
引用 3 楼 ccrun 的回复:
引用 2 楼 mengfeihong 的回复: OLE怎么贴图啊?网上貌似没有这个方法,用控件的话是worksheet调用剪贴板来粘贴,参考VC的话是用shapes.AddPicture,OLE里怎么弄? 请说出你的详细需求,至于在OLE中通过粘贴操作来贴图,我在以前回复别的网友问题时贴过代码,只是你搜索的方法不对而已。
已经解决了,借贴问最后一个问题了:现在就是保存不成功文件,代码如下: vExcelApp = Variant::CreateObject("Excel.Application"); vBook = vExcelApp.PG("ActiveWorkBook"); // 使其可视 vExcelApp.PS("Visible", true); // 打开一个Excel文档 if(DirectoryExists(ExcelName))DeleteFile(ExcelName); vExcelApp.OlePropertyGet("workbooks").OleFunction("Add"); 。。。 vBook.OleFunction("SaveAs",ExcelName.c_str()); vExcelApp.OleFunction("Quit"); /////////////////////////////////////////////////////////// 在vBook.OleFunction("SaveAs",ExcelName.c_str())处出错,ExcelName="e:\\111.xls".
ccrun.com 2012-11-26
  • 打赏
  • 举报
回复
引用 2 楼 mengfeihong 的回复:
OLE怎么贴图啊?网上貌似没有这个方法,用控件的话是worksheet调用剪贴板来粘贴,参考VC的话是用shapes.AddPicture,OLE里怎么弄?
请说出你的详细需求,至于在OLE中通过粘贴操作来贴图,我在以前回复别的网友问题时贴过代码,只是你搜索的方法不对而已。
蒙飞鸿 2012-11-26
  • 打赏
  • 举报
回复
引用 1 楼 ccrun 的回复:
为什么要两种方式一起使用呢?都用OLE代码来操作多方便。
OLE怎么贴图啊?网上貌似没有这个方法,用控件的话是worksheet调用剪贴板来粘贴,参考VC的话是用shapes.AddPicture,OLE里怎么弄?
ccrun.com 2012-11-26
  • 打赏
  • 举报
回复
为什么要两种方式一起使用呢?都用OLE代码来操作多方便。
包含使用和开发接口文档,及Delphi、VB、VC++、C#.net、VB.net的demo。 ACReport简介 Anycell Report(简称ACReport)是一款中国式报表组件,是国内最早的基于表格,支持图文混排、公式和脚本的中国式报表工具之一。就如Anycell Report的名称那样,灵活强大的表格功能一直是AC Report区别于其它软件或控件最显著的特征之一,AC Report 表格取消了传统表格概念中“列”的概念,每一行上的单元格数量可以不等,且可以自由活动,不用上下对齐,在制作复杂的中国式报表更加方便和随心所欲,省省力,避免很多不必要的合并拆分操作。单元格支持多种丰富的形态,例如格式化文本、图片、图表、条码、OLE容器等。 AC Report的一些基本特点: 1.独具特色的表格,风格与Word表格相似,但可以做出比Word或Excel更灵活的表格来。 2. 功能全面、专业的中国式报表设计器,中国用户更易于学习和接受。 3.支持多种单元格样式,可以打印图像、图表(直方图、折线图等)、Rich文本、 条形码、中式财务帐薄、支持在报表中嵌入Word、Excel文档等。 4. 强大的计算和合计功能。内置表达式解析系统和函数库。 5. 可扩充性,可以在应用程序中给报表引擎扩充函数库、报表样式和单元格样式。 6.支持多种报表样式,如清单式、分组、交叉表、以及子报表等。 7. 支持多栏式报表。 8. 和应用程序完美结合,支持windows下所有的开发工具和程序语言(例如Delphi、C++、VB、PB、.NET、易语言),最终用户在设计器里可直接选择打印字段,生成表达式,报表设计器用户容易学习理解。 9. 支持脚本和窗体编程,报表设计人员可以编写脚本、在报表设计器里为报表添加窗体,为最终用户提供更丰富的交互功能。 10. 既可以使用应用程序中的数据集,也支持在报表中直接连接各种数据库,通过SQL直接获得报表需要的数据。 11.无失真导出为Excel、Word、Html格式的文档 Ver 2.25 主要新增或修改的功能 一、 增加报表行对象隐藏功能(支持在脚中设置,函数名:SetLineVisible(b: boolean))【设计器】 二、 增加单元格下拉列表框设置功能【设计器】 三、 增加宏替换功能(宏变量)的支持【设计器】 四、 增加IAcFuncionLib接口支持,以一种新的方式扩充函数库【SDK】 五、 增加LoadFromStream和SaveToStream方法及IAcNetStream接口支持【SDK】 六、 修改了单元格批量复制粘帖功能,当粘帖位置行数不够,粘帖自动增加行。【设计器】 七、 修改了单元格拖动会出现字符显示错位的问题【设计器】 八、 屏蔽了设计器中打开模板如果数据库控件连接字符串无效报错的信息【脚本】 九、 设计器增加了行号显示功能 十、 增加了SetAppConnectionString方法,数据库连接控件增加了AlwaysUseAppConnString等相关属性,在报表中直接访问数据库更加方便。 十一、清单报表明细支持横向分栏
包含使用和开发接口文档,及Delphi、VB、VC++、C#.net、VB.net的demo。 ACReport简介 Anycell Report(简称ACReport)是一款中国式报表组件,是国内最早的基于表格,支持图文混排、公式和脚本的中国式报表工具之一。就如Anycell Report的名称那样,灵活强大的表格功能一直是AC Report区别于其它软件或控件最显著的特征之一,AC Report 表格取消了传统表格概念中“列”的概念,每一行上的单元格数量可以不等,且可以自由活动,不用上下对齐,在制作复杂的中国式报表更加方便和随心所欲,省省力,避免很多不必要的合并拆分操作。单元格支持多种丰富的形态,例如格式化文本、图片、图表、条码、OLE容器等。 AC Report的一些基本特点: 1.独具特色的表格,风格与Word表格相似,但可以做出比Word或Excel更灵活的表格来。 2. 功能全面、专业的中国式报表设计器,中国用户更易于学习和接受。 3.支持多种单元格样式,可以打印图像、图表(直方图、折线图等)、Rich文本、 条形码、中式财务帐薄、支持在报表中嵌入Word、Excel文档等。 4. 强大的计算和合计功能。内置表达式解析系统和函数库。 5. 可扩充性,可以在应用程序中给报表引擎扩充函数库、报表样式和单元格样式。 6.支持多种报表样式,如清单式、分组、交叉表、以及子报表等。 7. 支持多栏式报表。 8. 和应用程序完美结合,支持windows下所有的开发工具和程序语言(例如Delphi、C++、VB、PB、.NET、易语言),最终用户在设计器里可直接选择打印字段,生成表达式,报表设计器用户容易学习理解。 9. 支持脚本和窗体编程,报表设计人员可以编写脚本、在报表设计器里为报表添加窗体,为最终用户提供更丰富的交互功能。 10. 既可以使用应用程序中的数据集,也支持在报表中直接连接各种数据库,通过SQL直接获得报表需要的数据。 11.无失真导出为Excel、Word、Html格式的文档 Ver 2.25 主要新增或修改的功能 一、 增加报表行对象隐藏功能(支持在脚中设置,函数名:SetLineVisible(b: boolean))【设计器】 二、 增加单元格下拉列表框设置功能【设计器】 三、 增加宏替换功能(宏变量)的支持【设计器】 四、 增加IAcFuncionLib接口支持,以一种新的方式扩充函数库【SDK】 五、 增加LoadFromStream和SaveToStream方法及IAcNetStream接口支持【SDK】 六、 修改了单元格批量复制粘帖功能,当粘帖位置行数不够,粘帖自动增加行。【设计器】 七、 修改了单元格拖动会出现字符显示错位的问题【设计器】 八、 屏蔽了设计器中打开模板如果数据库控件连接字符串无效报错的信息【脚本】 九、 设计器增加了行号显示功能 十、 增加了SetAppConnectionString方法,数据库连接控件增加了AlwaysUseAppConnString等相关属性,在报表中直接访问数据库更加方便。 十一、清单报表明细支持横向分栏 最新版v2.25,请从这里下载: http://download.csdn.net/source/2931469 (若发现bug或有什么问题请加qq:1655373859)

703

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder ActiveX/COM/DCOM
社区管理员
  • ActiveX/COM/DCOM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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