PA.*_*PA. 8 delphi excel office-automation
我编写了一个Delphi程序,它将单个.XLS文件的几个不同电子表格中的数据提取并合并到一个文本文件中,以便以后处理.这是一个Delphi 7 控制台程序.
最相关的代码段的摘录将向您展示,显然,我的程序表现得非常好,或者至少与它需要的程序一样多.
uses ... ActiveX, ComObj ... ;
procedure Fatal(s:string);
...
Halt(1);
var ExcelApp:Variant; (* global var *)
begin (* main program block *)
coInitialize(nil);
ExcelApp:=CreateOleObject('Excel.Application');
try
ExcelApp.Visible:=False;
ExcelApp.WorkBooks.Open(ExcelFileName);
...
XLSSheet := ExcelApp.Worksheets[ExcelSheetName];
...
try
XLSRange := XLSSheet.Range[ExcelRangeName];
except
Fatal('Range "'+ExcelRangeName+'" not found');
end;
if VarIsNull(XLSRange) then Fatal('Range '+ExcelRangeName+' not found');
for row:=XLSRange.Row to XLSRange.Rows[XLSRange.Rows.Count].Row do
for col:=XLSRange.Column to XLSRange.Columns[XLSRange.Columns.Count].Column do
CellValue:=XLSSheet.Cells[Row,Col].Value;
...
if CellValue<>'' then ...
...
ExcelApp.Workbooks.Close;
...
finally
ExcelApp.Quit;
coUninitialize;
end;
end.
Run Code Online (Sandbox Code Playgroud)
有时,当程序退出时,XLS保持锁定状态.查看任务管理器,我看到在客户端程序运行时启动的Excel.exe进程仍在运行,eventhoug客户端程序已退出并成功卸载.
你碰巧知道这种行为的常见嫌疑人是什么?知道在哪里寻找总是在客户端执行时卸载excel?
您需要发布ExcelApp变体.它仍然保持引用计数为1,因此Excel不会完全关闭.
将其添加到您的代码(标记的行):
finally
ExcelApp.Quit;
ExcelApp := Unassigned; // Add this line
coUninitialize;
end;
Run Code Online (Sandbox Code Playgroud)
以下是一些重现问题的简单代码,并测试解决方案:
// Add two buttons to a form, and declare a private form field.
// Add OnClick handlers to the two buttons, and use the code provided.
// Run the app, and click Button1. Wait until Excel is shown, and then click
// Button2 to close it. See the comments in the Button2Click event handler.
type
TForm1=class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
ExcelApp: Variant;
end;
implementation
uses
ComObj;
procedure TForm1.Button1Click(Sender: TObject);
begin
ExcelApp := CreateOleObject('Excel.Application');
ExcelApp.Visible := True;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ExcelApp.Visible := False;
ExcelApp.Quit;
// Leave the next line commented, run the app, and click the button.
// After exiting your app NORMALLY, check Task Manager processes, and you'll
// see an instance of Excel.exe still running, even though it's not
// in the Applications tab.
//
// Do an "end process" in Task Manager to remove the orphaned instance
// of Excel.exe left from the above. Uncomment the next line of code
// and repeat the process, again closing your app normally after clicking
// Button2. You'll note that Excel.exe is no longer in
// Task Manager Processes after closing your app.
// ExcelApp := Unassigned;
end;
end.
Run Code Online (Sandbox Code Playgroud)