DELPHI "the object invoked has disconnected from its clients"

DELPHI "the object invoked has disconnected from its clients"

excel运行时,打开我处理的数据文件。 (如果我关闭这个文件,我的程序就会停止)

unit UBImportFromExcel;

interface

uses
  MainDM, Contnrs, DB, Classes, UGeneral, BSYSTMGlobals,
  SysUtils, ADODB, BDataSet, NThermo, ComObj, Graphics, Forms, ShellAPI, Windows, Math, DBClient;

type

  TBImportFromExcel = class
    private
      ExcelApp, ExcelWorkbook, ExcelWorksheet,
      Unassigned : Variant;
      iStartingRow : Integer;
      iSheetCount : Integer;
      iRowCount : Integer;
    public
      function ReadCell(iRow : Integer; iColumn : Integer) : string;
      procedure Worksheet(iWorksheetIndex : integer = 1);
    protected

    published
      property StartingRow : Integer read iStartingRow write iStartingRow;
      property SheetCount : Integer read iSheetCount;
      property RowCount : Integer read iRowCount;

      constructor Create(sFile : string); virtual;
      destructor Destroy; override;
  end;


implementation

{ TBImportFromExcel }

constructor TBImportFromExcel.Create(sFile : string);
begin
  ExcelApp        := CreateOleObject('Excel.Application');
  ExcelWorkbook   := ExcelApp.WorkBooks.Open(sFile);
  iSheetCount     := ExcelWorkbook.Worksheets.Count;
  iStartingRow    := 2;
end;

destructor TBImportFromExcel.Destroy;
begin
  ExcelWorkbook.Close(False);
  ExcelWorksheet := Unassigned;
  ExcelWorkbook := Unassigned;
  ExcelApp := Unassigned;
  inherited;
end;

function TBImportFromExcel.ReadCell(iRow, iColumn: Integer): string;
var
  oCell : OleVariant;
begin
  oCell       := ExcelWorksheet.Cells[iRow, iColumn];
  Result      := oCell.Value;
end;

procedure TBImportFromExcel.Worksheet(iWorksheetIndex: integer);
begin
  ExcelWorksheet  := ExcelWorkbook.Worksheets.Item[iWorksheetIndex];
  ExcelWorksheet.Activate;
  ExcelWorksheet.Select;
  iRowCount       := ExcelWorksheet.UsedRange.Rows.Count;
end;

end.

如果 excel 文件自行打开,我会在 header 中收到错误,我的程序会中断。 对不起,我的英语不好。 createoleobject 无法创建独立 object。为什么?

如果我理解正确的话,我想我可能有办法解决你的问题。

除了Visible,Excel的OLE对象还有两个相关属性:

  • DisplayAlerts 确定 Excel 应用程序是否生成警报 显示在屏幕上;和

  • Interactive,判断是否Excel对象(使用CreateOleObject创建) 可以与用户通过 Windows gui 启动的 Excel 实例进行交互。如果设置为 False, Excel OLE 实例与用户的桌面实例完全“隔离”。

这两个都由 MS 记录,请参阅 here Interactive.

的文档

所以我创建了一个简单的测试应用程序,只有两个按钮和两个复选框以及这段代码

procedure TForm1.Start;
begin
  sFile := ExtractFilePath(Application.ExeName) + 'Test.Xlsx';
  ExcelApplication := CreateOleObject('Excel.Application');

  ExcelApplication.Interactive := cbInteractive.Checked;
  ExcelApplication.Visible := cbVisible.Checked;
  ExcelApplication.DisplayAlerts := ExcelApplication.Visible; // no point in displaying alerts if Excel app is not visible

  ExcelWorkbook  := ExcelApplication.WorkBooks.Open(sFile);
end;

procedure TForm1.Stop;
begin
  ExcelWorkBook.Close;  // Needed to hide Excel if it was started with Visible = True
  ExcelApplication.Quit;
  ExcelWorkBook := Unassigned;
  ExcelApplication := Unassigned;
end;

procedure TForm1.btnStartClick(Sender: TObject);
begin
  Start;
end;

procedure TForm1.btnStopClick(Sender: TObject);
begin
  Stop;
end;

将 cbInteractive 复选框设置为 False 确实可以将 OLE 创建的实例与任何交互式创建的实例隔离开来。

总之,先试试看,看看能不能满足你的需求。