Skip to content

6. Archivos de texto

Un fichero de texto es un fichero 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 utilización

Programa
Resultados
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.

Comentarios

  • la línea 7 crea un objeto archivo de tipo "Scripting.FileSystemObject"por la función CreateObject("Scripting.FileSystemObject"). Un objeto de este tipo permite acceder a cualquier archivo del sistema, no sólo a archivos de texto.
  • la línea 9 crea un "TextStream". La creación de este objeto está asociada a la creación del fichero testfile.txt. Este archivo no se designa con un nombre absoluto como c:\dir1\dir2\....\testfile.txt sino por un sustantivo relativo testfile.txt. A continuación, se creará en el directorio desde el que se emitirá la orden para ejecutar el archivo.
  • el sistema de archivos del sistema windows no conoce conceptos como archivos de texto o archivos que no son de texto. Sólo conoce los archivos. Por lo tanto, depende del que utiliza este archivo para saber si lo tratará como un archivo de texto o no.
  • La línea 9 crea un objeto, de ahí el comando configure utilizado para la asignación. La creación de un objeto de archivo de texto implica la creación de 2 objetos:
    • crear un objeto Scripting.FileSystemObject (línea 7)
    • creando un "TextStream" (archivo de texto) utilizando el OpenTextFile el objeto Scripting.FileSystemObject que tiene varios parámetros:
      • el nombre del fichero que se va a gestionar (obligatorio)
      • cómo se utiliza el archivo. Se trata de un número entero con 3 valores posibles:
        • 1: utilizando el archivo de lectura
        • 2: utilización del fichero de escritura. Si no existe ya y si el 3er parámetro está presente y tiene el valor true, se crea, en caso contrario no. Si ya existe, se sobrescribe.
        • 8: utilizar el fichero además, c.a.d. escribir hasta el final del fichero. Si el fichero no existe ya y si el 3er parámetro está presente y tiene el valor true, se crea, en caso contrario no.
  • la línea 11 escribe una línea de texto utilizando la función WriteLine del objeto TextStream creado.
  • la línea 13 "cierra" el archivo. Ya no se podrá 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 escribirán detrás de las líneas existentes.
  • la línea 18 escribe dos nuevas líneas, teniendo en cuenta que la constante vbCRLF es el marcador de fin de línea para archivos de texto.
  • la línea 20 vuelve a cerrar el archivo
  • la línea 23 lo reabre en modo "lectura": vamos a leer el contenido del fichero.
  • La línea 27 lee una línea de texto utilizando la función ReadLine el objeto TextStream. Cuando el fichero se acaba de "abrir", se sitúa en la primera línea de texto del fichero. Cuando ésta ha sido leída por el ReadLinete posicionas en la segunda línea. Por tanto, la Línea de lectura no sólo lee la línea actual, sino que "avanza" automáticamente a la línea siguiente.
  • Para alinear todas las líneas de texto, la tecla ReadLine debe aplicarse repetidamente en un bucle. Este bucle (línea 26) termina cuando el atributo AtEndOfStream el objeto TextStream tiene el valor true. Esto significa que no hay más líneas que leer en el archivo.

6.2. Casos de error

Hay dos casos frecuentes de error:

  • apertura de lectura de un fichero que no existe
  • escribir la apertura o adición de un archivo que no existe, con el tercer parámetro establecido en false en la llamada a la función OpenTextFile.

El siguiente programa muestra cómo detectar estos errores:

Programa
' crear y rellenar un archivo de texto
Option Explicit
Dim objFichier,MyFile
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Dim codeErreur

' crear un objeto archivo
Set objFichier=CreateObject("Scripting.FileSystemObject")

' abrir un archivo de texto que debe ser legible
On Error Resume Next
Set MyFile= objFichier.OpenTextFile("abcd", ForReading)
codeErreur=err.number
On Error GoTo 0
If codeErreur<>0 Then  
    ' el fichero no existe
    wscript.echo "Le fichier [abcd] n'existe pas"
Else
    ' cerrar el archivo de texto  
    MyFile.Close
End If


' abrir un archivo de texto que debe poder escribirse
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
    ' cerrar el archivo de texto
    MyFile.Close
End If

' abrir un archivo de texto que debe existir como una 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
    ' cerrar el archivo de texto
    MyFile.Close
End If

' fin
wscript.quit 0
Resultados
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

6.3. La aplicación IMPOTS con un fichero de texto

