Ein Projekt das ich vorstellen möchte auch mit der Absicht vielleicht den ein oder anderen Entwickler an der Mitarbeit zu interessieren, in welcher Form auch immer.
LateBindingApi.Excel ist ein kleines Framework für den latebinded Zugriff auf MS Excel. Die Hauptseite auf Codeplex beschreibt den Sinn und Zweck ausreichend.
Jedoch nochmal ganz kurzl: LateBindingApi.Excel ist ein ObjektModell das den latebinded Zugriff auf Excel in ein Objekt Modell kapselt das dem EarlyBind Modell(in C# den Pia's) 1:1 identisch ist.
Aufrufe wie diese
excelCOMReference.GetType().InvokeMember("Workbooks", BindingFlags.GetProperty, null, excelReference, new object[]{1}, myThreadCulture);
werden dadurch obsolet.
Stattdessen können saubere Calls verwendet werden.
string workbookName = excelApplication.Workbooks[1].Name;
Das Framework mappt den Call zu einem latebinded Auruf.
Das Framework kümmert sich ausserdem um alle COMReferencen.
Die Excel Instanz verschwindet in jedem Fall aus dem Speicher wenn man es möchte.
Ich bin im besonderen für Kritik hinsichtlich des Designs des Modell, Codes, etc. sehr empfänglich.
XlThanksForComments
Etwas erfreuliches:
Zum Download steht: Release LateBindingApi.Excel Release 0.7e
sowie eine Performance-Vergeichstabelle die aufzeigt wie Early, LateBinding, Dynamic Objects etc. welche Ausführungsgeschwindigkeit die jeweiligen Varianten
bieten. SourceCode der Performance-Vergleichsprojekte inklusive falls jemand selbst testen möchte.
Umbenennung zu LateBindingApi.Excel und Wechsel der Url zu
http://excel.codeplex.com
Die alte Url tuts aber auch noch =)
Hi Sebastian,
sehr gute Arbeit.
Nur zum Verständnis: In den Beispielen, die ich gerade gestartet habe, wurde immer eine Excel Datei erzeugt und dann mit Excel geöffnet. Heißt das, dass dein Framework primär zum Erstellen von Excel-Dateien gedacht ist?
Was würde denn passieren, wenn auf einem Rechner gar kein Excel installiert wäre?
Dem Beitrag angehängt habe ich noch einen Warnhinweis, den Excel direkt nach dem Start gebracht hat. Ich vermute mal, dass im ".xlsx" Format geschrieben wird, obwohl die Dateiendung ".xls" ist.
Gruß
Roland
Hallo Blacal,
Bei den Beispielen habe ich nicht bedacht das Excel 2 Dateiendungen kennt, ich werde das diese Woche korrigieren.
Grundsätzlich gibt es keine bestimme Prämisse für die Verwendung ausser eben den versionsunabhängigen Zugriff. Ansonsten ist alles möglich was auch in VBA möglich ist.
Excel muss auf dem Zielrechner zum Zeitpunkt der Verwendung installiert sein.
Das erstellen von Excel-Dateien auf diesem Weg ist aus der Sicht von Microsoft sicher 'depricated'. Die Verwendung der Spreadsheet ML ist hier zu bevorzugen.
Ich suche gerade Möglichkeiten die Verwendung der ML in das Framework zu integrieren.
Für mich persönlich sehe ich den Fokus des Frameworks vor allem in der Addin Entwicklung. Oftmals möchte man nur ein paar zusätzliche Services oder einfach nur ein paar Daten per Mausklick in ein Excel Sheet importieren. Viele Produkte bzw. Systeme bringen dazu ein Addin mit weil der Kunde es wünscht. Das Addin muss problemlos mit allen Versionen funktionieren, fallweise Events unterstützen, keinen Installationsstress verursachen und die untere Grenze ist Excel 2000(das die Spreadsheet ML nicht beherrscht). Zumindest ist das meine Erfahrung. Das Framework erfüllt diese Punkte und wird von mir in diversen Projekten auch so eingesetzt.
Gruss & falls du nen Bug findest 😉 sag Bescheid
Sebastian
Hallo Sebastian,
erstmal vielen Dank für die Entwicklung dieser API!
Trotzdem habe ich eine Frage, die ich auch in den mitgelieferten Beispielen nicht beantwortet finde. Wie kann ich in meinem Exceldokument eine Zeile an einem bestimmten Index hinzufügen?
Viele Grüße,
Markus 😃
Hallo,
Ach herjee, die Insert Methode + Overloads für Range und ShapeNodes ist mir doch glatt durchgerutscht. Ich habe sie inzwischen ergänzt und Release 0.7f
erstellt.
Changes von Version e zu f
Hallo Sebastian,
schläfst du nicht? =)
Ganz herzlichen Dank für die schnelle Antwort und den Fix des Problems!
Viele Grüße aus Hannover,
Markus 🙂
Hallo nochmal,
ich komme nicht drumrum mich nochmal zu melden. Ich versuche bei Zellen den Hintergrund zu entfernen (In Excel wäre das "No Fill"). Das kann ich aber über die Interior.Color-Eigenschaft nicht erreichen, denn sogar wenn ich Color.Transparent angebe füllt er die Zelle weiß.
Möglich sein müsste das mit der Interior.ColorIndex-Eigenschaft, dem man dann die Konstante XlColorIndex.xlColorIndexNone übergeben kann...
Und dann möchte ich gerne Zeilen gruppieren (so dass vorne ein [+] oder ein * zum Auf- oder Zuklappen steht. Das sollte (wenn man diversen Google-Funden glauben darf [klick]) die Methode Range.Group erledigen. Auch wenn ich aus der hier verlinkten Doku nicht schlau werde...
Finale Frage: Kannst du diese Dinge noch einbauen?
Viele Grüße,
Markus 😃
Hallo Sebastian,
vielen Dank für die Umsetzung!
Viele Grüße,
Markus 😃
Ein neues Release: LateBindingApi.Excel 0.9
Bisher wurde nur der gemeinsame Nenner alle Excel Versionen unterstützt.
Jetzt werden alle Funktionalitäten aller Versionen unterstützt dank
eines verbesserten Code-Generators.
Das SupportByLibrary Attribute hilft zu sehen welche Version welche Funktionalität unterstützt.
Beispiel:
[SupportByLibrary("XL10","XL11","XL12","XL14","XL9")]
public class _Application : COMObject
{
[SupportByLibrary("XL10","XL11","XL12","XL14","XL9")]
public bool Visible
[SupportByLibrary("XL12","XL14")]
public bool EnableLivePreview
[SupportByLibrary("XL14")]
public bool PrintCommunication
}
Die ekligen Prefixe und Namespaces entfallen aufgrund der neuen Architektur.
Die Doku besteht aus 4 kleinen Dateien und ist leicht zu lesen.
Roadmap: Version 1.0 wird auch die Office Produkte Word, Outlook, Access und Frontpage unterstützen.
Danke für die Hinweise die Kritik und die Verbesserungsvorschlägedie die mich erreicht haben.
Hallo Sebastian,
vielen Dank für deine Arbeit.
Ich habe zwei Fragen:
objSheet = (Excel._Worksheet)objSheets[1];
Geht das auch mit dem Tabellennamen?
objSheet = (Excel._Worksheet)objSheets["Signal"];
(Excel.Workbook)System.Runtime.InteropServices.Marshal.BindToMoniker(filePath + file);
objSheets = objWorkbook.Application.Sheets;
Dazu konnte ich in deinen Beispielen leider nichts finden, dort werden Datein eher neu erstellt als das auf geöffnete Dateien zugegriffen wird. Wie geht das am besten?
Danke,
dansmo
Hallo dansmo,
Die 1. Frage hatte ich ja bereits beantwortet.
Du kannst genau so gut den Namen übergeben.
Die 2. Frage
So gehts natürlich auch nicht so wie du das vor hast.
Du bekommst ja von BindToMoniker den nativen COMProxy zurück.
So gehts aber.
object proxy = System.Runtime.InteropServices.Marshal.BindToMoniker(filePath + file);
Excel.Workbook book = new LateBindingApi.Excel.Workbook(null, proxy);
// your code here
book.Dispose();
Viele Erfolg
Tolles Projekt und super nutzbar! Danke.
Frage:
Durch Modifikationen müsste das doch auch für andere Produke (Office etc.) möglich sein oder?
Hallo fod,
Die Klassen und Interfaces wurden von einem Tool generiert das COM TypeLibs
ausliest und daraus die LateBinding Wrapper Klassen generiert.
Dieses Tool schreibe ich gerade nochmal neu.
http://latebindingapi.codeplex.com/
Wenn es fertig werde ich damit natürlich Wrapper für
Word, Outlook und Powerpoint erstellen.
any requests are welcome 😃
Ich hab die LateBindingAPI ja vor einiger Zeit für ein Programm benutzt, was auch erstmal toll und kompfortabel geklappt hat aber scheinbar schaufelt die API den RAM voll bei längerem gebraucht. Das fällt sicherlich bei den meisten Anwendungen garnicht auf.
Nachdem ich ewig den Fehler gesucht hatte, hab ich aus allen XlApplications, XLWorkBooks usw, wieder normale Workbooks usw gemacht und die übrigen Befehle entsprechend angepasst. Und siehe da, die Speicherauslastung meines Programms bleibt konstant bei 30MB. Mit der Api wird pro "Füge eine Zeile ans Excelfile an"-Durchlauf der Speicher voller, sodass nach ca. einem Tag die 2GB Ram voll sind.
Es ist vermutlich mal kein Anwendungsfehler meinerseits, da es ja mit den umständlichen Klassen des Interop.Excel problemlos funktioniert. Wäre schön wenn wir irgendwie rausfinden könnten wieso der angenehmere Umweg über die API den Speicher füllt.