退出后的Excel Ole Object Still Process List

时间:2017-10-03 21:09:42

标签: excel delphi process ole delphi-xe7

我有这段代码:

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;

但是在退出Quit命令之后,该过程仍然保留在列表中,注意事项:我执行了搜索并理解如果有引用的对象它仍然在列表中,但我相信我已经全部发布了。

1 个答案:

答案 0 :(得分:5)

Excel的Quit()命令不同步,进程实际退出可能需要一段时间。

是的,你可能有活跃的对象引用。如果您的RangeMatrix循环中发生异常,则不会清除repeat,因此在XlsToStringGrid()退出之前可能无法清除。您应该使用多个try/finally块,每个对象一个。

请不要在FreeAndNil()变量上致电(Ole)Variant!它只适用于TObject指针。

请改为尝试:

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;