Volvemos a la aplicación de cálculo de impuestos, suponiendo que los datos necesarios para calcular el impuesto están en un fichero 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 de límites de la aplicación, coeffR y coeffN. Gracias a la modularización de nuestra aplicación, los cambios se realizan esencialmente en la línea getData encargado de construir las tres mesas. El nuevo programa es el siguiente:

Programa
' cálculo de la deuda tributaria del contribuyente
' el programa debe llamarse con tres parámetros: salario de los hijos casados
' casado: carácter Y si está casado, N si no lo está
' hijos: número de hijos
' salario: salario anual sin céntimos

' declaración obligatoria de variables
Option Explicit
Dim erreur

' recuperar los argumentos y comprobar 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)

' recuperamos los datos necesarios para calcular los impuestos
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 error
wscript.quit 0

' ------------ funciones y procedimientos

' ----------- getArguments
Function getArguments(byref marie, ByRef enfants, ByRef salaire)
    ' debe recuperar tres valores pasados como argumentos al programa principal
    ' un argumento se pasa al programa sin espacios delante y detrás de él
    ' se utilizarán expresiones regulares para comprobar la validez de los datos

    ' devuelve una variante de 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, en caso 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)"

    ' comprobamos que hay 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 ser uno de 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")
        ' nos vamos
        Exit Function
    End If
    ' el valor
    If lcase(wscript.arguments(0)) = "o"Then
        marie=true
    Else
        marie=false
    End If

    ' children debe ser un 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")
        ' nos vamos
        Exit Function
    End If
    ' 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")
        ' nos vamos
        Exit Function
    End If
    ' el valor
    salaire=clng(wscript.arguments(2))

    ' terminado sin error
    getArguments=array(0,"")
End Function

' ----------- getData
Function getData(byref limites, ByRef coeffR, ByRef coeffN)
    ' los datos de las tres tablas de límites, coeffR, coeffN están en un fichero de texto
    ' llamado data.txt. Cada matriz ocupa una línea de la forma val1 val2 ... valn
    ' encontramos en orden límite, coeffR, coeffN

    ' devuelve una variante de error en una matriz de 2 elementos para tratar el posible error
    ' error(0): 0 si no hay error, un entero >0 en caso contrario
    ' error(1): el mensaje de error si error

    Dim objFichier,MyFile,codeErreur
    Const ForReading = 1, dataFileName="data.txt"

    ' crear un objeto archivo
    Set objFichier=CreateObject("Scripting.FileSystemObject")
    ' abrir el archivo data.txt para su lectura
    On Error Resume Next
    Set MyFile= objFichier.OpenTextFile(dataFileName, ForReading)
    ' ¿Error?
    codeErreur=err.number
    On Error GoTo 0
    If codeErreur<>0 Then
        ' ha habido un error - tomaremos nota de ello
        getData=array(1,"Impossible d'ouvrir le fichier des données [" & dataFileName & "] en lecture")
        ' estamos de vuelta
        Exit Function
    End If

    ' ahora suponemos que el contenido es correcto y no realizamos ninguna comprobación
    ' leer 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

    ' cerrar el archivo
    MyFile.close

    ' terminado sin error
    getData=array(0,"")
End Function

' ----------- getDataFromLine
Sub getDataFromLine(byref ligne, ByRef tableau)
    ' coloca los valores numéricos contenidos en la línea
    ' separadas por uno o varios espacios

    ' inicialmente la tabla está vacía
    tableau=array()
    ' definimos un modelo para la línea
    Dim modele, correspondances
    Set modele= New RegExP
    With modele
        .pattern="\d+,\d+|\d+"    ' 140,5 o 140
        .global=true              ' todos los valores
    End With

    ' analizar la línea
    Set correspondances=modele.execute(ligne)
    Dim i
    For i=0 To correspondances.count-1
        ' redimensionar la tabla
        ReDim Preserve tableau(i)
        ' asignar 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 acciones
    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

    ' calculamos la cuota 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.txten este caso, los valores pueden estar separados por uno o varios espacios, por lo que no era posible utilizar la función split para recuperar los valores de la línea. Tuvimos que utilizar una expresión regular
  • la función getData devuelve, además de las tres matrices límite, coeffR, coeffN, un resultado que indica si se ha producido o no un error. Este resultado es una matriz variante de dos elementos. El primer elemento es un código de error (0 si no ha habido error), el segundo el mensaje de error si ha habido 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.