Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
 Завершение процесса Excel из Delphi  [new]
brighton
Member

Откуда:
Сообщений: 13
Есть такая проблема: в Delphi-форме - объект OleContainer, в него выгружается содержимое рабочей книги Excel. После просмотра того, что выгрузилось, форма закрывается. Но вот вопрос - каким образом завершить процесс Excel, потому что после закрытия формы Excel.exe продолжает занимать память...
17 мар 04, 00:01    [581647]     Ответить | Цитировать Сообщить модератору
 Re: Завершение процесса Excel из Delphi  [new]
Grigoriy
Member

Откуда: Краснодар
Сообщений: 1484
finally
if not VarIsEmpty(XLApp) then
begin
XLApp.Quit;
end;
17 мар 04, 09:59    [581943]     Ответить | Цитировать Сообщить модератору
 Re: Завершение процесса Excel из Delphi  [new]
Denis Uskov
Member

Откуда: New Urengoi
Сообщений: 482
+
FreeAndNil(XLApp);
после Quit
------------------------
С уважением, Denis Uskov
17 мар 04, 10:03    [581952]     Ответить | Цитировать Сообщить модератору
 Re: Завершение процесса Excel из Delphi  [new]
Andriy Tysh
Member

Откуда: Ukraine
Сообщений: 299
Была у меня год назад такая же проблема. И всё то, что описали выше не работало. Что я только не делал: и Квит, и ФриЭндНил, и Клоус. В большинстве случаев не работало.
Прошу не начинать сейчас бранить меня за правду!
Было. ПРикольная ситуация, Екселей нет, а впроцессах их тьма.
То я написал процедуру, которая перебирала все процессы с названием "Microsoft Excel" и у которых нет окон (тоесть следы Екселя). И потом ТерминейтПроцесс.
К сожалению под рукой нет процедуры.
17 мар 04, 11:27    [582255]     Ответить | Цитировать Сообщить модератору
 Re: Завершение процесса Excel из Delphi  [new]
Grigoriy
Member

Откуда: Краснодар
Сообщений: 1484
+
FreeAndNil(XLApp);
после Quit

да, не указал:
XLAPP := Unassigned;
Sheet := Unassigned;

А вот как эта конструкция могла не работать? Где постоянство в жизни...
17 мар 04, 11:46    [582312]     Ответить | Цитировать Сообщить модератору
 Re: Завершение процесса Excel из Delphi  [new]
Mik Prokoshin
Member

Откуда: Барнаул
Сообщений: 1240
2 Andriy Tysh:
Работать мог только Quit (не Close и не FreeAndNil). И обязательно перед ним надо было либо как-то закрывать все окна, либо выполнять DisplayAlerts:=False; Иначе Excel мог пытаться спросить Ваше мнение по поводу записи модифицированных таблиц (или оставшегося Clipboard с данными). В режиме OLE-сервера на этом все заканчивалось, Excel оставался висеть в процессах.
17 мар 04, 14:26    [582840]     Ответить | Цитировать Сообщить модератору
 Re: Завершение процесса Excel из Delphi  [new]
mv
Member

Откуда:
Сообщений: 8884
А я знаю как!
Терпите, сейчас найду, только проект откопаю.
17 мар 04, 14:38    [582881]     Ответить | Цитировать Сообщить модератору
 Re: Завершение процесса Excel из Delphi  [new]
mv
Member

Откуда:
Сообщений: 8884
Немножко соврал, не совсем то, что хочешь... Ну да ладно, про TOleContainer's, думаю, людям тоже интересно будет:

- на форме TrepX_BaseReport лежат три компонента:


exApp: TExcelApplication;
exWB: TExcelWorkbook;
exWS: TExcelWorksheet;


Так вот, установленные свойства:

для exApp

AutoConnect = False
ConnectKind = ckNewInstance
AutoQuit = False

для exWB

    AutoConnect = False

ConnectKind = ckRunningOrNew


для exWs

    AutoConnect = False

ConnectKind = ckRunningOrNew


Создается форма, в диалоге которой задаются параметры отчета:

class function TrepX_BaseReport.ShowReport(id_Inp : Integer): Integer;

