Мучаюсь больше полдня, эта тема от меня далека, но вот потребовалось.
Требуется из программы (на Delphi 7) создать документ Excel из шаблона, заполнить, и оставить открытым (отключиться от него).
// uses ComObj;procedure TForm1.Button1Click(Sender: TObject);
var
x: OleVariant;
begin
x := CreateOleObject('Excel.Application');
x.Visible := true;
// создание и заполнение документа
x := Unassigned; // Excel закрываетсяend;
Проблема в том, что как только переменная теряет свое значение — Excel автоматически закрывается. Как сделать чтобы он не закрывался? Может есть свойство какое типа AutoClose, которое нужно := false ?
B>Проблема в том, что как только переменная теряет свое значение — Excel автоматически закрывается. B>Как сделать чтобы он не закрывался? Может есть свойство какое типа AutoClose, которое нужно := false ?
При достижении ссылок равных нулю Ком сервер уничтожается. Решение держать ссылку в глобальных переменных.
Либо запусти Эксель и попробуй подключиться к нему через GetActiveOleObject
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S>При достижении ссылок равных нулю Ком сервер уничтожается. Решение держать ссылку в глобальных переменных.
Пользователь может закрыть программу после формирования документа, тут документ и закроется. Нельзя.
S>Либо запусти Эксель и попробуй подключиться к нему через GetActiveOleObject
Некрасиво. Можно не тот Excel подцепить. Да и не факт что его не закроет.
Здравствуйте, Baskak, Вы писали:
S>>При достижении ссылок равных нулю Ком сервер уничтожается. Решение держать ссылку в глобальных переменных. B>Пользователь может закрыть программу после формирования документа, тут документ и закроется. Нельзя.
S>>Либо запусти Эксель и попробуй подключиться к нему через GetActiveOleObject B>Некрасиво. Можно не тот Excel подцепить. Да и не факт что его не закроет.
BE>>Можно так, но это не совсем корректно.
B>TExcelApplication вместо CreateOleObject? B>Другая технология. Есть минусы у нее? Это не привязка к конкретной версии Excel?
B>Не хотелось бы конечно из-за такой мелочи технологию менять. Неужели проблема не решаема?
Технология та же. Это просто обертка из TLB файла. Насколько я понимаю, то здесь будет висеть ссылка BE>> dd.Workbooks.Add('', 0);
поэтому excel в итоге не закроется, но внешне все ок, хотя при длительной работе конечно могут быть и проблемы.
Здравствуйте, Baskak, Вы писали:
B>Здравствуйте, Serginio1, Вы писали:
S>>При достижении ссылок равных нулю Ком сервер уничтожается. Решение держать ссылку в глобальных переменных. B>Пользователь может закрыть программу после формирования документа, тут документ и закроется. Нельзя.
Можешь сделаль Addref. Правда Эксель не закроется и будет висеть в задачах
Или сохранить файл, закрыть эксель и открыть его как процесс указав в командной строке файл или ..
и солнце б утром не вставало, когда бы не было меня
BE>Технология та же. Это просто обертка из TLB файла. Насколько я понимаю, то здесь будет висеть ссылка BE>>> dd.Workbooks.Add('', 0); BE>поэтому excel в итоге не закроется, но внешне все ок, хотя при длительной работе конечно могут быть и проблемы.
Технология я так понял что разная — раннее vs позднее связывание. Хотя это не критично конечно.
Переделывать неохота все сделанное под новые классы. И проблем не хочется.
В крайнем случае сохраню документ в файл, и ShellExecute на него натравлю.
Но думаю что должно быть нормальное решение. Поищу еще.
Здравствуйте, Serginio1, Вы писали:
S> Можешь сделаль Addref. Правда Эксель не закроется и будет висеть в задачах
Уже ближе. При потере значения переменной Excel остается. Правда при закрытии программы все равно Excel закрывается.
S>Или сохранить файл, закрыть эксель и открыть его как процесс указав в командной строке файл или ..
Да, ShellExecute. Оставлю как запасной вариант.
Здравствуйте, Baskak, Вы писали:
S>>Или сохранить файл, закрыть эксель и открыть его как процесс указав в командной строке файл или .. B>Да, ShellExecute. Оставлю как запасной вариант.
Здравствуйте, BlackEric, Вы писали: BE>Здравствуйте, Baskak, Вы писали: S>>>Или сохранить файл, закрыть эксель и открыть его как процесс указав в командной строке файл или .. B>>Да, ShellExecute. Оставлю как запасной вариант. BE>Это, наверное, самый правильный вариант.
НЮ-НЮ
type
TExcelShowDirty = class(TObject)
private
FxlExport: Excel2000.ExcelApplication;
public
procedure BeforeDestruction; override;
procedure xlShowDirty(const FileName: string);
end;
....
{$region 'TExcelShowDirty'}procedure TExcelShowDirty.xlShowDirty(const FileName: string);
{
Этот код не пропускает Avast :-(
ShellExecute(Application.Handle, 'open', PChar(FileName), nil, nil, SW_SHOWNORMAL);
Приходиться делать через Ж.
}var
unk: IUnknown;
xl: ExcelApplication;
begin
FxlExport := nil;// отпускаем предыдущий экземплярtry{$region 'ActiveObject'}try
GetActiveObject(CLASS_ExcelApplication, nil, unk);
except
unk := CoExcelApplication.Create();
end;
{$endregion}try
if not Supports(unk, ExcelApplication, xl) then
Exit;
FxlExport := xl;
FxlExport.Workbooks.Add(FileName, lcid);
// Включаем интерактивность
FxlExport.EnableEvents := True;
FxlExport.UserControl := True;
FxlExport.Interactive[lcid] := True;
FxlExport.DisplayAlerts[lcid] := True;
FxlExport.ScreenUpdating[lcid]:= True;
FxlExport.Visible[lcid] := True;
if FxlExport.WindowState[lcid] = xlMinimized then
FxlExport.WindowState[lcid] := xlNormal;
finally{ Это и есть Ж - мы не отпускаем экземпляр а оставляем его болтаться в памяти.
xl := nil;
unk := nil;
}end;
except//eat exceptionend;
end;
procedure TExcelShowDirty.BeforeDestruction;
begin
inherited;
FxlExport := nil;
end;
{$endregion}
Успехов!
C уважением, Алексей.
------------------------------------------------
Хороших %s не бывает — бывает не худший вариант.
Здравствуйте, Baskak, Вы писали:
B>Здравствуйте.
B>Мучаюсь больше полдня, эта тема от меня далека, но вот потребовалось. B>Требуется из программы (на Delphi 7) создать документ Excel из шаблона, заполнить, и оставить открытым (отключиться от него).
B>
B>// uses ComObj;
B>procedure TForm1.Button1Click(Sender: TObject);
B>var
B> x: OleVariant;
B>begin
B> x := CreateOleObject('Excel.Application');
B> x.Visible := true;
B> // создание и заполнение документа
B> x := Unassigned; // Excel закрывается
B>end;
B>
B>Проблема в том, что как только переменная теряет свое значение — Excel автоматически закрывается. B>Как сделать чтобы он не закрывался? Может есть свойство какое типа AutoClose, которое нужно := false ?
Вот так все будет работать:
x := CreateOleObject('Excel.Application');
try
Workbook := x.WorkBooks.Open(...);
Здравствуйте, Baskak, Вы писали:
B>Здравствуйте.
B>Мучаюсь больше полдня, эта тема от меня далека, но вот потребовалось. B>Требуется из программы (на Delphi 7) создать документ Excel из шаблона, заполнить, и оставить открытым (отключиться от него).
B>
B>// uses ComObj;
B>procedure TForm1.Button1Click(Sender: TObject);
B>var
B> x: OleVariant;
B>begin
B> x := CreateOleObject('Excel.Application');
B> x.Visible := true;
B> // создание и заполнение документа
B> x := Unassigned; // Excel закрывается
B>end;
B>
B>Проблема в том, что как только переменная теряет свое значение — Excel автоматически закрывается. B>Как сделать чтобы он не закрывался? Может есть свойство какое типа AutoClose, которое нужно := false ?
А попробуйте x присваивать не Unassigned а просто nil, так как это разные значения в данном случае и значение Unassigned присваивается автоматически переменной при ее первой инициализации.