2015-01-20 18 views
5

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.
+0

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? –

+0

@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

+0

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. –

risposta

-1

Smaltire ogni variabile di Excel nell'ordine inverso di creazione della variabile, quindi l'oggetto excel va smaltito correttamente.

+0

Si prega di consultare il programma di esempio nella domanda. – Kromster

Problemi correlati