希望在数据库备份的同时显示一个进度条,当然进度条的步长是根据数据库的大小来确定的,所以不是那么贴切,但是比没有强。
为了实现上面的功能,使用了一线程来更新进度条。可是,测试时发现,要等数据库备份完成后,这个线程才开始执行,并不是边备份,边更新进度条。是什么原因?代码:procedure TForm1.Button1Click(Sender: TObject);
var Thd: TestThd ;
begin
Thd := TestThd.Create(false) ;
adoCnn.Execute('BACKUP DATABASE Pubs TO DISK =''C:\Test004.dat'' WITH INIT') ;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
adoCnn.Connected := true ;
end;end./////////////////////////////////////线程的代码,很简单测试用//////////////////////
unit Unit2;interfaceuses
Classes,SysUtils,unit1;type
TestThd = class(TThread)
private
{ Private declarations }
procedure UpdatePro ;
protected
procedure Execute; override;
end;implementation{ TestThd }procedure TestThd.Execute;
begin
FreeOnTerminate := true ;
while Form1.ProgressBar1.Position <> Form1.ProgressBar1.Max do
begin
Synchronize(UpdatePro) ;
Sleep(100) ;
end ;
end;procedure TestThd.UpdatePro;
begin
Form1.ProgressBar1.StepBy(5) ;
end;end.
为了实现上面的功能,使用了一线程来更新进度条。可是,测试时发现,要等数据库备份完成后,这个线程才开始执行,并不是边备份,边更新进度条。是什么原因?代码:procedure TForm1.Button1Click(Sender: TObject);
var Thd: TestThd ;
begin
Thd := TestThd.Create(false) ;
adoCnn.Execute('BACKUP DATABASE Pubs TO DISK =''C:\Test004.dat'' WITH INIT') ;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
adoCnn.Connected := true ;
end;end./////////////////////////////////////线程的代码,很简单测试用//////////////////////
unit Unit2;interfaceuses
Classes,SysUtils,unit1;type
TestThd = class(TThread)
private
{ Private declarations }
procedure UpdatePro ;
protected
procedure Execute; override;
end;implementation{ TestThd }procedure TestThd.Execute;
begin
FreeOnTerminate := true ;
while Form1.ProgressBar1.Position <> Form1.ProgressBar1.Max do
begin
Synchronize(UpdatePro) ;
Sleep(100) ;
end ;
end;procedure TestThd.UpdatePro;
begin
Form1.ProgressBar1.StepBy(5) ;
end;end.
解决方案 »
- 点打印时,为什么出来的是空白面, 想打印panel 上的内容,主要是edit,label 内容
- 哪里有这个控件下载啊flatUtilitys.dcu
- 写注册表开机执行的代码出现的问题
- 用dbedit修改数据的问题(在线等,马上结贴)
- 各位如果 我贴出去的帖子没人解答了是不是也要给分??
- 请问如果超过百万条记录的一个程序。。。。
- adoquery通过odbc连接sql_server,网络中断后,如何自己回复连接?
- 一个小问题,分可不少
- 急,谁知道如何在设计期调试自编写组件?
- 关于多层服务器的开发及应用。
- 自己写的Socks5代理的源码,还有些问题没有解决,请大家指教!(1)
- 如何使应用程序最小化
unit WaitPas1;interfaceuses
Classes, Windows, SysUtils, Dialogs, ADODB ;type
WaitPas = class(TThread)
Filename : String; //往线程中注入备份或还原的文件名
Messages : String; //显示信息
IDs : Integer; //识别应该执行什么样的操作
ADOQ : TADOQuery;
//备份文件
function BackUpData:Boolean;
//还原文件
function RevertData:Boolean;
//关闭等待窗口
procedure CloseWaitWindow;
//更新等待窗口信息
procedure PostMessgesToWaitWindow;
private
{ Private declarations }
protected
procedure Execute; override;
public
constructor Create(CaseS: TADOQuery; FileNames:String;LoadID:integer);
end;implementationuses Wait, Connect;{ WaitPas }function WaitPas.BackUpData:Boolean;
begin
Messages:='正在备份数据库,请稍候……';
Synchronize(PostMessgesToWaitWindow);
with ADOQ do try
Close;
SQL.Clear;
SQL.Add('backup database 通迅录 to disk='+#39+FileName+#39+' WITH INIT');
Prepared;
Execsql;
Result:=true;
except
Result:=false;
end;end;procedure WaitPas.CloseWaitWindow;
begin
WaitForm.Close;
end;constructor WaitPas.Create(CaseS: TADOQuery; FileNames: String; LoadID: Integer);
begin
//初始化进程
IDs := LoadID;
ADOQ := CaseS;
FileName := FileNames;
inherited Create(False);end;procedure WaitPas.Execute;
var IsSucceed : Boolean;
begin
IsSucceed:=false;
case IDs of
1 : IsSucceed := BackUpData; //备份
2 : IsSucceed := RevertData; //还原
end;
Synchronize(CloseWaitWindow);
if IsSucceed then
Messagebox(0,'数据库维护操作成功!','提示',MB_OK+MB_ICONINFORMATION+MB_TOPMOST)
ELSE ShowMessage(ConnectForms.ShowError);
{ Place thread code here }
end;procedure WaitPas.PostMessgesToWaitWindow;
begin
WaitForm.RzLabel1.Caption:=Messages;
end;function WaitPas.RevertData: Boolean;
begin
Messages:='正在还原数据库,请稍候……';
Synchronize(PostMessgesToWaitWindow);
with ADOQ do try
Close;
SQL.Clear;
sql.Add('use master');
sql.Add('ALTER DATABASE 通迅录 SET OFFLINE WITH ROLLBACK IMMEDIATE');
sql.Add('RESTORE DATABASE 通迅录 FROM DISK ='''+(FileName)+''' with FILE=1,RECOVERY,REPLACE');
sql.Add('ALTER DATABASE 通迅录 SET ONLINE WITH ROLLBACK IMMEDIATE');
SQL.Add('Use 通迅录');
Prepared;
execsql;
Result:=true;
except
Result:=false;
end;end;end.
Classes, windows, SysUtils;type
OutToExcel = class(TThread)
SentMsg : String; //传递进程信息
I1 : Integer; //总数
I2 : Integer; //进度数
procedure postMessages; //传递信息
procedure QueryMessage; //显示过程
procedure DoOutData; //导出数据
private
{ Private declarations }
protected
procedure Execute; override;
public
constructor Create(Runing:Boolean);
end;implementationuses Progress, Comobj, DM;{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example, Synchronize(UpdateCaption); and UpdateCaption could look like, procedure OutToExcel.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }{ OutToExcel }constructor OutToExcel.Create(Runing: Boolean);
begin
SentMsg:='正在准备将数据导出到Excel,请稍候…………';
Synchronize(postMessages);
ProgressForm.RzProgressBar1.Percent:=0;
inherited Create(Not Runing);
end;procedure OutToExcel.DoOutData;
var
exls,sheet : variant;
fieldNum,I,j : integer;
S,S2 : String;
begin
try
exls:=createoleobject('Excel.application');
sheet:=createoleobject('excel.sheet');
except
Messagebox(handle,'未发现系统中安装了Microsoft Excel,在使用该功能前,请先将其安装!','错误',mb_ok+mb_iconwarning);
Exit;
end;
try
sheet:=exls.workBooks.add;
Exls.worksheets[1].range['A1:L1'].Merge(True);
Exls.Cells[1,1].value:='我的通迅录';
Exls.Cells[1,1].Font.Size:=30;
ExLs.worksheets[1].Range['A1:L1'].Font.Name := '楷体_GB2312';
//第一行高39
Exls.worksheets[1].Rows[1].RowHeight := 39;
with DM1.ADODataSet1 do try
DisableControls;
I1:=RecordCount;
FieldNum:=FieldCount;
for i:=1 to FieldNum-2 do begin
Exls.Cells[2,i].value:=FieldDefList.Strings[i-1];
Exls.Cells[2,i].Font.Size:=9;
end;
Exls.Cells[2,1].ColumnWidth:=10;
Exls.Cells[2,2].ColumnWidth:=12;
Exls.Cells[2,3].ColumnWidth:=10;
Exls.Cells[2,4].ColumnWidth:=10;
Exls.Cells[2,5].ColumnWidth:=10;
Exls.Cells[2,6].ColumnWidth:=23;
Exls.Cells[2,7].ColumnWidth:=10;
Exls.Cells[2,8].ColumnWidth:=23;
Exls.Cells[2,9].ColumnWidth:=23;
Exls.Cells[2,10].ColumnWidth:=18;
Exls.Cells[2,11].ColumnWidth:=8;
Exls.Cells[2,12].ColumnWidth:=40;
First;
SentMsg:='正在将数据导出到Excel,请稍候…………';
Synchronize(postMessages);
i:=3;
while not eof do begin
I2:=I-2;
Synchronize(QueryMessage);
for j:=1 to fieldNum-2 do begin
exls.Cells[i,j]:=fields[j-1].AsString;
exls.Cells[i,j].Font.Size:=9; //设置字体为小五
end;
next;
i:=i+1;
end;
EnableControls ;
//为表格加入边框
S:='A2:L'+IntToStr(RecordCount+2);
S2:='A2:L'+IntToStr(RecordCount+2);
Exls.worksheets[1].Range[S].Borders.LineStyle := 1;
//设置文字垂直、水平居中
ExlS.worksheets[1].range[S2].HorizontalAlignment := $FFFFEFF4;
ExlS.worksheets[1].range[S2].VerticalAlignment := $FFFFEFF4; //加粗第1、2行文字
Exls.Cells[1,1].Font.Bold:=true;
Exls.worksheets[1].Rows[2].Font.bold:=true;
//加入一行作者信息]
S:='A'+IntToStr(RecordCount+4)+':L'+IntToStr(RecordCount+4);
Exls.worksheets[1].range[S].Merge(True);
Exls.Cells[(RecordCount+4),1].value:='“我的通迅录”,作者:李栋;E-Mail:[email protected]';
Exls.Cells[(RecordCount+4),1].Font.Size:=9;
Exls.Cells[RecordCount+4,1].Font.Bold:=true;
//显示Excel
exls.visible:=true;
except
Messagebox(handle,'数据导出到Excel时,发生意外失败。请稍候再试!','错误',MB_OK+MB_ICONERROR);
Exit;
end;
except
Messagebox(handle,'将数据导出到Excel失败!请稍候再试!','错误',mb_ok+mb_iconerror);
end;
end;procedure OutToExcel.Execute;
begin
{ Place thread code here }
try
DoOutData;
finally
Progressform.Close;
end;
end;procedure OutToExcel.postMessages;
begin
ProgressForm.RzGroupBox1.Caption:=SentMSG;
end;procedure OutToExcel.QueryMessage;
begin
progressForm.RzProgressBar1.Percent:=round(100*(i2/i1));
end;end.//////以上是www.delphibox.com上别人的代码,自己参考一下吧....
不过,我的目的是在执行下面的Sql语句的同时(因为备份、恢复可能需要较长时间)更新进度条,如果只需要显示 '正在备份数据库,请稍候……' 就不需要这么复杂了:)。
SQL.Add('backup database 通迅录 to disk='+#39+FileName+#39+' WITH INIT');
谢谢 gxgyj(杰克.逊) 的启发!
这个东东实际上是在主线程里执行的,而主线程都去backup了,自然没有CPU时间了