难题,几个论坛都没人能解决,Excel的问题!!!!(100分)

L

ltf_ty

Unregistered / Unconfirmed
GUEST, unregistred user!
下面的代码执行后,有个Excel的进程不能结束,问题出在哪里,请高手不吝赐教!!!
将ComObj包含到一个新工程,加一个Button,将下面的代码拷入,修改文件1和文件2的名字为
实际存在的Excel文件的名字就可以执行,然后,用Excel打开任何一个Excel文件都看不见,
强行结束任务时发现有个Excel进程没杀死!!!


procedure TfmMain.BitBtn1Click(Sender: TObject);
var
WorkBook1, WorkBook2: OLEVariant;
begin
try
Excel := Unassigned;
Excel := CreateOleObject('Excel.Application');

//打开文件1
Excel.WorkBooks.Open(fe2000.Text);
WorkBook1 := Excel.ActiveWorkBook;
WorkBook1.Close;

//打开文件2
Excel.WorkBooks.Open(fe2001.Text);
WorkBook2 := Excel.ActiveWorkBook;
WorkBook2.Close;
finally
if not VarISEmpty(Excel) then
Excel.Quit;
Excel := Unassigned;
end;

end;
 
我发现方法了,在大富翁上查的,不是正途,但可以解决问题,原理是杀死Excel
的进程,如有直接的解决方法,请大虾们不吝告知!!!谢谢!!!解决办法如下:

//杀死Excel的进程的函数(感谢这位朋友,我没记住他的ID,抱歉)
procedure TerminateOLE;
var
FSnapshotHandle:THandle;
FProcessEntry32:TProcessEntry32;
Ret : BOOL;
ProcessID : integer;
s:string;
begin
FSnapshotHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
FProcessEntry32.dwSize:=Sizeof(FProcessEntry32);
Ret:=Process32First(FSnapshotHandle,FProcessEntry32);
while Ret do
begin
s:=ExtractFileName(FProcessEntry32.szExeFile);
if s='EXCEL.EXE' then
begin
ProcessID:=FProcessEntry32.th32ProcessID;
TerminateProcess(OpenProcess(PROCESS_TERMINATE,false,ProcessID),1);
s:='';
end;
Ret:=Process32Next(FSnapshotHandle,FProcessEntry32);
end;
end;

//我的旧代码
procedure TfmMain.BitBtn1Click(Sender: TObject);
var
WorkBook1, WorkBook2: OLEVariant;
begin
try
Excel := Unassigned;
Excel := CreateOleObject('Excel.Application');

//打开文件1
Excel.WorkBooks.Open(fe2000.Text);
WorkBook1 := Excel.ActiveWorkBook;
WorkBook1.Close;

//打开文件2
Excel.WorkBooks.Open(fe2001.Text);
WorkBook2 := Excel.ActiveWorkBook;
WorkBook2.Close;
finally
if not VarISEmpty(Excel) then
Excel.Quit;
Excel := Unassigned;
TerminateOLE; //加到这里
end;

end;


执行之后,发现Excel的进程没有了,也可以打开Excel文件了!!!
我发现这个问题在各个论坛上都有,但只有一个哥们将答案贴出来了,
很多都说“谢谢,我知道答案了,请斑竹结束这个帖子吧”,我希望
如果某位大虾提的问题自己解决了,请将答案也贴出来,这样也给别的
难兄难弟提供方便,希望得到大家的响应!!!




 
我们在PowerBuilder中碰到过一个类似的问题,最后发现是由于关闭PowerBuilder中的ole
对象的时候Excel没有立即关闭,然后释放这个对象后就出现了你这样的现象,最后是在关
闭ole对象后先延时30秒,就解决了。

希望对你有用。
 
程序退出时Excel := Unassigned;
 
我用以上代码以后,不能通过编译,很多线程函数都不能找到,我不知道它们是在那个单元,请
具体指点一下,谢谢!
 
to :bensonhe

要在 uses 部分添加 Comobj和TLHelp32单元。
 
我执行上面的代码没有问题,Excel进程,能正常关闭,不过我的系统是WinXp

还有,上面的代码其实什么都没有干,用Excel打开文件之后又马上关了,
我想,你实际的代码不是这样的吧,可能要看过你实际的代码,才知道问题的关键之处。

