6. Los archivos de texto
Un archivo de texto es un archivo que contiene líneas de texto. Veamos la creación y el uso de este tipo de archivos con algunos ejemplos.
6.1. Creación y uso
Programa |
![]() |
Resultados |
Comentarios
- La línea 7 crea un objeto de archivo de tipo «Scripting.FileSystemObject» mediante la función CreateObject(«Scripting.FileSystemObject»). Este tipo de objeto permite acceder a cualquier archivo del sistema, no solo a archivos de texto.
- La línea 9 crea un objeto «TextStream». La creación de este objeto está asociada a la creación del archivo testfile.txt. Este archivo no se designa con un nombre absoluto del tipo c:\dir1\dir2\....\testfile.txt, sino con un nombre relativo testfile.txt. Se creará, por tanto, en el directorio desde el que se ejecute el comando para ejecutar el archivo.
- El sistema de archivos de Windows no distingue entre conceptos como «archivo de texto» o «archivo no de texto». Solo reconoce archivos. Por lo tanto, es el programa que utiliza este archivo el que debe determinar si lo va a tratar como un archivo de texto o no.
- La línea 9 crea un objeto a partir del cual se utiliza el comando set para la asignación. La creación de un objeto de archivo de texto implica la creación de dos objetos:
- la creación de un objeto Scripting.FileSystemObject (línea 7)
- y, a continuación, la creación de un objeto «TextStream» (archivo de texto) mediante el método OpenTextFile del objeto Scripting.FileSystemObject, que admite varios parámetros:
- el nombre del archivo a gestionar (obligatorio)
- el modo de uso del archivo. Se trata de un entero con 3 valores posibles:
- 1: uso del archivo en modo lectura
- 2: uso del archivo en modo escritura. Si aún no existe y el tercer parámetro está presente y tiene el valor true, se crea; de lo contrario, no. Si ya existe, se sobrescribe.
- 8: uso del archivo en modo de adición, c.a.d. Escritura al final del archivo. Si el archivo aún no existe y el tercer parámetro está presente y tiene el valor «true», se crea; de lo contrario, no.
- La línea 11 escribe una línea de texto con el método WriteLine del objeto TextStream creado.
- La línea 13 «cierra» el archivo. A partir de ese momento, ya no se puede escribir ni leer en él.
- La línea 16 crea un nuevo objeto «TextStream» para utilizar el mismo archivo que antes, pero esta vez en modo «añadir». Las líneas que se escriban se añadirán detrás de las líneas existentes.
- La línea 18 escribe dos nuevas líneas, sabiendo que la constante vbCRLF es el marcador de fin de línea de los archivos de texto.
- La línea 20 vuelve a cerrar el archivo
- la línea 23 lo vuelve a abrir en modo «lectura»: vamos a leer el contenido del archivo.
- La línea 27 lee una línea de texto con el método ReadLine del objeto TextStream. Cuando el archivo acaba de «abrirse», nos situamos en la primera línea de texto del mismo. Una vez leída esta línea mediante el método ReadLine, nos situamos en la segunda línea. Así, el método Readline no solo lee la línea actual, sino que además «avanza» automáticamente a la siguiente línea.
- Para procesar todas las líneas de texto, el método ReadLine debe aplicarse repetidamente en un bucle. Este bucle (línea 26) finaliza cuando el atributo AtEndOfStream del objeto TextStream tiene el valor true. Esto significa que ya no hay más líneas que leer en el archivo.
6.2. Casos de error
Se dan dos casos de error frecuentes:
- apertura en lectura de un archivo que no existe
- apertura en escritura o adición de un archivo que no existe con el tercer parámetro establecido en false en la llamada al método OpenTextFile.
El siguiente programa muestra cómo detectar estos errores:
Programa
' creación y rellenado de un archivo de texto
Option Explicit
Dim objFichier,MyFile
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Dim codeErreur
' se crea un objeto de archivo
Set objFichier=CreateObject("Scripting.FileSystemObject")
' se abre un archivo de texto que debe existir en modo de lectura
On Error Resume Next
Set MyFile= objFichier.OpenTextFile("abcd", ForReading)
codeErreur=err.number
On Error GoTo 0
If codeErreur<>0 Then
' el archivo no existe
wscript.echo "Le fichier [abcd] n'existe pas"
Else
' se cierra el archivo de texto
MyFile.Close
End If
' se abre un archivo de texto que debe existir en modo de escritura
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
' se cierra el archivo de texto
MyFile.Close
End If
' se abre un archivo de texto que debe existir en modo de adición
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
' se cierra el archivo de texto
MyFile.Close
End If
' fin
wscript.quit 0
Resultados
6.3. La aplicación IMPOTS con un archivo de texto
Retomamos la aplicación de cálculo de impuestos suponiendo que los datos necesarios para el cálculo se encuentran en un archivo de texto llamado 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
Las tres líneas contienen, respectivamente, los datos de las tablas límite coeffR y coeffN de la aplicación. Gracias a la modularización de nuestra aplicación, las modificaciones se producen principalmente en el procedimiento getData, encargado de construir las tres tablas. El nuevo programa es el siguiente:
Programa
' cálculo del impuesto de un contribuyente
' el programa debe ejecutarse con tres parámetros: casado, hijos, salario
' casado: carácter O si está casado, N si no lo está
' hijos: número de hijos
' salario: salario anual sin céntimos
' declaración obligatoria de las variables
Option Explicit
Dim erreur
' se recuperan los argumentos comprobando su validez
Dim marie, enfants, salaire
erreur=getArguments(marie,enfants,salaire)
' ¿Error?
If erreur(0)<>0 Then wscript.echo erreur(1) : wscript.quit erreur(0)
' se recuperan los datos necesarios para el cálculo del impuesto
Dim limites, coeffR, coeffN
erreur=getData(limites,coeffR,coeffN)
' ¿Error?
If erreur(0)<>0 Then wscript.echo erreur(1) : wscript.quit 5
' se muestra el resultado
wscript.echo "impôt=" & calculerImpot(marie,enfants,salaire,limites,coeffR,coeffN)
' salimos sin errores
wscript.quit 0
' ------------ funciones y procedimientos
' ----------- getArguments
Function getArguments(byref marie, ByRef enfants, ByRef salaire)
' debe recuperar tres valores pasados como argumento al programa principal
' un argumento se transmite al programa sin espacios delante ni detrás
' se utilizarán expresiones regulares para verificar la validez de los datos
' devuelve una variable de tipo matriz de error con 2 valores
' error(0): código de error, 0 si no hay error
' error(1): mensaje de error si hay error; de lo contrario, cadena vacía
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)"
' se comprueba que haya 3 argumentos
Dim nbArguments
nbArguments=wscript.arguments.count
If nbArguments<>3 Then
' mensaje de error
getArguments= array(1,syntaxe & vbCRLF & vbCRLF & "erreur : nombre d'arguments incorrect")
' fin
Exit Function
End If
Dim modele, correspondances
Set modele=new regexp
' el estado civil debe estar entre los caracteres oOnN
modele.pattern="^[oOnN]$"
Set correspondances=modele.execute(wscript.arguments(0))
If correspondances.count=0 Then
' mensaje de error
getArguments=array(2,syntaxe & vbCRLF & vbCRLF & "erreur : argument marie incorrect")
' salimos
Exit Function
End If
' se recupera el valor
If lcase(wscript.arguments(0)) = "o"Then
marie=true
Else
marie=false
End If
' hijos debe ser un número entero >=0
modele.pattern="^\d{1,2}$"
Set correspondances=modele.execute(wscript.arguments(1))
If correspondances.count=0 Then
' error
getArguments= array(3,syntaxe & vbCRLF & vbCRLF & "erreur : argument enfants incorrect")
' salir
Exit Function
End If
' se recupera el valor
enfants=cint(wscript.arguments(1))
' el salario debe ser un número entero >=0
modele.pattern="^\d{1,9}$"
Set correspondances=modele.execute(wscript.arguments(2))
If correspondances.count=0 Then
' error
getArguments= array(4,syntaxe & vbCRLF & vbCRLF & "erreur : argument salaire incorrect")
' salir
Exit Function
End If
' se recupera el valor
salaire=clng(wscript.arguments(2))
' se ha completado sin errores
getArguments=array(0,"")
End Function
' ----------- getData
Function getData(byref limites, ByRef coeffR, ByRef coeffN)
' los datos de las tres tablas límite, coeffR, coeffN, están en un archivo de texto
' llamado data.txt. Cada tabla ocupa una línea con el formato val1 val2 ... valn
' se encuentran, en orden, los límites coeffR y coeffN
' devuelve una variante de tabla de error de 2 elementos para gestionar el posible error
' error(0): 0 si no hay error, un número entero >0 en caso contrario
' error(1): el mensaje de error si hay error
Dim objFichier,MyFile,codeErreur
Const ForReading = 1, dataFileName="data.txt"
' se crea un objeto de archivo
Set objFichier=CreateObject("Scripting.FileSystemObject")
' se abre el archivo data.txt en modo lectura
On Error Resume Next
Set MyFile= objFichier.OpenTextFile(dataFileName, ForReading)
' ¿error?
codeErreur=err.number
On Error GoTo 0
If codeErreur<>0 Then
' se ha producido un error; lo anotamos
getData=array(1,"Impossible d'ouvrir le fichier des données [" & dataFileName & "] en lecture")
' se introduce
Exit Function
End If
' Ahora se da por hecho que el contenido es correcto y no se realiza ninguna comprobación
' se leen las 3 líneas
' límites
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
' se cierra el archivo
MyFile.close
' se ha completado sin errores
getData=array(0,"")
End Function
' ----------- getDataFromLine
Sub getDataFromLine(byref ligne, ByRef tableau)
' coloca en una tabla los valores numéricos contenidos en la línea
' Estos están separados por uno o varios espacios
' al principio, la tabla está vacía
tableau=array()
' se define un modelo para la línea
Dim modele, correspondances
Set modele= New RegExP
With modele
.pattern="\d+,\d+|\d+" ' 140,5 ou 140
.global=true ' toutes les valeurs
End With
' se analiza la línea
Set correspondances=modele.execute(ligne)
Dim i
For i=0 To correspondances.count-1
' se redimensiona la tabla
ReDim Preserve tableau(i)
' se asigna un valor al nuevo elemento
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)
' se calcula el número de participaciones
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
' se calcula el coeficiente familiar y la base imponible
Dim revenu, qf
revenu=0.72*salaire
qf=revenu/nbParts
' se calcula el impuesto
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
Comentarios:
- En el archivo de texto data.txt, los valores pueden estar separados por uno o varios espacios, por lo que no es posible utilizar la función split para extraer los valores de la línea. Ha sido necesario recurrir a una expresión regular
- la función getData devuelve, además de las tres tablas límite, coeffR, coeffN, un resultado que indica si se ha producido un error o no. Este resultado es una variante de tabla de dos elementos. El primer elemento es un código de error (0 si no hay error), el segundo es el mensaje de error si se ha producido un error.
- La función getData no comprueba la validez de los valores encontrados en el archivo data.txt. En una situación real, debería hacerlo.
