| 

.NET C# Java Javascript Exception

2
Hallo zusammen,

ich habe ein kleines Problem mit einer VB.NET Applikation, welche intensiv mit Excel kommuniziert. Unter anderem werden umfangreiche Zeitreihen aus der VB-Anwendung in ein Excel-Sheet eingetragen. Dies erfolgt, in dem die Werte über die Value-Property der Zellen geschrieben werden.

xlMyRange = mExcelSheet.Range("A1")
xlMyRange.Cells.Offset(pZielspalte, 1).Value = pValue


Bei einer Arbeitsblattgröße von 250 Spalten und mehreren hundet Zeilen dauert es ewig (> 5 Minuten), bis das Blatt aufgebaut ist. Man kann sehen, wie Zelle für Zelle gefüllt wird.

Um die Performance zu erhöhen, habe ich versucht die Property "ScreenUpdating" des Application-Objektes auf False zu setzen. Dies zeigt aber leider keine Wirkung, weil nach jedem Zugriff auf das Arbeitsblatt die Property "ScreenUpdating" wieder auf True steht.

Das ganze hängt wahrscheinlich damit zusammen, wie wir die Excel-Instanz in die Anwendung eingebettet haben (in einem kleinen Testprogramm kann ich das Verhalten jedenfalls nicht nachvollziehen).

Wir haben wir bei der Implementierung ein wenig in die Trickkiste gegriffen. Ursprünglich war die Anwendung in VB6 geschrieben und hat das OLE-Container-Control verwendet um eine Excel-Instanz in die Anwendung einzubetten. Dies haben wir nach der Migration nach .NET mit einem selbst geschriebenen User-Control simuliert.
Des weiteren findet eine bidirektionale Kommunikation zwischen dem Excel-Sheet und der Anwendung statt. D.h. wenn der Anwender im Excel-Sheet einen Wert ändert, wird dieser automatisch in dei VB-Anwendung übernommen und umgekehrt. Dies haben wir über eine COM-DLL, die sowohl in Excel als auch in der Anwendung referenziert wird und ein wenig VBA-Code realisiert.

Im VBA-Code des Worksheets haben wir eine Property definiert, mit deren Hilfe wir eine in der Anwendung erzeugte Instanz der COM-DLL an Excel übergeben. Im Change-Event des Worksheet übergeben wir die geänderten Werte an diese Instanz und feuern ein Event, welches in der COM-DLL definiert wurde und dafür sorgt, dass die Werte in der Anwendung aktualisiert werden.

Wenn ich das Change-Event im Excel-Template auskommentiere bleibt die ScreenUpdating Property auf dem gesetzten Wert False und der Aufbau des Sheets erfolgt wesentlich schneller. Da die bidirektionale Kommunikation den entscheidenden Mehrwert für den Anwender darstellt kann ich diese Funktionalistät nicht einfach ausschalten.

Die Anwendung arbeitet sowohl mit Excel 2003 als auch mit Excel 2010 zusammen. Die Excel-Version spielt bei dem Problem keine Rolle.

Gibt es irgendeine Möglichkeit dieses Verhalten in Excel zu beeinflussen? Ich bin für jeden Hinweis, der zur Lösung meines Problems führen könnte, dankbar.

Gruß
Klaus
20.11.2012
luedi 2,0k 1 9
1
Kannst du das Excel-Template so umschreiben, dass das Feuern des Change-Events von einer Property abhängt?
Meine Idee hinter dieser Frage: Während des Eintragens der Zeitreihen wird diese bidirektionale Kommunikation wohl kaum benötigt (und ist wohl auch kaum nutzbar während dieser Zeitspanne)... also wäre es doch möglicherweise schon hilfreich, das Change-Event für diesen Zeitraum zu "deaktivieren"...
Karill Endusa 20.11.2012
1
Das einzelne Beschreiben von sehr vielen Zeilen/Spalten dauerte schon immer sehr lange. Werden die Spalten und Zeilen in Eurer Anwendung nacheinander geschrieben? Wenn ja, schreibe es zunächst intern in ein Array und klatsche es dann mit einem Befehl (Range, gleiche Dimension wie Array) in das Excelsheet. Das Schreiben geschieht dann im Sekundenbruchteil!
JEwen 20.11.2012
@Karill: Ich kann aus VB eine Variable im Excel-Sheet setzen, welche den Code innerhalb des Change-Events unterdrückt. Trotzdem ist die ScreenUpdating-Property danach wieder auf True. Ich bin nicht so firm in VBA. Gibt es dort eine Möglichkeit Events programmatisch zu verdrahten (wie in .NET)?
luedi 20.11.2012
@JEwen: Deinen Vorschlag haben wir auch schon in Erwägung gezogen. Das Problem ist hierbei, dass wir umfangreiche Änderungen im Code vornehmen müssten. Da dieser recht alt ist und häufig geändert wurde (Stichwort "Spagetti-Code"), wird dies nicht so einfach ohne unerwünschte Nebenwirkungen gehen.
luedi 20.11.2012
2
@luedi: Evtl. könntet ihr dem Code mit relativ wenigen Änderungen ein gefaktes Excel-Sheet unterschieben (normales POCO-Objekt mit Methoden, die genauso heißen wie die des echten Objekts), das erst mal nur mitprotokolliert, was alles nach Excel geschrieben werden soll. Am Ende stellt dieses Fake-Sheet die Daten gesammelt als Array bereit, und ihr könnt sie dann ins echte Sheet rüberschieben.
Nur so'ne Idee....
Matthias Hlawatsch 20.11.2012
@luedi: Schade, hätte einen gewaltigen Perfomanceschub gebracht. Soweit ich weiß, wird von Excel ScreenUpdating automatisch nach jedem Call, oder Durchlauf eines Makros, wieder eingeschaltet! ich glaube, selbst das aktivieren einer anderen Mappe führt dazu. Mal in dieser Richtung schauen.
JEwen 20.11.2012
@jewen: Genau das ist das Verhalten. Immer wenn ich ein Makro oder eine VBA-Funktion aufrufe ist ScreentUpdating danach wieder True
luedi 20.11.2012
1 Antwort
0
erstmal vielen Dank für die hilfreichen Kommentare zu meiner Frage.

Die Diskussion hat mir gezeigt, dass ich wohl ein ernstes Wort mit meinem Auftraggeber reden muss ;-)). Wir haben schon öfters diskutiert, diese Funktionalität neu zu implementieren, alleine weil die Wartung und Erweiterung des bestehenden Codes sehr schwierig ist. Bisher war meinem Auftraggeber das Risiko einer Neu-Implementierung allerdings zu groß. Die Performance-Probleme treten verstärkt auf, weil das Unternehmen zur Zeit von Windows XP auf Windows 7 umstellt und die Anwendung wegen des Speicherbedarfs auf 64-Bit umgestellt wurde (ja, der Speicherbedarf ist in einigen Szenarien wirklich > 2GB). Ich hoffe, dass der Leidensdruck jetzt so groß wird, das mein Auftraggeber einer aus meiner Sicht längst fälligen Neuimplementierung zustimmt.

Gruß
Klaus
20.11.2012
luedi 2,0k 1 9

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH