VBA
Ich bekam den Auftrag in Access mit VBA eine Funktion zu Programmieren, welche auf unsere Zeiterfassungsdatenbank (Dynabase2) zugreift, die Daten im ausgewählten Zeitrahmen ausliest und diese anschliessend auf die Korrektheit überprüft.
Da ich noch keine Ahnung hatte begann ich sehr einfach.
Zuerst suchte ich mir in den Bereits vorhandenen Funktionen den Datenbank-Zugriff und das Select-Statement.
Dabei fand ich folgende Code Zeilen:
Dim Db as Datebase
Dim Rs as Recordset
Set Db = CurrentDb()
Set Rs = Db.OpenRecordset("Select-Statement")
Die ersten beiden Zeilen deklarieren die Variablen Db als Datenbank und Rs als Recordset(Enthält Kopien von Datensätzen).
Mit CurrentDb() wird der Variable Db die aktuell im Access geöffnete DB zugewiesen. Mit OpenRecordset wird der Variable Rs eine Kopie der Daten, welche durch das Select-Statement ausgewählt werden zugewiesen.
Ich musste nun als erstes mein Select-Statement anpassen.
Ich brauchte die MitarbeiterID, das Datum und die beiden Uhrzeiten, welche Start und Beginn einer Arbeitsphase sind, aus der Tabelle Aktivitaet von allen Datensätzen, welche innerhalb des per GUI ausgewählten Datums lagen.
Also musste ich herausfinden, wie ich auf ein Objekt der benutzeroberfläche Zugriff.
Da ich die ganze Funktion per Button in der dazugehörigen Form aufrief, Programmierte ich bereits in der Richtigen Form. Aus diesem Grund konnte ich direkt über Me auf die Objekte zugreifen.
Das Startdatum wurde im Objekt ctlStart gespeichert und das Enddatum in ctlEnde. Da ich nun auf die Werte zugreifen wollte musste ich also die Values abrufen.
Das funktioniert so:
StartDatum = Me.ctlStart.Value
EndDatum = Me.ctlEnde.Value
Wobei StartDatum und EndDatum Date-Variablen darstellen.
Da ich später bemerkte dass das Select-Statement das Datum "Amerikanisch" interpretiert, also die 1 Zahl als Monat nahm, musste ich mir etwas anderes Einfallen lassen.
Dazu brauchte ich nun die Funktionen Year(), Month() und Day(). Als Parameter übergab man diesen Funktionen ein Datum und sie lasen automatisch jeweils Jahr, Monat und Tag heraus. Diese Werte konnte ich anschliessend an Variablen übergeben und das Datum der Select-Statement-Syntax anpassen.
Dabei musste ich es folgendermassen Formatieren: 03/24/2011 also Monat/Tag/Jahr
In der SQL Abfrage musste ich vor und hinter die Daten je noch ein # stellen und die Daten wurden erkannt.
Schlussendlich lautete mein Select-Statement folgendermassen:
"SELECT [MitarbeiterID], [Datum], [Zeit1], [Zeit2] FROM [Aktivitaet] WHERE [Datum] >= #" & Zeit1 & "# ABD [Datum] <= #" & Zeit2 & "# ORDER BY [MitarbeiterID], [Datum], [Zeit1]"
Die Wörter in [] sind dabei Spalten oder Tabellen(Aktivitaet) innerhalb der Datenbank. Zeit1 und Zeit2 beinhalten die ausgewählten Start- und End-Daten. Geordnet wurde die Ausgabe nach Mitarbeiter, dann nach Datum und dann nach Zeit.
Nun musste ich auf die einzelnen ausgegebenen Datensätze zugreifen.
Das funktioniert über folgende While-Schlaufe:
Do While Not Rs.EOF
Rs.MoveNext
Loop
Mit Not Rs.EOF wird die Schlaufe so lange durchlaufen, bis der Zeiger im Recordset ans Ende gelangt ist.
Mit Rs.MoveNext springe ich bei jedem Durchlauf auf den Nächsten Datensatz.
Nun brauchte ich noch den Zugriff auf die einzelnen Zellen des Datensatzes und das funktioniert so:
Variabel = Rs![Datum]
So wird der Variabel den Wert des Feldes Datum zugeordnet.
Zum Schluss muss man den Recordset und die Datenbank schliessen, bzw. die Instanzierung auflösen.
Das funktioniert mit Close.
Rs.Close
Db.Close
Alle Anderen Funktionen welche ich verwendete, sind hier irrelevant, weil sie entweder zu grundlegend waren oder ich sie bereits einmal in einem Anderen Post erwähnt habe. Ebenfalls haben sie nicht direkt etwas mit dem Datenbank-Programmieren zutun, sondern sind bloss normale VB bzw. VBA Funktionen.
Mittwoch, 30. März 2011
Montag, 28. Februar 2011
Februar 2011 / WSH
WSH
Wir begannen mit dem 2. Semester des 2. Schuljahres und daher begannen wir auch mit den neuen Modulen.
Im Modul 122 - Abläufe mit Skripts/Makros automatisieren lernten wir den WSH kennen.
WSH bedeutet Windows Script(auch Scripting) Host und dient dazu Funktionen unter Windows zu Automatisieren. Der Windows Script Host stellt JScript und VBScript als Programmiersprachen zur Verfügung, deckt die Funktionen der älteren Batch-Scripts ab und ermöglicht die Steuerung von einigen Programmen wie dem Internet Explorer, Datenbanken oder den Office-Programmen.
In der Schule begannen wir vorerst mit VBScript zu arbeiten. Daher sind die Dateiendungen unserer Scripts auch ".vbs".
Ich habe bereits 1 mal über VBScript geschrieben. Jedoch hatte ich damals keine Ahnung was genau wie funktionierte, welche Zeile genau welche Funktion hatte usw.
Ausserdem programmierte ich damals für Windows CE, was nur eine sehr abgespeckte VBScript Version zur Verfügung stellte.
Im Unterricht begannen wir jedoch komplett bei 0 und wir lernten das Grundlegende im Selbststudium.
Das WScript-Objekt
Das WScript-Objekt ist das einzige Objekt, welches man direkt verwenden kann, ohne dieses zuerst instanziieren zu müssen.
Dieses Objekt hat mehrere Methoden und Eigenschaften, so wie eigentlich fast jedes andere Objekt auch.
Die Methode .echo() hat eine sehr einfache Funktion: Sie gibt eine Meldung aus.
Dabei muss ein Parameter übergeben werden. Also entweder ein Text, eine Variable oder eine Eigenschaft. Das sieht dann so aus:
Wscript.echo Wscript.Name oder Wscipt.echo "Test"
Dabei kann der Parameter auch in Klammern Stehen.
Nun zu der Eigenschaft die ich bereits verwendet habe, Name
Verwende ich diese Eigenschaft als Parameter bei der Methode .echo gibt die Meldung "Windows Script Host" aus.
Nun schön damit können wir jedoch noch nicht besonders viel anfangen.
Das FileSystemObject
Das nächste Objekt dass wir kennen lernten war das FileSystemObject und es war mir nicht ganz unbekannt. Im Gegensatz zum Wscript-Objekt muss dieses Objekt, wie alle anderen auch, instanziiert werden, dafür hat es aber keine "direkten" Eigenschaften sondern nur Methoden, die Eigenschaften von File-Objekten liest.
Instanziieren bedeutet dass das Objekt "Kopiert" wird, dafür Speicherplatz reserviert wird und einem Namen übergeben wird, damit man es leichter ansprechen kann.
Das FileSystemObject instanziiert man folgendermassen:
Dim Fso
Set Fso = CreateObjext("Scripting.FileSystemObject")
Mit dem Befehl Dim deklariere ich Fso als Variable. Der Name wird standardmässig für das FileSystemObject verwendet und dient zur Übersichtlichkeit.
Danach instanziiere ich das Objekt mit dem Set-Befehl.
Nun kann ich über Fso alle Eigenschaften und Methoden des FileSystemObjects aufrufen.
Dazu ein kleines beispiel mit der Methode .CopyFile()
Mit folgender Zeile kopiere ich eine Textdatei und benenne Sie um.
Fso.CopyFile ("C:\Textdatei.txt", "C:\Neue Textdatei.txt")
Der erste Parameter übergibt das zu kopierende File und der 2. den Zielpfad + Namen.
Die GetFile() Methode ist eine Weitere Methode, mit dem man eine Datei einer Variabel zuordnen kann. So sichert man den Speicherplatz und den Zugriff auf die Datei.
Das Objekt das daraus entsteht heisst File Objekt.
Daher muss auch hier wieder ein Objekt instanziiert werden.
Dim f
Set f = Fso.GetFile("C:\Textdatei.txt")
Nun kann man viel einfacher auf die Datei zugreifen und muss nicht über das FileSystemObject gehen.
Möchte man die Datei löschen kann man das nun so:
f.Delete
Über das FileSystemObject müsste man das so machen:
Fso.DeleteFile("C:\Textdatei.txt")
Wie bereits erwähnt, kann man über das FileSystemObject auch Eigenschaften von File-Objekten auslesen. Natürlich geht das ganze wieder einfacher, wenn man direkt über das File-Objekt gehen kann.
Wir begannen mit dem 2. Semester des 2. Schuljahres und daher begannen wir auch mit den neuen Modulen.
Im Modul 122 - Abläufe mit Skripts/Makros automatisieren lernten wir den WSH kennen.
WSH bedeutet Windows Script(auch Scripting) Host und dient dazu Funktionen unter Windows zu Automatisieren. Der Windows Script Host stellt JScript und VBScript als Programmiersprachen zur Verfügung, deckt die Funktionen der älteren Batch-Scripts ab und ermöglicht die Steuerung von einigen Programmen wie dem Internet Explorer, Datenbanken oder den Office-Programmen.
In der Schule begannen wir vorerst mit VBScript zu arbeiten. Daher sind die Dateiendungen unserer Scripts auch ".vbs".
Ich habe bereits 1 mal über VBScript geschrieben. Jedoch hatte ich damals keine Ahnung was genau wie funktionierte, welche Zeile genau welche Funktion hatte usw.
Ausserdem programmierte ich damals für Windows CE, was nur eine sehr abgespeckte VBScript Version zur Verfügung stellte.
Im Unterricht begannen wir jedoch komplett bei 0 und wir lernten das Grundlegende im Selbststudium.
Das WScript-Objekt
Das WScript-Objekt ist das einzige Objekt, welches man direkt verwenden kann, ohne dieses zuerst instanziieren zu müssen.
Dieses Objekt hat mehrere Methoden und Eigenschaften, so wie eigentlich fast jedes andere Objekt auch.
Die Methode .echo() hat eine sehr einfache Funktion: Sie gibt eine Meldung aus.
Dabei muss ein Parameter übergeben werden. Also entweder ein Text, eine Variable oder eine Eigenschaft. Das sieht dann so aus:
Wscript.echo Wscript.Name oder Wscipt.echo "Test"
Dabei kann der Parameter auch in Klammern Stehen.
Nun zu der Eigenschaft die ich bereits verwendet habe, Name

