Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Excel richtig beenden aus Delphianwendung (https://www.delphipraxis.net/109658-excel-richtig-beenden-aus-delphianwendung.html)

okoeller 5. Mär 2008 16:21


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:
 xxx.Quit
wird zwar die sichtbare Excelanwendung geschlossen, aber im Windows-Task-Manager kann man immer noch sehen das ein Excelprozess (EXCEL.EXE) läuft.
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

Larsi 5. Mär 2008 16:25

Re: Excel richtig beenden aus Delphianwendung
 
Mit KillProcess vielleicht (killt halt wie der Name schon sagt den Process, in dem Fall dann"Excelexe")!

s-off 5. Mär 2008 16:37

Re: Excel richtig beenden aus Delphianwendung
 
Zitat:

Zitat von Larsi
Mit KillProcess vielleicht (killt halt wie der Name schon sagt den Process, in dem Fall dann"Excelexe")!

Und wo gräbst Du etwas wie 'KillProcess' aus?

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;

Kill0r 5. Mär 2008 16:52

Re: Excel richtig beenden aus Delphianwendung
 
Dieses Problem hatte ich auch erst kürzlich ;)
Delphi-Quellcode:
xxx := Unassigned;
Nach der Quit Zeile hat mir geholfen, habe dies mal in einem Codeschnippsel gefunden. :wink:
Viel Spass beim weiterprogrammieren :)

Grüsse aus der Schweiz

okoeller 5. Mär 2008 17:30

Re: Excel richtig beenden aus Delphianwendung
 
Hallo,

Delphi-Quellcode:
 xxx := unassigned;
brachte leider keinen Erfolg.

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

Apollonius 5. Mär 2008 17:40

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.

okoeller 5. Mär 2008 18:22

Re: Excel richtig beenden aus Delphianwendung
 
Zitat:

Ich würde auf jeden Fall von solchen TerminateProcess-Abenteuern abraten. Das behebt nur die Symptome und nicht das zugrunde liegende Problem.
Ok, wie kann ich denn nun rausfinden woran es liegt das Excel sich nicht aus dem Speicher löschen lässt.????

Oliver

Chemiker 5. Mär 2008 19:07

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

okoeller 5. Mär 2008 20:11

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:
procedure TExcelImport.QuitExcel;
begin
  FExcel.DisplayAlerts := False; // exit gracefully, no prompts, etc.
  FExcel.Quit;

  { TODO Excel aus dem Speicher löschen}
end;
Gruß
Oliver

Larsi 5. Mär 2008 20:14

Re: Excel richtig beenden aus Delphianwendung
 
bei dem killtask musste glaubich tlhelp32 bei den uses einbinden dann gehts bei mir^^

Chemiker 5. Mär 2008 20:27

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

dominikkv 5. Mär 2008 22:14

Re: Excel richtig beenden aus Delphianwendung
 
Delphi-Quellcode:
WorkBobj.Close (saveChanges:=TRUE, FileName:=DateiName);
Was ist das für ein Aufruf?

Chemiker 5. Mär 2008 22:53

Re: Excel richtig beenden aus Delphianwendung
 
Hallo dominikkv,

damit wird die Arbeitsmappe unter den angegeben Dateiname abgespeichert.

Bis bald Chemiker

okoeller 6. Mär 2008 11:12

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

shmia 6. Mär 2008 11:22

Re: Excel richtig beenden aus Delphianwendung
 
Zitat:

Zitat von Apollonius
Ich würde auf jeden Fall von solchen TerminateProcess-Abenteuern abraten. Das behebt nur die Symptome und nicht das zugrunde liegende Problem.

Da hast du wirklich recht!!
Ich wiederhole den Sourcecode nochmal:
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;
Also gibt es jetzt 2 aktive Objekte: FExcel und FSheet !!
Nur wenn man beide auf Unassigned setzt, kann sich Excel selbst beenden.

Chemiker 6. Mär 2008 19:51

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:
if VarIsEmpty(FExcel) then
begin
    EXCELStarten (FExcel);
end;
Um Excel restlos aus den Speicher zu löschen, ohne die Delphi – Anwendung zu schließen:

Delphi-Quellcode:
procedure TExcelImport.QuitExcel;
begin
  FSheet:= Unassigned;
  if not VarIsEmpty(FExcel) then
  begin
    FExcel.DisplayAlerts := False;
    FExcel.Quit;
    FExcel:= Unassigned;
  end;
end;
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.

Bis bald Chemiker

dominikkv 6. Mär 2008 20:29

Re: Excel richtig beenden aus Delphianwendung
 
Zitat:

Zitat von Chemiker
Hallo dominikkv,

damit wird die Arbeitsmappe unter den angegeben Dateiname abgespeichert.

Bis bald Chemiker

Mir geht es um die Argumente...

Chemiker 6. Mär 2008 20:58

Re: Excel richtig beenden aus Delphianwendung
 
Hallo dominikkv,

Delphi-Quellcode:
WorkBobj.Close (saveChanges:=TRUE, FileName:=DateiName);
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.

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

okoeller 6. Mär 2008 21:54

Re: Excel richtig beenden aus Delphianwendung
 
Hallo Chemiker,

mit der untenstehenden Methode lässt sich Excel nun endlich aus dem Speicher entfernen.

Delphi-Quellcode:
procedure TExcelImport.QuitExcel;
begin
  FExcel.DisplayAlerts := False;
  FExcel.Quit;
  FExcel := unassigned;
  FSheet := unassigned;

end;
Der springende Punkt war, dass auch FSheet auf unassinged gesetzt werden musste.
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

gmc616 6. Mär 2008 23:37

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