Laden...

LateBindingApi.Excel - Framework für den versionsfreien Zugriff

Erstellt von gelöschtem Konto vor 13 Jahren Letzter Beitrag vor 13 Jahren 12.800 Views
Gelöschter Account
vor 13 Jahren
LateBindingApi.Excel - Framework für den versionsfreien Zugriff

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.

http://excel.codeplex.com/

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

Gelöschter Account
vor 13 Jahren
XlLateBinding -> LateBindingApi.Excel

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 =)

B
387 Beiträge seit 2005
vor 13 Jahren

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

Gelöschter Account
vor 13 Jahren

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

360 Beiträge seit 2005
vor 13 Jahren

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 😃

Gelöschter Account
vor 13 Jahren

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

  • XlConverter.ToRgb umbenannt zu XlConverter.ToDouble
  • XlConverter.GetFileExtension hinzugefügt (.xls oder .xlsx)
  • Insert Methoden+Overloads für Range und ShapeNodes
  • Xml Doku im Code entfernt
360 Beiträge seit 2005
vor 13 Jahren

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 🙂

360 Beiträge seit 2005
vor 13 Jahren

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 😃

Gelöschter Account
vor 13 Jahren

Hallo Marcus,

Ich habe die entsprechenden Features nun ergänzt, getestet und in ein neues Release gepackt.

XlRegards
Sebastian

360 Beiträge seit 2005
vor 13 Jahren

Hallo Sebastian,

vielen Dank für die Umsetzung!

Viele Grüße,
Markus 😃

Gelöschter Account
vor 13 Jahren

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.

D
14 Beiträge seit 2011
vor 13 Jahren

Hallo Sebastian,

vielen Dank für deine Arbeit.

Ich habe zwei Fragen:

  1. Wie greife ich auf ein bestimmtes, benanntes Worksheet zu?
    In deinen Beispielen finde ich nur die Möglichkeit via Nummerierung einen Abruf zu machen:
objSheet = (Excel._Worksheet)objSheets[1];

Geht das auch mit dem Tabellennamen?

objSheet = (Excel._Worksheet)objSheets["Signal"];
  1. Wie steuere ich eine laufende Excel Anwendung und Tabelle an?
    Ohne dein Latebinding habe ich das so gemacht, was jetzt aber zu einem Fehler führt:
    objWorkbook =
(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

Gelöschter Account
vor 13 Jahren

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

D
14 Beiträge seit 2011
vor 13 Jahren

Sehr gut, danke.

F
84 Beiträge seit 2008
vor 13 Jahren

Tolles Projekt und super nutzbar! Danke.

Frage:
Durch Modifikationen müsste das doch auch für andere Produke (Office etc.) möglich sein oder?

Gelöschter Account
vor 13 Jahren

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 😃

54 Beiträge seit 2010
vor 13 Jahren

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.

Gelöschter Account
vor 13 Jahren

Hallo Xander,

Zunächst rate ich dir natürlich zum updaten auf die neue Version.
Alles weitere per PM.

Update:
Das Problem lag in der fehlenden Verwendung von .Dispose()
Das API verursacht keine Speicherlecks.

B
101 Beiträge seit 2008
vor 13 Jahren

Weltklasse!