Excel freigeben

    • VB.NET

      Excel freigeben

      Excel -mehr noch alle Com-Objekte überhaupt, wie sie bei Excel-InterOp. Word, Winexplorer, (viele weitere...) entstehen, haben eine äusserst unschöne Eigenschaft: Sie werden nicht von selbst freigegeben.
      Bei Excel führt das zum Beispiel dazu, dass die Excel-Anwendung, nachdem man sie mit xcelApp.Quitt() geschlossen hat, noch immer unsichtbar im Speicher verbleibt. Das merkt man erst, wenn man Excel anschließend normal öffnen will - das geht dann nämlich nicht.
      MSDN erklärt auf englisch die Lösung, und schließt lapidar: "This behavior is by design"
      HIer nochmal auf deutsch (Beispiel Excel):
      Die Lösung liegt also darin, jedes einzelne Excel-Interop-Objekt mit Marshal.FinalRelease wieder freizugeben. Das verkompliziert excel-interop-Programmierung erheblich, ist aber nicht unmöglich.

      Also sowas führt zum Fehlverhalten:

      VB.NET-Quellcode

      1. xcelApp.Workbooks(1).Worksheets("Tabelle1").Cells(5,9).Value = 99
      In dieser popeligen Zeile entstehen neben dem vorrausgesetzten Excel.Application - Objekt noch 6 weitere Excel-Objekte, die alle einzeln freizugeben sind:
      1. das Workbooks-Objekt - eine Auflistung der Workbooks wird angesprochen
      2. das Workbook, welches per Integer-Index (1) aus den Workbooks ausgewählt wurde
      3. das Worksheets-Objekt - die Auflistung der im Workbook enthaltenen Worksheets
      4. das Worksheet-Objekt, welches per String-Index ("Tabelle1") aus den Worksheets ausgewählt wurde
      5. das Cells-Objekt - die Auflistung der Zellen dieser Tabelle
      6. ein Range-Objekt - die mit (5,9) addressierte Zelle
      Sauber geproggt wäre also:

      VB.NET-Quellcode

      1. dim wkbs=xcelApp.Workbooks
      2. dim wkb=wkbs(1)
      3. dim wkss=wkb.Worksheets
      4. dim wks=wkss("Tabelle1")
      5. dim oCells=wks.Cells
      6. dim rng=oCells(5,9)
      7. rng.Value=99
      8. for each obj in new Object(){wkbs, wkb, wkss, wks,oCells,rng}
      9. System.Runtime.InteropServices.Marshal.FinalReleaseComObject(obj)
      10. next
      beachte: das xcelApp - Objekt wurde hier noch nicht released, wg Annahme, dasses noch weiter verwendet werden soll.

      Es gibt noch 2 weitere Lösungen
      1. Quick & Dirty: Man kann mit der Process-Klasse den Excel-Prozess suchen und terminieren.
        Ist nichtmal weiter kompliziert, jdfs. wenn man das Excel-Objekt selbst erstellt hat und unsichtbar belassen - dann kann man nach MainWindowTitle = "" suchen, wie hier gezeigt.
      2. Man kann - wenn man nur xls-Dateien bearbeiten will, ohne Excel-Anzeige - sich eine OpenSource-Excel-Library downloaden. Die hat bei weitem nicht den vollen Leistungs-Umfang von Excel-InterOp, aber für die meisten üblichen Erfordernisse wird es ausreichen, und ist darüberhinaus Resourcensparend und schneller.


      Credits an:

      Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ErfinderDesRades“ ()