Zugriff auf laufende Excel-Prozesse

jayel

Grünschnabel
Hallo

ich habe ein ziemliches Problem mit dem Zugriff auf Excel :(
Szenario: Meine Aplikation soll mehrere male hintereinander Daten in jeweils ein neues Excel-Sheet einer Arbeitsmappe pumpen.

Dazu erstelle ich beim ersten Export einen neuen Excel-Prozesse mittels:
ExcelApp = new Excel.ApplicationClass();

mit dieser Excel-Applikation kann ich dann alles machen was ich will.

Da nun aber nutzerseitig die Möglichkeit besteht, daß Excel geschlossen wird, während mein Programm läuft, möchte ich beim nächsten Export auf eine laufende Excel-Applikation zugreifen. Welche das ist kann ich scheinbar nicht beeinflussen, aber unter umständen ist es ja sogar meine :)

kompletter code:

private void export_Click(object sender, System.EventArgs e)
this.Cursor = System.Windows.Forms.Cursors.WaitCursor;
try
{
ExcelApp = (Excel.ApplicationClass) System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
}
catch
{
ExcelApp = new Excel.ApplicationClass();
}

//add new Workbook and new Worksheet and set Worksheet-Name
//... do something

System.Runtime.InteropServices.Marshal.ReleaseComObject(ExcelApp);
this.Cursor = System.Windows.Forms.Cursors.Default;

ExcelApp = null;
}

Probleme damit:
- System.Runtime.InteropServices.Marshal.GetActiveObject gibt Cast-Exceptions
- es wird jedesmal ein neues Exel-Dokument geöffnet
- im Taskmanager erscheinen gleich mal 3 Prozesse
- nach beenden von Excel oder meinem Programm bleiben die Leichen im Taskmanager
erhalten.

Vielleicht hat sich schonmal jemand damit beschäftigt und kann mir den "zündenden Tip" geben.

Grüße

JayeL
 
moin

Du kannst doch net einfach irgendeinen laufenden Excel-Prozess nehmen und deine Daten da hineinschreiben!

Erklär mal n bisschen genauer, was du willst.

Und benutz bitte die Code-Tags, damit man deinen Code besser lesen kann.

mfg broetchen
 
ich will einfach nur Daten nach Excel pumpen. Und zwar mehrere male hintereinander, manuell aus meiner applikation heraus aufgerufen. Da alle neuen Exports dann aber in ein neues Sheet geschrieben werden sollen, muß ich zwangsläufig in eine bestehende Excel-Applikation hineinschreiben.

