Abou Chleih

{the magic lies between the brackets}

Menü Schließen

Monat: Juli 2013

[C#] Auslesen einer Excel Datei #1 – Interop-Assembly

Um Daten aus einer Excel-Datei in das Programm zu laden, gibt es mehrere Wege:

  • Zugriff auf die Excel-Datei über die Interop-Schnittstelle
  • Zugriff auf die Excel-Datei über einen Datenbank-Provider (hier: OLEDB)

Beginnen wir mit dem ersten genannten Weg, dem Zugriff über die Interop-Assembly.
Um einen Zugriff zu erhalten, müssen wir zuerst die Assembly einbinden, dies tun wir, indem wir einen Verweis auf die DLL hinzufügen.
Dazu klicken wir mit der rechten Maustaste auf das Item „Verweise“ im gewünschten Projekt und betätigen das Feld „Verweis hinzufügen…“.
Verweis_hinzufügen

Anschließend öffnet sich Dialog, indem wir einige DLLs finden.
Wir benötigen die Microsoft.Office.Interop.Excel-DLL, welche im Reiter .NET zu finden ist.

Interop_Excel_Verweis
Anschließend binden wir den Namespace der DLL in das Projekt (die gewünschte Klasse) ein.

 using Microsoft.Office.Interop.Excel; 

Nun zum eigentlichen Auslesen.
Zuerst müssen wir die verschiedenen Variablen anlegen, die Excel benötigt:

  • Die Excel-Applikation
  • Das Workbook
  • Das Worksheet
ApplicationClass app = new ApplicationClass(); //Die Excel-Applikation
Workbook book = null; //Das Workbook
Worksheet sheet = null; //Das Worksheet

Nun weisen wir die Werte zu:

 book = app.Workbooks.Open(path, Missing.Value, Missing.Value,
                                         Missing.Value, Missing.Value, Missing.Value, Missing.Value,
                                         Missing.Value, Missing.Value, Missing.Value, Missing.Value,
                                         Missing.Value, Missing.Value, Missing.Value, Missing.Value);

Dies lässt Excel das Workbook öffnen.
Falls dies im Hintergrund geschehen soll (Excel soll nicht sichtbar laufen), müssen folgende Optionen gesetzt sein:

 app.Visible = false;
app.ScreenUpdating = false;
app.DisplayAlerts = false; 

Nun da wir das komplette Excel-File geöffnet haben, wollen wir die Dateien der verschiedenen Worksheets (zu Deutsch: Tabellenblätter) auslesen.
Dazu weisen wir dem Objekt vom Typ Worksheet das Worksheet aus dem Excel-File zu:

 sheet = (Worksheet)book.Worksheets[1]; 

Es ist zu beachten, dass hier das erste Worksheet auch den Index 1 hat. (Kein zero-based-indexing!)
Jetzt lesen wir das Worksheet aus. Dazu muss man angeben, ab welcher Zelle und bis zu welcher Zelle man auslesen will, man muss also einen Bereich (eine Range) angeben.
Für dies existiert die Klasse Range.
Nun weisen wir der Range den gesamten Bereich zu, in dem Werte stehen.
Dazu erstellen wir ein char-Array bzw. einen string (ein String ist ein char-Array):

 string alphabet= "ABCDEFGHIJKLMNOPQRSTUVQXYZ"; 

Nun lesen wir aus, wie viele Spalten es gibt:

 int colCount = sheet.UsedRange.Columns.Count; 

Den Buchstaben der letzten Spalte bekommen wir nun ganz einfach durch Nutzen des Index (colCount):

 char lastColChar = alphabet[iColumnCount]; 

Um die letzte genutzte Spalte zu finden nutzen wir:

int rowCount = sheet.UsedRange.Rows.Count; 

Die Range definieren wir dann wie folgt:

 Range range = sheet.get_Range("A1", lastColChar.toString() + rowCount.toString()); 

Der erste Parameter definiert die obere, rechte Zelle, der zweite die untere, linke.
Nun haben wir den Bereich definiert.
Das Auslesen ist nun sehr simpel:
Da wir alle benötigten Daten haben, können wir ein Array erstellen und das Array schnell füllen:

 object[,] myExcelFileValues = (object[,])range.Value2; 

Nun haben wir alle Zellen im Speicher und können Excel beenden (!!!), dies ist wichtig, da die Datei sonst nicht freigegeben wird.
Dies geschieht nach dem First-In-Last-Out-Prinzip.
Zuerst löschen wir also das Range-Objekt:

 range = null; 

Nun löschen wir das Worksheet und rufen den GarbageCollector auf:

Marshal.FinalReleaseComObject(sheet);
app.DisplayAlerts = false;
sheet = null; 
GC.Collect();
GC.WaitForPendingFinalizers(); 

Anschließend lassen wir das Workbook schließen und löschen das Workbook-Objekt:

  book.Close(false, Missing.Value, Missing.Value); 
 Marshal.FinalReleaseComObject(book);
 book = null;

Daraufhin schließen wir Excel/die Applikation und löschen diese aus dem Speicher:

 app.Quit();
Marshal.FinalReleaseComObject(app);
app = null; 

Nun ist das Programm beendet.

[C#] Serialisieren von Listen (eigener Objekte)

In manchen Fällen kann es sinnvoll sein Listen und deren Inhalt zu speichern.
In meinem Fall wurde die Liste mit Objekten einer eigens erstellen Klasse gefüllt, dadurch ist es sehr schwierig diese Liste mit dem XmlSerializer zu serialisieren/speichern.

Für solche Fälle eignet sich der BinaryFormatter

Um die Daten zu serialisieren benötigen wir folgende Namespaces:

using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization; //Kann fürdas Exception-Handling genutzt werden
//bspw. SerializationException

Zusätzlich benötigt man natürlich auch das zu sichernde Objekt – in meinem Fall eine Liste mit Objekten vom Typ „Receiver“ mit Namen receiverList

List<Receiver> receiverList = new List<Receiver>();

Meine Receiver-Klasse sieht wie folgt aus:

    [Serializable()]
    public class Receiver
    {
        public string Name { get; set; }
        public string MACAddress { get; set; }
        public IPAddress IP { get; set; }
        public string Info { get; set; }

        public Receiver(string pName, string pMAC, string pIPAddress, string pInfo)
        {
            Name = pName;
            MACAddress = pMAC;
            if (pIPAddress != null && pIPAddress != "")
            {
                IP = IPAddress.Parse(pIPAddress);
            }
            Info = pInfo;
        }
    }

Und schon haben wir den ersten wichtigen Punkt: Die Klasse muss als serialisierbar(engl. Serializable) gekennzeichnet sein, daher muss das Serializable-Attribut [Serializable()] über dem Header der Klasse angebracht werden, eine paramterlosen Konstruktor, wie bei XmlSerializer benötigt man nicht

Nun zum eigentlichen Speichern der Liste, man könnte natürlich auch jedes Objekt einzeln speichern, jedoch halte ich das für aufwendiger und man benötigt die genaue Anzahl der zu serialisierenden Objekte. Deshalb speichern wir die Collection selbst und schreiben sie komplett in einen FileStream (Datenstrom).

        private void SaveReceiverList()
        {
            FileStream stream;
            stream = new FileStream(@"receiverList.dat", FileMode.Create);
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream, receiverList);
            stream.Close();
        }

Zum Laden der Liste benutzen wir folgenden Code:

        private void LoadReceiverList()
        {
            FileStream fs = new FileStream(@"receiverList.dat", FileMode.Open); ;
            BinaryFormatter formatter = new BinaryFormatter();
            receiverList = (List<Receiver>)formatter.Deserialize(fs);
        }

Bisher wurde, zum Nutzen der Übersicht, kein Exception-Handling eingebaut, dies sollte man aber unbedingt nachholen. Gerade beim Lesen und Schreiben von Dateien kommt es immer mal wieder zu Ausnahmen (bspw. UnauthorizedAccessException)

[WP7] Der erste Tag/Systemvoraussetzungen

Da ich gerade an einer App für das mobile Betriebssystem Windows Phone 7(genauer 7.8) arbeite, dachte ich, dass ich meine ersten Eindrücke und Erfahrungen bei der Entwicklung dieser Applikation schildere.

Zum Entwicklung benötigen wir zuallererst Windows Phone SDK 7.1 oder 8 und zum Entwickeln für Windows Phone 7.8 das SDK Update[560MB,English](dieses ist mit beiden Versionen des SDK kompatibel).

Ich persönlich verwende SDK 8, da ich in Zukunft auch für Windows Phone in der Version 8 programmieren möchte.

Systemvoraussetzungen für SDK:

  • Windows 8 x64 (die Zeiten von 32-bit neigen sich wohl dem Ende)
  • 6,5 GB Festplattenspeicher
  • 4 GB Ram, wobei ich meiner VM nur 3 gegeben habe und bisher keine Probleme sehe

Zusätzliche Systemvoraussetzungen für den Emulator:

  • Windows 8 Pro oder höher
  • Prozessor mit SLAT(Second Level Address Translation)
    • Prozessoren, welche SLAT unterstützen:
    • Intel(hier EPT genannt): Intel Core i3, i5, i7 ab Nehalem(komplette Liste)
    • AMD(hier RVI genannt): Prozessoren ab der dritten Generation von Opteron(Prozessorenliste)

Da ich „nur“ einen Intel C2Q Q6600 in meinem Prozessor verbaut habe, musste ich leider auf den Emulator verzichten(da ich ein fürs Entwickeln freigeschaltenes Phone besitze, war das aber kein Problem)

Nie wieder! – Endloskette an der SV 650

So war es mal so weit.
Die alte Kette meiner SV hatte ihren Zenit erreicht (sogar schon überschritten) und musste gewechselt werden.
Also schnell zur Tante L. gefahren und eine neue Kette gekauft – leider gab und gibt es dort nur Endlosketten (also Ketten, die schon komplett vernietet waren).
Kein Problem, dachte ich, baue ich halt kurz die Schwinge raus und ziehe die neue Kette drauf.
Das soll sich noch als großer Irrtum herausstellen.
So hat die SV einige Probleme, die das Aufziehen einer Endloskette erschweren:

  1. Man muss zum Ausbau der Schwinge den Krümmer und das Federbein ausbauen
  2. Die SV hat keinen Hauptständer
  3. Die SV ist hinten schwerer also vorne

So benötigte ich eine Leiter, die ich so aufstellte:
IMG_20130625_210731

Vorne stemmte ich das Bike mit einem Ständer für das Lenkkopflager hoch.
Nun waren die Probleme eins und zwei beseitigt.
Ich baute nun die Schwinge aus, was auch wieder nur mit Spezialwerkzeug (einem sog. Nutmutternschlüssel) funktionierte und habe gedacht, dass es damit erledigt sei, leider lässt sich die Schwinge beim Ausbau der Schwingenachse nicht weit genug herausziehen, um die Kette einzufädeln.
So musste ich nun den gesamten Krümmer mitsamt Endtopf und das Federbein ausbauen.
Schlussendlich, nach einigen Stunden Arbeit habe ich dann also alles ausgebaut und das neue Kettenrad, Ritzel und die neue Kette einbauen können.
Fertig mit der Arbeit, nur noch zusammen bauen.
Nun habe ich eine neue Kette, viel Öl an den Händen, die Maschine ist dreckig und muss gewaschen werden… und das alles wegen einer Kette.
Das nächste Mal werde ich einfach eine offene kaufen ;-)

© 2018 Abou Chleih. Alle Rechte vorbehalten.

Thema von Anders Norén.