VI. Les fichiers texte▲
Un fichier texte est un fichier contenant des lignes de texte. Examinons la création et l'utilisation de tels fichiers sur des exemples.
VI-A. Création et utilisation▲
C:\>cscript fic1.vbs
C:\>dir
FIC1 VBS 352 07/01/02 7:07 fic1.vbs
TESTFILE TXT 25 07/01/02 7:07 testfile.txt
C:\>more testfile.txt
Ceci est un autre test.
Commentaires
- la ligne 7 crée un objet fichier de type "Scripting.FileSystemObject" par la fonction CreateObject("Scripting.FileSystemObject"). Un tel objet permet l'accès a tout fichier du système pas simplement a des fichiers texte.
- la ligne 9 crée un objet "TextStream". La création de cet objet est associée a la création du fichier testfile.txt. Ce fichier n'est pas désigne par un nom absolu du genre c:\dir1\dir2\….\testfile.txt mais par un nom relatif testfile.txt. Il sera alors crée dans le répertoire d'ou sera lancée la commande d'exécution du fichier.
- le système de fichiers du système windows n'a pas connaissance de concepts tels que fichier texte ou fichier non texte. Il ne connaît que des fichiers. C'est donc au programme qui exploite ce fichier de savoir s'il va le traiter comme un fichier texte ou non.
-
La ligne 9 crée un objet d'où la commande set utilisée pour l'affectation. La création d'un objet fichier texte passe par la création de 2 objets :
- la création d'un objet Scripting.FileSystemObject (ligne 7)
-
puis par la création d'un objet "TextStream" (fichier texte) par la méthode OpenTextFile de l'objet Scripting.FileSystemObject qui admet plusieurs paramètres :
- le nom du fichier a gérer (obligatoire)
-
le mode d'utilisation du fichier. C'est un entier avec 3 valeurs possibles :
- 1 : utilisation du fichier en lecture
- 2 : utilisation du fichier en écriture. S'il n'existe pas déjà et si le 3ième paramètre est présent et a la valeur true, il est créé sinon il n'est pas. S'il existe déjà, il est écrasé.
- 8 : utilisation du fichier en ajout, c.a.d. écriture en fin de fichier. Si le fichier n'existe pas déjà et si le 3ième paramètre est présent et a la valeur true, il est créé sinon il n'est pas.
- la ligne 11 écrit une ligne de texte avec la méthode WriteLine de l'objet TextStream crée.
- la ligne 13 "ferme" le fichier. On ne peut alors plus écrire ou lire dedans.
- la ligne 16 crée un nouvel objet "TextStream" pour exploiter le même fichier que précédemment mais cette fois-ci en mode "ajout". Les lignes qui seront écrites le seront derrière les lignes existantes.
- la ligne 18 écrit deux nouvelles lignes sachant que la constante vbCRLF est la marque de fin de ligne des fichiers texte.
- la ligne 20 ferme de nouveau le fichier
- la ligne 23 le rouvre en mode "lecture" : on va lire le contenu du fichier.
- La ligne 27 lit une ligne de texte avec la méthode ReadLine de l'objet TextStream. Lorsque le fichier vient d'être "ouvert", on est positionne sur la 1ere ligne de texte de celui-ci.Lorsque celle-ci a été lue par la méthode ReadLine, on est positionné sur la seconde ligne.
Ainsi la méthode Readline non seulement lit la ligne courante mais "avance" ensuite automatiquement a la ligne suivante. - Pour lire toutes les lignes de texte, la méthode ReadLine doit être appliquée de façon répétée dans une boucle. Celle-ci (ligne 26) se termine lorsque l'attribut AtEndOfStream de l'objet TextStream a la valeur true. Cela signifie alors qu'il n'y a plus de lignes a lire dans le fichier.
VI-B. Les cas d'erreur▲
On rencontre deux cas d'erreur fréquents :
- ouverture en lecture d'un fichier qui n'existe pas
- ouverture en écriture ou ajout d'un fichier qui n'existe pas avec le troisième paramètre a false dans l'appel a la méthode OpenTextFile.
Le programme suivant montre comment détecter ces erreurs :
' création & remplissage d'un fichier texte
Option
Explicit
Dim
objFichier,MyFile
Const
ForReading =
1
, ForWriting =
2
, ForAppending =
8
Dim
codeErreur
' on crée un objet fichier
Set
objFichier=
CreateObject
(
"Scripting.FileSystemObject"
)
' on ouvre un fichier texte devant exister en lecture
On
Error
Resume
Next
Set
MyFile=
objFichier.OpenTextFile
(
"abcd"
, ForReading)
codeErreur=
err
.number
On
Error
GoTo
0
If
codeErreur<>
0
Then
' le fichier n'existe pas
wscript.echo
"Le fichier [abcd] n'existe pas"
Else
' on ferme le fichier texte
MyFile.Close
End
If
' on ouvre un fichier texte devant exister en écriture
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
' on ferme le fichier texte
MyFile.Close
End
If
' on ouvre un fichier texte devant exister en ajout
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
' on ferme le fichier texte
MyFile.Close
End
If
' fin
wscript.quit
0
C:\>dir
FIC1 VBS 964 07/01/02 7:54 fic1.vbs
TESTFILE TXT 0 07/01/02 8:18 testfile.txt
FIC2 VBS 1 252 07/01/02 8:23 fic2.vbs
3 fichier(s) 2 216 octets
2 répertoire(s) 4 007.11 Mo libre
C:\>cscript fic2.vbs
Le fichier [abcd] n'existe pas
Le fichier [abcd] n'existe pas
Le fichier [abcd] n'existe pas
VI-C. L'application IMPOTS avec un fichier texte▲
Nous reprenons l'application de calcul de l'impôt en supposant que les données nécessaires au calcul de l'impôt sont dans un fichier texte appelé data.txt :
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
Les trois lignes contiennent respectivement les données des tableaux limites, coeffR et coeffN de l'application. Grâce à la modularisation de notre application, les modifications interviennent essentiellement dans la procédure getData chargée de construire les trois tableaux. Le nouveau programme est le suivant :
' calcul de l'impôt d'un contribuable
' le programme doit être appelé avec trois paramètres : marié enfants salaire
' marié : caractère O si marié, N si non marié
' enfants : nombre d'enfants
' salaire : salaire annuel sans les centimes
' déclaration obligatoire des variables
Option
Explicit
Dim
erreur
' on récupère les arguments en vérifiant leur validité
Dim
marie, enfants, salaire
erreur=
getArguments
(
marie,enfants,salaire)
' erreur ?
If
erreur
(
0
)<>
0
Then
wscript.echo
erreur
(
1
) : wscript.quit
erreur
(
0
)
' on récupère les données nécessaires au calcul de l'impôt
Dim
limites, coeffR, coeffN
erreur=
getData
(
limites,coeffR,coeffN)
' erreur ?
If
erreur
(
0
)<>
0
Then
wscript.echo
erreur
(
1
) : wscript.quit
5
' on affiche le résultat
wscript.echo
"impôt="
&
calculerImpot
(
marie,enfants,salaire,limites,coeffR,coeffN)
' on quitte sans erreur
wscript.quit
0
' ------------ fonctions et procédures
' ----------- getArguments
Function
getArguments
(
byref
marie, ByRef
enfants, ByRef
salaire)
' doit récupérer trois valeurs passées comme argument au programme principal
' un argument est transmis au programme sans espaces devant et derrière
' on utilisera des expression régulières pour vérifier la validité des données
' rend un variant tableau erreur à 2 valeurs
' erreur(0) : code d'erreur, 0 si pas d'erreur
' erreur(1) : message d'erreur si erreur sinon la chaîne vide
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)"
' on vérifie qu'il y a 3 arguments
Dim
nbArguments
nbArguments=
wscript.arguments.count
If
nbArguments<>
3
Then
' msg d'erreur
getArguments=
array
(
1
,syntaxe &
vbCRLF
&
vbCRLF
&
"erreur : nombre d'arguments
incorrect")
' fin
Exit
Function
End
If
Dim
modele, correspondances
Set
modele=
new
regexp
' le statut marital doit être parmi les caractères oOnN
modele.pattern
=
"^[oOnN]$"
Set
correspondances=
modele.execute
(
wscript.arguments
(
0
))
If
correspondances.count
=
0
Then
' msg d'erreur
getArguments=
array
(
2
,syntaxe &
vbCRLF
&
vbCRLF
&
"erreur : argument marie
incorrect")
' on quitte
Exit
Function
End
If
' on récupère la valeur
If
lcase
(
wscript.arguments
(
0
)) =
"o"
Then
marie=
true
Else
marie=
false
End
If
' enfants doit être un nombre entier >=0
modele.pattern
=
"^\d{1,2}$"
Set
correspondances=
modele.execute
(
wscript.arguments
(
1
))
If
correspondances.count
=
0
Then
' erreur
getArguments=
array
(
3
,syntaxe &
vbCRLF
&
vbCRLF
&
"erreur : argument enfants
incorrect")
' on quitte
Exit
Function
End
If
' on récupère la valeur
enfants=
cint
(
wscript.arguments
(
1
))
' salaire doit être un entier >=0
modele.pattern
=
"^\d{1,9}$"
Set
correspondances=
modele.execute
(
wscript.arguments
(
2
))
If
correspondances.count
=
0
Then
' erreur
getArguments=
array
(
4
,syntaxe &
vbCRLF
&
vbCRLF
&
"erreur : argument salaire
incorrect")
' on quitte
Exit
Function
End
If
' on récupère la valeur
salaire=
clng
(
wscript.arguments
(
2
))
' c'est fini sans erreur
getArguments=
array
(
0
,""
)
End
Function
' ----------- getData
Function
getData
(
byref
limites, ByRef
coeffR, ByRef
coeffN)
' les données des trois tableaux limites, coeffR, coeffN sont dans un fichier texte
' appelé data.txt. Chaque tableau occupe une ligne sous la forme val1 val2 ... valn
' on trouve dans l'ordre limites, coeffR, coeffN
' rend un variant erreur tableau à 2 éléments pour gérer l'éventuelle erreur
' erreur(0) : 0 si pas d'erreur, un nombre entier >0 sinon
' erreur(1) : le message d'erreur si erreur
Dim
objFichier,MyFile,codeErreur
Const
ForReading =
1
, dataFileName=
"data.txt"
' on crée un objet fichier
Set
objFichier=
CreateObject
(
"Scripting.FileSystemObject"
)
' on ouvre le fichier data.txt en lecture
On
Error
Resume
Next
Set
MyFile=
objFichier.OpenTextFile
(
dataFileName, ForReading)
' erreur ?
codeErreur=
err
.number
On
Error
GoTo
0
If
codeErreur<>
0
Then
' il y a eu erreur - on la note
getData=
array
(
1
,"Impossible d'ouvrir le fichier des données ["
&
dataFileName &
"]
en lecture")
' on rentre
Exit
Function
End
If
' on suppose maintenant que le contenu est correct et on ne fait aucune vérification
' on lit les 3 lignes
' limites
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
' on ferme le fichier
MyFile.close
' c'est fini sans erreur
getData=
array
(
0
,""
)
End
Function
' ----------- getDataFromLine
Sub
getDataFromLine
(
byref
ligne, ByRef
tableau)
' met dans tableau les valeurs numériques contenues dans ligne
' celles-ci sont séparées par un ou plusieurs espaces
' au départ le tableau est vide
tableau=
array
(
)
' on définit un modèle pour la ligne
Dim
modele, correspondances
Set
modele=
New
RegExP
With
modele
.pattern
=
"\d+,\d+|\d+"
' 140,5 ou 140
.global
=
true
' toutes les valeurs
End
With
' on analyse la ligne
Set
correspondances=
modele.execute
(
ligne)
Dim
i
For
i=
0
To
correspondances.count
-
1
' on redimensionne le tableau
ReDim
Preserve
tableau
(
i)
' on affecte une valeur au nouvel élément
tableau
(
i)=
cdbl
(
correspondances
(
i).value
)
Next
'fin
End
Sub
' ----------- calculerImpot
Function
calculerImpot
(
byval
marie,ByVal
enfants,ByVal
salaire, ByRef
limites, ByRef
coeffR, ByRef
coeffN)
' on calcule le nombre de parts
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
' on calcule le quotient familial et le revenu imposable
Dim
revenu, qf
revenu=
0
.72
*
salaire
qf=
revenu/
nbParts
' on calcule l'impôt
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
Commentaires :
- dans le fichier texte data.txt, les valeurs peuvent être séparées par un ou plusieurs espaces, d'ou l'impossibilité d'utiliser la fonction split pour récupérer les valeurs de la ligne. Il a fallu passer par une expression régulière
- la fonction getData rend, outre les trois tableaux limites, coeffR, coeffN, un résultat indiquant s'il y a eu erreur ou non. Ce résultat est un variant tableau de eux éléments. Le premier élément est un code d'erreur (0 si pas d'erreur), le second le message d'erreur s'il y a eu erreur.
- la fonction getData ne teste pas la validité des valeurs trouvées dans le fichier data.txt. En situation réelle, elle devrait le faire.