Verwende ich diese Eigenschaft als Parameter bei der Methode .echo gibt die Meldung "Windows Script Host" aus.
Nun schön damit können wir jedoch noch nicht besonders viel anfangen.
Das FileSystemObject
Das nächste Objekt dass wir kennen lernten war das FileSystemObject und es war mir nicht ganz unbekannt. Im Gegensatz zum Wscript-Objekt muss dieses Objekt, wie alle anderen auch, instanziiert werden, dafür hat es aber keine "direkten" Eigenschaften sondern nur Methoden, die Eigenschaften von File-Objekten liest.
Instanziieren bedeutet dass das Objekt "Kopiert" wird, dafür Speicherplatz reserviert wird und einem Namen übergeben wird, damit man es leichter ansprechen kann.
Das FileSystemObject instanziiert man folgendermassen:
Dim Fso
Set Fso = CreateObjext("Scripting.FileSystemObject")
Mit dem Befehl Dim deklariere ich Fso als Variable. Der Name wird standardmässig für das FileSystemObject verwendet und dient zur Übersichtlichkeit.
Danach instanziiere ich das Objekt mit dem Set-Befehl.
Nun kann ich über Fso alle Eigenschaften und Methoden des FileSystemObjects aufrufen.
Dazu ein kleines beispiel mit der Methode .CopyFile()
Mit folgender Zeile kopiere ich eine Textdatei und benenne Sie um.
Fso.CopyFile ("C:\Textdatei.txt", "C:\Neue Textdatei.txt")
Der erste Parameter übergibt das zu kopierende File und der 2. den Zielpfad + Namen.
Die GetFile() Methode ist eine Weitere Methode, mit dem man eine Datei einer Variabel zuordnen kann. So sichert man den Speicherplatz und den Zugriff auf die Datei.
Das Objekt das daraus entsteht heisst File Objekt.
Daher muss auch hier wieder ein Objekt instanziiert werden.
Dim f
Set f = Fso.GetFile("C:\Textdatei.txt")
Nun kann man viel einfacher auf die Datei zugreifen und muss nicht über das FileSystemObject gehen.
Möchte man die Datei löschen kann man das nun so:
f.Delete
Über das FileSystemObject müsste man das so machen:
Fso.DeleteFile("C:\Textdatei.txt")
Wie bereits erwähnt, kann man über das FileSystemObject auch Eigenschaften von File-Objekten auslesen. Natürlich geht das ganze wieder einfacher, wenn man direkt über das File-Objekt gehen kann.
Mittwoch, 26. Januar 2011
Januar 2011 / Windows Server 2008 R2
Windows Server 2008 R2
Im Modul 123 - Serverdienste in Betrieb nehmen, haben wir während des letzten Semesters einen Virtuellen Windows Server 2008 konfiguriert. Dabei lernten wir einzelne Funktionen und Rollen des Servers kennen.
Wir konfigurierten unseren Server nach einem Fallbeispiel.
In diesem Fallbeispiel teilen sich eine Arztpraxis und ein Altersheim den Server und den Internet-Anschluss. Dabei soll alles, wie Berechtigungen, Interne Website usw. auf dem Server geregelt sein. Die Arztpraxis und das Altersheim sollen jedoch nichts vom jeweils anderen "Betrieb" mitbekommen, was bedeutet, dass sie in einer Domäne getrennt gehandelt werden sollen.
Zuerst richteten wir den DNS-Server ein, damit wir anschliessend das AD installieren konnten.
Der DNS-Server dient dazu, URLs wie z.b. http://www.google.ch/ in IP-Adressen umzuwandeln.
Hier lernten wir wie das Ganze genau funktioniert, wie der Server die URLs auflöst.
Dann richteten wir das ADDS (Active Directory Domain Services) ein. Es ist der Verzeichnisdienst unter Windows Server 2008. Er ermöglicht, die Aufteilung des Netzwerks entsprechend der Struktur einer Firma, oder der räumlichen Verteilung.
Beim Installieren lernten wir viele neue Begriffe und deren Zusammenhänge kennen wie Tree, Forest, Global-Catalog usw. Diese Begriffe hier aufzuzählen und zu erklären halte ich nicht für sinnvoll.
Jedoch mussten wir uns überlegen, wie genau wir unser Netzwerk aufteilen können. Dazu lernten wir die Organisationseinheiten(OU's) kennen.
Wir teilten unsere OU's entsprechend dem Fallbeispiel in Altersheim und Arztpraxis und den jeweiligen Computern, Gruppen und Benutzern auf.
Beim Installieren erstellten wir eine neue Gesamtstruktur(Forest). Der Top-Level-Name ist dabei local, was sich für nicht-öffentliche Domänen eingebürgert hat.
Schlussendlich nannten wir unsere Domäne Sonnenhof.local.
Nachdem wir das ADDS installiert hatten, widmeten wir uns dem IIS
(Internet Information Server).
Dabei lernten wir die genaue die 4 verschiedenen Authentifications kennen:
Die Anonymous Authentification dient dazu, dass jeder Zugriff ohne Name/Passwort hat.
Mit der Basic Authentification braucht man einen Namen und ein Passwort für den Zugriff.
Die Digest Authentification hat die gleiche Funktion wie die Basic Authentification, ist jedoch sicherer.
Bei der Windows Authentification wird der Zugriff im Intranet über den Domain-Client geregelt.
Der IUSR dient dabei bei der Anonymous Authentification als Anonymer Benutzer. So kann der Administrator die Rechte des Anonymen Benutzers regeln.
Wir installierten uns einen Webserver für dir Intranet-Sites, auf welche wir den Zugriff per Windows Authentification regelten.
Nun erstellten wir noch all unsere Benutzer und Gruppen, vergaben Rechte und lernten die GPOs kennen.
Im Modul 123 - Serverdienste in Betrieb nehmen, haben wir während des letzten Semesters einen Virtuellen Windows Server 2008 konfiguriert. Dabei lernten wir einzelne Funktionen und Rollen des Servers kennen.
Wir konfigurierten unseren Server nach einem Fallbeispiel.
In diesem Fallbeispiel teilen sich eine Arztpraxis und ein Altersheim den Server und den Internet-Anschluss. Dabei soll alles, wie Berechtigungen, Interne Website usw. auf dem Server geregelt sein. Die Arztpraxis und das Altersheim sollen jedoch nichts vom jeweils anderen "Betrieb" mitbekommen, was bedeutet, dass sie in einer Domäne getrennt gehandelt werden sollen.
Zuerst richteten wir den DNS-Server ein, damit wir anschliessend das AD installieren konnten.
Der DNS-Server dient dazu, URLs wie z.b. http://www.google.ch/ in IP-Adressen umzuwandeln.
Hier lernten wir wie das Ganze genau funktioniert, wie der Server die URLs auflöst.
Dann richteten wir das ADDS (Active Directory Domain Services) ein. Es ist der Verzeichnisdienst unter Windows Server 2008. Er ermöglicht, die Aufteilung des Netzwerks entsprechend der Struktur einer Firma, oder der räumlichen Verteilung.
Beim Installieren lernten wir viele neue Begriffe und deren Zusammenhänge kennen wie Tree, Forest, Global-Catalog usw. Diese Begriffe hier aufzuzählen und zu erklären halte ich nicht für sinnvoll.
Jedoch mussten wir uns überlegen, wie genau wir unser Netzwerk aufteilen können. Dazu lernten wir die Organisationseinheiten(OU's) kennen.
Wir teilten unsere OU's entsprechend dem Fallbeispiel in Altersheim und Arztpraxis und den jeweiligen Computern, Gruppen und Benutzern auf.
Beim Installieren erstellten wir eine neue Gesamtstruktur(Forest). Der Top-Level-Name ist dabei local, was sich für nicht-öffentliche Domänen eingebürgert hat.
Schlussendlich nannten wir unsere Domäne Sonnenhof.local.
Nachdem wir das ADDS installiert hatten, widmeten wir uns dem IIS
(Internet Information Server).
Dabei lernten wir die genaue die 4 verschiedenen Authentifications kennen:
Die Anonymous Authentification dient dazu, dass jeder Zugriff ohne Name/Passwort hat.
Mit der Basic Authentification braucht man einen Namen und ein Passwort für den Zugriff.
Die Digest Authentification hat die gleiche Funktion wie die Basic Authentification, ist jedoch sicherer.
Bei der Windows Authentification wird der Zugriff im Intranet über den Domain-Client geregelt.
Der IUSR dient dabei bei der Anonymous Authentification als Anonymer Benutzer. So kann der Administrator die Rechte des Anonymen Benutzers regeln.
Wir installierten uns einen Webserver für dir Intranet-Sites, auf welche wir den Zugriff per Windows Authentification regelten.
Nun erstellten wir noch all unsere Benutzer und Gruppen, vergaben Rechte und lernten die GPOs kennen.
Mittwoch, 15. Dezember 2010
Dezember 2010 / Normalisierung
Normalisierung
Im Modul 104 - Datenmodell erstellen und implementieren befassen wir uns mit der Planung und Erstellung von Datenbanken.
Nun haben wir uns dem Thema Normalisierung gewitmet.
Im Fachdeutsch bedeutet die Normalisierung die schrittweise Zerlegung von Relationen, um Redundanzen innerhalb eines Datenschemas zu vermeiden.
In meinen eigenen Worten würde ich die Normalisierung so beschreiben:
Die Normalisierung ist ein Vorgehen, mit welchem man überprüfen kann, ob die Tabellen und Beziehung korrekt sind. Entsprechen Sie nicht den vorgegebenen Richtlinien, werden Sie korrigiert.
Das Ziel der gesamten Normalisierung ist es, die Kosistenz der Datenbank zu erhöhen und so Fehlerquellen zu verringern.
Sie wird bei der Plangung der Datenbank durchgeführt.
Die Normalisierung besteht aus 6 Normalformen, wovon wir jedoch nur die ersten 3 benötigen.
Um die 1. Normalform zu erreichen, müssen folgende Punkte eingehalten werden:
- Es sind keine Zusammengesetzen Attributwerte vorhanden
Beispiel: Adresse muss in PLZ, Ort, Strasse, Hausnummer aufgeteilt werden.
- Es dürfen nicht mehrere Werte innerhalb eines Wertfeldes vorkommen
Beispiel: Mehrere Titel-Namen einer Audio-CD in einem Wertefeld
Hier noch das Beispiel aus Wikipedia:
Datenschema in der "0." Normalform.

Datenschema nach der Normalisierung in der 1. Normalform.
Wie man sieht, wurden die Mehrfachen Titel in einzelne Felder aufgeteilt und das Album vom Interpret getrennt.
Nun bilden CD_ID und Track einen Verbundschlüssel, welchen den Primärschlüssel repräsentiert.
Damit sich ein Datenschema in der 2. Normalform befindet, müssen folgende Punkte eingehalten werden:
- Das Datenschema muss sich in der 1. Normalform befinden
- Jedes Attribut, welches keinen Schlüssel darstellt, ist von Allen Schlüsseln(also vom gesamten Verbundschlüssel) abhängig
Beispiel: In der 1. NF sind Album von der CD_ID abhängig, nicht aber vom Track.
Um dieses Datenschema in die 2. Normalform zu bringen müssen folgende Schritte vorgenommen werden:
Da die Attribute Album, Interpret und Jahr der Gründung nicht von beidem Schlüsselteilen abhängig ist, wird die Tabelle in mehrere Tabellen aufgeteilt. Anschliessend werden die Redundanten Daten gelöscht. Daraus ergeben sich folgende Tabellen:
In der 2. Tabelle stellt CD_ID einen fremdschlüssel dar, da er auf die CD_ID der 1. Tabelle verweisst.
Damit sich ein Datenschema in der 3. Normalform befindet, müssen alle Transiven abhängigkeiten von nicht-schlüssel-Attributen auf schlüssel-Attribute aufgelöst werden. Eine Transive Abhängigkeit wird folgendermassen beschrieben:
Hängt das Attribut C vom Attribut B ab und das Attribut B vom Attribut A, hängt das Attribut C transiv(also indirekt) vom Attribut A ab.
In unserem Beispiel gibt es ebenfalls so einen Fall.
Das Jahr der Gründung hängt vom Interpreten ab, der Interpret wiederum hängt vom Album ab. Also ist das Jahr der Gründung Transiv vom Album abhängig. Das führt zu redundanten (mehrfach vorkommenden) Daten.
Um das zu verhindern, muss eine 3. Tabelle erstellt werden.
Dabei bildet Interpret den Primärschlüssel und bei der 1. Tabelle wird Interpret als Fremdschlüssel hinzugefügt:

Im Modul 104 - Datenmodell erstellen und implementieren befassen wir uns mit der Planung und Erstellung von Datenbanken.
Nun haben wir uns dem Thema Normalisierung gewitmet.
Im Fachdeutsch bedeutet die Normalisierung die schrittweise Zerlegung von Relationen, um Redundanzen innerhalb eines Datenschemas zu vermeiden.
In meinen eigenen Worten würde ich die Normalisierung so beschreiben:
Die Normalisierung ist ein Vorgehen, mit welchem man überprüfen kann, ob die Tabellen und Beziehung korrekt sind. Entsprechen Sie nicht den vorgegebenen Richtlinien, werden Sie korrigiert.
Das Ziel der gesamten Normalisierung ist es, die Kosistenz der Datenbank zu erhöhen und so Fehlerquellen zu verringern.
Sie wird bei der Plangung der Datenbank durchgeführt.
Die Normalisierung besteht aus 6 Normalformen, wovon wir jedoch nur die ersten 3 benötigen.
Um die 1. Normalform zu erreichen, müssen folgende Punkte eingehalten werden:
- Es sind keine Zusammengesetzen Attributwerte vorhanden
Beispiel: Adresse muss in PLZ, Ort, Strasse, Hausnummer aufgeteilt werden.
- Es dürfen nicht mehrere Werte innerhalb eines Wertfeldes vorkommen
Beispiel: Mehrere Titel-Namen einer Audio-CD in einem Wertefeld
Hier noch das Beispiel aus Wikipedia:
Datenschema in der "0." Normalform.

Datenschema nach der Normalisierung in der 1. Normalform.
Wie man sieht, wurden die Mehrfachen Titel in einzelne Felder aufgeteilt und das Album vom Interpret getrennt.Nun bilden CD_ID und Track einen Verbundschlüssel, welchen den Primärschlüssel repräsentiert.
Damit sich ein Datenschema in der 2. Normalform befindet, müssen folgende Punkte eingehalten werden:
- Das Datenschema muss sich in der 1. Normalform befinden
- Jedes Attribut, welches keinen Schlüssel darstellt, ist von Allen Schlüsseln(also vom gesamten Verbundschlüssel) abhängig
Beispiel: In der 1. NF sind Album von der CD_ID abhängig, nicht aber vom Track.
Um dieses Datenschema in die 2. Normalform zu bringen müssen folgende Schritte vorgenommen werden:
Da die Attribute Album, Interpret und Jahr der Gründung nicht von beidem Schlüsselteilen abhängig ist, wird die Tabelle in mehrere Tabellen aufgeteilt. Anschliessend werden die Redundanten Daten gelöscht. Daraus ergeben sich folgende Tabellen:
In der 2. Tabelle stellt CD_ID einen fremdschlüssel dar, da er auf die CD_ID der 1. Tabelle verweisst.Damit sich ein Datenschema in der 3. Normalform befindet, müssen alle Transiven abhängigkeiten von nicht-schlüssel-Attributen auf schlüssel-Attribute aufgelöst werden. Eine Transive Abhängigkeit wird folgendermassen beschrieben:
Hängt das Attribut C vom Attribut B ab und das Attribut B vom Attribut A, hängt das Attribut C transiv(also indirekt) vom Attribut A ab.
In unserem Beispiel gibt es ebenfalls so einen Fall.
Das Jahr der Gründung hängt vom Interpreten ab, der Interpret wiederum hängt vom Album ab. Also ist das Jahr der Gründung Transiv vom Album abhängig. Das führt zu redundanten (mehrfach vorkommenden) Daten.
Um das zu verhindern, muss eine 3. Tabelle erstellt werden.
Dabei bildet Interpret den Primärschlüssel und bei der 1. Tabelle wird Interpret als Fremdschlüssel hinzugefügt:

Dieses Datenschema befindet sich nun in der 3. Normalform und kann so realisiert werden. Was in diesesm Falle etwas speziell ist, ist der Zusammengesetzte Fremdschlüssel in der 3. Tabelle. Der Titel ist immer vom Track und von der CD_ID abhängig. Das bedeutet, dass man keine Titel ohne dazugehöriges Album und der Track-Nummer erfassen kann und keine CD ohne Titel.
Montag, 8. November 2010
November 2010 / WNotificator
In der Firma
WNotificator:
In der Firma habe ich das Programm WNotificator getestet.
Dieses Programm wurde von der indico electronic AG entwickelt und war in der Test-Phase.
Ich übernahm dabei hauptsächlich die Rolle des Testers. Für mich war diese Rolle neu und wie sich herausstellte auch nicht gerade einfach: Man muss jede mögliche Situation testen, jeden Button anklicken, jedem möglichen Navigationsweg folgen usw.
Es war das erste Mal, dass ich in unserer Firma, in einem Team an einem Projekt arbeiten musste, welches möglichst schnell fertig gemacht bzw. auf einem Vertretbaren Stand gebracht werden musste.
Ich spielte also eine wesentliche Rolle in einem echten Projekt. Würde ich meine Arbeit nicht korrekt erledigen bekäme unsere Firma ein Problem. Das hat mich einerseits unter Druck gestellt, andererseits jedoch auch angespornt.
Auch dass ich nur bedingt kontrolliert wurde und dass ich anderen Mitarbeitern mitteilen musste, was sie zu tun haben, war eine neue Erfahrung. Es ist nicht gerade einfach alles richtig und für den Gegenüber verständlich auszudrücken, daher gab es auch Missverständnisse.
Mein Fazit davon ist:
Das ausführliche Testen eines Programmes ist sehr wichtig und anspruchsvoll. Es muss auf das kleinste Detail geachtet werden und wird etwas geändert, muss man den bereits getesteten und damals funktionierenden Teil anschliessend wieder testen. Ein Abschliessender Test ist auch sehr wichtig. Denn was einmal getestet wurde und korrekt funktionierte, kann nach 10 neuen Versionen möglicherweise nichtmehr funktionieren.
CPU-Testsystem - C#
Abgesehen von den Zahlreichen Tests, entwickelte ich ein weiteres Programm mit C#.
Das CPU-Testsystem dient dazu die Wettronic 1 zu testen.
An sich hatten wir bereits ein funktionierendes System, dafür benötigten wir jedoch extra einen Computer, denn es lief nicht auf Windows und es hatte keine Grafische Benutzeroberfläche.
Die Kommunikation mit dem Gerät erfolgte über die RS232-Schnittstelle.
Den Code für die Kommunikation war jedoch bereits vorhanden, also musste ich mich nicht darum kümmern, wie das genau funktionieren würde. Stattdessen musste ich bloss verschiedene Bits setzen, welche dann einen Test starteten. Bei den ersten Tests musste der Tester von Hand überprüfen, ob alles korrekt funktionierte. Das hiess für mich, dass ich bloss eine Messagebox öffnen und damit fragen musste, ob alles korrekt funktionierte. Das ganze musste anschliessend noch in einen Log geschrieben werden.
Den Log stellte ich als ListView dar, damit ich den Hintergrund der Einträge färben konnte.
Um einen Listview-Eintrag zu erstellen, nutzte ich eine Methode, damit ich nicht bei jedem Eintrag viel schreiben musste.
Hier seht ihr nun, wie man den Listview befüllt.
Mit der nächsten Zeile kann man die 1. Spalte der Listview befüllen. Wobei Log den Listview darstellt.
ListViewItem Item = Log.Items.Add();
Mit folgender Zeile kann man die 2. Spalte der Listview befüllen.
item.SubItems.Add("");
Um den Logeintrag nun noch einzufärben kann man folgendes benutzen.
item.BackColor = Color.Beliebige Farbe;
Damit man den Eingefügten Logeintrag auch immer sieht braucht es noch folgende Zeile:
item.EnsureVisible();
Der Effekt sieht so aus, als ob immer jemand mitscrollen würde.
Schlussendlich wurde mir von einem Mitarbeiter noch erklärt, dass man folgende Zeile ebenfalls einfügen soll, damit alles korrekt angezeigt wird.
Log.Refresh();
Warum genau es einen Refresh braucht weiss ich selbst nicht.
WNotificator:
In der Firma habe ich das Programm WNotificator getestet.
Dieses Programm wurde von der indico electronic AG entwickelt und war in der Test-Phase.
Ich übernahm dabei hauptsächlich die Rolle des Testers. Für mich war diese Rolle neu und wie sich herausstellte auch nicht gerade einfach: Man muss jede mögliche Situation testen, jeden Button anklicken, jedem möglichen Navigationsweg folgen usw.
Es war das erste Mal, dass ich in unserer Firma, in einem Team an einem Projekt arbeiten musste, welches möglichst schnell fertig gemacht bzw. auf einem Vertretbaren Stand gebracht werden musste.
Ich spielte also eine wesentliche Rolle in einem echten Projekt. Würde ich meine Arbeit nicht korrekt erledigen bekäme unsere Firma ein Problem. Das hat mich einerseits unter Druck gestellt, andererseits jedoch auch angespornt.
Auch dass ich nur bedingt kontrolliert wurde und dass ich anderen Mitarbeitern mitteilen musste, was sie zu tun haben, war eine neue Erfahrung. Es ist nicht gerade einfach alles richtig und für den Gegenüber verständlich auszudrücken, daher gab es auch Missverständnisse.
Mein Fazit davon ist:
Das ausführliche Testen eines Programmes ist sehr wichtig und anspruchsvoll. Es muss auf das kleinste Detail geachtet werden und wird etwas geändert, muss man den bereits getesteten und damals funktionierenden Teil anschliessend wieder testen. Ein Abschliessender Test ist auch sehr wichtig. Denn was einmal getestet wurde und korrekt funktionierte, kann nach 10 neuen Versionen möglicherweise nichtmehr funktionieren.
CPU-Testsystem - C#
Abgesehen von den Zahlreichen Tests, entwickelte ich ein weiteres Programm mit C#.
Das CPU-Testsystem dient dazu die Wettronic 1 zu testen.
An sich hatten wir bereits ein funktionierendes System, dafür benötigten wir jedoch extra einen Computer, denn es lief nicht auf Windows und es hatte keine Grafische Benutzeroberfläche.
Die Kommunikation mit dem Gerät erfolgte über die RS232-Schnittstelle.
Den Code für die Kommunikation war jedoch bereits vorhanden, also musste ich mich nicht darum kümmern, wie das genau funktionieren würde. Stattdessen musste ich bloss verschiedene Bits setzen, welche dann einen Test starteten. Bei den ersten Tests musste der Tester von Hand überprüfen, ob alles korrekt funktionierte. Das hiess für mich, dass ich bloss eine Messagebox öffnen und damit fragen musste, ob alles korrekt funktionierte. Das ganze musste anschliessend noch in einen Log geschrieben werden.
Den Log stellte ich als ListView dar, damit ich den Hintergrund der Einträge färben konnte.
Um einen Listview-Eintrag zu erstellen, nutzte ich eine Methode, damit ich nicht bei jedem Eintrag viel schreiben musste.
Hier seht ihr nun, wie man den Listview befüllt.
Mit der nächsten Zeile kann man die 1. Spalte der Listview befüllen. Wobei Log den Listview darstellt.
ListViewItem Item = Log.Items.Add();
Mit folgender Zeile kann man die 2. Spalte der Listview befüllen.
item.SubItems.Add("");
Um den Logeintrag nun noch einzufärben kann man folgendes benutzen.
item.BackColor = Color.Beliebige Farbe;
Damit man den Eingefügten Logeintrag auch immer sieht braucht es noch folgende Zeile:
item.EnsureVisible();
Der Effekt sieht so aus, als ob immer jemand mitscrollen würde.
Schlussendlich wurde mir von einem Mitarbeiter noch erklärt, dass man folgende Zeile ebenfalls einfügen soll, damit alles korrekt angezeigt wird.
Log.Refresh();
Warum genau es einen Refresh braucht weiss ich selbst nicht.
Montag, 18. Oktober 2010
Oktober 2010 / PHP
ÜK 307 + 131
Ich besuchte die ÜKs 307(Interaktive Website erstellen) und 131(Arbeitspaket aus einem IT Projekt abwickeln). Die ÜKs hatten wir im "doppelpack". Das heisst wir haben eine Website mit Datenbankanbindung erstellt und dieses Projekt für unsere Übungen aus dem Modul 131 genommen.
Wir bildeten ein 3er Team. Ich war zuständig für den Code der Website, ein anderer für das Design und noch einer für die Dokumentation. Unsere Website stellt die besten Filme aus dem Jahre 2009 vor. Wir haben 7 Filme gewählt, die ziemlich gut abgeschnitten haben, oder wir sehr gut fanden und fügten zu jedem Film einen Eintrag in unsere Datenbank mit einer kurzen Zusammenfassung des Inhalts und einem Trailer ein. Den Seiteninhalt der einzelnen Filmseiten holten wir so aus der Datenbank.
Wir fügten ebenfalls ein Gästebuch ein. Dort kann jeder Besucher etwas hineinschreiben. Jedoch werden URLs geblockt um Spam zu verhindern.
Ebenfalls fügten wir die Besucherzahl unserer Website ein, welche wir jedoch nicht in der Datenbank sondern in einem Textfile speicherten.
Dabei lernte ich natürlich PHP kennen. PHP kann eine Website mit einer Datenbank verbinden und dazu nutzten wir es auch.
Um PHP nutzen zu können, kann man ein ganz normales HTML-File nehmen und PHP Code einfügen. Jedoch muss man anschliessend noch die Dateiendung in .php ändern.
Leider versucht dieser Blog meinen PHP Code zu interpretieren und daher kann ich euch nicht die korrekte Syntax zeigen, bzw. ich kopiere die Eröffnung des PHP Codes als Bild hinein.
Es muss immer deklariert werden, sobald PHP-Code vorkommt. Das geschieht folgendermassen:

?>
Innerhalt dieser beiden Zeichen-Codes kann man php-codieren. Aufgrund des oben genannten Problems werde ich diese Eröffnung und Schliessung des PHP-Codes nichtmehr einfügen.
Das einfachste ist eigentlich einen Text auszugeben. Das funktioniert folgendermassen:
echo "Mein Text";
So erscheint auf der Website der Text "Mein Text".
Als Nächstes kann man Variablen verwenden. Sie sind sehr einfach zu verwenden und müssen nicht direkt deklariert, sondern können direkt verwendet werden. Eine Variabel wird immer mit einem $ davor verwendet. Hier ein Beispiel:
$variabel1 = "Mein Text";
echo $variabel1
Das Ergebnis ist dasselbe wie beim oberen Beispiel, jedoch wird es über eine Variabel gemacht.
Die Verbindung auf den SQL-Server war einer der wichtigsten Punkte in unserem Projekt. Und so wird es gemacht:
$link = mysql_connect("host", "user", "password") or die ("Keine Verbindung möglich");
Damit wird versucht auf den MySQL-Server zuzugreifen. Mit "or die" kann man sagen, was passieren soll, wenn die Verbindung nicht aufgebaut werden kann. Hier wird "Keine Verbindung möglich" ausgegeben.
Anschliessend muss man noch die Datenbank auswählen, auf welche man zugreifen möchte:
mysql_select_db("filme") or die ("Die Datenbank existiert nicht");
Wird die angegebene Datenbank, hier "filme", nicht gefunden wird wieder durch "or die" eine Meldung ausgegeben. Hier: "Die Datenbank existiert nicht"
Das ganze könnte man natürlich auch ohne "or die" machen, ich denke jedoch es ist nützlich wenn man eine kurze Meldung ausgibt, weshalb es nicht funktioniert.
Um an den Inhalt der Datenbank zu gelangen, muss man das Select-Statement verwenden:
$Abfrage = "SELECT * FROM film WHERE titel = 'Avatar' ";
Das übergibt der Variabel Abfrage das Select-Statement. In unserer Datenbank "filme" gibt es eine Tabelle namens "film", diese wird hier ausgewählt. Es werden alle Einträge heraus genommen, in denen im Datenfeld "titel" "Avatar" steht. Bei uns gibt es natürlich nur einen Eintrag mit diesem Namen und daher konnten wir ihn so identifizieren.
Der Inhalt aus der Datenbank ist jedoch immer noch nicht geholt. Die Variabel hat nur das Statement gespeichert, es wurde noch nicht ausgeführt. Dazu benutzen wir folgendes:
Ich besuchte die ÜKs 307(Interaktive Website erstellen) und 131(Arbeitspaket aus einem IT Projekt abwickeln). Die ÜKs hatten wir im "doppelpack". Das heisst wir haben eine Website mit Datenbankanbindung erstellt und dieses Projekt für unsere Übungen aus dem Modul 131 genommen.
Wir bildeten ein 3er Team. Ich war zuständig für den Code der Website, ein anderer für das Design und noch einer für die Dokumentation. Unsere Website stellt die besten Filme aus dem Jahre 2009 vor. Wir haben 7 Filme gewählt, die ziemlich gut abgeschnitten haben, oder wir sehr gut fanden und fügten zu jedem Film einen Eintrag in unsere Datenbank mit einer kurzen Zusammenfassung des Inhalts und einem Trailer ein. Den Seiteninhalt der einzelnen Filmseiten holten wir so aus der Datenbank.
Wir fügten ebenfalls ein Gästebuch ein. Dort kann jeder Besucher etwas hineinschreiben. Jedoch werden URLs geblockt um Spam zu verhindern.
Ebenfalls fügten wir die Besucherzahl unserer Website ein, welche wir jedoch nicht in der Datenbank sondern in einem Textfile speicherten.
Dabei lernte ich natürlich PHP kennen. PHP kann eine Website mit einer Datenbank verbinden und dazu nutzten wir es auch.
Um PHP nutzen zu können, kann man ein ganz normales HTML-File nehmen und PHP Code einfügen. Jedoch muss man anschliessend noch die Dateiendung in .php ändern.
Leider versucht dieser Blog meinen PHP Code zu interpretieren und daher kann ich euch nicht die korrekte Syntax zeigen, bzw. ich kopiere die Eröffnung des PHP Codes als Bild hinein.
Es muss immer deklariert werden, sobald PHP-Code vorkommt. Das geschieht folgendermassen:

?>
Innerhalt dieser beiden Zeichen-Codes kann man php-codieren. Aufgrund des oben genannten Problems werde ich diese Eröffnung und Schliessung des PHP-Codes nichtmehr einfügen.
Das einfachste ist eigentlich einen Text auszugeben. Das funktioniert folgendermassen:
echo "Mein Text";
So erscheint auf der Website der Text "Mein Text".
Als Nächstes kann man Variablen verwenden. Sie sind sehr einfach zu verwenden und müssen nicht direkt deklariert, sondern können direkt verwendet werden. Eine Variabel wird immer mit einem $ davor verwendet. Hier ein Beispiel:
$variabel1 = "Mein Text";
echo $variabel1
Das Ergebnis ist dasselbe wie beim oberen Beispiel, jedoch wird es über eine Variabel gemacht.
Die Verbindung auf den SQL-Server war einer der wichtigsten Punkte in unserem Projekt. Und so wird es gemacht:
$link = mysql_connect("host", "user", "password") or die ("Keine Verbindung möglich");
Damit wird versucht auf den MySQL-Server zuzugreifen. Mit "or die" kann man sagen, was passieren soll, wenn die Verbindung nicht aufgebaut werden kann. Hier wird "Keine Verbindung möglich" ausgegeben.
Anschliessend muss man noch die Datenbank auswählen, auf welche man zugreifen möchte:
mysql_select_db("filme") or die ("Die Datenbank existiert nicht");
Wird die angegebene Datenbank, hier "filme", nicht gefunden wird wieder durch "or die" eine Meldung ausgegeben. Hier: "Die Datenbank existiert nicht"
Das ganze könnte man natürlich auch ohne "or die" machen, ich denke jedoch es ist nützlich wenn man eine kurze Meldung ausgibt, weshalb es nicht funktioniert.
Um an den Inhalt der Datenbank zu gelangen, muss man das Select-Statement verwenden:
$Abfrage = "SELECT * FROM film WHERE titel = 'Avatar' ";
Das übergibt der Variabel Abfrage das Select-Statement. In unserer Datenbank "filme" gibt es eine Tabelle namens "film", diese wird hier ausgewählt. Es werden alle Einträge heraus genommen, in denen im Datenfeld "titel" "Avatar" steht. Bei uns gibt es natürlich nur einen Eintrag mit diesem Namen und daher konnten wir ihn so identifizieren.
Der Inhalt aus der Datenbank ist jedoch immer noch nicht geholt. Die Variabel hat nur das Statement gespeichert, es wurde noch nicht ausgeführt. Dazu benutzen wir folgendes:
$res = mysql_query($Abfrage);
$row = mysql_fetch_assoc($res);
Der mysql-query Befehl gibt bei erfolgreichem ausführen einen Ereignis-Handler zurück. Mit diesem kann man auf die zurückgegebenen Datensätze zugreifen.
Mit dem mysql_fetch_assoc Befehl wird der Ereignis-Handler an die row Variabel übergeben und man kann die Feldnamen als Schlüssel verwenden.
Unsere Tabelle hat 3 Spalten: "titel", "trailer" und "inhalt".
Nun konnte ich auf den Inhalt des geholten Datensatzes zugreifen. Mit folgendem Code gebe ich den Inhalt des Trailer-Feldes aus:
echo $row['trailer'];
So konnte ich dann auf alle Informationen aus der Datenbank zugreifen und das Projekt realisieren.
Zum Schluss gibt es noch unser Design, welches nicht ich erstellt habe:

Dienstag, 14. September 2010
September 2010 / C#
C#
In der Firma habe ich an einigen Projekten gearbeitet und andere kleinere Aufgaben gelöst.
Leider hatte ich nichts grosses, oder etwas worüber ich hier noch nie geschrieben hätte. Deshalb schreibe ich wieder über C# da sich meine Kenntnisse in diesem Bereich stetig verbessern.
Die Split-Funktion:
Damit ich Strings in mehrere kleinere Teile unterteilen kann gibt es die Split-Funktion. Sie funktioniert Folgendermassen:
In der Firma habe ich an einigen Projekten gearbeitet und andere kleinere Aufgaben gelöst.
Leider hatte ich nichts grosses, oder etwas worüber ich hier noch nie geschrieben hätte. Deshalb schreibe ich wieder über C# da sich meine Kenntnisse in diesem Bereich stetig verbessern.
Sinn und Zweck des Auftrags:
Ich bekam den Auftrag ein Programm zu entwickeln, welches Daten aus bestimmten .csv-Files lesen, zusammenfügen und geordnet abspeichern kann. Die Files haben immer 2 Spalten. In der 1. Spalte befinden sich Zeitstempel und in der 2. Werte dazu. Mein Programm musste die Zeitstempel und Werte des "Hauptfiles" und die Werte aller im selben Ordner gespeicherten .csv-Files nehmen, zusammenfügen und abspeichern. Wo die .csv-Files liegen, welches das "Hauptfile" ist und wo und mit welchem Namen die Fertige Datei gespeichert werden soll, wird mit Hilfe von Start-Parametern mitgeteilt.
Hier sehen Sie 3 Bilder der .csv-Files. Das 1. (Value1) ist das Hauptfile, die anderen 2 befinden sich im selben Ordner.
Aus diesen 3 Files sollte nun folgendes Entstehen:
Wie man sieht haben die 3 Dateien nicht gleich viele Zeilen. Daher passen sich alle Files dem Masterfile an. Wenn eine Datei zu viele Zeilen hat, werden die überflüssigen gelöscht. Hat eine Datei zu wenig, werden in den restlichen Zeilen leere Einträge eingefügt. Auch die 1. Zeile wird vom Masterfile genommen. Allerdings sollten alle Dateien die gleichen Zeitstempel haben, ansonsten würde es keinen Sinn ergeben sie zusammenzufügen.
Ich erarbeitete mir 2 verschiedene Versionen.
Die erste entwickelte ich ohne fremde Hilfe.
Ich hatte jedoch ein Problem: Man kann nicht gleichzeitig Daten aus einem File lesen und es mit anderen Daten beschreiben. Meine Lösung las jedoch jede Datei einzeln und speicherte die gelesenen Informationen gleich Zeile für Zeile in ein .csv-File. Es gibt keine Funktion mit der ich einfach etwas ans Ende einer Zeile schreiben könnte, wie ich es gebraucht hätte, oder diese hätte ich zumindest nicht gefunden. Daher musste ich die Datei immer auslesen und gleichzeitig wieder beschreiben.
Die einzige Lösung welche mir einfiel war, die Datei nach jedem Beschrieb zu kopieren um so die Daten aus der Kopierten Datei lesen und die Originaldatei beschreiben zu können. Schlussendlich wäre die kopierte Datei gelöscht worden und alles hätte funktioniert.
Jedoch verlangsamt diesen vermehrten Dateizugriff das Programm stark und der Mitarbeiter, welcher mir den Auftrag gab war damit natürlich nicht einverstanden. Das war mir eigentlich bereits klar, jedoch viel mir keine bessere Lösung ein.
Mithilfe der Tipps des Mitarbeiters erstellte ich dann meine 2. Lösung.
Sie nutzt Listen um die Daten auszulesen und zu speichern. Zuerst wird für jede Datei eine Liste erstellt und mit den Daten abgefüllt. Anschliessend werden diese Dateien noch in einer Liste abgespeichert. So kann ich dann auf die einzelnen Einträge der Listen zugreifen und das .csv-File so beschreiben.
Code des Auftrags:
Damit man auch etwas lernt, hier noch die verwendeten Funktionen:
Der Zugriff auf die Startparameter erfolgt so:
string[] args; //damit wird args als String mit mehrere Einträgen definiert
args = Enviroment.GetCommandLineArgs(); // damit werden die Startparameter übergeben.
Die einzelnen Parameter kann ich nun mit args[1] auslesen. Die Zahl dient zur Auswahl, welchen Parameter man verwenden möchte.
Die Foreach-Schleife:
Damit ich auf jedes File im Ordner zugreifen konnte, unabhängig davon wie viele Dateien sich im Ordner befinden verwendete ich eine Foreach-Schleife. So wird sie verwendet:
DirectoryInfo variabel1 = new DirectoryInfo(Pfad); // damit weise ich der variabel1 ein Verzeichnis zu.
Mit der nächsten Zeile werden alle Befehle welche in der Foreach-Schleife vorhanden sind auf alle .csv Dateien aus dem Verzeichnis ausgeführt.
foreach (FileInfo "variabel2" in "variabel1.GetFiles("*.csv")) { Befehle; }
Das "*.csv" definiert, dass alle Dateien die am ende .csv haben in die Schlaufe genommen werden sollen. Das * steht für eine beliebige Anzahl Zeichen.
Ich erarbeitete mir 2 verschiedene Versionen.
Die erste entwickelte ich ohne fremde Hilfe.
Ich hatte jedoch ein Problem: Man kann nicht gleichzeitig Daten aus einem File lesen und es mit anderen Daten beschreiben. Meine Lösung las jedoch jede Datei einzeln und speicherte die gelesenen Informationen gleich Zeile für Zeile in ein .csv-File. Es gibt keine Funktion mit der ich einfach etwas ans Ende einer Zeile schreiben könnte, wie ich es gebraucht hätte, oder diese hätte ich zumindest nicht gefunden. Daher musste ich die Datei immer auslesen und gleichzeitig wieder beschreiben.
Die einzige Lösung welche mir einfiel war, die Datei nach jedem Beschrieb zu kopieren um so die Daten aus der Kopierten Datei lesen und die Originaldatei beschreiben zu können. Schlussendlich wäre die kopierte Datei gelöscht worden und alles hätte funktioniert.
Jedoch verlangsamt diesen vermehrten Dateizugriff das Programm stark und der Mitarbeiter, welcher mir den Auftrag gab war damit natürlich nicht einverstanden. Das war mir eigentlich bereits klar, jedoch viel mir keine bessere Lösung ein.
Mithilfe der Tipps des Mitarbeiters erstellte ich dann meine 2. Lösung.
Sie nutzt Listen um die Daten auszulesen und zu speichern. Zuerst wird für jede Datei eine Liste erstellt und mit den Daten abgefüllt. Anschliessend werden diese Dateien noch in einer Liste abgespeichert. So kann ich dann auf die einzelnen Einträge der Listen zugreifen und das .csv-File so beschreiben.
Code des Auftrags:
Damit man auch etwas lernt, hier noch die verwendeten Funktionen:
Der Zugriff auf die Startparameter erfolgt so:
string[] args; //damit wird args als String mit mehrere Einträgen definiert
args = Enviroment.GetCommandLineArgs(); // damit werden die Startparameter übergeben.
Die einzelnen Parameter kann ich nun mit args[1] auslesen. Die Zahl dient zur Auswahl, welchen Parameter man verwenden möchte.
Die Foreach-Schleife:
Damit ich auf jedes File im Ordner zugreifen konnte, unabhängig davon wie viele Dateien sich im Ordner befinden verwendete ich eine Foreach-Schleife. So wird sie verwendet:
DirectoryInfo variabel1 = new DirectoryInfo(Pfad); // damit weise ich der variabel1 ein Verzeichnis zu.
Mit der nächsten Zeile werden alle Befehle welche in der Foreach-Schleife vorhanden sind auf alle .csv Dateien aus dem Verzeichnis ausgeführt.
foreach (FileInfo "variabel2" in "variabel1.GetFiles("*.csv")) { Befehle; }
Das "*.csv" definiert, dass alle Dateien die am ende .csv haben in die Schlaufe genommen werden sollen. Das * steht für eine beliebige Anzahl Zeichen.
Die Split-Funktion:
Damit ich Strings in mehrere kleinere Teile unterteilen kann gibt es die Split-Funktion. Sie funktioniert Folgendermassen:
Man muss eine Variabel, hier variabel1, aufteilen. Wo genau diese aufgeteilt wird, kann man mit dem Parameter, hier ':', übergeben. Dann muss man das ganze einer anderen Variabel zuweisen, hier variabel2:
variabel2 = variabel1.Split(':');
Die Variabel1 wird hier bei allen : aufgeteilt. Wäre in variabel1 also folgender Satz gespeichert gewesen: "Hier ist die Lösung:2" wäre in Variabel2 nun folgendes gespeichert:
variabel2[0] = Hier ist die Lösung
variabel2[1] = 2
Zu beachten ist hier noch, dass die variabel2 folgendermassen deklariert werden muss:
string[] variabel2; // So kann ich wie beim Args mehrere Einträge definieren.
variabel2 = variabel1.Split(':');
Die Variabel1 wird hier bei allen : aufgeteilt. Wäre in variabel1 also folgender Satz gespeichert gewesen: "Hier ist die Lösung:2" wäre in Variabel2 nun folgendes gespeichert:
variabel2[0] = Hier ist die Lösung
variabel2[1] = 2
Zu beachten ist hier noch, dass die variabel2 folgendermassen deklariert werden muss:
string[] variabel2; // So kann ich wie beim Args mehrere Einträge definieren.
Abonnieren
Posts (Atom)



