![]() |
Excel richtig beenden aus Delphianwendung
Hallo,
mit welchem Befehl kann ich einen Excel-Prozess aus dem Speicher/Windows-Task-Manager entfernen? Wir öffnen mit einer Delphianwendung eine Exceldatei und importieren Kundendaten. Mit dem Befehl
Delphi-Quellcode:
wird zwar die sichtbare Excelanwendung geschlossen, aber im Windows-Task-Manager kann man immer noch sehen das ein Excelprozess (EXCEL.EXE) läuft.
xxx.Quit
Der verschwindet erst, wenn ich meine Delphianwendung schliesse. Nun kann es aber sein, dass der User aus mehreren xls-Dateien mehrfach Kunden importiert. Macht er dies 5-mal sind 5 Excel-Prozesse im Speicher. Wie lässt sich dieser Excel-Prozess aus dem Speicher entfernen, so dass er nicht jedesmal die Delphianwendung schliessen und neu starten muss. Für ein paar Hinweise wäre ich sehr dankbar. Oliver |
Re: Excel richtig beenden aus Delphianwendung
Mit KillProcess vielleicht (killt halt wie der Name schon sagt den Process, in dem Fall dann"Excelexe")!
|
Re: Excel richtig beenden aus Delphianwendung
Zitat:
Probier's mal hiermit: (keine Ahnung, woher ich den Code ursprünglich habe)
Delphi-Quellcode:
function TForm1.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; |
Re: Excel richtig beenden aus Delphianwendung
Dieses Problem hatte ich auch erst kürzlich ;)
Delphi-Quellcode:
Nach der Quit Zeile hat mir geholfen, habe dies mal in einem Codeschnippsel gefunden. :wink:
xxx := Unassigned;
Viel Spass beim weiterprogrammieren :) Grüsse aus der Schweiz |
Re: Excel richtig beenden aus Delphianwendung
Hallo,
Delphi-Quellcode:
brachte leider keinen Erfolg.
xxx := unassigned;
Für den KillTask fehlen wohl einige Eintragungen in den uses, z.Bsp. kann ich nichts mit " TProcessEntry32 " anfangen. "Refactoring/Unit suchen" hat nichts gefunden. Vielleicht hilft es ja wenn ich mal die Öffnen Prozedur poste.
Delphi-Quellcode:
FExcel: Variant;
Delphi-Quellcode:
procedure TExcelImport.OeffneDatei(Dateiname: string);
begin try FExcel:= CreateOleObject('Excel.Application'); FExcel.Visible := false; FExcel.WorkBooks.Open(Dateiname); FSheet := FExcel.Workbooks[1].WorkSheets[1]; except on E:EOleException do begin FExcel.Quit; raise EFileAccessException.Erzeugen('Die Datei konnte nicht geöffnet werden: ' + E.ClassName); end; end; end; Oliver |
Re: Excel richtig beenden aus Delphianwendung
Ich würde auf jeden Fall von solchen TerminateProcess-Abenteuern abraten. Das behebt nur die Symptome und nicht das zugrunde liegende Problem.
|
Re: Excel richtig beenden aus Delphianwendung
Zitat:
Oliver |
Re: Excel richtig beenden aus Delphianwendung
Hallo okoeller,
wenn kein Fehler auftritt wird Excel auch nicht geschlossen. Geh einfach mit F7 die Procedure durch, dann wirst Du sehen, dass der Teil nach except nicht ausgeführt wird, also wird Excel auch nicht geschlossen. Bis bald Chemiker |
Re: Excel richtig beenden aus Delphianwendung
Hallo Chemiker,
es gibt natürlich noch eine Schliessen-Methode die nach dem Import aufgerufen wird. Aber wie oben beschrieben verbleibt eine Excel-Prozedur im Speicher. Wird der Import erneut aufgerufen sind anschliessend zwei Excel-Prozeduren im Speicher. Die " xxx.Quit " Methode greift leider nicht.
Delphi-Quellcode:
Gruß
procedure TExcelImport.QuitExcel;
begin FExcel.DisplayAlerts := False; // exit gracefully, no prompts, etc. FExcel.Quit; { TODO Excel aus dem Speicher löschen} end; Oliver |
Re: Excel richtig beenden aus Delphianwendung
bei dem killtask musste glaubich tlhelp32 bei den uses einbinden dann gehts bei mir^^
|
Re: Excel richtig beenden aus Delphianwendung
Hallo okoeller,
versuchst mal mit dieser Function:
Delphi-Quellcode:
{-------------------------------------------------------------------------------
Funktion: EXCELOhneNachFragenSchliessen() Bemerkung: Mit dieser Function wird das neu aktive WorkBook unter den unter DateiName angegeben Namen abgespeichert. Dabei wird die Rückfrage "Sollen Ihre Änderungen in <Datei> gespeichert werden?" erscheint immer, wenn eine Arbeitsmappe geschlossen wird, welche nicht gespeicherte Änderungen enthält unterdrückt. Die Datei wird immer abgespeichert, auch wenn diese keine Änderung enthält. Parameter: m_Excel :Variant // Ist die Excel-Apllication-Variable. WorkBobj:olevariant // Ist die Aktuelle Workbook-Variable. DateiName: String // Ist der komplette Path mit Laufwerk, Path // und DateiName. Functions-Wert: = TRUE // alles Klar die Datei ist normal abgespeichert // worden. = FALSE // Es ist beim Abspeichern ein Fehler aufgetreten. Version: 1.01 letz.Ändr.: 12.05.2006 -------------------------------------------------------------------------------} function EXCELOhneNachFragenSchliessen(m_Excel: Variant; WorkBobj: olevariant; const DateiName: String): Boolean; begin Result:= FALSE; m_Excel.Application.DisplayAlerts := False; // Alle Rückfragen ausstellen try WorkBobj.saved := FALSE; WorkBobj.Close (saveChanges:=TRUE, FileName:=DateiName); Result:= TRUE; // Alles OK dann wird TRUE zurückgegeben. finally m_Excel.Application.DisplayAlerts := TRUE; // Alle Rückfragen anstellen m_Excel.Quit; end; end; Bis bald Chemiker |
Re: Excel richtig beenden aus Delphianwendung
Delphi-Quellcode:
Was ist das für ein Aufruf?
WorkBobj.Close (saveChanges:=TRUE, FileName:=DateiName);
|
Re: Excel richtig beenden aus Delphianwendung
Hallo dominikkv,
damit wird die Arbeitsmappe unter den angegeben Dateiname abgespeichert. Bis bald Chemiker |
Re: Excel richtig beenden aus Delphianwendung
Liste der Anhänge anzeigen (Anzahl: 1)
Also ich hab mir mit Process Explorer die laufenden Prozesse angesehen. Wenn ich das richtig interpretiere wird beim Öffenen der ExcelDatei vom Betriebssystem ein Termialprozess zur Verfügung gestellt, der leider nicht geschlossen/beendet wird, wenn Excel von der Delphianwendung geschlossen wird. Ob man da nun eingreifen kann/sollte bin ich mir nicht so sicher, ich bein kein Experte.
Oliver |
Re: Excel richtig beenden aus Delphianwendung
Zitat:
Ich wiederhole den Sourcecode nochmal:
Delphi-Quellcode:
Also gibt es jetzt 2 aktive Objekte: FExcel und FSheet !!
procedure TExcelImport.OeffneDatei(Dateiname: string);
begin try FExcel:= CreateOleObject('Excel.Application'); FExcel.Visible := false; FExcel.WorkBooks.Open(Dateiname); FSheet := FExcel.Workbooks[1].WorkSheets[1]; except on E:EOleException do begin FExcel.Quit; raise EFileAccessException.Erzeugen('Die Datei konnte nicht geöffnet werden: ' + E.ClassName); end; end; end; Nur wenn man beide auf Unassigned setzt, kann sich Excel selbst beenden. |
Re: Excel richtig beenden aus Delphianwendung
Hallo okoeller,
das Problem ist, dass Du Excel mehrmals öffnest, ohne es zuvor zu Schließen. 1 Excel Aufruf 2 Excel Aufruf 1 Excel Schließen Dann verbleibt der 1 Excel – Aufruf im Speicher. Selbst wenn Du die Delphi – Anwendung schließt bleibt er dort. Um den Speicher ordentlich zu hinterlassen sollte man so vorgehen: 1 Excel Aufruf 1 Excel Schließen 2 Excel Aufruf 2 Excel Schließen usw. Geht man so vor, bleibt ein Excel – Prozess im Speicher bis die Delphi – Anwendung geschlossen wird. Man könnte nun prüfen, ob Excel schon läuft unter der Variable FExcel.
Delphi-Quellcode:
Um Excel restlos aus den Speicher zu löschen, ohne die Delphi – Anwendung zu schließen:
if VarIsEmpty(FExcel) then
begin EXCELStarten (FExcel); end;
Delphi-Quellcode:
Wenn noch weitere Objekte eine Verbindung zu Excel haben, sind diese auch zu schließen, bevor Excel geschlossen wird, sonst verbleibt der Excel – Prozess bis zum Beenden der Delphi – Anwendung im Speicher.
procedure TExcelImport.QuitExcel;
begin FSheet:= Unassigned; if not VarIsEmpty(FExcel) then begin FExcel.DisplayAlerts := False; FExcel.Quit; FExcel:= Unassigned; end; end; Bis bald Chemiker |
Re: Excel richtig beenden aus Delphianwendung
Zitat:
|
Re: Excel richtig beenden aus Delphianwendung
Hallo dominikkv,
Delphi-Quellcode:
Mit dem Parameter saveChanges wird festgelegt, ob die Änderung in der Arbeitsmappe gespeichert oder verworfen wird. Gibt man saveChanges nicht an, so wird der Benutzer danach gefragt.
WorkBobj.Close (saveChanges:=TRUE, FileName:=DateiName);
TRUE = Änderungen werden gespeichert FALSE = Änderungen werden verworfen Sollte die Arbeitmappe noch keinen Namen haben, und sollen die Änderungen gespeichert werden, muss unter FileName ein Dateiname angegeben werden. Ansonsten wird der Benutzer aufgefordert, einen Namen und Path anzugeben. Die Funktion soll diese beiden Nachfragen unterdrücken, damit wird Excel geschlossen ohne lästiges Nachfragen. Bis bald Chemiker |
Re: Excel richtig beenden aus Delphianwendung
Hallo Chemiker,
mit der untenstehenden Methode lässt sich Excel nun endlich aus dem Speicher entfernen.
Delphi-Quellcode:
Der springende Punkt war, dass auch FSheet auf unassinged gesetzt werden musste.
procedure TExcelImport.QuitExcel;
begin FExcel.DisplayAlerts := False; FExcel.Quit; FExcel := unassigned; FSheet := unassigned; end; Jetzt funktioniert es einwandfrei. Anmerkung: Vielleicht ist das auch vom Betriebssystem abhängig, auf Vista hatten wir dies Problem gar nicht. Ich bedanke mich für alle Beträge und die wertvollen Hinweise. Oliver |
Re: Excel richtig beenden aus Delphianwendung
Auch wenn ich, zugegeben, nicht alle Posts gelesen hab, ich hab schon mit MS-Office 2000 festgestellt, dass es besser ist, sich an einem laufendem MS-Word/Excel/Visio-Process "ran zu hängen" als es im Code explizit neu zu starten.
Wenn man feststellen kann, dass ein Excel bereits läuft, dann öffnet man das Excel-Dokument in laufenden Excel, wenn kein Excel läuft, dann startet man Excel man halt neu per ActiveX. Wie das alles funktioniert steht definitiv hier im DP-Forum! (Denn von da hab ich den Delphi-Code her :wink: ) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz