2017-10-03 13 views
0

Ich habe diesen Code:Excel Ole Objekt noch Prozessliste beenden, nachdem

function XlsToStringGrid(AGrid: TStringGrid; AXLSFile: string): Boolean; 
const 
    xlCellTypeLastCell = $0000000B; 
var 
    XLApp, Sheet: OLEVariant; 
    RangeMatrix: Variant; 
    x, y, k, r: Integer; 
begin 
    Result:=False; 
    //Cria Excel- OLE Object 
    XLApp:=CreateOleObject('Excel.Application'); 
    try 

     XLApp.Visible:=False; 

     XLApp.Workbooks.Open(AXLSFile); 
     Sheet:=XLApp.Workbooks[ExtractFileName(AXLSFile)].WorkSheets[1]; 
     Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate; 

     x:=XLApp.ActiveCell.Row; 

     y:=XLApp.ActiveCell.Column; 

     AGrid.RowCount:=x; 
     AGrid.ColCount:=y; 

     RangeMatrix:=XLApp.Range['A1', XLApp.Cells.Item[X, Y]].Value; 

     k:=1; 
     repeat 
      for r:=1 to y do 
       AGrid.Cells[(r - 1),(k - 1)]:=RangeMatrix[K, R]; 
      Inc(k,1); 
     until k > x; 
     RangeMatrix:=Unassigned; 
     Result:=True; 

    finally 

     if not VarIsEmpty(XLApp) then 
     begin 
      Sheet:=Unassigned; 
      XLApp.Workbooks[ExtractFileName(AXLSFile)].Close; 
      XLApp.Quit; 
      XLAPP:=Unassigned; 
     end; 
     try freeandnil(XLAPP) except; end; 
     try freeandnil(Sheet) except; end; 
    end; 
end; 

aber nachdem er mit dem Befehl Beenden beenden, bleibt der Prozess noch in der Liste, Überlegungen: Ich Suche durchgeführt und verstanden, dass, wenn es Ein referenziertes Objekt bleibt in der Liste, aber ich glaube, dass ich alles freigegeben habe.

+1

ich das Verhalten nicht reproduzieren können Sie beschreiben. Vielleicht verschwindet eine Sekunde nach dem Beenden der Anwendung Excel aus der Aufgabenliste. Wenn Sie 'Sheet.Cells.SpecialCells (xlCellTypeLastCell, EmptyParam) auskommentieren .Activate; [...] RangeMatrix: = Nicht zugewiesen;' erhalten Sie immer noch das Verhalten? Wenn Sie das tun, würde ich vermuten, dass es spezifisch für den Inhalt Ihres WorkBooks ist, so dass die Leser nicht weiterhelfen können, wenn Sie keinen Code zur Verfügung stellen, um sie von Grund auf neu zu erstellen. – MartynA

+0

Wow, ich habe es in Teilen vergessen, ich habe es wirklich nicht versucht, jetzt nachdem ich die Aktionen kommentiert habe, bemerkte ich, dass die Variable RangeMatrix, die den Fehler erzeugt, den Prozess geöffnet zu bekommen, irgendeine Funktion hat, sie zu säubern? ohne nur Unassigned zu setzen? –

+0

Ich kann Ihr Problem immer noch nicht reproduzieren. Ich glaube nicht, dass Leser bereitwillig eine Beispieltabelle herunterladen, die Malware enthalten könnte. Das einzige, was ich vorschlagen kann, ist, Ihrem q den Code hinzuzufügen, der notwendig ist, um eine Datei zu generieren, die das Problem aufweist. – MartynA

Antwort

5

Der Befehl Quit() von Excel ist nicht synchron. Es kann eine Weile dauern, bis der Prozess tatsächlich beendet wird.

Und ja, Sie haben möglicherweise aktive Objektreferenzen. Sie löschen RangeMatrix nicht, wenn in Ihrer repeat Schleife eine Ausnahme auftritt, so dass es möglicherweise nicht gelöscht wird, bis XlsToStringGrid() beendet wird. Sie sollten mehrere try/finally Blöcke verwenden, einen für jedes Objekt.

Und bitte, rufen Sie nicht auf (Ole)Variant Variablen! Es funktioniert nur auf TObject Zeiger.

Versuchen Sie stattdessen:

function XlsToStringGrid(AGrid: TStringGrid; AXLSFile: string): Boolean; 
const 
    xlCellTypeLastCell = $0000000B; 
var 
    XLApp, WorkBook, Sheet: OLEVariant; 
    RangeMatrix: Variant; 
    x, y, k, r: Integer; 
begin 
    Result := False; 

    XLApp := CreateOleObject('Excel.Application'); 
    try 
    XLApp.Visible := False; 

    XLApp.Workbooks.Open(AXLSFile); 
    try 
     WorkBook := XLApp.Workbooks[ExtractFileName(AXLSFile)]; 
     try 
     Sheet := WorkBook.WorkSheets[1]; 
     try 
      Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate; 

      x := XLApp.ActiveCell.Row; 
      y := XLApp.ActiveCell.Column; 

      AGrid.RowCount := x; 
      AGrid.ColCount := y; 

      RangeMatrix := XLApp.Range['A1', XLApp.Cells.Item[X, Y]].Value; 
      try  
      k := 1; 
      repeat 
       for r := 1 to y do 
       AGrid.Cells[(r - 1),(k - 1)] := RangeMatrix[K, R]; 
       Inc(k); 
      until k > x; 
      finally 
      RangeMatrix := Unassigned; 
      end; 

      Result := True; 
     finally 
      Sheet := Unassigned; 
     end; 
     finally 
     WorkBook.Close; 
     WorkBook := Unassigned; 
     end; 
    finally 
     XLApp.Workbooks.Close; 
    end; 
    finally 
    XLApp.Quit; 
    XLAPP := Unassigned; 
    end; 
end; 
+0

Danke für die Erklärung, ich kannte diese Einschränkung der Verwendung von FreeAndNil nicht, aber selbst nach dem Austausch der Funktion durch erwähnt bleibt der Prozess in der Liste. Vielleicht schafft es ein bestimmter Tabellenkalkulationsinhalt? Hinweis: Ich habe die Anwendung geschlossen und der Prozess verbleibt in der Liste. –

Verwandte Themen