6. Textdateien
Eine Textdatei ist eine Datei, die Textzeilen enthält. Betrachten wir die Erstellung und Verwendung solcher Dateien anhand von Beispielen.
6.1. Erstellung und Verwendung
Programm |
![]() |
Ergebnisse |
Kommentare
- In Zeile 7 wird mit der Funktion CreateObject("Scripting.FileSystemObject") ein Dateiobjekt vom Typ „Scripting.FileSystemObject“ erstellt. Ein solches Objekt ermöglicht den Zugriff auf alle Dateien im System, nicht nur auf Textdateien.
- In Zeile 9 wird ein Objekt „TextStream“ erstellt. Die Erstellung dieses Objekts ist mit der Erstellung der Datei testfile.txt verbunden. Diese Datei wird nicht durch einen absoluten Pfadnamen wie c:\dir1\dir2\....\testfile.txt bezeichnet, sondern durch einen relativen Pfadnamen testfile.txt. Sie wird dann in dem Verzeichnis erstellt, von dem aus der Befehl zur Ausführung der Datei gestartet wird.
- Das Dateisystem von Windows kennt keine Konzepte wie Textdatei oder Nicht-Textdatei. Es kennt nur Dateien. Es ist daher Aufgabe des Programms, das diese Datei verarbeitet, zu entscheiden, ob es sie als Textdatei behandelt oder nicht.
- In Zeile 9 wird ein Objekt erstellt, aus dem der Befehl set für die Zuweisung stammt. Die Erstellung eines Textdateiobjekts erfolgt über die Erstellung von zwei Objekten:
- die Erstellung eines Objekts Scripting.FileSystemObject (Zeile 7)
- und anschließend die Erstellung eines Objekts „TextStream“ (Textdatei) über die Methode OpenTextFile des Objekts Scripting.FileSystemObject, die mehrere Parameter akzeptiert:
- den Namen der zu bearbeitenden Datei (obligatorisch)
- den Verwendungsmodus der Datei. Dabei handelt es sich um eine Ganzzahl mit drei möglichen Werten:
- 1: Datei im Lesemodus verwenden
- 2: Die Datei wird zum Schreiben verwendet. Wenn sie noch nicht existiert und der dritte Parameter vorhanden ist und den Wert „true“ hat, wird sie angelegt, andernfalls nicht. Wenn sie bereits existiert, wird sie überschrieben.
- 8: Datei im Anfüge-Modus verwenden, c.a.d. Schreiben am Ende der Datei. Wenn die Datei noch nicht existiert und der dritte Parameter vorhanden ist und den Wert „true“ hat, wird sie angelegt, andernfalls nicht.
- Zeile 11 schreibt eine Textzeile mit der Methode „WriteLine“ des erstellten Objekts „TextStream“.
- Zeile 13 „schließt“ die Datei. Es kann dann nicht mehr in sie geschrieben oder aus ihr gelesen werden.
- In Zeile 16 wird ein neues Objekt „TextStream“ erstellt, um dieselbe Datei wie zuvor zu bearbeiten, diesmal jedoch im Modus „Hinzufügen“. Die neuen Zeilen werden hinter den bestehenden Zeilen geschrieben.
- Zeile 18 schreibt zwei neue Zeilen, wobei die Konstante vbCRLF das Zeilenendezeichen für Textdateien darstellt.
- Zeile 20 schließt die Datei wieder.
- Zeile 23 öffnet sie erneut im Modus „Lesen“: Der Inhalt der Datei wird gelesen.
- Zeile 27 liest eine Textzeile mit der Methode ReadLine des Objekts TextStream. Wenn die Datei gerade „geöffnet“ wurde, befindet sich der Cursor auf der ersten Textzeile der Datei. Nachdem diese mit der Methode ReadLine gelesen wurde, befindet sich der Cursor auf der zweiten Zeile. Somit liest die Methode Readline nicht nur die aktuelle Zeile, sondern „springt“ anschließend automatisch zur nächsten Zeile.
- Um alle Textzeilen zu verarbeiten, muss die Methode ReadLine in einer Schleife wiederholt angewendet werden. Diese Schleife (Zeile 26) endet, wenn das Attribut AtEndOfStream des Objekts TextStream den Wert true annimmt. Dies bedeutet dann, dass keine Zeilen mehr aus der Datei gelesen werden können.
6.2. Fehlerfälle
Es treten zwei häufige Fehlerfälle auf:
- Öffnen einer nicht vorhandenen Datei zum Lesen
- das Öffnen zum Schreiben oder das Hinzufügen einer nicht vorhandenen Datei, wobei der dritte Parameter beim Aufruf der Methode OpenTextFile auf „false“ gesetzt ist.
Das folgende Programm zeigt, wie diese Fehler erkannt werden können:
Programm
' Erstellung und Ausfüllen einer Textdatei
Option Explicit
Dim objFichier,MyFile
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Dim codeErreur
' Es wird ein Dateiobjekt angelegt
Set objFichier=CreateObject("Scripting.FileSystemObject")
' Eine bereits vorhandene Textdatei wird im Lesemodus geöffnet
On Error Resume Next
Set MyFile= objFichier.OpenTextFile("abcd", ForReading)
codeErreur=err.number
On Error GoTo 0
If codeErreur<>0 Then
' Die Datei existiert nicht
wscript.echo "Le fichier [abcd] n'existe pas"
Else
' Die Textdatei wird geschlossen
MyFile.Close
End If
' Eine bereits vorhandene Textdatei wird zum Schreiben geöffnet
On Error Resume Next
Set MyFile= objFichier.OpenTextFile("abcd", ForWriting, False)
codeErreur=err.number
On Error GoTo 0
If codeErreur<>0 Then
wscript.echo "Le fichier [abcd] n'existe pas"
Else
' Die Textdatei wird geschlossen
MyFile.Close
End If
' Eine Textdatei wird im Modus „Hinzufügen“ geöffnet, die bereits vorhanden sein muss
On Error Resume Next
Set MyFile= objFichier.OpenTextFile("abcd", ForAppending, False)
codeErreur=err.number
On Error GoTo 0
If codeErreur<>0 Then
wscript.echo "Le fichier [abcd] n'existe pas"
Else
' Die Textdatei wird geschlossen
MyFile.Close
End If
' Ende
wscript.quit 0
Ergebnisse
6.3. Die Anwendung IMPOTS mit einer Textdatei
Wir greifen die Anwendung zur Steuerberechnung wieder auf und gehen davon aus, dass sich die für die Steuerberechnung erforderlichen Daten in einer Textdatei namens data.txt befinden:
12620 13190 15640 24740 31810 39970 48360 55790 92970 127860 151250 172040 195000 0
0 0,05 0,1 0,15 0,2 0,25 0,3 0,35 0,4 0,45 0,5 0,55 0,6 0,65
0 631 1290,5 2072,5 3309,5 4900 6898,5 9316,5 12106 16754,5 23147,5 30710 39312 49062
Die drei Zeilen enthalten jeweils die Daten der Grenztabellen coeffR und coeffN der Anwendung. Dank der Modularisierung unserer Anwendung erfolgen die Änderungen im Wesentlichen in der Prozedur getData, die für die Erstellung der drei Tabellen zuständig ist. Das neue Programm lautet wie folgt:
Programm
' Berechnung der Steuer eines Steuerpflichtigen
' Das Programm muss mit drei Parametern aufgerufen werden: verheiratet, Kinder, Gehalt
' verheiratet: Zeichen O, wenn verheiratet, N, wenn unverheiratet
' Kinder: Anzahl der Kinder
' Gehalt: Jahresgehalt ohne Cent
' obligatorische Variablendeklaration
Option Explicit
Dim erreur
' Die Argumente werden abgerufen und auf ihre Gültigkeit überprüft
Dim marie, enfants, salaire
erreur=getArguments(marie,enfants,salaire)
' Fehler?
If erreur(0)<>0 Then wscript.echo erreur(1) : wscript.quit erreur(0)
' Die für die Steuerberechnung erforderlichen Daten werden abgerufen
Dim limites, coeffR, coeffN
erreur=getData(limites,coeffR,coeffN)
' Fehler?
If erreur(0)<>0 Then wscript.echo erreur(1) : wscript.quit 5
' Das Ergebnis wird angezeigt
wscript.echo "impôt=" & calculerImpot(marie,enfants,salaire,limites,coeffR,coeffN)
' Beenden ohne Fehler
wscript.quit 0
' ------------ Funktionen und Prozeduren
' ----------- getArguments
Function getArguments(byref marie, ByRef enfants, ByRef salaire)
' muss drei Werte abrufen, die als Argumente an das Hauptprogramm übergeben wurden
' Ein Argument wird ohne Leerzeichen davor und dahinter an das Programm übergeben
' Zur Überprüfung der Gültigkeit der Daten werden reguläre Ausdrücke verwendet
' gibt eine Fehler-Array-Variant mit zwei Werten zurück
' Fehler(0): Fehlercode, 0, wenn kein Fehler vorliegt
' Fehler(1): Fehlermeldung, falls ein Fehler vorliegt, andernfalls eine leere Zeichenkette
Dim syntaxe
syntaxe= _
"Syntaxe : pg marié enfants salaire" & vbCRLF & _
"marié : caractère O si marié, N si non marié" & vbCRLF & _
"enfants : nombre d'enfants (entier >=0)" & vbCRLF & _
"salaire : salaire annuel sans les centimes (entier >=0)"
' Es wird überprüft, ob 3 Argumente vorhanden sind
Dim nbArguments
nbArguments=wscript.arguments.count
If nbArguments<>3 Then
' Fehlermeldung
getArguments= array(1,syntaxe & vbCRLF & vbCRLF & "erreur : nombre d'arguments incorrect")
' Ende
Exit Function
End If
Dim modele, correspondances
Set modele=new regexp
' Der Familienstand muss aus den Zeichen oOnN bestehen
modele.pattern="^[oOnN]$"
Set correspondances=modele.execute(wscript.arguments(0))
If correspondances.count=0 Then
' Fehlermeldung
getArguments=array(2,syntaxe & vbCRLF & vbCRLF & "erreur : argument marie incorrect")
' Beenden
Exit Function
End If
' Wert abrufen
If lcase(wscript.arguments(0)) = "o"Then
marie=true
Else
marie=false
End If
' „Kinder“ muss eine ganze Zahl >= 0 sein
modele.pattern="^\d{1,2}$"
Set correspondances=modele.execute(wscript.arguments(1))
If correspondances.count=0 Then
' Fehler
getArguments= array(3,syntaxe & vbCRLF & vbCRLF & "erreur : argument enfants incorrect")
' Beenden
Exit Function
End If
' Wert wird abgerufen
enfants=cint(wscript.arguments(1))
' Das Gehalt muss eine ganze Zahl >= 0 sein
modele.pattern="^\d{1,9}$"
Set correspondances=modele.execute(wscript.arguments(2))
If correspondances.count=0 Then
' Fehler
getArguments= array(4,syntaxe & vbCRLF & vbCRLF & "erreur : argument salaire incorrect")
' Beenden
Exit Function
End If
' Wert wird abgerufen
salaire=clng(wscript.arguments(2))
' Der Vorgang wurde ohne Fehler abgeschlossen
getArguments=array(0,"")
End Function
' ----------- getData
Function getData(byref limites, ByRef coeffR, ByRef coeffN)
' Die Daten der drei Grenzwerttabellen coeffR und coeffN befinden sich in einer Textdatei
' mit dem Namen data.txt. Jedes Array nimmt eine Zeile in der Form val1 val2 ... valn ein
' finden sich in der Reihenfolge die Grenzwerte coeffR und coeffN
' gibt eine Fehlervariante mit zwei Elementen zurück, um einen möglichen Fehler zu behandeln
' Fehler(0): 0, wenn kein Fehler vorliegt, andernfalls eine ganze Zahl > 0
' Fehler(1): die Fehlermeldung, falls ein Fehler vorliegt
Dim objFichier,MyFile,codeErreur
Const ForReading = 1, dataFileName="data.txt"
' Es wird ein Dateiobjekt erstellt
Set objFichier=CreateObject("Scripting.FileSystemObject")
' Die Datei data.txt wird zum Lesen geöffnet
On Error Resume Next
Set MyFile= objFichier.OpenTextFile(dataFileName, ForReading)
' Fehler?
codeErreur=err.number
On Error GoTo 0
If codeErreur<>0 Then
' Es ist ein Fehler aufgetreten – wird vermerkt
getData=array(1,"Impossible d'ouvrir le fichier des données [" & dataFileName & "] en lecture")
' Eingabe
Exit Function
End If
' Es wird nun davon ausgegangen, dass der Inhalt korrekt ist, und es wird keine Überprüfung durchgeführt
' Die drei Zeilen werden gelesen
' Grenzwerte
Dim ligne, i
ligne=MyFile.ReadLine
getDataFromLine ligne,limites
' coeffR
ligne=MyFile.ReadLine
getDataFromLine ligne,coeffR
' coeffN
ligne=MyFile.ReadLine
coeffN=split(ligne," ")
getDataFromLine ligne,coeffN
' Die Datei wird geschlossen
MyFile.close
' Fertig, ohne Fehler
getData=array(0,"")
End Function
' ----------- getDataFromLine
Sub getDataFromLine(byref ligne, ByRef tableau)
' Die in der Zeile enthaltenen numerischen Werte werden in eine Tabelle übertragen
' Diese sind durch ein oder mehrere Leerzeichen getrennt
' Zu Beginn ist das Array leer
tableau=array()
' Es wird ein Muster für die Zeile definiert
Dim modele, correspondances
Set modele= New RegExP
With modele
.pattern="\d+,\d+|\d+" ' 140,5 ou 140
.global=true ' toutes les valeurs
End With
' die Zeile wird analysiert
Set correspondances=modele.execute(ligne)
Dim i
For i=0 To correspondances.count-1
' Das Array wird in der Größe angepasst
ReDim Preserve tableau(i)
' dem neuen Element wird ein Wert zugewiesen
tableau(i)=cdbl(correspondances(i).value)
Next
'Ende
End Sub
' ----------- calculerImpot
Function calculerImpot(byval marie,ByVal enfants,ByVal salaire, ByRef limites, ByRef coeffR, ByRef coeffN)
' Die Anzahl der Anteile wird berechnet
Dim nbParts
If marie=true Then
nbParts=(enfants/2)+2
Else
nbParts=(enfants/2)+1
End If
If enfants>=3 Then nbParts=nbParts+0.5
' Der Familienquotient und das zu versteuernde Einkommen werden berechnet
Dim revenu, qf
revenu=0.72*salaire
qf=revenu/nbParts
' die Steuer wird berechnet
Dim i, impot
i=0
Do While i<ubound(limites) And qf>limites(i)
i=i+1
Loop
calculerImpot=int(revenu*coeffr(i)-nbParts*coeffn(i))
End Function
Anmerkungen:
- In der Textdatei data.txt können die Werte durch ein oder mehrere Leerzeichen getrennt sein, weshalb die Funktion „split“ nicht verwendet werden kann, um die Werte der Zeile zu extrahieren. Daher musste ein regulärer Ausdruck verwendet werden
- Die Funktion getData liefert neben den drei Grenzwert-Arrays coeffR und coeffN ein Ergebnis, das angibt, ob ein Fehler aufgetreten ist oder nicht. Dieses Ergebnis ist ein Array-Variant mit zwei Elementen. Das erste Element ist ein Fehlercode (0, wenn kein Fehler vorliegt), das zweite die Fehlermeldung, falls ein Fehler aufgetreten ist.
- Die Funktion getData prüft nicht die Gültigkeit der in der Datei data.txt gefundenen Werte. In der Praxis sollte sie dies jedoch tun.