前段时间我写过类似的程序,也发现通过Ole控制Word/Excel打开无法正常关闭的现象,后来发现在启动Word/Excel的时候,启动类型有误,调整参数后,就没有问题了。

当时我出现的情况略有不同,如果Ole控制的是记事本等小型程序,都能正常退出,Word/Excel这样大型软件就无法正常退出。
 
to :bensonhe
Win98 + Delphi5;
全文如下,多谢关注!!!


unit main;


interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,comobj,
StdCtrls, Menus, ComCtrls,ExtCtrls, Db, ADODB,
Mask, ToolEdit, Grids, DBGridEh, Buttons, DBGridEhImpExp, TLHelp32;

type
TfmMain = class(TForm)
adoqryMain: TADOQuery;
cbWorkBooks: TComboBox;
lbWorkBooks: TLabel;
lbSheets: TLabel;
cbSheets: TComboBox;
Panel1: TPanel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
fe2000: TFilenameEdit;
fe2001: TFilenameEdit;
fe2002: TFilenameEdit;
cbMain: TCheckBox;
Panel2: TPanel;
cbSlave: TCheckBox;
feSlave: TFilenameEdit;
Label5: TLabel;
adoqrySlave: TADOQuery;
DBGridEh1: TDBGridEh;
adoqryTmp: TADOQuery;
adocntSlave: TADOConnection;
adocntMain: TADOConnection;
adoMainTmp: TADOQuery;
Panel3: TPanel;
Label6: TLabel;
feResult: TFilenameEdit;
cbResult: TCheckBox;
mmHelp: TMemo;
BitBtn1: TBitBtn;
DataSource1: TDataSource;
procedure btExample1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure fe2000ButtonClick(Sender: TObject);
procedure feSlaveButtonClick(Sender: TObject);
procedure cbSlaveClick(Sender: TObject);
procedure cbMainClick(Sender: TObject);
procedure feResultButtonClick(Sender: TObject);
procedure cbResultClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
private
Excel: Variant;
procedure ImportMain(FileN: string; Y: string = '');
procedure ImportSlave(SlaveName, TName: string);
procedure CompareData(FN: string);
procedure CompareMain(var FindSum: Integer; TName, SName: string);
procedure InsertSame(TName: string);
procedure UpdateMain(TName, SName: string);
procedure InsertDiff;
procedure SaveResult(FN: string);
public
procedure InsertToAccess(Money, No, TName: string; Y: string = '');
procedure ImportMainTable(SysDir: string);
procedure ImportSlaveTable(SysDir: string);

end;
const
CS1 = 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=';
CS2 = ';Persist Security Info=False';
var
fmMain: TfmMain;


implementation

uses ShareUnit;

{$R *.DFM}

(*var
WorkBook:Variant;*)


procedure TfmMain.btExample1Click(Sender: TObject);
begin
try
Excel := Unassigned;
Excel := CreateOleObject('Excel.Application'); //创建Excel对象


if not VarIsEmpty(Excel) then
Excel.Quit;
finally
adocntMain.Close;
adocntSlave.Close;
Excel := Unassigned;
end;
end;

procedure TfmMain.FormDestroy(Sender: TObject);
begin
if VarIsEmpty(Excel) = False then
Excel.Quit;
Excel := Unassigned;
end;


procedure TfmMain.InsertToAccess(Money, No, TName: string; Y: string = '');
var
S: string;
begin
if Y <> '' then
begin
S := 'Insert Into T_Main' + Y + ' (cMoney, cNo) Values(''' + Money + ''',''' + No + ''')';
Share.ExecuteSQL(adoMainTmp, S);
end
else
begin
S := 'Insert Into T_Slave Values(''' + Money + ''',''' + No + ''',''' + TName + ''')';
Share.ExecuteSQL(adoqryTmp, S);
end;
end;

procedure TfmMain.ImportMain(FileN, Y: string);
var
WorkBook, Sheet: Variant;
Row, RowCount: Integer;
Money, No: string;
begin
Excel.WorkBooks.Open(FileN);
try
WorkBook := Excel.WorkBooks[1];
Sheet := WorkBook.WorkSheets[1];
RowCount := Excel.ActiveSheet.UsedRange.Rows.Count;
for Row := 1 to RowCount do
begin
Application.ProcessMessages;
Money := Sheet.Cells[Row, 1];
No := Sheet.Cells[Row, 2];
if No <> '' then
try
InsertToAccess(Money, Format('%0.8d', [StrToInt(No)]),'', Y);
except
Continue;
end;
Caption := '[' + ExtractFileName(FileN) + '] ' + IntToStr(Row) + '/' + IntToStr(RowCount);
end;
finally
Excel.WorkBooks[1].Close;
end;

end;

procedure TfmMain.ImportSlave(SlaveName, TName: string);
var
WorkBook, Sheet: Variant;
Row, RowCount: Integer;
Money, No: string;
begin
Excel.WorkBooks.Open(feSlave.Text);
try
WorkBook := Excel.WorkBooks[1];
Sheet := WorkBook.WorkSheets[1];
RowCount := Excel.ActiveSheet.UsedRange.Rows.Count;
for Row := 1 to RowCount do
begin
Application.ProcessMessages;
Money := Sheet.Cells[Row, 1];
No := Sheet.Cells[Row, 2];
if No <> '' then
try
InsertToAccess(Money, Format('%0.8d', [StrToInt(No)]), TName, '');
except
Continue;
end;
Caption := IntToStr(Row);
end;
finally
WorkBook.Close;
end;
adoqrySlave.Close;
adocntSlave.Close;

end;

procedure TfmMain.CompareData(FN: string);
var
FindSum: Integer;
S: string;
begin
if not FileExists(FN) then
begin
Share.HintMsgBox('目的表不存在,需要导入从表');
Exit;
end;

S := 'Delete From T_SameData';
Share.ExecuteSQL(adoqryTmp, S);
S := 'Delete From T_DiffData';
Share.ExecuteSQL(adoqryTmp, S);

S := 'SELECT * FROM T_SLAVE';
Share.SelectSQL(adoqrySlave, S);
with adoqrySlave do
begin
while not Eof do
begin
FindSum := 0;
CompareMain(FindSum, 'T_Main2000', ExtractFileName(FN)); //与主表2000比较
CompareMain(FindSum, 'T_Main2001', ExtractFileName(FN)); //与主表2001比较
CompareMain(FindSum, 'T_Main2002', ExtractFileName(FN)); //与主表2002比较
if FindSum = 0 then
InsertDiff; //如果3个主表中均无此条数据,则插入T_DiffData

// SaveResult(FN);

Next;
end;
end;
end;

procedure TfmMain.CompareMain(var FindSum: Integer; TName, SName: string);
var
S: string;
C: Integer;
begin
S := 'SELECT COUNT(*) FROM ' + TName
+ ' WHERE CMONEY = ''' + adoqrySlave.FieldByName('cMoney').AsString
+ ''' AND CNO = ''' + adoqrySlave.FieldByName('cNo').AsString + ''' ';
Share.SelectSQL(adoQryMain, S);
C := adoqryMain.Fields[0].AsInteger;
if C > 0 then //有相同记录
begin
FindSum := C;
InsertSame(TName); //写相同记录表
UpdateMain(TName, SName); //将主表作标记
end;
end;

procedure TfmMain.InsertSame(TName: string);
var
S, cMoney, cNo: string;
begin
cMoney := adoqrySlave.FieldByName('cMoney').AsString;
cNo := adoqrySlave.FieldByName('cNo').AsString;

S := 'Insert Into T_SameData Values(''' + cMoney
+ ''', ''' + cNo + ''',''' + TName + ''')';
Share.ExecuteSQL(adoqryTmp, S);
end;

procedure TfmMain.UpdateMain(TName, SName: string);
var
S: string;
begin
S := 'SELECT * FROM ' + TName
+ ' WHERE CMONEY = ''' + adoqrySlave.FieldByName('cMoney').AsString
+ ''' AND CNO = ''' + adoqrySlave.FieldByName('cNo').AsString + ''' ';
Share.SelectSQL(adoMainTmp, S);
with adoMainTmp do
begin
Edit;
FieldByName('nCount').AsInteger := FieldByName('nCount').AsInteger + 1;
FieldByName('cSlaveName').AsString := FieldByName('cSlaveName').AsString + ', ' + SName;
Post;
end;

{S := 'Update ' + TName
+ ' Set cCount = cCount + 1, cSlaveName = ''' + SName
+ ''' Where cMoney = ''' + Money + ''' and cNo = ''' + No + ''' ';
Share.ExecuteSQL(adoMainTmp, S); }
end;

procedure TfmMain.InsertDiff;
var
S, cMoney, cNo: string;
begin
cMoney := adoqrySlave.FieldByName('cMoney').AsString;
cNo := adoqrySlave.FieldByName('cNo').AsString;
S := 'Insert Into T_DiffData Values(''' + cMoney + ''', ''' + cNo + ''')';
Share.ExecuteSQL(adoqryTmp, S);
end;

procedure TfmMain.fe2000ButtonClick(Sender: TObject);
begin
if not cbMain.Checked then
cbMain.Checked := True;
end;

procedure TfmMain.feSlaveButtonClick(Sender: TObject);
begin
if not cbSlave.Checked then
cbSlave.Checked := True;
end;

procedure TfmMain.cbSlaveClick(Sender: TObject);
begin
if cbSlave.Checked then
feSlave.SetFocus;
end;

procedure TfmMain.cbMainClick(Sender: TObject);
begin
if cbMain.Checked then
fe2000.SetFocus;
end;


procedure TfmMain.feResultButtonClick(Sender: TObject);
begin
if not cbResult.Checked then
cbResult.Checked := True;
end;

procedure TfmMain.cbResultClick(Sender: TObject);
begin
if cbResult.Checked then
feResult.SetFocus;
end;

procedure TfmMain.FormCreate(Sender: TObject);
var
SysDir: string;
begin
SysDir := ExtractFileDir(Application.ExeName);
mmHelp.Lines.LoadFromFile(SysDir + '/help.txt');

fe2000.InitialDir := SysDir + '/主表';
fe2001.InitialDir := SysDir + '/主表';
fe2002.InitialDir := SysDir + '/主表';

feSlave.InitialDir := SysDir + '/从表';

feResult.InitialDir := SysDir + '/结果表';
end;

procedure TfmMain.SaveResult(FN: string);
var
S, Tmp, FSame, FDiff: string;
begin
DataSource1.DataSet := adoqrySlave;

//重复的数据
Tmp := Copy(FN, 1, Length(FN) - 4);
FSame := Tmp + '(重复).xls';
S := 'Select cMoney as 金额, cNo as 票号, (Count(*) - 1) as 重复次数 From T_SameData '
+ 'Group By cMoney, cNo Having Count(*) > 2';
Share.SelectSQL(adoqrySlave, S);
SaveDBGridEhToExportFile(TDBGridEhExportAsXLS,DBGridEh1, FSame, True);

//不重复的数据
FDiff := Tmp + '(不重复).xls';
S := 'Select cMoney as 金额, cNo as 票号 From T_DiffData ';
Share.SelectSQL(adoqrySlave, S);
SaveDBGridEhToExportFile(TDBGridEhExportAsXLS,DBGridEh1, FDiff, True);

end;

procedure TerminateOLE;
var
FSnapshotHandle:THandle;
FProcessEntry32:TProcessEntry32;
Ret : BOOL;
ProcessID : integer;
s:string;
begin
FSnapshotHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
FProcessEntry32.dwSize:=Sizeof(FProcessEntry32);
Ret:=Process32First(FSnapshotHandle,FProcessEntry32);
while Ret do
begin
s:=ExtractFileName(FProcessEntry32.szExeFile);
if s='EXCEL.EXE' then
begin
ProcessID:=FProcessEntry32.th32ProcessID;
TerminateProcess(OpenProcess(PROCESS_TERMINATE,false,ProcessID),1);
s:='';
end;
Ret:=Process32Next(FSnapshotHandle,FProcessEntry32);
end;
end;
procedure TfmMain.BitBtn1Click(Sender: TObject);
var
SysDir: string;
begin
try
Excel := Unassigned;
Excel := CreateOleObject('Excel.Application'); //创建Excel对象

SysDir := ExtractFileDir(Application.ExeName); //系统路径

ImportMainTable(SysDir); //导入指定主表

ImportSlaveTable(SysDir); //导入指定副表

if not VarIsEmpty(Excel) then
Excel.Quit;
finally
adocntMain.Close;
adocntSlave.Close;
Excel := Unassigned;
TerminateOLE; //结束进程
end;
Share.HintMsgBox('处理完毕!');
end;

procedure TfmMain.ImportMainTable(SysDir: string);
var
MainTable: string;
begin
MainTable := SysDir + '/主表/主表.mdb';
adocntMain.ConnectionString := CS1 + MainTable + CS2;

//导入3个主表
if cbMain.Checked then
begin
Share.ExecuteSQL(adoqryMain, 'DELETE FROM T_MAIN2000');
Share.ExecuteSQL(adoqryMain, 'DELETE FROM T_MAIN2001');
Share.ExecuteSQL(adoqryMain, 'DELETE FROM T_MAIN2002');

if fe2000.Text <> '' then
ImportMain(fe2000.Text, '2000');

if fe2001.Text <> '' then
ImportMain(fe2001.Text, '2001');

if fe2002.Text <> '' then
ImportMain(fe2002.Text, '2002');
end;


end;

procedure TfmMain.ImportSlaveTable(SysDir: string);
var
FN, STable, DTable: string;
begin
if cbSlave.Checked then
begin
STable := SysDir + '/从表/从表.mdb';

FN := ExtractFileName(feSlave.Text);
DTable := SysDir + '/结果表/' + Copy(FN, 1, Length(FN) - 4) + '.mdb';

if FileExists(DTable) then
if not Share.ConfirmMsgBox('【' + DTable + '】:该文件已存在,是否覆盖') then Exit;

if CopyFile(PChar(STable), PChar(DTable), False) then
begin
adocntSlave.ConnectionString := CS1 + DTable + CS2;
ImportSlave(feSlave.Text, FN); //导入从表
CompareData(DTable); //处理数据
SaveResult(DTable); //保存结果
end
else
Share.HintMsgBox('拷贝从表模板文件失败!');
end;

end;

end.


 
to :biggo
Sorry! 刚才写错了!!!
这是我为一个作会计的朋友写的程序,只有一个单元,处理流程也很简单,只是Ole调用出现
我所说的问题,如果有时间,希望大家都帮着看看!!!
再次感谢各位!!!

Win98 + Delphi5;
全文如下,多谢关注!!!


unit main;


interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,comobj,
StdCtrls, Menus, ComCtrls,ExtCtrls, Db, ADODB,
Mask, ToolEdit, Grids, DBGridEh, Buttons, DBGridEhImpExp, TLHelp32;

type
TfmMain = class(TForm)
adoqryMain: TADOQuery;
cbWorkBooks: TComboBox;
lbWorkBooks: TLabel;
lbSheets: TLabel;
cbSheets: TComboBox;
Panel1: TPanel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
fe2000: TFilenameEdit;
fe2001: TFilenameEdit;
fe2002: TFilenameEdit;
cbMain: TCheckBox;
Panel2: TPanel;
cbSlave: TCheckBox;
feSlave: TFilenameEdit;
Label5: TLabel;
adoqrySlave: TADOQuery;
DBGridEh1: TDBGridEh;
adoqryTmp: TADOQuery;
adocntSlave: TADOConnection;
adocntMain: TADOConnection;
adoMainTmp: TADOQuery;
Panel3: TPanel;
Label6: TLabel;
feResult: TFilenameEdit;
cbResult: TCheckBox;
mmHelp: TMemo;
BitBtn1: TBitBtn;
DataSource1: TDataSource;
procedure btExample1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure fe2000ButtonClick(Sender: TObject);
procedure feSlaveButtonClick(Sender: TObject);
procedure cbSlaveClick(Sender: TObject);
procedure cbMainClick(Sender: TObject);
procedure feResultButtonClick(Sender: TObject);
procedure cbResultClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
private
Excel: Variant;
procedure ImportMain(FileN: string; Y: string = '');
procedure ImportSlave(SlaveName, TName: string);
procedure CompareData(FN: string);
procedure CompareMain(var FindSum: Integer; TName, SName: string);
procedure InsertSame(TName: string);
procedure UpdateMain(TName, SName: string);
procedure InsertDiff;
procedure SaveResult(FN: string);
public
procedure InsertToAccess(Money, No, TName: string; Y: string = '');
procedure ImportMainTable(SysDir: string);
procedure ImportSlaveTable(SysDir: string);

end;
const
CS1 = 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=';
CS2 = ';Persist Security Info=False';
var
fmMain: TfmMain;


implementation

uses ShareUnit;

{$R *.DFM}

(*var
WorkBook:Variant;*)


procedure TfmMain.btExample1Click(Sender: TObject);
begin
try
Excel := Unassigned;
Excel := CreateOleObject('Excel.Application'); //创建Excel对象


if not VarIsEmpty(Excel) then
Excel.Quit;
finally
adocntMain.Close;
adocntSlave.Close;
Excel := Unassigned;
end;
end;

procedure TfmMain.FormDestroy(Sender: TObject);
begin
if VarIsEmpty(Excel) = False then
Excel.Quit;
Excel := Unassigned;
end;


procedure TfmMain.InsertToAccess(Money, No, TName: string; Y: string = '');
var
S: string;
begin
if Y <> '' then
begin
S := 'Insert Into T_Main' + Y + ' (cMoney, cNo) Values(''' + Money + ''',''' + No + ''')';
Share.ExecuteSQL(adoMainTmp, S);
end
else
begin
S := 'Insert Into T_Slave Values(''' + Money + ''',''' + No + ''',''' + TName + ''')';
Share.ExecuteSQL(adoqryTmp, S);
end;
end;

procedure TfmMain.ImportMain(FileN, Y: string);
var
WorkBook, Sheet: Variant;
Row, RowCount: Integer;
Money, No: string;
begin
Excel.WorkBooks.Open(FileN);
try
WorkBook := Excel.WorkBooks[1];
Sheet := WorkBook.WorkSheets[1];
RowCount := Excel.ActiveSheet.UsedRange.Rows.Count;
for Row := 1 to RowCount do
begin
Application.ProcessMessages;
Money := Sheet.Cells[Row, 1];
No := Sheet.Cells[Row, 2];
if No <> '' then
try
InsertToAccess(Money, Format('%0.8d', [StrToInt(No)]),'', Y);
except
Continue;
end;
Caption := '[' + ExtractFileName(FileN) + '] ' + IntToStr(Row) + '/' + IntToStr(RowCount);
end;
finally
Excel.WorkBooks[1].Close;
end;

end;

procedure TfmMain.ImportSlave(SlaveName, TName: string);
var
WorkBook, Sheet: Variant;
Row, RowCount: Integer;
Money, No: string;
begin
Excel.WorkBooks.Open(feSlave.Text);
try
WorkBook := Excel.WorkBooks[1];
Sheet := WorkBook.WorkSheets[1];
RowCount := Excel.ActiveSheet.UsedRange.Rows.Count;
for Row := 1 to RowCount do
begin
Application.ProcessMessages;
Money := Sheet.Cells[Row, 1];
No := Sheet.Cells[Row, 2];
if No <> '' then
try
InsertToAccess(Money, Format('%0.8d', [StrToInt(No)]), TName, '');
except
Continue;
end;
Caption := IntToStr(Row);
end;
finally
WorkBook.Close;
end;
adoqrySlave.Close;
adocntSlave.Close;

end;

procedure TfmMain.CompareData(FN: string);
var
FindSum: Integer;
S: string;
begin
if not FileExists(FN) then
begin
Share.HintMsgBox('目的表不存在,需要导入从表');
Exit;
end;

S := 'Delete From T_SameData';
Share.ExecuteSQL(adoqryTmp, S);
S := 'Delete From T_DiffData';
Share.ExecuteSQL(adoqryTmp, S);

S := 'SELECT * FROM T_SLAVE';
Share.SelectSQL(adoqrySlave, S);
with adoqrySlave do
begin
while not Eof do
begin
FindSum := 0;
CompareMain(FindSum, 'T_Main2000', ExtractFileName(FN)); //与主表2000比较
CompareMain(FindSum, 'T_Main2001', ExtractFileName(FN)); //与主表2001比较
CompareMain(FindSum, 'T_Main2002', ExtractFileName(FN)); //与主表2002比较
if FindSum = 0 then
InsertDiff; //如果3个主表中均无此条数据,则插入T_DiffData

// SaveResult(FN);

Next;
end;
end;
end;

procedure TfmMain.CompareMain(var FindSum: Integer; TName, SName: string);
var
S: string;
C: Integer;
begin
S := 'SELECT COUNT(*) FROM ' + TName
+ ' WHERE CMONEY = ''' + adoqrySlave.FieldByName('cMoney').AsString
+ ''' AND CNO = ''' + adoqrySlave.FieldByName('cNo').AsString + ''' ';
Share.SelectSQL(adoQryMain, S);
C := adoqryMain.Fields[0].AsInteger;
if C > 0 then //有相同记录
begin
FindSum := C;
InsertSame(TName); //写相同记录表
UpdateMain(TName, SName); //将主表作标记
end;
end;

procedure TfmMain.InsertSame(TName: string);
var
S, cMoney, cNo: string;
begin
cMoney := adoqrySlave.FieldByName('cMoney').AsString;
cNo := adoqrySlave.FieldByName('cNo').AsString;

S := 'Insert Into T_SameData Values(''' + cMoney
+ ''', ''' + cNo + ''',''' + TName + ''')';
Share.ExecuteSQL(adoqryTmp, S);
end;

procedure TfmMain.UpdateMain(TName, SName: string);
var
S: string;
begin
S := 'SELECT * FROM ' + TName
+ ' WHERE CMONEY = ''' + adoqrySlave.FieldByName('cMoney').AsString
+ ''' AND CNO = ''' + adoqrySlave.FieldByName('cNo').AsString + ''' ';
Share.SelectSQL(adoMainTmp, S);
with adoMainTmp do
begin
Edit;
FieldByName('nCount').AsInteger := FieldByName('nCount').AsInteger + 1;
FieldByName('cSlaveName').AsString := FieldByName('cSlaveName').AsString + ', ' + SName;
Post;
end;

{S := 'Update ' + TName
+ ' Set cCount = cCount + 1, cSlaveName = ''' + SName
+ ''' Where cMoney = ''' + Money + ''' and cNo = ''' + No + ''' ';
Share.ExecuteSQL(adoMainTmp, S); }
end;

procedure TfmMain.InsertDiff;
var
S, cMoney, cNo: string;
begin
cMoney := adoqrySlave.FieldByName('cMoney').AsString;
cNo := adoqrySlave.FieldByName('cNo').AsString;
S := 'Insert Into T_DiffData Values(''' + cMoney + ''', ''' + cNo + ''')';
Share.ExecuteSQL(adoqryTmp, S);
end;

procedure TfmMain.fe2000ButtonClick(Sender: TObject);
begin
if not cbMain.Checked then
cbMain.Checked := True;
end;

procedure TfmMain.feSlaveButtonClick(Sender: TObject);
begin
if not cbSlave.Checked then
cbSlave.Checked := True;
end;

procedure TfmMain.cbSlaveClick(Sender: TObject);
begin
if cbSlave.Checked then
feSlave.SetFocus;
end;

procedure TfmMain.cbMainClick(Sender: TObject);
begin
if cbMain.Checked then
fe2000.SetFocus;
end;


procedure TfmMain.feResultButtonClick(Sender: TObject);
begin
if not cbResult.Checked then
cbResult.Checked := True;
end;

procedure TfmMain.cbResultClick(Sender: TObject);
begin
if cbResult.Checked then
feResult.SetFocus;
end;

procedure TfmMain.FormCreate(Sender: TObject);
var
SysDir: string;
begin
SysDir := ExtractFileDir(Application.ExeName);
mmHelp.Lines.LoadFromFile(SysDir + '/help.txt');

fe2000.InitialDir := SysDir + '/主表';
fe2001.InitialDir := SysDir + '/主表';
fe2002.InitialDir := SysDir + '/主表';

feSlave.InitialDir := SysDir + '/从表';

feResult.InitialDir := SysDir + '/结果表';
end;

procedure TfmMain.SaveResult(FN: string);
var
S, Tmp, FSame, FDiff: string;
begin
DataSource1.DataSet := adoqrySlave;

//重复的数据
Tmp := Copy(FN, 1, Length(FN) - 4);
FSame := Tmp + '(重复).xls';
S := 'Select cMoney as 金额, cNo as 票号, (Count(*) - 1) as 重复次数 From T_SameData '
+ 'Group By cMoney, cNo Having Count(*) > 2';
Share.SelectSQL(adoqrySlave, S);
SaveDBGridEhToExportFile(TDBGridEhExportAsXLS,DBGridEh1, FSame, True);

//不重复的数据
FDiff := Tmp + '(不重复).xls';
S := 'Select cMoney as 金额, cNo as 票号 From T_DiffData ';
Share.SelectSQL(adoqrySlave, S);
SaveDBGridEhToExportFile(TDBGridEhExportAsXLS,DBGridEh1, FDiff, True);

end;

procedure TerminateOLE;
var
FSnapshotHandle:THandle;
FProcessEntry32:TProcessEntry32;
Ret : BOOL;
ProcessID : integer;
s:string;
begin
FSnapshotHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
FProcessEntry32.dwSize:=Sizeof(FProcessEntry32);
Ret:=Process32First(FSnapshotHandle,FProcessEntry32);
while Ret do
begin
s:=ExtractFileName(FProcessEntry32.szExeFile);
if s='EXCEL.EXE' then
begin
ProcessID:=FProcessEntry32.th32ProcessID;
TerminateProcess(OpenProcess(PROCESS_TERMINATE,false,ProcessID),1);
s:='';
end;
Ret:=Process32Next(FSnapshotHandle,FProcessEntry32);
end;
end;
procedure TfmMain.BitBtn1Click(Sender: TObject);
var
SysDir: string;
begin
try
Excel := Unassigned;
Excel := CreateOleObject('Excel.Application'); //创建Excel对象

SysDir := ExtractFileDir(Application.ExeName); //系统路径

ImportMainTable(SysDir); //导入指定主表

ImportSlaveTable(SysDir); //导入指定副表

if not VarIsEmpty(Excel) then
Excel.Quit;
finally
adocntMain.Close;
adocntSlave.Close;
Excel := Unassigned;
TerminateOLE; //结束进程
end;
Share.HintMsgBox('处理完毕!');
end;

procedure TfmMain.ImportMainTable(SysDir: string);
var
MainTable: string;
begin
MainTable := SysDir + '/主表/主表.mdb';
adocntMain.ConnectionString := CS1 + MainTable + CS2;

//导入3个主表
if cbMain.Checked then
begin
Share.ExecuteSQL(adoqryMain, 'DELETE FROM T_MAIN2000');
Share.ExecuteSQL(adoqryMain, 'DELETE FROM T_MAIN2001');
Share.ExecuteSQL(adoqryMain, 'DELETE FROM T_MAIN2002');

if fe2000.Text <> '' then
ImportMain(fe2000.Text, '2000');

if fe2001.Text <> '' then
ImportMain(fe2001.Text, '2001');

if fe2002.Text <> '' then
ImportMain(fe2002.Text, '2002');
end;


end;

procedure TfmMain.ImportSlaveTable(SysDir: string);
var
FN, STable, DTable: string;
begin
if cbSlave.Checked then
begin
STable := SysDir + '/从表/从表.mdb';

FN := ExtractFileName(feSlave.Text);
DTable := SysDir + '/结果表/' + Copy(FN, 1, Length(FN) - 4) + '.mdb';

if FileExists(DTable) then
if not Share.ConfirmMsgBox('【' + DTable + '】:该文件已存在,是否覆盖') then Exit;

if CopyFile(PChar(STable), PChar(DTable), False) then
begin
adocntSlave.ConnectionString := CS1 + DTable + CS2;
ImportSlave(feSlave.Text, FN); //导入从表
CompareData(DTable); //处理数据
SaveResult(DTable); //保存结果
end
else
Share.HintMsgBox('拷贝从表模板文件失败!');
end;

end;

end.
 
顶部