控件方式与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();

}
...全文
252 13 打赏 收藏 转发到动态 举报
写回复
用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代码来操作多方便。

703

社区成员

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

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