C++Builder 6中开拓Office措施心得(一)
当前位置:以往代写 > C/C++ 教程 >C++Builder 6中开拓Office措施心得(一)
2019-06-13

C++Builder 6中开拓Office措施心得(一)

C++Builder 6中开拓Office措施心得(一)

副标题#e#

一、用控件照旧用OLEAutomation?

这个问题应该说很常见。我也在任何大概的环境下僵持我的主张:用BCB 6提供的Server控件组。假如你是用Delphi 6/7版本开拓,那么用Delphi提供的Server控件组。

这样做有什么长处?我小我私家认为至少有如下两个:

第一,维护布局化+OO的措施设计气势气魄。譬喻:

ExcelApplication1->set_DisplayAlerts(0,false);
ExcelApplication1->Quit();

又如:

int SheetCount=ExcelWorkbook1->Worksheets->Count;

这些代码都照旧较量直观的。并且很具有OO的美感。

第二,强范例查抄胜于弱范例查抄。

假如利用OleGetProperty可能OleSetProperty函数,那么对通报给这两个函数的参数,是没有步伐节制的。譬喻,我完全可以随心配置一个单位格的属性FOO为100。可是这样的函数挪用在运行期必然会堕落。而利用Server控件就不会有这个问题——编译期就不能通过。可以在编译期发明并更正的错误,不要留到运行期去办理。这是我的主张。

二、须要的帮助手段

利用BCB编写节制Excel的措施,是很繁琐的。因为有时编译通事后会呈现难以琢磨的异常!又有一种很无助的感受:BCB在这上面的辅佐的确是BS。CodeInsight的速度又是相当的慢,无法忍受!

不外,我们不要等闲放弃。按照我的履历,在BCB下要想好好把握Excel编程,必需把握三个得到辅佐的途径。这三个得到辅佐的途径就是(以我小我私家爱好的水平降序分列):

Excel自己的宏呼吁。我此刻的习惯是,假如我要在BCB中实现一个成果,可是却不知道相应的要领和参数,我就会打开Excel,在随便一个Sheet顶用宏记录下我要举办的操纵,然后研究宏代码。这样做,必定能得到正确的要领名,可是对参数的数量和范例却不敢担保:这是因为VBA可以选择不PASS一些缺省参数。按照我的小我私家履历,这样做的有效性应该在80%阁下,浅易性在100%。

Office自带的VBA辅佐。这个辅佐在Office安装进程中一般不是缺省安装的。对付Office 2003中文版的用户,应该查抄C:\Program Files\Microsoft Office\OFFICE11\2052\下是否有雷同VBAxxnn.chm文件。个中xx应该是如下字符串之一:AC(Access),GR(Microsoft Graphics),OF(Office),OL(Outlook),OWS(Office Web Service),PB(Publisher),PP(PowerPoint),WD(Word),XL(Excel)。而nn是对应的Office应用的版本号。假如没有这些文件,请运行Office安装措施,在自界说安装中将这些文件安装即可。这些文件,对付我们领略Office应用中的DOM模子长短常有用的。其有效性为85%,浅易性约为80%。

BCB6中关于Server的头文件。这些头文件的位置应该是在:C:\Program Files\Borland\CBuilder6\Include\Vcl\下。我这里只截一张图。从这张图中,我们也可以看到,BCB6对Office的支持只到Office 2000。Delphi 7可以支持到Office XP。不外它们都能很好的在Office 2003下事情。自Delphi 8之后,我们应该用Interop来操纵Office了。这个要领的有效性是100%——因为你必然可以在内里找到BCB支持的要领,可是浅易性只有10%——因为这些头文件都相当的大:excel_2k.h的巨细是8M+!

C++Builder 6中开辟Office法子心得(一)

这三个手段应该相互帮衬,才气在更短的时间内找到正确的要领。并且通过这三个途径找到的要领、参数应该是相互对应、相互一致的。譬喻,移动一个Sheet到另一个Sheet的Move要领,其在上述三个辅佐途径中的界说别离如下:

在Excel的VBA宏里:Sheets("Sheet2").Move After:=Sheets(3)

Excel的VBA辅佐:见下图

C++Builder 6中开辟Office法子心得(一)

BCB的Excel头文件:

// *********************************************************************//
// Interface: IWorksheets
// Flags: (4112) Hidden Dispatchable
// GUID: {000208B1-0001-0000-C000-000000000046}
// *********************************************************************//
interface IWorksheets : public IDispatch
{
public:
… …
HRESULT STDMETHODCALLTYPE Copy(VARIANT Before/*[in,opt]*/= TNoParam(),
VARIANT After/*[in,opt]*/= TNoParam(),
… …
HRESULT STDMETHODCALLTYPE Move(VARIANT Before/*[in,opt]*/= TNoParam(),
VARIANT After/*[in,opt]*/= TNoParam(),
long lcid/*[in]*/= TDefLCID()); // [637]
… …


#p#副标题#e#

三、编程指南

(一) ExcelApplication的启动、退出

我们平时所说的启动/退出Excel,在BCB6中应该被确切的说成是ExcelApplication的启动/退出。对应的控件是C++Builder 6中开辟Office法子心得(一)。用来启动、退出的代码别离如下:

#p#分页标题#e#

void __fastcall TMainForm::EABtnClick(TObject *Sender)
{
try
{
EA->Connect();
}
catch(…)
{
ShowMessage("Can not launch server");
}
   EA->set_Caption((WideString)"Excel Server Invoked by BCB");
EA->set_Visible(0,true);
}
   __fastcall TMainForm::~TMainForm()
{
EA->set_DisplayAlerts(0,false);
EA->Quit();
}

留意,Office控件多以接口形式相互关联,所以毗连的要领也被贯之以Connect的名称。由于Excel Application必然是顶层工具,所以它的Connect要领不需要指定参数。

set_Caption是用来配置Excel Application的标题。请留意要用WideString,而不是String。

set_Visible(0, true)是使Excel Application可见。这里参数0是Locale ID。

Excel控件的封装是很奇怪的——也许是因为BCB 6只支持到Office 2000而今朝我们根基都是要操纵Office 2003而引起的版本兼容问题。一般来说,我们但愿直接利用雷同属性的操纵要领来修改。可是,有些属性,如Visible,就必需用“set_属性/get_属性 ”的方法举办操纵。这不是说Excel Application控件中没有Visible这个属性。这个属性确实存在于Excel Application控件中,可是假如你想直接操纵Visible属性,那么无论你写成:“EA->Visible=true;”照旧“EA->Visible[0]=true;”,编译时城市堕落!提示“TExcelApplication::Visible is not accessible. ”。而更奇怪的是,假如我们直接操纵属性,那么纵然编译可以或许通过,也大概没有实际效用!有乐趣的读者可以测试一下Caption属性的操纵。

一般而言,用set_属性/get_属性的方法,必然可以操纵一个属性。可是,有些Set要领的定名也不遵守这个纪律,后文即将涉及。

退出时,可以按照小我私家的爱好,配置DisplayAlerts属性。假如配置为true,那么在退出时,假如对Sheet或Workbook举办了一些需要存盘的操纵,会有一个确认框呈现。

以前曾经有一种说法,说是这样启动并正常退出的Excel Application,退出后会在内存中留下一个Excel历程。在我的呆板上,没有这样的景象。

需要增补的是ExcelApplication控件的ConnectKind属性。它一共有五个可选值:ckAttachToInterface/ckNewInstance/ckRunningOrNew/ckRemote/ckRunning。一般我城市用ckRunningOrNew。其它的选项我倒没有举办过测试。

#p#副标题#e#

(三) ExcelWorksheet的操纵

在上文毗连Workbook的代码中,我也同时毗连了TExcelWorksheet,其控件图标是C++Builder 6中开辟Office法子心得(一)。所以完整的代码段如下:

void __fastcall TMainForm::EWBBtnClick(TObject *Sender)
{
EWB->ConnectTo(EA->Workbooks->Add(TNP, 0));
// Connect to worksheet as well
EWS1->ConnectTo(EWB->Worksheets->get_Item(V("Sheet1")));
EWS2->ConnectTo(EWB->Worksheets->get_Item(V(2)));
  EWS3P=EWB->Worksheets->get_Item(V("Sheet3"));
EWS3->ConnectTo(EWS3P);
EWS3->Activate();
}

我们知道,缺省环境下,一个空缺的Excel Workbook有三个空缺的Worksheet,所以上文中我用三个ExcelWorksheet控件来毗连这三个Worksheet。

我们既可以用表的名字(如“Sheet1”),也可以用表的序号(如“2”)来作为一个表的索引号。请留意V要领,它也是我界说的一个宏:

#define V TVariant

所以,它只是一个用来结构TVariant参数的宏。它和上面的TNP宏都是蛮有用的界说。

下面是一些针对Excel Worksheet的操纵,不再一一具体说明。

void __fastcall TMainForm::MoveSheetBtnClick(TObject *Sender)
{
EWS1->Move(TNP, V(EWB->Worksheets->get_Item(V("Sheet3"))), 0);
}
//---------------------------------------------------------------------------
  void __fastcall TMainForm::RenameBtnClick(TObject *Sender)
{
String NewName;
InputQuery("Rename Excel Worksheet", "Input a new name", NewName);
EWS1->set_Name((WideString)NewName);
}
//---------------------------------------------------------------------------
  void __fastcall TMainForm::CreateBtnClick(TObject *Sender)
{
EWS4->ConnectTo(EWB->Sheets->
Add(TNP,V(EWB->Worksheets->get_Item(V("Sheet3"))),V(1),V(xlWorksheet)));
}
//---------------------------------------------------------------------------
  void __fastcall TMainForm::DelSheetBtnClick(TObject *Sender)
{
EWS2->Delete(0);
}

我们已经操纵到了Worksheet级别,可是在我们日常操纵中,打仗最多的是Range(范畴)和Cell(单位格),在后文我们将继承深入接头,并接头如何毗连数据库、如何画数据图,以及如何用TExcelQueryTable加快数据导入的要领。

这样生成的Excel Application只是一个空架子。我们要增加Workbook(事情簿)。

#p#副标题#e#

(二) ExcelWorkbook的建设和相关操纵

#p#分页标题#e#

假如我们把ExcelWorkbook简朴的领略为等价于一个xls文件,应该不会不同太大,并且应该对我们有辅佐。它的控件图标是C++Builder 6中开辟Office法子心得(一)。我们来看如何建设Workbook,代码如下:

void __fastcall TMainForm::EWBBtnClick(TObject *Sender)
// 本文转自 C++Builder研究 - http://www.ccrun.com/article.asp?i=1044&d=xr3888
{
EWB->ConnectTo(EA->Workbooks->Add(TNP, 0));
... ...
}

首先,我们要毗连到一个Workbook的接口上去,这里我们用的是新增一个Workbook的方法。留意TNP参数,我们会在许多场所利用它。它是我本身措施中界说的一个宏:

#define TNP TNoParam()

而第二个参数0,则又是Locale ID(简称LID)。

ExcelWorkbook还可以用来毗连——可能说“打开”更得当——一个现有的Workbook(一个xls文件),详细代码如下:

EWB->ConnectTo(EA->Workbooks->Open((WideString)"c:\\temp\\test.xls",
                 TNP, TNP, TNP, TNP,
                 TNP, TNP, TNP, TNP,
                 TNP, TNP, TNP, TNP, 0));

上述代码中打开了位于c:\temp下的test.xls文件。这个要领有许多参数,一般我城市通报TNP给它。详细参数的寄义,可以参考相关文档。

#p#副标题#e#

(三) ExcelWorksheet的操纵

在上文毗连Workbook的代码中,我也同时毗连了TExcelWorksheet,其控件图标是C++Builder 6中开辟Office法子心得(一)。所以完整的代码段如下:

void __fastcall TMainForm::EWBBtnClick(TObject *Sender)
{
EWB->ConnectTo(EA->Workbooks->Add(TNP, 0));
// Connect to worksheet as well
EWS1->ConnectTo(EWB->Worksheets->get_Item(V("Sheet1")));
EWS2->ConnectTo(EWB->Worksheets->get_Item(V(2)));
EWS3P=EWB->Worksheets->get_Item(V("Sheet3"));
EWS3->ConnectTo(EWS3P);
EWS3->Activate();
}

我们知道,缺省环境下,一个空缺的Excel Workbook有三个空缺的Worksheet,所以上文中我用三个ExcelWorksheet控件来毗连这三个Worksheet。

我们既可以用表的名字(如“Sheet1”),也可以用表的序号(如“2”)来作为一个表的索引号。请留意V要领,它也是我界说的一个宏:

#define V TVariant

所以,它只是一个用来结构TVariant参数的宏。它和上面的TNP宏都是蛮有用的界说。

下面是一些针对Excel Worksheet的操纵,不再一一具体说明。

void __fastcall TMainForm::MoveSheetBtnClick(TObject *Sender)
{
EWS1->Move(TNP, V(EWB->Worksheets->get_Item(V("Sheet3"))), 0);
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::RenameBtnClick(TObject *Sender)
{
String NewName;
InputQuery("Rename Excel Worksheet", "Input a new name", NewName);
EWS1->set_Name((WideString)NewName);
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::CreateBtnClick(TObject *Sender)
{
EWS4->ConnectTo(EWB->Sheets->
Add(TNP,V(EWB->Worksheets->get_Item(V("Sheet3"))),V(1),V(xlWorksheet)));
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::DelSheetBtnClick(TObject *Sender)
{
EWS2->Delete(0);
}

我们已经操纵到了Worksheet级别,可是在我们日常操纵中,打仗最多的是Range(范畴)和Cell(单位格),在后文我们将继承深入接头,并接头如何毗连数据库、如何画数据图,以及如何用TExcelQueryTable加快数据导入的要领。

    关键字:

在线提交作业