Einfach eine Excel.Applikation zu erstellen und selbige immer wieder zu nutzen läßt sich mit Nutzungegewohnheiten einiger leider nicht kombinieren :(
Wenn nämlich der User das Excel komplett schließt, verweist die Referenz ins Nirvana und der nächste Export bricht mit nem Fehler ab.

So muß ich auf eine laufende Excel-Instanz zugreifen um meine Daten dort reinzupumpen.
Am liebsten wäre mir die zuletzt aktuelle oder sowas. Im Visual Basic kann man das mit nem Excel-OLE-Object machen, aber im C# habe ich keine Ahnung wie ich das anstellen soll :(

Die Variante:
Code:
_Application ExcelApp = (_Application)Sstem.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");

geht auchnciht richtig, weil "_Application" nur ein Interface ist und ich das nicht referenzieren kann.
 
Also wenn ich das richtig verstanden habe, sollen gewisse Daten auf Knopfdruck in ein Excel-Sheet geschrieben werden und wenn Excel nicht mehr läuft, schmierst du ab!?
Stimmt's so?

Du kannst Excel sagen, dass er das Sheet, welches du aus deinem Programm heraus öffnest, nicht anzeigen soll und für das Problem des nicht laufenenden Excel: mach doch einfach eine Abfrage ob Excel rennt. Wenn ja, dann ist alles schön und gut, wenn nicht, dann starte es einfach.

Was das Öffnen bzw. Schreiben von Excel-Files anbelangt kann ich dir nur diese zwei Links geben:
How to Open and Read an Excel Spreadsheet into a ListView in .NET
Faster MS Excel Reading using Office Interop Assemblies

mfg broetchen
 
So in etwa ist es. Mein Programm läuft zuweilen mehrere Stunden hintereinander und kann zig unterschiedliche Daten exportieren (alles Tabellen). Um zu gewährleisten, das ich ein neues Workbook bzw. Worksheet erzeugen kan, muß ich eine Instanz eines Excel.ApplicationClass - Objects in meinem Programm referenzieren.

Wenn nun ein paar Exports ins Exel hintereinander gelaufen sind, macht der User vielleicht mal was anderes und schlißt spontan das Excel, wobei mein Programmweiterläuft. In diesem Fall, referenziere ich ins Nirvana und ich kann auf mein Excel.ApplicationClass - Object kein Workbook mehr erstellen.

Variablentyp:
Code:
private  Excel.ApplicationClass ExcelApp;

Ich dachte mir halt, daß ich teste ob eine Instanz eines Excel´s läuft, was ich mir "greifen" kann um meine Daten zu exportieren.

aber:
Code:
Excel.ApplicationClass ExcelApp = (Excel.ApplicationClass) System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
liefert nen Cast-Fehler und läßt Excel-Prozess-Leichen übrig.

Code:
_Application ExcelApp = (_Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
ist nur ein Interface, auf dem ich kein Workbook anlegen kann, obwohl mir die Referenz "ExcelApp" alle Methoden aus Excel zur Verfügung stellt.

Einzige von mir ersichtliche Lösung ist es wohl, ständig ein neues Excel aufzumachen für jeden Export und so meine Taskleite unendlich zuzumüllen :(

mfg

JayeL
 
Wenn ich mich Recht erinnere (is ne Weile her, dass ich mit Excel gearbeitet hab und leider hab ich den Code net, sodass ich net nachschauen kann) brauchst du nur Application (also weder ApplicationClass noch _Application).
Du darfst hierbei allerdings nicht auf IntelliSense achten, weil das nur Müll ausspuckt.

Code:
Excel.Application ExcelObj = new Excel.Application();

ExcelObj.Visible = false; //damit kannst diese Excel-Instanz net sehn

Aber lies dir mal die Links von vorhin durch und lad dir die Beispiele runter. Dann sollte eigentlich alles klar sein.

mfg broetchen
 
Zuletzt bearbeitet:
super, das war es ... es sind also immer die einfachen Wege die zum Ziel führen ;-)

so funktioniert es also:

Code:
private void export_Click(object sender, System.EventArgs e)
{
  try
  {
    ExcelApp = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
  }
  catch
  {
    ExcelApp = new Excel.Application();
  }

  //add new Workbook and new Worksheet and set Worksheet-Name
  try 
  {
    myWorkbook = ExcelApp.ActiveWorkbook;
  }
  catch
  {
    myWorkbook = ExcelApp.Workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet);
  }

  myWorkSheet = (Excel.Worksheet)myWorkbook.Worksheets.Add(Type.Missing, Type.Missing, Type.Missing, Type.Missing);

//
//Zellen füllen, fomatieren etc. pp.
//

  ExcelApp.Visible = true;
  System.Runtime.InteropServices.Marshal.ReleaseComObject(ExcelApp);
  ExcelApp = null;
}

ab und an bleibt zwar immernoch eine Prozessleiche übrig, bin mir aber nicht sicher, ob das nicht an meinem Debug-Modus im Visual Studio liegt.

Dank dir, broetchen ;-)

mfg

JayeL
 
Zuletzt bearbeitet:
Gerne doch!

Da die Syntax jetzt ja stimmt, könnte man ja immer noch über die Semantik diskutieren.

Ich find's immer noch etwas suspekt einfach ein laufendes Workbook zu nehmen und mit Daten vollzustopfen. Immerhin weiß man ja nie, was für ein Workbook gerade offen ist und der Benutzer ist sicher sehr überrascht, wenn auf einmal ein Worksheet dazukommt und von Geisterhand gefüllt wird.

Was die Leichen anbelangt, ich glaube es gibt Close-, Quit- oder wie die sonst so heissen-Methoden.

Schau einfach mal hier

mfg broetchen
 
Zurück