Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.06.09;
Скачать: CL | DM;

Вниз

Как надежно закрыть связь с Excel-документом   Найти похожие ветки 

 
AbrosimovA   (2003-05-23 09:04) [0]

В своей программе(частично код указан ниже) я делаю чтение данных из файла и записываю их в таблицу Excel(Excel невидим), затем по окончании записи делаю таблицу видимой, пытаюсь разорвать связь с этой таблицей для того, чтобы закрыть свою программу. Вроде все выполняется, но...
При последующем ручном закрытии Excel-документа в менеджере задач я вижу, что Excel еще висит, а с ним и моя программа.
Никаких исключений не было ни разу.
Принудительно в менеджере задач убиваю Excel, а с ним также исчезает и моя программа. Я заметил, что это происходит тогда, когда записываю данных больше определенного числа, которое я пока не смог определить. Если данных меньше, то связь разрывается нормально. Как же понадежнее разорвать связь с открытым через OLE документом Excel?

uses ..., Registry, Variants, OleServer, Excel97, Excel2000,...;

type
TMainForm = class(TForm)
.
.
.
ExcelApplication: TExcelApplication;
ExcelWorkSheet: TExcelWorksheet;
ExcelWorkBook: TExcelWorkbook;
.
.
.
procedure ConnectExcel;
procedure DisconnectExcel;

private

public
end;

var
MainForm: TMainForm;
Excel,WorkBook,WorkSheet1:OleVariant;

implementation

uses ComObj, ActiveX;

//Соединение с Excel и настройка страницы
procedure TMainForm.ConnectExcel;
var cls_ExcelObject:string;
begin
cls_ExcelObject := "Excel.Application";
//Определение установленной версии Excel
regData := TRegistry.Create;
regData.RootKey := HKEY_CLASSES_ROOT;
try
if regData.OpenKey("\Excel.Application\CurVer", False) then begin
cls_ExcelObject := regData.ReadString("");
regData.CloseKey;
end
finally
regData.Free;
end;
try
Excel:=CreateOleObject(cls_ExcelObject);
// Отключаем реакцию Excel на события, чтобы ускорить вывод информации
Excel.Application.EnableEvents := false;
if Not FileExists(ExtractFilePath(Application.ExeName)
+"data.xls") then begin
Workbook :=Excel.WorkBooks.Add;
WorkBook.SaveAs(ExtractFilePath(Application.ExeName)
+"data.xls");
WorkBook.Close;
end;
WorkBook:=Excel.WorkBooks.Open(ExtractFilePath
(Application.ExeName)+"data.xls");
WorkSheet1:=WorkBook.WorkSheets[1];
WorkSheet1.Name:="Данные";
WorkSheet1.Activate;
finally
........;
end;
end;

procedure TMainForm.DisconnectExcel;
begin
try
WorkBook.Save;
Excel.Visible:=true;
finally
WorkSheet1:= UnAssigned;
WorkBook:= UnAssigned;
Excel:= UnAssigned;
end;
Application.Terminate;//Выход из программы
end;

........

end.


 
Palladin ©   (2003-05-23 09:08) [1]

что то я не вижу у тебя
Excel.Quit;


 
Андрей   (2003-05-23 09:21) [2]

я незнаю для чего так сложно цепляться к excelю вот мой вариант:

procedure OpenFileToExcel(FileName:string);
var
XL: OleVariant;
begin
try
Screen.Cursor:=crHourglass;
XL := CreateOleObject("Excel.Application");
XL.Workbooks.OpenText(FileName;

дальше делаешь с ним все что нужно

finally
XL.Visible:=True;
Screen.Cursor:=crDefault;
end;

ну а здесь можно и закрыть свою программу, а excel останется открытым

end;


.... помоему так.


 
Lord Warlock ©   (2003-05-23 09:26) [3]

procedure TMainForm.DisconnectExcel;
begin
try
WorkBook.Save;
Excel.Visible:=true;
finally
WorkSheet1:= UnAssigned;
WorkBook:= UnAssigned;
Excel.Disconnect;
Excel:= UnAssigned;
end;
Application.Terminate;//Выход из программы
end;


 
AbrosimovA   (2003-05-23 09:26) [4]

Надо разорвать только связь программы с Excel-документом и затем выйти из программы, а сформированный документ должен остаться на экране. И затем после его закрытия вручную мышкой, в памяти ничего не должно остаться.


 
AbrosimovA   (2003-05-23 09:46) [5]

Lord Warlock: Не помогает Excel.Disconnect.

Andrey: Чем же твой пример отличается от моего. У меня тоже
остается остается один Excel. Но при его последующем
закрытии в памяти он же все-таки остается( если в него
записано много информации
), хотя на экране его не видно.
Если данных записывается мало, то память после закрытия
Excel чистая.
Я в обоих случаях делаю одно и тоже, но результат разный.


 
bolega   (2003-05-23 10:20) [6]

> Надо разорвать только связь программы с Excel-документом и
> затем выйти из программы, а сформированный документ должен
> остаться на экране

Excel.UserControl:=True; // !!!
Excel:=UnAssigned;


 
AbrosimovA   (2003-05-23 11:20) [7]

Excel.UserControl:=True тоже не дает желаемого результата.


 
Rocker ©   (2003-05-24 09:15) [8]

...
var app:olevariant;
...
{присваиваем app excel.application, либо запущенный, либо создаем}
app.quite;
app:=unassigned;
...


 
Stray   (2003-05-25 14:59) [9]

Я открываю Ехсел так же как Андрей, но думаю принципиального различия нет. Действительно у меня (и не только..) постоянно были проблемы с формированием отчетов (Больших!). В основном это то, что Ехсел остается в памяти даже если моя прога отработала и закрылась. Иногда висла... Пытались решить проблему разными способами. (Кстати под виндой 2000 таких проблем небыло! Только под 98...). В результате пришел к такому методу победы :)) :
Запсукаю ехсел
XL: OleVariant;
XL := CreateOleObject("Excel.Application");

получаю его PID
Делаю с ним все что мне нужно (процесс невидим...)
по окончании XL.Quit;
и ДЛЯ ВЕРНОСТИ убиваю процесс:
TerminateProcess(OpenProcess(PROCESS_TERMINATE, false, PID), 0);
Если Ехсел вышел нормальното ничего страшного не случится, иначе грохнем принудительно.
Затем сформированный документ окрываю:
ShellExecute(Application.Handle, "open", PChar(FileName), nil, nil, SW_SHOWNORMAL);
Согласен, может и грубо! Но я так долго парился, что мне это надело и сделал так. Если кто знает более безболезненный способ подскажите попробую.
Кстати AbrosimovA, тебе может помочь следующее (не обязательно делать процесс нивидимым, мы пришли к выводу, что это вредит и именно когда большой объем данных):
XL.WindowState := -4140; // xlMinimized
XL.Visible := true;
XL.ScreenUpdating := false;
........

XL.ScreenUpdating := true;
XL.Quit; // или XL.WindowState = -4143; // xlNormal

Может поможет...





 
AbrosimovA   (2003-05-28 15:43) [10]

Ребята, большое вам спасибо. Мне удалось решить проблему, но другим способом, чем Stray.

Моей ошибкой было то, что я записывал данные последовательно в каждую ячейку в цикле. Для небольшого числа данных это может быть ничего, но для большого числа данных - швах.
Пришлось сделать массив типа Variant, в который перед тем, как отправлять в Excel, записал все данные. Затем одним разом данные массива отправил в Excel. Этот способ оказался в несколько раз быстрее, чем поячеечное присваивание и в результате после выхода из Excel"я в памяти было чисто. Этот способ я проверял для достаточно больших данных и везде получал положительный результат.


 
andrey_pst ©   (2003-05-28 15:53) [11]

интересно, чем это объясняется ?


 
AbrosimovA   (2003-05-28 16:03) [12]

Я думаю фактор "время передачи*объем данных"


 
asafr ©   (2003-05-28 16:04) [13]

Обязательно Excel.Free и все получится



Страницы: 1 вся ветка

Текущий архив: 2003.06.09;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.015 c
14-26672
k-man
2003-05-24 09:54
2003.06.09
Glut 3.7


1-26598
Intell
2003-05-26 17:43
2003.06.09
Как текст из Edit перевести в цифры?


1-26494
Rastafarra
2003-05-28 21:27
2003.06.09
поиск в RichEdit


14-26762
KA-87
2003-05-22 22:12
2003.06.09
А сколько программеры зарабатывают?


1-26449
Spartak
2003-05-21 07:39
2003.06.09
Как передавать данные с формы из dll не закрывая формы ?