Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.06.09;
Скачать: [xml.tar.bz2];

Вниз

Как надежно закрыть связь с 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.009 c
7-26799
Tenrai
2003-03-30 07:55
2003.06.09
Как отследить нажатие определенной клавиши?


14-26650
ZoomerSahs
2003-05-13 23:38
2003.06.09
Зацените офигительну демку.


6-26636
EvgeniyR
2003-04-09 09:26
2003.06.09
Болталка в локальной сетке


1-26468
pumba
2003-05-23 17:47
2003.06.09
Прозрачность


3-26393
KIR
2003-05-21 15:32
2003.06.09
Есть ли в IB аналог SELECT TOP 5 * FROM MyTable





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский