Ho riscontrato un problema strano sulla falsariga della domanda reasons why excel.exe remains loaded after running a delphi client automation program?. Il problema è un passo più profondo però.Excel.exe rimane caricato dopo aver eseguito un programma Delphi con accesso var nidificato
Ho il codice scritto in Delphi 7 e l'ho aggiornato a XE2. Dopo questo modo ho avuto lo stesso problema in XE2 e mentre la soluzione suggerita lavora in semplice applicazione di test, non appena io uso queste righe Excel.exe rimane caricato dopo l'uscita del programma:
fExcel: Variant; // Tried both as a field of a class and global variable
fExcel := CreateOleObject('Excel.Application');
try
fExcel.Workbooks.Open(srcPathName);
fExcel.DisplayAlerts := False;
...
// Offending lines
fExcel.ActiveWorkBook.ActiveSheet.Range[ //
fExcel.ActiveWorkBook.ActiveSheet.Cells[3, 2], //
fExcel.ActiveWorkBook.ActiveSheet.Cells[3+i,1+XL_PT_Tip_FieldCount] //
].Formula := VarArr; //
...
fExcel.ActiveWorkBook.SaveAs(tgtPathName, -4143, '', '', False, False);
fExcel.ActiveWorkBook.Close;
finally
fExcel.Application.Quit;
fExcel.Quit;
fExcel := Unassigned;
end;
Tuttavia, se mi presento variabili TEMP cl,ch: Variant
e sostituire sopra con:
cl := fExcel.ActiveWorkBook.ActiveSheet.Cells[3, 2];
ch := fExcel.ActiveWorkBook.ActiveSheet.Cells[3+i,1+XL_PT_Tip_FieldCount];
fExcel.ActiveWorkBook.ActiveSheet.Range[cl, ch].Formula := VarArr;
Inizia magicamente a funzionare e Excel.exe viene smaltito correttamente.
stesso accade se si utilizza una variabile foglio, aggiungendo variabile Temp guarisce:
sheetDynamicHb := fExcel.ActiveWorkBook.Sheets['Dynamics Hb'];
cl := sheetDynamicHb.Cells[52, 2];
ch := sheetDynamicHb.Cells[52+i, 2+3];
sheetDynamicHb.Range[cl, ch].Formula := VarArr;
qualche modo introducendo variabili temporanee (cl,ch: Variant
) fa il trucco. Sembra che l'accesso variabile Excel
nidificato abbia qualcosa di strano (con il conteggio ref?). Non so spiegare perché funzioni così, ma funziona esattamente come descritto e mi fa impazzire un po '.
Esiste un motivo per tale comportamento e una soluzione diversa dall'aggiunta di variabili temporanee ogni volta?
Come richiesto: un programma completo:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, ActiveX, ComObj;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
ex, VarArr, cl, ch: Variant;
begin
ex := CreateOleObject('Excel.Application');
try
// Loading template XLS
ex.Workbooks.Open('C:\Documents and Settings\...\TemplateCommon.xls');
ex.DisplayAlerts := False;
//Selecting work sheet
ex.ActiveWorkBook.Sheets['Sheet ABC'].Select;
VarArr := VarArrayCreate([0, 9, 0, 12], varVariant);
// This code works fine
{cl := ex.ActiveWorkBook.ActiveSheet.Cells[3, 2];
ch := ex.ActiveWorkBook.ActiveSheet.Cells[3 + 9, 2 + 12];
ex.ActiveWorkBook.ActiveSheet.Range[cl, ch].Formula := VarArr;}
// This code leaves Excel running
ex.ActiveWorkBook.ActiveSheet.Range[
ex.ActiveWorkBook.ActiveSheet.Cells[3, 2],
ex.ActiveWorkBook.ActiveSheet.Cells[3 + 9, 2 + 12]
].Formula := VarArr;
ex.ActiveWorkBook.SaveAs('C:\Documents and Settings\...\out.xls', -4143, '', '', False, False);
ex.ActiveWorkBook.Close;
finally
ex.Quit;
ex := Unassigned;
end;
end;
end.
programma reale è molto più complicato, ma anche in questo semplice test-caso esiste il bug:
- In caso di temperatura vars Excel viene eliminato immediatamente.
- Nel caso di vassoi nidificati, Excel viene eliminato solo quando il programma viene chiuso, come se qualcosa avesse un riferimento o qualcosa del genere.
Mi aspetto che il compilatore debba creare temps nascosti quando non si usano i locali. Tuttavia non possiamo dire nulla sull'ambito di questo codice. Un programma completo ci avrebbe mostrato questo. Francamente, mi hai sentito tutti dire che è un periodo di migliaia di miliardi. Perché le persone non riescono ancora a dedicare i 5 minuti in più necessari per pubblicare programmi completi? –
@DavidHeffernan: Grazie per il tuo commento. Sono riluttante a postare un programma completo perché sembrerà una richiesta di "debugarlo per me". Sto pubblicando un piccolo campione nel caso qualcuno abbia incontrato questo modello e possa condividere le sue conoscenze. – Kromster
Non vogliamo ** il tuo ** programma completo. Solo ** un ** programma completo. Tagliato dal programma reale per essere la riproduzione più piccola possibile. Forse non importa qui che abbiamo un programma completo, ma qualcosa ha cambiato idea in me. Scusate. –