Tician Geschrieben 7. Juni 2016 Geschrieben 7. Juni 2016 Hallo ihr Informatiker! mein nächster Versuch in C# durchzusteigen bringt wieder Probleme auf. Kurz beschrieben: Ich erstelle eine Excel-Tabelle anhand der Eingaben in einer GUI, benutze dazu den Verweis "Microsoft.Office.Interop.Excel" in meinem Code und an sich hat auch alles funktioniert - bis mir plötzlich Fehlermeldungen um die Ohren geschmissen wurden obwohl ich gar nichts verändert hatte. Ein Blick in den Taskmanager zeigte mir das Excel quasi 20 mal nicht sichtbar offen war. Im Internet gibt es massig dazu und ich habe auch einiges ausprobiert, bis ich zwar das Problem mit dem "nicht-ganz-schließenden Excel" losgeworden bin, dafür aber immer ein Exception geworfen wird, sobald ich die Excel-Tabelle schließe. -> Ausnahme ausgelöst: "System.Runtime.InteropServices.COMException" in mscorlib.dll Grob mein Code (die ganzen Formatierungen innerhalb Excels ausgelassen): using Excel= Microsoft.Office.Interop.Excel; //Variablen Deklarieren Excel.Application myExcelApplication; Excel.Workbook myExcelWorkbook; Excel.Worksheet myExcelWorksheet; try { //Excel Prozess initialisieren myExcelApplication = new Excel.Application(); myExcelApplication.Visible = true; myExcelApplication.ScreenUpdating = true; //myExcelApplication = null; //Excel Datei anlegen: Workbook var myCount = myExcelApplication.Workbooks.Count; myExcelWorkbook = (Excel.Workbook)(myExcelApplication.Workbooks.Add(System.Reflection.Missing.Value)); myExcelWorksheet = (Excel.Worksheet)myExcelWorkbook.ActiveSheet; ... ... ... //release COM System.Runtime.InteropServices.Marshal.ReleaseComObject(myExcelWorksheet); System.Runtime.InteropServices.Marshal.ReleaseComObject(myExcelWorkbook); System.Runtime.InteropServices.Marshal.ReleaseComObject(myExcelApplication); System.Runtime.InteropServices.Marshal.ReleaseComObject(range1); System.Runtime.InteropServices.Marshal.ReleaseComObject(range2); System.Runtime.InteropServices.Marshal.ReleaseComObject(range3); System.Runtime.InteropServices.Marshal.ReleaseComObject(range4); System.Runtime.InteropServices.Marshal.ReleaseComObject(range5); System.Runtime.InteropServices.Marshal.ReleaseComObject(range6); System.Runtime.InteropServices.Marshal.ReleaseComObject(range7); System.Runtime.InteropServices.Marshal.ReleaseComObject(range8); System.Runtime.InteropServices.Marshal.ReleaseComObject(range9); System.Runtime.InteropServices.Marshal.ReleaseComObject(range10); } catch { MessageBox.Show("Fehler erkannt"); } finally { GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); GC.WaitForPendingFinalizers(); } Ich kann auch nicht mit Haltepunkten arbeiten, da das Programm an sich komplett durchläuft. Ich habe ja ein Fenster das im Hintergrund noch offen ist, allerdings ist es nicht schließbar solange die Excel-Tabelle offen ist (das ist erst so seit ich die Marshal-Klasse benutze um die Com-Objekte zu "lösen". Was muss ich also tun damit mein Programm 1. nach dem Schließen des Excel-Fensters auch wirklich alles schließt und nicht noch im Task-manager hängt 2. keine Exception schmeißt oder um das Problem genauer einzugrenzen? Ich hoffe ihr könnte mir helfen Grüße Tician Zitieren
ronaldus Geschrieben 30. Juni 2016 Geschrieben 30. Juni 2016 Hallo Tician, private Microsoft.Office.Interop.Excel.Application myExcelApplication = null; private Microsoft.Office.Interop.Excel.Workbook myExcelWorkbook = null; private void Release() { myExcelApplication.Quit(); releaseObject(myExcelWorkbook); releaseObject(myExcelApplication); } private void releaseObject(object obj) { try { System.Runtime.InteropServices.Marshal.ReleaseComObject(obj); obj = null; } catch (Exception ex) { obj = null; MessageBox.Show("Exception Occured while releasing object " + ex.ToString()); } finally { GC.Collect(); } } Gruß Ronald Zitieren
Tician Geschrieben 4. Juli 2016 Autor Geschrieben 4. Juli 2016 Werde ich ausprobieren, danke! Zitieren
Whiz-zarD Geschrieben 6. August 2016 Geschrieben 6. August 2016 Aus eigener Erfahrung gebe ich dir den Rat Die Interop-Schnittstelle nicht zu verwenden! Du handelst dir damit mächtig viele potenzielle Fehler ein. Selbst Microsoft rät von diesem Weg ab. Ein weiteres Problem ist, dass die Architektur ab Excel 2013 sich grundlegend geändert hat, sodass man gar nicht mehr sicher mit der Interop-Schnittstelle arbeiten kann. Früher war es so, dass man immer einen separaten Prozess gestartet hat, über den man arbeiten konnte. Inzwischen wird aber nur ein Prozess gestartet. Führt man also ab Excel 2013 new Excel.Application(); aus, so erhält man intern immer den selben Prozess. Die Properties ActiveSheet oder ActiveWorkbook funktionieren dann nicht mehr korrekt, wenn man nebenbei noch an einer weiteren Excel-Datei arbeitet. Man merkt aber erst beim Speichern, dass da irgendwas schiefgelaufen ist. Darüber hinaus ist auch die Interop-Schnittstelle extrem langsam und während die Excel-Datei erstellt wird, kann man auch die Copy/Paste-Funktion nicht mehr benutzen, weil die Interop-Schnittstelle darüber die Daten nach Excel Transferiert. Wenn du Excel-Dateien erstellen möchtest, dann verwende eine Bibliothek dafür, wie z.B. EPPlus. Das hat auch den Vorteil, dass man von einer Excel-Installation unabhängig ist, da Excel nicht benötigt wird. Zitieren
Tician Geschrieben 8. August 2016 Autor Geschrieben 8. August 2016 Ich hatte es soweit geschafft zumindest den Prozess gescheit zu beenden, dazu habe ich einfach alles benutzt was ich irgendwie gefunden habe... Main { ... //Der verzweifelte Versuch alle ComObjekte wieder zu "entlassen" System.Runtime.InteropServices.Marshal.ReleaseComObject(myExcelWorksheet); System.Runtime.InteropServices.Marshal.ReleaseComObject(myExcelWorkbook); System.Runtime.InteropServices.Marshal.ReleaseComObject(myExcelApplication); System.Runtime.InteropServices.Marshal.ReleaseComObject(range1); System.Runtime.InteropServices.Marshal.ReleaseComObject(range2); System.Runtime.InteropServices.Marshal.ReleaseComObject(range3); System.Runtime.InteropServices.Marshal.ReleaseComObject(range4); System.Runtime.InteropServices.Marshal.ReleaseComObject(range5); System.Runtime.InteropServices.Marshal.ReleaseComObject(range6); System.Runtime.InteropServices.Marshal.ReleaseComObject(range7); System.Runtime.InteropServices.Marshal.ReleaseComObject(range8); System.Runtime.InteropServices.Marshal.ReleaseComObject(range9); System.Runtime.InteropServices.Marshal.ReleaseComObject(range10); } catch { MessageBox.Show("Fehler erkannt"); } finally { //Ein weiterer Versuch Excel nach dem schließen auch aus dem Taskmanager zu haben, 2 mal weil es so im internet geraten wird GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); GC.WaitForPendingFinalizers(); } Sollte ich nochmal etwas mit Excel machen werde ich mir mal die Bibliothek anschauen Whiz-zard Zitieren
HJST1979 Geschrieben 12. August 2016 Geschrieben 12. August 2016 Hast du schon mal drüber nachgedacht es so umzusetzen, dass du auf den jeweiligen Rechner überhaupt kein Excel benötigst? Ich verwende zum Beispiel zum Excel und Word-Dateien erzeugen das Microsoft Open XML SDK, damit klappt es sehr gut und es gibt einige gute Beispiele im Internet. Zitieren
Tician Geschrieben 15. August 2016 Autor Geschrieben 15. August 2016 Naja eine Excel-Datei zu öffnen ist ja gewollt. Das Programm soll Excel öffnen, dann wie ein Makro seinen Code ausführen (was es ja auch tut) und sich beenden, sodass man mit der Excel-Tabelle manuell weiterarbeiten kann. Und jetzt tut auch alles, ich warte nur noch auf einen Datenbank-Zugang meines Ausbbilders Zitieren
Whiz-zarD Geschrieben 15. August 2016 Geschrieben 15. August 2016 (bearbeitet) vor 4 Stunden schrieb Tician: Naja eine Excel-Datei zu öffnen ist ja gewollt. Das Programm soll Excel öffnen, dann wie ein Makro seinen Code ausführen (was es ja auch tut) und sich beenden, sodass man mit der Excel-Tabelle manuell weiterarbeiten kann. Und jetzt tut auch alles, ich warte nur noch auf einen Datenbank-Zugang meines Ausbbilders Und nun stelle dir mal vor, dass der Rechner, an dem du sitzt, überhaupt kein Excel verfügt, du aber trotzdem eine Excel-Datei erstellen möchtest. Angenommen, du arbeitest an einer Client-Server-Software und der Server soll die Excel-Datei erstellen. Dann muss auf dem Server Excel installiert sein und genau das wird von Microsoft nicht empfohlen, da Excel ein interaktives Tool ist und ggf. Dialoge aufpoppen können, auf die der Server nicht reagiert, da die Reaktion vom Nutzer erwartet wird. Ich habe mal an so einer Architektur gearbeitet (sie stammte nicht von mir). Es sollte eine Excel-Datei geladen und geändert werden, die aber beim Öffnen ein Makro startet, welches ein Willkommensdialog öffnet. Wir mussten also noch über die COM-Schnittstelle ein Entertasten-Druck mitschicken, damit der Dialog geschlossen wird, damit wir die Datei bearbeiten konnten... Also Entweder du ignorierst die Warnung von Microsoft und installierst Excel auf dem Server (und da zeigen schon viele Kunden dir den Vogel) oder die ganze Logik zur Erstellung der Excel-Datei muss im Client implementiert werden. Beides will man aber eigentlich nicht, da man sehr viele Gefahren eingeht und ich spreche aus Erfahrung: Das sind VIELE Gefahren und bei jeder neuen Excel-Version kommen weitere hinzu. Die Software soll also bestmöglich unabhängig von Excel Excel-Dateien erstellen können. Also bleibt dir da nichts anderes übrig, als eine Bibliothek zu verwenden. Das Office Open SDK von Microsoft geht dafür auch, aber ich finde es sehr komplex und nicht gerade Trivial. Excel kann ja weiterhin geöffnet werden, aber erst nachdem die Datei erstellt und tatsächlich Excel installiert wurde. Alles andere ist unklug. Es kann ja auch gut sein, dass der Rechner, vor dem du gerade sitzt nur einen Excel Viewer installiert hat. Excel-Dateien kannst du dir zwar über den Rechner anschauen aber nicht erstellen. Bearbeitet 15. August 2016 von Whiz-zarD Zitieren
Tician Geschrieben 15. August 2016 Autor Geschrieben 15. August 2016 vor 2 Stunden schrieb Whiz-zarD: Und nun stelle dir mal vor, dass der Rechner, an dem du sitzt, überhaupt kein Excel verfügt, du aber trotzdem eine Excel-Datei erstellen möchtest. Dann könnten wir nochmal darüber reden Es ist wirklich nichts großes, es soll ein Hotline-Plan für unsere Abteilung sein, der Feiertage und Urlaubstage aus einer Datenbank ließt und Zufallsmäßig in 3-Tages-Blöcken Früh und Späthotline verteilt und das soll natürlich auch sichtbar und druckbar sein. Quasi rein zur Übung und um das monatliche Hotline verteilen zu ersparen Zitieren
Gooose Geschrieben 15. August 2016 Geschrieben 15. August 2016 Warum bindet ihr nicht einfach die Datenbank als Datenquelle in Excel ein? Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.