DELPHI «вызванный объект отключился от своих клиентов» - PullRequest
1 голос
/ 13 июля 2020

При запуске 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.

img1 img2 img3

Если файл Excel, открытый сам по себе, закрыт, я получаю сообщение об ошибке в заголовке, и моя программа ломается. извините за мой плохой англи sh. createoleobject не может создать автономный объект. почему?

1 Ответ

2 голосов
/ 14 июля 2020

Если я вас правильно понял, я думаю, что могу найти решение вашей проблемы.

Помимо Visible объект OLE Excel имеет еще два важных свойства:

  • DisplayAlerts, который определяет, отображаются ли на экране предупреждения, созданные приложением Exccel; и

  • Interactive, который определяет, может ли объект Excel (созданный с помощью CreateOleObject) взаимодействовать с экземпляром Excel, запущенным пользователем через Windows gui. Если установлено значение False, экземпляр OLE Excel полностью «изолирован» от экземпляра рабочего стола пользователя.

Оба эти документа задокументированы MS, см. здесь для документации для 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, от любого экземпляра, созданного в интерактивном режиме.

В любом случае, поэкспериментируйте с этим и посмотрите, соответствует ли он вашим потребностям.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...