begin
with Self.Create(Application) do
try
FId := id_Inp;
if ShowModal = mrOk then
DoExcel; // Запускаем Excel
finally
Free;
end
end;


Все самое главное - тут:

procedure TrepX_BaseReport.DoExcel;

begin
try
try
fMain.stbarMain.Panels[2].Text := 'Excel - подключение ...'; // фигня разная Application.ProcessMessages;
exApp.Connect;
exApp.Application.EnableEvents := false; [b]// Ускоряем[/b]
fMain.stbarMain.Panels[2].Text := 'Excel - новая книга ...';
Application.ProcessMessages;
exApp.SheetsInNewWorkbook[0] := 1;
exApp.Workbooks.Add(EmptyParam{xlWBATWorksheet},0);
exWB.ConnectTo(exApp.ActiveWorkbook);
exWS.ConnectTo(exWB.Sheets[1] as _Worksheet);
except
on E : Exception do begin
ShowMessage('Ошибка активизации приложения Microsoft Excel. '+
E.Message);
exit
end;
end;

try
BuildReport; [b]// Тут где-то строится отчет[/b]
except // Авария!
on E : Exception do begin
ShowMessage('Ошибка создания отчета в Microsoft Excel. '+
E.Message);
if Assigned(exApp) then
if (exApp.Workbooks.Count > 0) then // Вот здесь!!
exApp.AutoQuit := True; // Пусть не зависает фигня в системе!
exit
end;
end

finally
...
fMain.stbarMain.Panels[2].Text := 'Excel - отключение ...';
Application.ProcessMessages;
fMain.stbarMain.Panels[2].Text := '';

end;

end;


Самая главная строчка -
exApp.AutoQuit := True;

Ну, а если аварии не было, то делаем Excel видимым, и позволяем юзеру закрывать его, когда вздумается!
17 мар 04, 14:54    [582932]     Ответить | Цитировать Сообщить модератору
 Re: Завершение процесса Excel из Delphi  [new]
viman
Member

Откуда: Тамбов
Сообщений: 1111
Я вот так мочу:

function KillTask(ExeFileName: string): integer;
const
PROCESS_TERMINATE=$0001;
var
ContinueLoop: BOOL;
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32;
begin
result := 0;

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(ExeFileName))
or (UpperCase(FProcessEntry32.szExeFile) =
UpperCase(ExeFileName))) then
Result := Integer(TerminateProcess(OpenProcess(
PROCESS_TERMINATE, BOOL(0),
FProcessEntry32.th32ProcessID), 0));
ContinueLoop := Process32Next(FSnapshotHandle,
FProcessEntry32);
end;

CloseHandle(FSnapshotHandle);
end;

.......
KillTask('excel.exe');


Картинка с другого сайта.
17 мар 04, 14:55    [582936]     Ответить | Цитировать Сообщить модератору
 Re: Завершение процесса Excel из Delphi  [new]
mv
Member

Откуда:
Сообщений: 8884
KillTask('excel.exe'); - это классно, конечно...

А если ты породил несколько сессий Excel-ей, а убить надо только те, при которых ошибка приключилась?
Может, для твоего варианта запускать его (Excel) каждый раз с унакальными именами, а потом по ним убавать?
17 мар 04, 15:13    [582989]     Ответить | Цитировать Сообщить модератору
 Re: Завершение процесса Excel из Delphi  [new]
viman
Member

Откуда: Тамбов
Сообщений: 1111
В моем случае побарабану было...Просто создавал кучу файлов, а потом прибивал ексели. В моем случае из 30-40 открытых-закрытых процессов 1-2 обязательно оставались висеть в памяти. Просто не было времени разбираться в проблеме. А выходил я так

v.ActiveWorkbook.SaveAs(s+'\razdel3_'+inttostr(x)+'.xls');
v.ActiveWorkbook.Close;
v := UnAssigned;

Когда создается 1,2 файла таких проблем не было.

Надо будет AutoQuit попробовать...

Картинка с другого сайта.
17 мар 04, 15:35    [583072]     Ответить | Цитировать Сообщить модератору
 Re: Завершение процесса Excel из Delphi  [new]
Sclif
Member

