【问题标题】:Excel Ole Object Still Process List after quit退出后Excel Ole对象仍处理列表
【发布时间】:2017-10-03 21:09:42
【问题描述】:

我有这个代码:

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 命令退出后,进程仍然保留在列表中,注意事项:我进行了搜索,了解到如果有引用的对象,它仍然保留在列表中,但我相信我已经全部释放了。

【问题讨论】:

  • 我无法重现您描述的行为。可能在应用程序终止一秒钟后,Excel 就会从任务列表中消失。如果您注释掉Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate;[...] RangeMatrix:=Unassigned;,您仍然会得到这种行为吗?如果你这样做了,那么我会怀疑它特定于你的 WorkBook 的内容,所以除非你能提供代码从头开始生成它,否则读者将无能为力。
  • 哇,我忘了做部分,我真的没有尝试这个,现在看到评论操作后我注意到生成进程打开错误的变量 RangeMatrix,会有一些功能打扫?而不仅仅是设置未分配?
  • 我仍然无法重现您的问题。我认为读者不会愿意下载可能包含恶意软件的示例电子表格,因此我唯一可以建议的是将生成显示问题的文件所需的代码添加到您的 q 中。
  • 整体情况是:我有一个数据表,并把它转换成一个TstringGrid来查看和随后更新数据,上面我在一个If中使用的函数开始扫描:if XlsToStringGrid(sgrd_excel,e_arquivo.Text) then begin // code here end;

标签: excel delphi process ole delphi-xe7


【解决方案1】:

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

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

请不要在(Ole)Variant 变量上调用FreeAndNil()!它仅适用于 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;

【讨论】:

  • 谢谢你的解释,我不知道FreeAndNil的使用限制,但是即使在交换了提到的函数之后,进程仍然在列表中。也许一些特定的电子表格内容可以管理这个?注意:我关闭了应用程序,进程仍保留在列表中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-25
  • 2016-07-01
  • 2013-03-21
  • 1970-01-01
  • 1970-01-01
  • 2020-09-04
  • 1970-01-01
相关资源
最近更新 更多