Schnellste Weg, um eine Schnittstelle zwischen den Leben (nicht gespeicherte) Excel-Daten und C# - Objekten
Ich will wissen, was der Schnellste Weg ist, das Lesen und schreiben von Daten zu und von einer geöffneten Excel-Arbeitsmappe zu c# - Objekte. Der hintergrund ist, dass ich bei der Entwicklung einer c# - Anwendung, die verwendet wird, aus Excel und verwendet Daten in excel.
Die business-Logik befinden sich in der c# - Anwendung, aber die Daten befinden sich in einer Excel-Arbeitsmappe. Der Benutzer wird mithilfe von Excel und klicken Sie auf eine Schaltfläche (oder etwas ähnliches) auf die excel-Arbeitsmappe zu initiieren, die c# - Anwendung. Der c# - Anwendung liest dann die Daten aus der excel-Arbeitsmappe, die Daten zu verarbeiten und dann schreiben die Daten zurück in die excel-Arbeitsmappe.
Möglicherweise gibt es zahlreiche Blöcke von Daten, die erforderlich sind, um abgelesen und geschrieben, die excel-Arbeitsmappe, aber Sie werden in der Regel von einer relativ kleinen Größe, sagen wir 10 Zeilen und 20 Spalten. Gelegentlich eine große Liste von Daten können verarbeitet werden müssen, von der Reihenfolge von 50.000 Zeilen und 40 Spalten.
Weiß ich, dass dies relativ einfach zu sagen, die mithilfe von VSTO, aber ich will wissen was die Schnellste (aber immer noch robuste und elegante) Lösung ist, und bekommen eine Vorstellung von der Geschwindigkeit. Ich habe nichts dagegen, wenn die Lösung empfiehlt die Verwendung von Produkten von Drittanbietern verwendet oder C++.
Die naheliegende Lösung ist die Verwendung von VSTO-oder interop-aber ich weiß nicht, was die Leistung wie gegen VBA, die ich bin derzeit mit Lesen in den Daten, oder wenn es irgendwelche anderen Lösungen.
Dieser wurde geschrieben am Experten austauschen, die sagen, dass VSTO wurde dramatisch langsamer als mit VBA, aber das war vor ein paar Jahren und ich weiß nicht, ob die Leistung verbessert hat.
http://www.experts-exchange.com/Microsoft/Development/VSTO/Q_23635459.html
Dank.
InformationsquelleAutor der Frage jw_pr | 2010-10-01
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn die C# - Anwendung ist eine stand-alone-Anwendung, dann haben Sie immer die cross-Marshalling-Prozess beteiligt sind, die Sie überfordern alle Verbesserungen, die Sie tun können, durch Umschalten der Sprache von, sagen wir, von C# zu C++. Halten Sie sich an Ihre bevorzugte Sprache, in dieser situation, die so klingt, wie C#.
Wenn Sie bereit sind, um ein add-in, das läuft innerhalb Excel, dann aber, Ihre Operationen zu vermeiden, cross-process-Aufrufe und laufen über 50-mal schneller.
Wenn Sie innerhalb Excel als add-in VBA ist unter den schnellsten Möglichkeiten, aber es hat noch einbeziehen COM und so C++ - Anrufe über eine XLL-add-in wäre am schnellsten. Aber VBA ist immer noch Recht schnell in Bezug auf Anrufe auf die Excel-Objekt-Modell. Wie für die tatsächliche Berechnung der Geschwindigkeit, jedoch VBA läuft als P-Code, nicht als vollständig kompilierten code, und so führt etwa 2-3x langsamer als native code. Das klingt sehr schlimm, ist es aber nicht, weil die überwiegende Mehrheit der Ausführungszeit, die mit einer typischen Excel-add-in oder eine Anwendung beinhaltet Anrufe auf die Excel-Objekt-Modell, so dass VBA-vs. einer vollständig kompilierten COM-add-in, sagen wir mit nativ kompilierten VB 6.0, wäre nur etwa 5-15% langsamer, was nicht auffällt.
VB 6.0 ist ein kompiliertes COM-Ansatz, und läuft 2-3x schneller als VBA für nicht-Excel-bezogene Aufrufe, aber VB 6.0 ist über 12 Jahre alt zu diesem Zeitpunkt und läuft nicht im 64 bit-Modus sagen, wenn Office 2010 installieren, die installiert werden können, zum ausführen von 32-bit-oder 64-bit. Verwendung von 64-bit-Excel ist winzig im moment, aber wachsen in der Nutzung, und so würde ich vermeiden, VB 6.0 aus diesem Grund.
C#, wenn die Ausführung in-process als Excel-add-in ausgeführt würde anrufen, um die Excel-Objekt-Modell, so schnell wie VBA verwenden, und führen nicht-Excel-Anrufe 2-3x schneller als VBA-wenn ausgeführt unshimmed. Der Ansatz von Microsoft empfohlen, wird jedoch umfassend shimmed, zum Beispiel durch die Nutzung der COM Shim Wizard. Durch shimmed, Excel geschützt ist aus dem code (wenn es defekt) und der code ist vollständig geschützt, von anderen 3rd-party-add-ins, die sonst potenziell zu Problemen führen. Die down-Seite zu dieser, jedoch, ist, dass ein shimmed Lösung läuft in einer separaten Anwendungsdomäne, die benötigt cross-AppDomain marshaling, dass incurrs eine Ausführungsgeschwindigkeit Strafe von über 40x-das ist sehr Auffällig, in vielen zusammenhängen.
Add-ins mit Visual Studio Tools für Office (VSTO) werden automatisch geladen innerhalb einer shim und führt Sie in einer separaten Anwendungsdomäne. Es gibt keine, dies zu vermeiden, wenn die Verwendung von VSTO. Deshalb ruft die Excel-Objekt-Modell würde auch gegen einen etwa 40-fachen Ausführung Geschwindigkeit der degradation. VSTO ist ein wunderschönes system für sehr reiche Excel-add-ins, aber die Ausführung-Geschwindigkeit ist seine Schwäche für Anwendungen wie die Eure.
ExcelDna ist eine Kostenlose, open-source-Projekt, das ermöglicht die Verwendung von C# - code wird dann umgewandelt für Sie eine XLL-add-in, das verwendet C++ - code. Das ist, ExcelDna analysiert Ihre C# - code und erstellt die erforderlichen C++ - code für Sie. Ich habe nicht verwendet es selbst, aber ich bin vertraut mit dem Prozess und es ist sehr beeindruckend. ExcelDna bekommt sehr gute Kritiken von denen, die es verwenden. [Edit: Hinweis für die folgende Korrektur pro Govert ' s Kommentar: "Hallo Mike, ich möchte noch eine kleine Korrektur zu klären, die Excel-Dna Durchführung: alle managed-Excel-Kleber funktioniert zur Laufzeit aus der verwalteten assembly mit reflection - es ist keine zusätzliche vor-Kompilierung Schritt-oder C++ - code-Generierung. Auch wenn Excel-Dna verwendet .NET, es muss nicht jeder COM-interop beteiligt, wenn im Gespräch mit Excel, als .xll mit der nativen Schnittstelle kann verwendet werden, direkt von .NET (obwohl Sie können auch die Verwendung von COM wenn Sie wollen). Dies macht high-performance-UDFs und Makros möglich." – Govert]
Vielleicht möchten Sie auch zu schauen, Add-in Express. Es ist nicht kostenlos, aber es würde ermöglichen es Ihnen, code in C# und obwohl es shims Ihre Lösung in einer separaten Anwendungsdomäne, ich glaube, dass es die Ausführung, die Geschwindigkeit ist hervorragend. Wenn ich das Verständnis seiner Ausführungsgeschwindigkeit richtig, dann bin ich nicht sicher, wie Sie Add-in Express, dies zu tun, aber es könnte unter Ausnutzung des sogenannten FastPath-AppDomain marshaling. Zitieren Sie mich nicht auf irgendwelche von diesem, aber, so wie ich bin nicht sehr vertraut mit Add-in Express. Sie sollten check it out, obwohl, und tun Sie Ihre eigene Forschung. [Edit: Lesung Charles Williams' Antwort, wie es aussieht, Add-in Express können sowohl die COM-und C-API zugreifen. Und Govert besagt, dass Excel auch die DNA ermöglicht sowohl COM-als auch die fastrer C-API-Zugriff. So würden Sie wahrscheinlich prüfen wollen, Sie beide und vergleichen Sie ExcelDna.]
Mein Rat wäre, um die Forschung Add-in Express und ExcelDna. Beide Ansätze erlauben würde, Sie bis zum code in C#, die Sie scheinen die meisten vertrauten mit.
Die andere Frage ist, wie machen Sie Ihre Anrufe. Zum Beispiel, Excel ist sehr schnell, wenn das handling eine ganze Reihe von Daten, die übergeben hin und her wie ein array. Dies ist erheblich effizienter als die Schleife durch die Zellen einzeln. Zum Beispiel der folgende code macht Gebrauch von Excel.Bereich.set_Value accessor-Methode zum zuweisen einer 10 x 10 array von Werten an einen 10 x 10 Bereich von Zellen in einem Schuss:
Kann man ebenso nutzen Excel.Bereich.get_Value accessor-Methode zum Lesen ein array von Werten aus einer Reihe in einem Schritt. Dies zu tun und dann die Schleife durch die Werte in dem array ist wesentlich schneller als die Schleife durch die Werte in den Zellen der Reihe einzeln.
InformationsquelleAutor der Antwort Mike Rosenblum
Ich nehm das als Herausforderung, und wird Wette-der Schnellste Weg zu mischen Sie Ihre Daten zwischen Excel und C# ist die Verwendung von Excel-Dna - http://exceldna.codeplex.com.
(Disclaimer: ich entwickle Excel-Dna. Aber es ist immer noch wahr...)
Weil es verwendet die native .xll-Schnittstelle überspringt alle COM-integration-overhead, Sie hätten mit VSTO oder einen anderen COM-basierten add-in-Ansatz. Mit Excel-Dna, könnte man ein makro machen, das ist angeschlossen an ein Menü-oder Multifunktionsleisten-Schaltfläche, die liest einen Bereich ein, verarbeitet Sie und schreibt Sie zurück in einen Bereich in Excel. Alle mit den systemeigenen Excel-Schnittstelle aus C# - kein COM-Objekt ist nicht in Sicht.
Habe ich eine kleine test-Funktion, die die aktuelle Auswahl in ein array, Quadrate jede Zahl im array und schreibt das Ergebnis in Sheet 2 ab Zelle A1. Sie brauchen nur zu addieren das (Kostenlose) Excel-Dna-runtime, die Sie herunterladen können, von http://exceldna.codeplex.com.
Lese ich in C#, Prozess-und write-back, um eine Excel-Millionen-Zellbereich in unter einer Sekunde. Ist das schnell genug für Sie?
Meine Funktion sieht wie folgt aus:
InformationsquelleAutor der Antwort Govert
Weiter zu Mike Rosenblum ' s get Kommentare über die Verwendung von arrays, möchte ich hinzufügen, dass ich habe mit dem sehr Ansatz (VSTO + arrays) und wenn ich gemessen, die tatsächliche Lesegeschwindigkeit selbst war innerhalb von Millisekunden. Denken Sie daran, zu deaktivieren, event handling und Bildschirm-Aktualisierung vor dem Lesen/schreiben, und denken Sie daran, wieder zu aktivieren, nachdem der Vorgang abgeschlossen ist.
C# verwenden, können Sie erstellen 1-basierten arrays, die genau das gleiche wie Excel-VBA selbst. Dies ist ziemlich nützlich, vor allem, weil auch in VSTO, wenn Sie extrahieren das array aus einer Excel.Range-Objekt, das array ist 1-basiert, so halten Sie die Excel-orientiert-arrays 1-basiert, hilft Ihnen, zu vermeiden, müssen Sie immer überprüfen, ob das array ein-oder null-basiert.
(Wenn die Spalte position im array hat Bedeutung für Sie, für den Umgang mit 0-basierten und 1-basierten arrays kann eine echte Schmerzen).
In der Regel das Lesen der Excel.Bereich in ein array würde wie folgt Aussehen:
Meine variation von Mike Rosenblum ' s array-schreiben verwendet ein 1-basiertes array wie dieses:
InformationsquelleAutor der Antwort code4life
Die Schnellste Schnittstelle auf Excel-Daten ist die C-API. Es gibt eine Reihe von Produkten gibt, die link .NET zu Excel mit Hilfe dieser Schnittstelle.
2 Produkte, die ich mag, die dies tun, sind Excel-DNA (das ist kostenlos und open source) und Add-in-Express (das ist ein kommerzielles Produkt und hat sowohl die C-API und COM-Schnittstelle zur Verfügung).
InformationsquelleAutor der Antwort Charles Williams
First off, Ihre Lösung kann nicht sein, ein Excel-UDF (user-defined function). In unseren Handbüchern, geben wir die folgende definition: "Excel UDFs werden verwendet, um benutzerdefinierte Funktionen in Excel für den end-Benutzer, um Sie in Formeln." Ich hätte nichts dagegen, wenn Sie vorschlagen, eine bessere definition 🙂
Diese definition zeigt, dass eine UDF kann nicht fügen Sie eine Schaltfläche auf der Benutzeroberfläche (ich weiß, dass XLLs ändern können, das CommandBar-UI) oder abfangen von Tastenkombinationen wie auch als Excel-Ereignisse.
Ist, ExcelDNA out of scope, weil es vorgesetzt ist, die für die Entwicklung XLL-add-ins. Das gleiche gilt für Excel-gezielte Funktionalität von Add-in Express ist, denn es ermöglicht die Entwicklung von XLL-add-ins und Excel Automatisierungs-add-ins.
Weil Sie brauchen, um zu behandeln Excel Ereignisse, Ihre Lösung kann eine standalone-Anwendung, aber es gibt offensichtliche Beschränkungen eines solchen Ansatzes. Die einzige wirkliche Möglichkeit ist das erstellen eines COM-add-in; es ermöglicht die Handhabung von Excel-Ereignisse und das hinzufügen von benutzerdefinierten Dinge, um die Excel-Benutzeroberfläche. Sie haben drei Möglichkeiten:
Wenn das Gespräch über die Entwicklung eines Excel-COM-add-in, die 3 oben genannten Werkzeuge bieten unterschiedliche Funktionen: visual Designer, Unterlegscheiben, etc. Aber ich glaube nicht, dass Sie unterscheiden sich in der Geschwindigkeit der Zugriff auf die Excel-Objekt-Modell. Sagen, ich weiß nicht (und kann mir nicht vorstellen), warum immer ein COM-Objekt von der Standard-AppDomain sich von immer den gleichen COM-Objekt von einer anderen Anwendungsdomäne. BTW, können Sie überprüfen, ob ausgleichend beeinflusst die Geschwindigkeit des Betriebs durch die Schaffung einer shared-add-in, und verwenden Sie dann den COM Shim Wizard zu shim.
Speed II. Als ich schrieb Sie gestern: "Der beste Weg, um die Geschwindigkeit Lesen und schreiben auf einen Bereich von Zellen ist, um eine variable zu erstellen der Excel.Bereich geben Sie unter Bezugnahme auf das Angebot und dann Lesen/schreiben, die ein array von/an die Value-Eigenschaft der variable." Aber im Gegensatz zu dem, was Francesco sagt, ich weiß nicht führen dies auf VSTO; dies ist eine Funktion, die Excel-Objekt-Modell.
Speed III. Der Schnellste Excel UDFs geschrieben, in der systemeigenes C++, nicht in jedem .NET-Sprache. Ich habe nicht verglichen die Geschwindigkeit des XLL-add-in, hergestellt durch ExcelDNA und Add-in Express; ich glaube nicht, Sie finden einen wesentlichen Unterschied hier.
Zu summieren. Ich bin überzeugt, Sie sind auf einem falschen Weg: COM-add-ins auf Add-in Express, VSTO oder Shared Add-in sollte Lesen und schreiben von Excel-Zellen mit der gleichen Geschwindigkeit. Ich werde froh sein (mit freundlichen GRÜßEN) wenn jemand widerlegt diese Aussage.
Nun auf Ihre anderen Fragen. VSTO nicht erlaubt, die Entwicklung eines COM-add-in unterstützt Microsoft Office 2000-2010. Es erfordert drei verschiedene codebases und mindestens zwei Versionen von Visual Studio komplett support Office 2003-2010; Sie brauchen starke Nerven und eine portion Glück zum bereitstellen eines VSTO-basierten add-in für Excel 2003. Mit Add-in Express erstellen Sie ein COM-add-in für alle Office-Versionen mit einer einzigen quellcodebasis; Add-in Express bietet Ihnen ein setup-Projekt, die bereit ist, installieren Sie das add-in in Excel 2000-2010 (32-bit und 64-bit); die ClickOnce-Bereitstellung ist auch an Bord.
VSTO beats Add-in Express in einem Bereich: es ermöglicht die Erstellung von sogenannten document-level add-ins. Stellen Sie sich eine Arbeitsmappe oder eine Vorlage mit einigen .NET-code dahinter; ich wäre nicht überrascht, jedoch, wenn die Bereitstellung solcher Dinge ist ein Alptraum.
Auf Excel-Ereignisse. Alle Excel-Ereignisse finden Sie in der MSDN-Website, zum Beispiel, sehen Excel 2007-Veranstaltungen
Grüße aus Belarus (GMT+2),
Andrej Smolin
Add-in Express Team Leader
InformationsquelleAutor der Antwort Andrei Smolin - Add-in Express
Habe ich verwendet VBA-code (makro) zu sammeln & kompakt der Daten zu gewinnen und diese Daten in einen call zu C# und Umgekehrt. Dies wird wahrscheinlich die meisten performanten Ansatz.
Verwendung von C#, Sie müssen immer einige marshalling. Mit VSTO oder COM-Interop, die unterliegende Kommunikationsschicht (marshalling-overhead) ist das gleiche.
In VBA (Visual Basic For Application) arbeiten Sie direkt auf die Objekte in Excel. So ist der Zugriff auf diese Daten wird immer schneller.
Aber.... Sobald Sie die Daten in C#, die manipulation dieser Daten kann sehr viel schneller.
Wenn Sie mit VB6 oder C++, können Sie auch gehen über eine COM-Schnittstelle, und Sie wird auch vor cross-marshalling-Prozess.
Du suchst also eine Methode zur Minimierung des cross-process-Aufrufe und marshalling.
InformationsquelleAutor der Antwort GvS