Откуда:
Сообщений: 196
В Variant где хранится ссылка на Word.Application (ну или Excel) присвоить EmptyParam, после убивания по Quit.
17 мар 04, 17:48    [583581]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Завершение процесса Excel из Delphi  [new]
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]     Ответить | Цитировать Сообщить модератору
 Re: Завершение процесса Excel из Delphi  [new]
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]     Ответить | Цитировать Сообщить модератору
 Re: Завершение процесса Excel из Delphi  [new]
Megabyte
Member

Откуда: ближайшее заМКАДье
Сообщений: 4852
Во извращенцы))) Закрытие делается одной командой(Quit вроде и есть, не помню, исходники дома есть). Сам раньше про нее не знал и мучился с кучей процессов, потом умные люди подсказали.
7 ноя 07, 17:23    [4886801]     Ответить | Цитировать Сообщить модератору
 Re: Завершение процесса Excel из Delphi  [new]
Paty_dj
Member

Откуда:
Сообщений: 21
у меня вообщем такая же проблемка, убиваю процесс Quit ни*рена не получается. Вариант с убитем всех процессов не подходит, так как на машине пользователя возможно будут открыты другие экселевские документы.

Kill f***** Excel process
19 ноя 07, 15:21    [4934193]     Ответить | Цитировать Сообщить модератору
 Re: Завершение процесса Excel из Delphi  [new]
Flying-home
Member

Откуда: nas.vrostove.net
Сообщений: 14932
Я думаю, убивать процесс - это извращение.
Я сперва делал Quit и освобождал переменные. Все работало.
Потом показалось некрасиво, неизвестно, когда пользователь наглядится на отчет, плюс неизвестно, сохранил он его, или нет, приходилось делать проверку на неосвобожденность переменных Excel'я при выходе из программы, начал делать так:
Создаю отчет, сохраняю в профиле ползователя, закрываю Excel (OLE), открываю сохраненный отчет с помощью ShellExecute. Захочет - пересохранит. Чуть медленней, зато сердито. Никаких лишних процессов.
19 ноя 07, 15:53    [4934450]     Ответить | Цитировать Сообщить модератору
 Re: Завершение процесса Excel из Delphi  [new]
Flying-home
Member

Откуда: nas.vrostove.net
Сообщений: 14932
Создание отчета, есессно, при App.Visible := False
19 ноя 07, 16:05    [4934540]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Завершение процесса Excel из Delphi  [new]
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]     Ответить | Цитировать Сообщить модератору
 Re: Завершение процесса Excel из Delphi  [new]
Dmitri Krizhanovski
Member

Откуда:
Сообщений: 496
Lizard17rus,

У меня этот код отработал нормально и Excel-я в процессах нет.
Вместо ..... я написАл Sleep(1000)
17 окт 13, 13:36    [14985240]     Ответить | Цитировать Сообщить модератору
 Re: Завершение процесса Excel из Delphi  [new]
Lizard17rus
Member

Откуда:
Сообщений: 21
балиииииин(((((((((((((((((((
Пока свою прогу не закрою - в процессах торчит.
Embercadero XE3
А сам на чем компилил?
17 окт 13, 14:02    [14985390]     Ответить | Цитировать Сообщить модератору
 Re: Завершение процесса Excel из Delphi  [new]
Dmitri Krizhanovski
Member

Откуда:
Сообщений: 496
Lizard17rus,

Это стандартный код. Работал у меня на всех версиях до XE включительно.

А если XL.DisplayAlerts := True? Ничего не показывает?
Воспроизводится, если не делать Workbook := XL.WorkBooks.Open(FileName)?
А на новом проекте тоже воспроизводится?
17 окт 13, 14:13    [14985476]     Ответить | Цитировать Сообщить модератору
 Re: Завершение процесса Excel из Delphi  [new]
Lizard17rus
Member

Откуда:
Сообщений: 21
Жесть((
Решил опробировать свой же приведенный код. В таком виде - да - все норм. как только пускаю с обработкой данных - привет.
17 окт 13, 14:15    [14985488]     Ответить | Цитировать Сообщить модератору
 Re: Завершение процесса Excel из Delphi  [new]
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]     Ответить | Цитировать Сообщить модератору
 Re: Завершение процесса Excel из Delphi  [new]
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 Ответить