高分求教:如何在Delphi的应用程序中嵌入Excel,实现数据库和Excel数据的转换?

hua025 2003-05-20 10:50:34
1、要求在TOleContainer的界面上显示Excel,并且在用户点击了从数据库导出数据后,Excel能够把数据在Form的界面内显示,并且保存到文件中去;而当用户在Excel的工作表(可以是从用户准备好的现有的一个xls文件或者是新创建的一个空白文文件)编辑数据后,点击导入到数据库中去时,程序把数据导入到数据库中。
2、下面是我已经完成的一个程序,使用的是TExcelApplication(不是OLEContainer),缺点是Excel显示独立于程序的界面,而这是不允许的。不知道是因为我没有彻底掌握TExcelApplication的用法还是这种方法只能达到这样的效果?
3、请大侠指教哪些书有关于Delphi操作Excel、嵌入VBA的介绍?谢谢
------------------------------------------------------------------------------
unit MsgParam;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB, StdCtrls,Excel2000, OleCtnrs;

type
TForm1 = class(TForm)
BtnExportMsg: TButton;
ADOConnection1: TADOConnection;
ParamADOQuery: TADOQuery;
CloADOQuery: TADOQuery;
MsgParamSaveDialog: TSaveDialog;
BtnImportMsg: TButton;
MsgParamOpenDialog: TOpenDialog;
SelectStructComboBox: TComboBox;
Label1: TLabel;
OleContainer1: TOleContainer;
BtnCloseFile: TButton;
BtnExportParam: TButton;

procedure BtnExportMsgClick(Sender: TObject);
procedure BtnImportMsgClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure SelectStructComboBoxChange(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure BtnCloseFileClick(Sender: TObject);
procedure BtnExportParamClick(Sender: TObject);

private
{ Private declarations }
IsFileOPen:boolean;
StructName:string;
ExcelApplication1: TExcelApplication;
procedure ExportMsg(StructName:string;ExportFileName:string);

public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ExportMsg(StructName:string;ExportFileName:string);
var
ExcelWorksheet1: TExcelWorksheet;
ExcelWorkbook1: TExcelWorkbook;
i, j: integer;
begin
if StructName='' then
begin
exit;
end;

if ExportFileName='' then
begin
exit;
end;

ExcelWorksheet1 := TExcelWorksheet.Create(Application);
ExcelWorkbook1 := TExcelWorkbook.Create(Application);
try
ExcelApplication1.Workbooks.Add(EmptyParam, 0);
ExcelWorkbook1.ConnectTo(ExcelApplication1.Workbooks[1]);
ExcelWorksheet1.ConnectTo(ExcelWorkbook1.Worksheets[1] as _worksheet);

ExcelApplication1.Visible[0]:=True;//设置显示Excel
//打开数据库并显示已有的消息参数取值(即表格的第一行)
ParamADOQuery.Active:=false;
ParamADOQuery.SQL.Clear;
ParamADOQuery.SQL.Add('Select ParamName from MSGParamsOrder where StructName='''+StructName+''' order by ParamOrder');
ParamADOQuery.Active:=true;
ParamADOQuery.ExecSQL();
ParamADOQuery.First;
ExcelWorksheet1.Cells.item[1,1] :='MsgName';
ExcelWorksheet1.Cells.item[1,1].font.size := '10';
for i := 1 to ParamADOQuery.RecordCount do
begin
ExcelWorksheet1.Cells.item[1, i+1] := ParamADOQuery.Fields[0].Asstring;
ExcelWorksheet1.Cells.item[1, i+1].font.size := '10';
ParamADOQuery.Next;
end;
ParamADOQuery.First;
//下面首先填写位于表格第一列的消息名称
CloADOQuery.Active:=false;
CloADOQuery.SQL.Clear;
CloADOQuery.SQL.Add('Select MessageName from Messages where StructName='''+StructName+'''');
CloADOQuery.Active:=true;
CloADOQuery.ExecSQL();
CloADOQuery.First;
for i := 1 to CloADOQuery.RecordCount do
begin
ExcelWorksheet1.Cells.item[i+1, 1] := CloADOQuery.Fields[0].Asstring;
ExcelWorksheet1.Cells.item[i+1, 1].font.size := '10';
CloADOQuery.Next;
end;
CloADOQuery.First;
//以参数为外循环,消息名为内循环填写消息参数表。
for i:=1 to ParamADOQuery.RecordCount do
begin//外循环,每个参数为一列,按列填写。
CloADOQuery.Active:=false;
CloADOQuery.SQL.Clear;
CloADOQuery.SQL.Add('Select Content from MSGParamsTable where StructName='''+StructName+''' and ParamName= '''+ParamADOQuery.Fields[0].Asstring+'''order by MessageName ');//
//showmessage(CloADOQuery.SQL.Text);
CloADOQuery.Active:=true;
CloADOQuery.ExecSQL();
CloADOQuery.First;
for j:=1 to CloADOQuery.RecordCount do
begin
ExcelWorksheet1.Cells.item[j+1, i+1] := CloADOQuery.Fields[0].Asstring;
ExcelWorksheet1.Cells.item[j+1, i+1].font.size := '10';
CloADOQuery.Next;
end;
ParamADOQuery.Next;//移动游标到下一个参数,即开始写新的一列
end;
ExcelWorksheet1.Columns.AutoFit;

try
ExcelWorksheet1.SaveAs(ExportFileName);//注意,此处没有加保护,当用户取消保存时将出错
ShowMessage('该结构的消息已经成功备份到'+ExportFileName);
except
ShowMessage('备份失败');
end;
finally
ExcelWorksheet1.Free;
ExcelApplication1.Workbooks.Close(0);
ExcelWorkbook1.Free;
end;
end;



procedure TForm1.BtnExportMsgClick(Sender: TObject);
var
ExportFileName:string;
begin
//MsgParamSaveDialog.FileName:=StructName;
MsgParamSaveDialog.FileName:='';
MsgParamSaveDialog.Execute;
ExportFileName:=MsgParamSaveDialog.FileName;
if ExportFileName<>'' then
begin
ExportMsg(StructName,ExportFileName);
end
else
begin
ShowMessage('您已经放弃备份!');
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
i:integer;
begin
try//打开Excel
ExcelApplication1 := TExcelApplication.Create(Application);
ExcelApplication1.Connect;
except
Application.Messagebox('Excel.exe Not Found!', 'MsgPool', MB_ICONERROR + mb_Ok);
Abort;
end;

ParamADOQuery.Active:=false;
ParamADOQuery.SQL.Clear;
ParamADOQuery.SQL.Add('select StructName from Structs');
//ShowMessage(ParamADOQuery.SQL.Text);
ParamADOQuery.Active:=true;
for i := 1 to ParamADOQuery.RecordCount do
begin
SelectStructComboBox.AddItem(ParamADOQuery.Fields[0].Asstring,nil);
ParamADOQuery.Next;
end;
BtnImportMsg.Enabled:=false;
BtnExportMsg.Enabled:=false;
end;

procedure TForm1.SelectStructComboBoxChange(Sender: TObject);
begin
StructName:=SelectStructComboBox.Text;
BtnImportMsg.Enabled:=true;
BtnExportMsg.Enabled:=true;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ExcelApplication1.Disconnect;
ExcelApplication1.Quit;
//ExcelApplication1.Free;
end;
...全文
505 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
hua025 2003-09-21
  • 打赏
  • 举报
回复
不把Excel嵌入到程序里去了,搞不定。现在我是使用TExcelApplication等对象部分地实现了这些功能
hua025 2003-06-18
  • 打赏
  • 举报
回复
unit ParamList;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB, OleCtnrs, Menus, StdCtrls,Excel2000;

type
TForm1 = class(TForm)
ExcelMainMenu: TMainMenu;
ExcelOleContainer: TOleContainer;
MsgParamOpenDialog: TOpenDialog;
MsgParamSaveDialog: TSaveDialog;
ADOConnection1: TADOConnection;
ParamADOQuery: TADOQuery;
ColADOQuery: TADOQuery;
ParamFile: TMenuItem;
NewFile: TMenuItem;
OpenFile: TMenuItem;
N1: TMenuItem;
SaveFile: TMenuItem;
CloseFile: TMenuItem;
SelectStructComboBox: TComboBox;
ExportMsg: TMenuItem;
ImportMsg: TMenuItem;
N2: TMenuItem;
BtnExport: TButton;
BtnOpen: TButton;
BtnSave: TButton;
BtnNew: TButton;
BtnImport: TButton;
BtnClose: TButton;
procedure FormCreate(Sender: TObject);
procedure SelectStructComboBoxSelect(Sender: TObject);
procedure NewFileClick(Sender: TObject);
procedure OpenFileClick(Sender: TObject);
procedure SaveFileClick(Sender: TObject);
procedure CloseFileClick(Sender: TObject);
procedure ExportMsgClick(Sender: TObject);
procedure ImportMsgClick(Sender: TObject);
procedure BtnNewClick(Sender: TObject);
procedure BtnOpenClick(Sender: TObject);
procedure BtnExportClick(Sender: TObject);
procedure BtnImportClick(Sender: TObject);
procedure BtnSaveClick(Sender: TObject);
procedure BtnCloseClick(Sender: TObject);
private
{ Private declarations }
StructName:String;
CurFileName:String;
TemplateFileShortName:string;
TemplateFileFolder:String;
ParamTemplateFile:String;
ExcelApplication1: TExcelApplication;
procedure ReReadStruct();
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
TemplateFileFolder:=GetCurrentDir+'\ParamDoc\';
MsgParamOpenDialog.InitialDir:=GetCurrentDir;
MsgParamSaveDialog.InitialDir:=GetCurrentDir;
TemplateFileShortName:='EmptyBook.xls';
ParamTemplateFile:=TemplateFileFolder+TemplateFileShortName;
try//打开Excel
ExcelApplication1 := TExcelApplication.Create(Application);
ExcelApplication1.Connect;
except
Application.Messagebox('Excel.exe Not Found!', 'MsgPool', MB_ICONERROR + mb_Ok);
Abort;
end;
ReReadStruct();
end;



procedure TForm1.ImportMsgClick(Sender: TObject);
var
row,col:Integer;
nRowNum,nColNum:integer;
ParName:string;
MsgName:string;
ParamContent:string;
begin
row:=0;
col:=0;
if ExcelOleContainer.State <>osUIActive then
begin//如果没有已经打开的Excel文件,则需要打开一个文件
exit;
end;
//判断结构名是否存在
ParamADOQuery.Active:=false;
ParamADOQuery.SQL.Clear;
ParamADOQuery.SQL.Add('Select StructName from Structs where StructName='''+StructName+'''');
ParamADOQuery.Active:=true;
if ParamADOQuery.RecordCount<>1 then
begin
ShowMessage('结构名不存在。');
exit;
end;
Case Application.MessageBox('导入时将删除该结构原有的消息。建议先备份该结构原有的消息。确认要备份么?','提醒',MB_YESNOCANCEL) of
0://创建MessageBox失败。
exit;
IDCANCEL:
exit;
IDYES:
//导出到文件并保存。
;
IDNO:
;
end;

//下面开始清空该结构原有的消息
ParamADOQuery.Active:=false;
ParamADOQuery.SQL.Clear;
ParamADOQuery.SQL.Add('DELETE FROM MsgParamsTable WHERE StructName='''+StructName+'''');
ParamADOQuery.ExecSQL();

ParamADOQuery.Active:=false;
ParamADOQuery.SQL.Clear;
ParamADOQuery.SQL.Add('DELETE FROM Messages WHERE StructName='''+StructName+'''');
ParamADOQuery.ExecSQL();

ParamADOQuery.Active:=false;
ParamADOQuery.SQL.Clear;
ParamADOQuery.SQL.Add('DELETE FROM MSGParamsOrder WHERE StructName='''+StructName+'''');
ParamADOQuery.ExecSQL();

//下面首先读入参数表并写入数据库
row:=1;
col:=2;
ParamContent:='';
ParamContent:=ExcelOleContainer.OleObject.Application.Workbooks[1].Worksheets[1].Cells.Item[row,col];
while ParamContent<>''do
begin
ParamADOQuery.Active:=false;
ParamADOQuery.SQL.Clear;
ParamADOQuery.SQL.Add('INSERT INTO MsgParamsOrder(StructName,ParamName,ParamOrder) VALUES ('''+StructName+''','''+ParamContent+''','+IntToStr(col-2)+')');
//ShowMessage(ParamADOQuery.SQL.Text);
ParamADOQuery.ExecSQL();
col:=col+1;
ParamContent:=ExcelOleContainer.OleObject.Application.Workbooks[1].Worksheets[1].Cells.Item[row,col];
end;
nColNum:=col-1;

//读入参数表并写入数据库
row:=2;
col:=1;
ParamContent:='';
ParamContent:=ExcelOleContainer.OleObject.Application.Workbooks[1].Worksheets[1].Cells.Item[row,col];
while ParamContent<>''do
begin
ParamADOQuery.Active:=false;
ParamADOQuery.SQL.Clear;
ParamADOQuery.SQL.Add('INSERT INTO Messages(StructName,MessageName) VALUES ('''+StructName+''','''+ParamContent+''')');
//ShowMessage(ParamADOQuery.SQL.Text);
ParamADOQuery.ExecSQL();
row:=row+1;
ParamContent:=ExcelOleContainer.OleObject.Application.Workbooks[1].Worksheets[1].Cells.Item[row,col];
end;
nRowNum:=row-1;

for row:=2 to nRowNum do//以行(消息)为序扫描输入参数。
begin
MsgName:=ExcelOleContainer.OleObject.Application.Workbooks[1].Worksheets[1].Cells.Item[row,1];
for col:=2 to nColNum do
begin
ParName:=ExcelOleContainer.OleObject.Application.Workbooks[1].Worksheets[1].Cells.Item[1,col];
ParamContent:=ExcelOleContainer.OleObject.Application.Workbooks[1].Worksheets[1].Cells.Item[row,col];
if ParamContent='' then Continue;
ParamADOQuery.Active:=false;
ParamADOQuery.SQL.Clear;
ParamADOQuery.SQL.Add('INSERT INTO MsgParamsTable(StructName,MessageName,ParamName,Content) VALUES ('''+StructName+''','''+MsgName+''','''+ParName+''','''+ParamContent+''')');
//ShowMessage(ParamADOQuery.SQL.Text);
ParamADOQuery.ExecSQL();
end;
end;

ShowMessage('导入完毕!');
end;
wangguan007 2003-06-04
  • 打赏
  • 举报
回复
关注!!!
xiaoyuer0851 2003-06-03
  • 打赏
  • 举报
回复
呵呵,终于碰到同道中人了
前一段时间忙了几个晚上终于调试成功
然后毕业设计也因此而……

http://expert.csdn.net/Expert/topic/1855/1855520.xml?temp=.900387
自己去看看,多提点问题建议,
现在我觉得:导出excel表已经没有问题了
但是导入还是存在一点问题,就是有时候会提示导入失败,
提示信息好象是什么“与服务器断开联系……”
你试试,然后我们大家一起努力调整,不段完善。争取能够做一个完整的功能出来,
daniel007 2003-06-03
  • 打赏
  • 举报
回复
如果需要vba操作的相关知识的华,其实很简单,利用office里的录制宏功能录制一段相关操作(譬如改变字体大小等),然后察看宏中的相关vba代码即可。
wenyu2000 2003-06-03
  • 打赏
  • 举报
回复
不要紧张,我给你一个好的方法:在Microsoft Office软件中有一种内嵌的编程语言VBA,它是一种宏语言,利用它,你可以编写出功能强大的代码,如打开文件、修改数据、保存数据和设置字体等。另一方面,Microsoft Office软件中的宏能以VBA代码的形式记录下你的操作过程。因此借助宏操作,可以很轻松地实现某一功能,并把这些代码稍作修改嵌入到你的软件中。但是VBA也存在一个缺点,它必须有Microsoft Office作平台,在哪里编写,必须在哪里执行。例如在Excel下编写的一段VBA代码,则它只有在Excel下才能运行。因此,我的方法就是把VBA代码嵌入到Delphi中,从而实现用Delphi操作Excel。

  下面,我们以Delphi程序为例,说明这种调用方法:

  Unit excel;

  interface

  uses

  Windows,Messages,SysUtils,Classes,Graphics,Controls,Forms,Dialogs,StdCtrls,ComObj;

  //ComObj是操作OLE对象的函数集

  type TForm1 =class(TForm)

  Button1: TButton;

  procedure Button1Click(Sender: TObject);

  private

  { Private declarations }

  public

  { Public declarations }

  end;

  var

  Form1: TForm1;

  implementation

  {$R *.DFM}

  procedure TForm1.Button1Click(Sender: TObject);

  var

  eclApp,WorkBook:Variant;

  //声明为OLE Automation 对象

  xlsFileName:string;begin

  xlsFileName:='ex.xls';

  try

  //创建OLE对象Excel Application与 WorkBook

  eclApp:=CreateOleObject('Excel.Application');

  WorkBook:=CreateOleobject('Excel.Sheet');

  except

  ShowMessage('您的机器里未安装Microsoft Excel。');

  Exit;

  end;

  try

  ShowMessage('下面演示:新建一个XLS文件,并写入数据,最后关闭它。');

  workBook:=eclApp.workBooks.Add;

  eclApp.Cells(1 , 1):='字符型';

  eclApp.Cells(2 , 1):='Excel文件';

  eclApp.Cells(1 , 2):='Money型';

  eclApp.Cells(2 , 2):=10.01;

  eclApp.Cells(1 , 3):='日期型';eclApp.Cells(2 , 3):=Date;

  WorkBook.saveas(xlsFileName);

  WorkBook.close;

  ShowMessage('下面演示:打开刚创建的XLS文件,并修改其中的内容,然后,由用户决定是否保存。');

  WorkBook:=eclApp.workBooks.Open(xlsFileName);

  eclApp.Cells(2 , 1):='Excel文件类型';

  if MessageDlg(xlsFileName+'文件已被修改,是否保存?',mtConfirmation, [mbYes, mbNo], 0) = mrYes then

  WorkBook.save

  else

  workBook.Saved := True; //放弃修改

  WorkBook.Close;

  eclApp.Quit;

  //退出Excel Application

  //释放VARIANT变量

  eclApp:=Unassigned;

  except

  ShowMessage('不能正确操作Excel文件。可能是该文件已被其他程序打开,或系统错误。');

  WorkBook.close;

  eclApp.Quit;

  //释放VARIANT变量

  eclApp:=Unassigned;

  end;

  end;

  end.

  经过上述操作过程后,我们就可以很放心地将数据库中的数据转换成Excel文件了。
sunlight1980 2003-06-03
  • 打赏
  • 举报
回复
我用的TExcelAppllication,一会儿试试你的。
things 2003-06-02
  • 打赏
  • 举报
回复
2、下面是我已经完成的一个程序,使用的是TExcelApplication(不是OLEContainer),缺点是Excel显示独立于程序的界面,而这是不允许的。不知道是因为我没有彻底掌握TExcelApplication的用法还是这种方法只能达到这样的效果?
---------------------
好象是这样的!
hua025 2003-06-02
  • 打赏
  • 举报
回复
居然这么长时间就只有一个兄弟瞟了一眼:(。改天我就把这个帖子关闭了。
smallshu 2003-05-20
  • 打赏
  • 举报
回复
mark

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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