Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Delphi |
![]() ![]() |
Топик располагается на нескольких страницах: [1] 2 3 вперед Ctrl→ все |
brighton Member Откуда: Сообщений: 13 |
Есть такая проблема: в Delphi-форме - объект OleContainer, в него выгружается содержимое рабочей книги Excel. После просмотра того, что выгрузилось, форма закрывается. Но вот вопрос - каким образом завершить процесс Excel, потому что после закрытия формы Excel.exe продолжает занимать память... |
17 мар 04, 00:01 [581647] Ответить | Цитировать Сообщить модератору |
Grigoriy Member Откуда: Краснодар Сообщений: 1484 |
finally
if not VarIsEmpty(XLApp) then begin XLApp.Quit; end; |
17 мар 04, 09:59 [581943] Ответить | Цитировать Сообщить модератору |
Denis Uskov Member Откуда: New Urengoi Сообщений: 482 |
+
FreeAndNil(XLApp); после Quit ------------------------ С уважением, Denis Uskov |
17 мар 04, 10:03 [581952] Ответить | Цитировать Сообщить модератору |
Andriy Tysh Member Откуда: Ukraine Сообщений: 299 |
Была у меня год назад такая же проблема. И всё то, что описали выше не работало. Что я только не делал: и Квит, и ФриЭндНил, и Клоус. В большинстве случаев не работало.
Прошу не начинать сейчас бранить меня за правду! Было. ПРикольная ситуация, Екселей нет, а впроцессах их тьма. То я написал процедуру, которая перебирала все процессы с названием "Microsoft Excel" и у которых нет окон (тоесть следы Екселя). И потом ТерминейтПроцесс. К сожалению под рукой нет процедуры. |
17 мар 04, 11:27 [582255] Ответить | Цитировать Сообщить модератору |
Grigoriy Member Откуда: Краснодар Сообщений: 1484 |
да, не указал: XLAPP := Unassigned; Sheet := Unassigned; А вот как эта конструкция могла не работать? Где постоянство в жизни... |
||||||
17 мар 04, 11:46 [582312] Ответить | Цитировать Сообщить модератору |
Mik Prokoshin Member Откуда: Барнаул Сообщений: 1240 |
2 Andriy Tysh:
Работать мог только Quit (не Close и не FreeAndNil). И обязательно перед ним надо было либо как-то закрывать все окна, либо выполнять DisplayAlerts:=False; Иначе Excel мог пытаться спросить Ваше мнение по поводу записи модифицированных таблиц (или оставшегося Clipboard с данными). В режиме OLE-сервера на этом все заканчивалось, Excel оставался висеть в процессах. |
17 мар 04, 14:26 [582840] Ответить | Цитировать Сообщить модератору |
mv Member Откуда: Сообщений: 8876 |
А я знаю как!
Терпите, сейчас найду, только проект откопаю. |
17 мар 04, 14:38 [582881] Ответить | Цитировать Сообщить модератору |
mv Member Откуда: Сообщений: 8876 |
Немножко соврал, не совсем то, что хочешь... Ну да ладно, про TOleContainer's, думаю, людям тоже интересно будет:
- на форме TrepX_BaseReport лежат три компонента:
Так вот, установленные свойства: для exApp
для exWB
для exWs
Создается форма, в диалоге которой задаются параметры отчета:
Все самое главное - тут:
Самая главная строчка - exApp.AutoQuit := True; Ну, а если аварии не было, то делаем Excel видимым, и позволяем юзеру закрывать его, когда вздумается! |
||||||||||||
17 мар 04, 14:54 [582932] Ответить | Цитировать Сообщить модератору |
viman Member Откуда: Тамбов Сообщений: 1111 |
Я вот так мочу:
![]() |
||
17 мар 04, 14:55 [582936] Ответить | Цитировать Сообщить модератору |
mv Member Откуда: Сообщений: 8876 |
KillTask('excel.exe'); - это классно, конечно...
А если ты породил несколько сессий Excel-ей, а убить надо только те, при которых ошибка приключилась? Может, для твоего варианта запускать его (Excel) каждый раз с унакальными именами, а потом по ним убавать? |
17 мар 04, 15:13 [582989] Ответить | Цитировать Сообщить модератору |
viman Member Откуда: Тамбов Сообщений: 1111 |
В моем случае побарабану было...Просто создавал кучу файлов, а потом прибивал ексели. В моем случае из 30-40 открытых-закрытых процессов 1-2 обязательно оставались висеть в памяти. Просто не было времени разбираться в проблеме. А выходил я так
Когда создается 1,2 файла таких проблем не было. Надо будет AutoQuit попробовать... ![]() |
||
17 мар 04, 15:35 [583072] Ответить | Цитировать Сообщить модератору |
Sclif Member Откуда: Сообщений: 196 |
В Variant где хранится ссылка на Word.Application (ну или Excel) присвоить EmptyParam, после убивания по Quit. |
17 мар 04, 17:48 [583581] Ответить | Цитировать Сообщить модератору |
Между сообщениями интервал более 1 года. |
burton Member Откуда: Сообщений: 25 |
Вариант vimana хотелось бы дополнить. Дело в том, что действительно, при "убийстви процессов" происходит терминэйт всех EXCEL (Это уже было отмечено MV). Как один из вариантов - это после успешного создания XlsApp и открытия книги, сразу запомнить ID процесса, который в свою очередь будет последним EXCELевским процессом. Для этого потребуется всего навсего переписать ф-ию KillTask так, чтобы она возвращала значение типа TProcessEntry32. Что-то типа: function TForm1.GetProcessId: TProcessEntry32; const PROCESS_TERMINATE=$0001; var ContinueLoop: BOOL; FSnapshotHandle: THandle; FProcessEntry32: TProcessEntry32; begin FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); FProcessEntry32.dwSize := Sizeof(FProcessEntry32); ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32); while integer(ContinueLoop) <> 0 do begin if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase('excel.exe')) or (UpperCase(FProcessEntry32.szExeFile) = UpperCase('excel.exe'))) then Result := FProcessEntry32; ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32); end; CloseHandle(FSnapshotHandle); end;Получится, что ф-ия вернет ID последнего процесса. Таким образом, вырубить процесс удастся по конкретному FProcessEntry32.th32ProcessID, типа: TerminateProcess(OpenProcess (PROCESS_TERMINATE, BOOL(0), FProcessEntryExcel.th32ProcessID), 0);Сам затестил - работает))) |
7 ноя 07, 09:12 [4882980] Ответить | Цитировать Сообщить модератору |
burton Member Откуда: Сообщений: 25 |
Вариант vimana хотелось бы дополнить. Дело в том, что действительно, при "убийстви процессов" происходит терминэйт всех EXCEL (Это уже было отмечено MV). Как один из вариантов - это после успешного создания XlsApp и открытия книги, сразу запомнить ID процесса, который в свою очередь будет последним EXCELевским процессом. Для этого потребуется всего навсего переписать ф-ию KillTask так, чтобы она возвращала значение типа TProcessEntry32. Что-то типа: function TForm1.GetProcessId: TProcessEntry32; const PROCESS_TERMINATE=$0001; var ContinueLoop: BOOL; FSnapshotHandle: THandle; FProcessEntry32: TProcessEntry32; begin FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); FProcessEntry32.dwSize := Sizeof(FProcessEntry32); ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32); while integer(ContinueLoop) <> 0 do begin if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase('excel.exe')) or (UpperCase(FProcessEntry32.szExeFile) = UpperCase('excel.exe'))) then Result := FProcessEntry32; ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32); end; CloseHandle(FSnapshotHandle); end;Получится, что ф-ия вернет ID последнего процесса. Таким образом, вырубить процесс удастся по конкретному FProcessEntry32.th32ProcessID, типа: TerminateProcess(OpenProcess (PROCESS_TERMINATE, BOOL(0), FProcessEntryExcel.th32ProcessID), 0);Сам затестил - работает))) |
7 ноя 07, 09:13 [4882981] Ответить | Цитировать Сообщить модератору |
Megabyte Member Откуда: ближайшее заМКАДье Сообщений: 4973 |
Во извращенцы))) Закрытие делается одной командой(Quit вроде и есть, не помню, исходники дома есть). Сам раньше про нее не знал и мучился с кучей процессов, потом умные люди подсказали. |
7 ноя 07, 17:23 [4886801] Ответить | Цитировать Сообщить модератору |
Paty_dj Member Откуда: Сообщений: 21 |
у меня вообщем такая же проблемка, убиваю процесс Quit ни*рена не получается. Вариант с убитем всех процессов не подходит, так как на машине пользователя возможно будут открыты другие экселевские документы. Kill f***** Excel process |
19 ноя 07, 15:21 [4934193] Ответить | Цитировать Сообщить модератору |
Flying-home Member Откуда: kart.vrostove.net Сообщений: 15000 |
Я думаю, убивать процесс - это извращение. Я сперва делал Quit и освобождал переменные. Все работало. Потом показалось некрасиво, неизвестно, когда пользователь наглядится на отчет, плюс неизвестно, сохранил он его, или нет, приходилось делать проверку на неосвобожденность переменных Excel'я при выходе из программы, начал делать так: Создаю отчет, сохраняю в профиле ползователя, закрываю Excel (OLE), открываю сохраненный отчет с помощью ShellExecute. Захочет - пересохранит. Чуть медленней, зато сердито. Никаких лишних процессов. |
19 ноя 07, 15:53 [4934450] Ответить | Цитировать Сообщить модератору |
Flying-home Member Откуда: kart.vrostove.net Сообщений: 15000 |
Создание отчета, есессно, при App.Visible := False |
19 ноя 07, 16:05 [4934540] Ответить | Цитировать Сообщить модератору |
Между сообщениями интервал более 1 года. |
Lizard17rus Member Откуда: Сообщений: 21 |
Уважаемые! Убился ужо в конец........................ uses ...., ComObj; procedure TfrmMainForm.DataLoad(FileName: string; arFile: Pointer); var XL, Workbook, Sheet: OleVariant; begin XL := CreateOleObject('Excel.Application'); XL.DisplayAlerts := False; XL.Visible := True; Workbook := XL.WorkBooks.Open(FileName); Sheet := Workbook.WorkSheets[1]; .... Sheet := Unassigned; Workbook.Close; Workbook := Unassigned; XL.Quit; XL := Unassigned; end; И все равно Excel висит(!) в процессах до закрытия приложения. Перепробывал всё и вся, гугл уже не знает что подсказать. Сообщение было отредактировано: 17 окт 13, 20:41 |
17 окт 13, 13:24 [14985152] Ответить | Цитировать Сообщить модератору |
Dmitri Krizhanovski Member Откуда: Сообщений: 502 |
Lizard17rus, У меня этот код отработал нормально и Excel-я в процессах нет. Вместо ..... я написАл Sleep(1000) |
17 окт 13, 13:36 [14985240] Ответить | Цитировать Сообщить модератору |
Lizard17rus Member Откуда: Сообщений: 21 |
балиииииин((((((((((((((((((( Пока свою прогу не закрою - в процессах торчит. Embercadero XE3 А сам на чем компилил? |
17 окт 13, 14:02 [14985390] Ответить | Цитировать Сообщить модератору |
Dmitri Krizhanovski Member Откуда: Сообщений: 502 |
Lizard17rus, Это стандартный код. Работал у меня на всех версиях до XE включительно. А если XL.DisplayAlerts := True? Ничего не показывает? Воспроизводится, если не делать Workbook := XL.WorkBooks.Open(FileName)? А на новом проекте тоже воспроизводится? |
17 окт 13, 14:13 [14985476] Ответить | Цитировать Сообщить модератору |
Lizard17rus Member Откуда: Сообщений: 21 |
Жесть(( Решил опробировать свой же приведенный код. В таком виде - да - все норм. как только пускаю с обработкой данных - привет. |
17 окт 13, 14:15 [14985488] Ответить | Цитировать Сообщить модератору |
Lizard17rus Member Откуда: Сообщений: 21 |
вот вся процедура полностьюprocedure TfrmMainForm.DataLoad(FileName: string; arFile: Pointer); var XL, Workbook, Sheet: OleVariant; str: string; RefStyle, x, y, rows: Integer; ar: array of array[0..12] of string; const head: Integer = 3; begin try rows := 0; XL := CreateOleObject('Excel.Application'); XL.DisplayAlerts := False; XL.Visible := True; RefStyle := XL.ReferenceStyle; XL.ReferenceStyle := -4150; Workbook := XL.WorkBooks.Open(FileName); Sheet := Workbook.WorkSheets[1]; Sheet.Cells.Replace(What:='«', Replacement:='"'); Sheet.Cells.Replace(What:='»', Replacement:='"'); repeat Inc(rows); str := Sheet.Cells[rows+head, 1]; until str = ''; Dec(rows); Sheet.Range[Sheet.Cells[head+1, 1], Sheet.Cells[head+rows, 12]].UnMerge; Sheet.Range[Sheet.Cells[head+1, 1], Sheet.Cells[head+rows, 12]].Sort(Key1:=Sheet.Columns[3], Order1:=1, Key2:=Sheet.Columns[9], Key3:=Sheet.Columns[10]); Pointer(ar) := arFile; SetLength(ar, rows); for y := head+1 to head+rows do for x := 1 to 12 do begin ar[y-head-1,x-1] := Sheet.Cells[y, x]; end; ar := nil; XL.ReferenceStyle := RefStyle; Sheet := Unassigned; Workbook.Close; Workbook := Unassigned; XL.Quit; XL := Unassigned; except end; end; Сообщение было отредактировано: 17 окт 13, 20:41 |
17 окт 13, 14:19 [14985515] Ответить | Цитировать Сообщить модератору |
Lizard17rus Member Откуда: Сообщений: 21 |
решил подключать обработку кусками и выяснить на каком этапе происходит затык. нашел.... Sheet.Range[Sheet.Cells[head+1, 1], Sheet.Cells[head+rows, 12]].UnMerge; Sheet.Range[Sheet.Cells[head+1, 1], Sheet.Cells[head+rows, 12]].Sort(Key1:=Sheet.Columns[3], Order1:=1, Key2:=Sheet.Columns[9], Key3:=Sheet.Columns[10]); сортировка..... еле-еле ее смог прикрутить, а она торчит. умеет кто делать сортировку по 3 столбцам? Сообщение было отредактировано: 17 окт 13, 20:40 |
17 окт 13, 14:29 [14985582] Ответить | Цитировать Сообщить модератору |
Топик располагается на нескольких страницах: [1] 2 3 вперед Ctrl→ все |
Все форумы / Delphi | ![]() |