Trabajar con los datos de un archivo de texto

   
 

Por Enrique Martínez Montejo

 
 

Última revisión: 11/05/2003

   
 
 
 
 
Índice  
 
1. Utilizar objetos de acceso a datos con archivos de texto  
2. El archivo de información de esquema Schema.ini  
2.1. Estructura de los archivos Schema.ini  
2.2. El formato de archivo  
    2.3 Nombres, longitud y tipos de campos  
    2.4 Juego de caracteres  
    2.5 Otras opciones de formato y conversión de tipos de datos  
    2.6 Crear un archivo Schema.ini con el Administrador de orígenes de datos ODBC  
    2.7 Ejemplos de archivos de información de esquema Schema.ini  
3. El delimitador de texto y la opción TextDelimiter  
  4. Abrir directamente un archivo de texto  
4.1. Mediante DAO mostrando los datos en un DBGrid  
4.2. Mediante ADO visualizando la información en un DataGrid  
4.3. Mediante ADO utilizando el driver de texto ODBC  
    4.4. Utilizando ASP con un origen de datos (DSN)  
5.

Vinculación de archivos de texto

 
5.1. Vincular con ADOX un archivo de texto a una base de datos Access  
5.2. Utilizar DAO para vincular un archivo de texto  
  6.

Cómo crear y eliminar una tabla de texto

 
7.

Cómo importar los datos de un archivo de texto

 
7.1. Importar los datos a una base de Access  
7.2. Importar los datos a una hoja de cálculo Excel  
7.3. Importar los datos a otro archivo de texto  
8. Cómo exportar los datos desde el propio archivo de texto  
  9.

Cómo exportar datos a un archivo de texto

 
9.1. Exportar los datos de una tabla de Access  
9.2. Exportar los datos de una hoja de cálculo Excel  
10. Añadir registros a una tabla procedentes de un archivo de texto delimitado  
    10.1. Desde la propia base de datos Access activa  
    10.2. Desde el propio archivo de texto activo  
  11. Añadir nuevos registros a nuestro archivo de texto  
    11.1. Desde un archivo de dBASE activo  
    11.2 Desde el propio archivo de texto activo  
  12. Algunos artículos útiles de Microsoft Knowledge Base  
       
       
 

1. Utilizar objetos de acceso a datos con archivos de texto

Mediante el formato Text del Método de Acceso Secuencial Indexado Instalable (IISAM) de Microsoft Jet, podemos utilizar la información contenida en un archivo de texto, tanto si los campos están delimitados por caracteres como si son de longitud fija, para abrir dichos archivos de texto, o para importar, exportar o vincular los datos desde, o hacia, otros formatos de bases de datos, aunque en éste artículo, el único formato de base de datos que se utilizará es el formato de Microsoft Access 2000, utilizando para ello las dos bibliotecas más conocidas de acceso a datos, como son Microsoft DAO 3.6 Object Library (DAO) y Microsoft ActiveX Data Object (ADO).

Antes de comenzar, quiero hacer hincapié en la necesidad de tener instalado previamente en nuestro sistema el archivo MSTEXTxx.DLL, que es el controlador ISAM de texto, a fin de evitar el error Imposible encontrar el ISAM instalable. De estar instalado, por defecto se encontrará en la carpeta System, o en la carpeta que indique el valor win32 de la clave del registro de windows HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\x.x\Engines\Text, siendo x.x la versión correspondiente al motor Microsoft Jet que esté disponible en nuestro sistema. Por tanto, si al instalar Visual Basic no se instaló dicho controlador, ejecute de nuevo el programa de instalación y seleccione los controladores ISAM apropiados para proceder a su instalación. Si piensa utilizar la biblioteca de ADO, tenga en cuenta que la versión del proveedor necesaria que hay que utilizar es la versión del proveedor Jet 4.0; el proveedor Jet 3.51 no soporta los drivers ISAM de Jet. Para descargar las distintas versiones de los componentes de acceso a datos de Microsoft (MDAC), visite la siguiente dirección: http://www.microsoft.com/data.

En cuanto a la forma en que el motor Microsoft Jet reconoce los valores nulos, hay que tener en cuenta lo siguiente:

  • Datos delimitados por caracteres. Se reconocerá el valor nulo por la presencia de dos caracteres delimitadores consecutivos.
  • Datos de longitud fija. Se reconocerá dicho valor por la ausencia de datos (espacios en blanco) en la columna de datos correspondiente.

Otra cuestión importante a tener en cuenta son las limitaciones en cuanto al tamaño de las tablas y objetos de texto:

Elemento Tamaño máximo por archivo de texto
Campo 255
Nombre del campo 64 caracteres
Ancho del campo 32.766 caracteres
Tamaño del registro 65.000 bytes

Otra limitación importante que presenta el ISAM de Texto del motor Microsoft Jet, es que sólo nos permitirá añadir nuevos registros al archivo de texto, por lo que no podremos eliminar registros o actualizar los datos existentes en dicho archivo, ya que obtendremos el siguiente mensaje de error: Este ISAM no admite la actualización/eliminación de datos en una tabla vinculada. Por tanto, no podremos ejecutar los comandos DELETE o UPDATE de SQL, así como cualquier otro método de algún objeto de acceso a datos que implique ejecutar dichas acciones. Para más información, se puede consultar el siguiente artículo de la Knowledge Base: El driver de texto ODBC sólo soporta la instrucción INSERT.

A la hora de establecer una conexión con un archivo de texto, el contenido de la información necesaria para tal fin se especifica de la siguiente manera:

Elemento Información
Tipo de base de datos TEXT
Nombre de la base de datos Ruta completa de la carpeta que contiene el archivo de texto
Nombre de la tabla El nombre del archivo de texto, incluída su extensión. Si no se especifica la extensión del archivo, ésta tomará la extensión predeterminada .txt.

Por último, si tiene pensado utilizar un archivo de texto en un entorno multiusuario, váyase olvidando de tal posibilidad, porque cuando se abre un archivo de texto mediante Microsoft Jet, se tiene acceso exclusivo al archivo, y cualquier otro intento de conexión a dicho origen de datos por parte de algún otro usuario, obtendrá el correspondiente mensaje de error.

 
     
     
 

2. El archivo de información de esquema Schema.ini

Aunque el motor Microsoft Jet puede determinar el formato del archivo de texto con sólo leerlo directamente, siempre y cuando el archivo esté delimitado por el carácter predefinido en el registro de Windows, es recomendable, -y añadiría que hasta necesario-, utilizar un archivo de información de esquema si deseamos tener un control completo sobre la manera de conseguir la información contenida en un archivo de texto. De esto se encarga un archivo cuyo nombre siempre será Schema.ini, el cuál deberá de guardarse en la misma carpeta donde se encuentre el origen de datos, es decir, el archivo de texto con el que vamos a trabajar.

Dicho archivo de configuración se encarga de proporcionar al ISAM instalable la información sobre el formato general del archivo, el nombre de los campos o columnas, así como el tipo de datos que contienen, y su presencia siempre será obligatoria cuando:

  • Accedamos a datos de longitud fija.
  • El archivo de texto contenga tipos de datos DateTime, Currency o Decimal.
  • Deseamos elegir un juego de caracteres distinto al valor predeterminado existente en la configuración del registro de Windows.

Para que el lector se haga una idea de como trabaja el ISAM de Texto, comentaré que, en principio, el driver no obtiene los valores iniciales del archivo Schema.ini, sino que los obtiene directamente de los valores existentes en el registro de Windows, por tanto, se aplicará por defecto el mismo formato de archivo a todas las nuevas tablas de datos de texto que se creen. Sólo si los valores del registro son diferentes de los valores existentes en el archivo de información de esquema Schema.ini, se pasarán por alto los valores existentes en el registro, teniéndose en cuenta únicamente los valores especificados en el archivo Schema.ini para un archivo de texto en particular.

2.1. Estructura de los archivos Schema.ini

Al igual que cualquier otro archivo *.ini de configuración del sistema, el archivo Schema.ini se compone de una sección entre corchetes con el nombre del archivo de texto de origen, y de una serie de entradas cuyos valores contendrán la características de la tabla:

  • El formato del archivo.
  • Los nombres, longitud y tipos de los campos.
  • El juego de caracteres utilizado.
  • Conversiones especiales de tipos de datos.

Como se ha dicho, la primera sección del archivo de esquema siempre será el nombre del archivo de texto, el cual estará escrito entre corchetes. Si nuestro archivo de texto que contiene los datos se llama Clientes.txt, la sección del archivo de configuración será:

[Clientes.txt]

2.2. El formato del archivo

El valor Format especifica el formato del archivo de texto y su inclusión en un archivo Schema.ini, anulará la configuración existente en el Registro de Windows, para dicho archivo de texto en particular. En principio, se puede utilizar como delimitador de campos cualquier carácter, a excepción de las comillas dobles (''), aunque como se verá posteriormente al estudiar el parámetro TextDelimiter, existe la posibilidad de que se pueda utilizar también dicho valor. Los valores válidos para Format pueden ser:

Format Formato de la tabla
TabDelimited Los campos están delimitados por tabulaciones.
CSVDelimited Los campos están delimitados por comas (,).
Delimited (*) Los campos están delimitados por asteriscos. Se puede utilizar cualquier carácter, excepto las comillas dobles ('').
FixedLength Los campos del archivo son de longitud fija.

Para especificar un formato delimitado por comas, hay que escribir:

Format=CSVDelimited

Respecto al formato delimitado por comas, tengo que hacer la salvedad de que no funcionará en un sistema operativo con la configuración regional de español, ya que obtendremos el mensaje de error: El separador de campos de la especificación de archivo de texto coincide con el separador decimal o el delimitador de texto.

Esto es debido a que la configuración regional de español utiliza el signo de la coma para separar la parte entera de la fraccionaria, tanto de un valor numérico como monetario. Por tanto, tenemos tres posibilidades para evitar el citado error:

  • Modificar el carácter del símbolo decimal en la configuración regional de Windows a la hora de trabajar con los datos de un archivo de texto, de tal forma que sea distinto de la coma, no olvidando posteriormente restablecer la configuración anterior a fin de evitar problemas de interpretación con otros datos numéricos o monetarios.
  • Elegir otra configuración regional distinta a la de español que no utilice la coma como símbolo decimal (inglés, por ejemplo).
  • Debido a que se permite elegir cualquier carácter distinto de las comillas dobles, utilizar cualquier otro carácter diferente de la coma para delimitar los campos del archivo de texto, opción ésta que sería la más acertada para un usuario con una configuración regional de español. En los ejemplos del presente articulo, salvo que se indique lo contrario, se utilizará como delimitador de campos el carácter de punto y coma (;), que es el carácter por defecto del motor Jet establecido en la configuración del registro de Windows.

2.3. Nombres, longitud y tipos de campos

Hay que distinguir si el archivo de texto está delimitado por caracteres o es de longitud fija. En el primer caso, se puede especificar los nombres de los campos de dos formas:

A. Escribir los nombres de los campos en la primera línea del archivo de texto y establecer en el archivo de configuración el parámetro ColNameHeader a True. El utilizar éste parámetro anula el valor FirstRowHasNames, establecido en el Registro de Windows, sólo para éste archivo.

B. Especificar en el archivo de configuración cada campo por su número, asignándole al mismo tiempo el nombre y el tipo de datos del campo.

En el supuesto de archivos de texto de longitud fija, sólo se puede especificar cada campo de la forma expuesta en el apartado B.

Para determinar los tipos de datos que contendrán los campos se puede especificar el parámetro MaxScanRows, de ésta forma le indicamos al motor de base de datos el número de filas que debe examinar para que nos indique el tipo de campo de aquéllos. Al igual que los demás valores, el establecer éste parámetro anulará el valor existente en el registro de Windows para éste archivo en particular. El valor puede ser cualquier número; si el valor es cero (0), se examinará todo el archivo.

A continuación se muestra un ejemplo que utiliza los datos de la primera fila del archivo de texto para determinar los nombres de los campos. Asimismo, se le indica que examine el archivo completo para poder determinar los tipos de datos que contienen:

ColNameHeader = True
MaxScanRows = 0

Como se ha dicho anteriormente, la opción del número de columna Coln para la definición de los campos de la tabla, es opcional para los archivos delimitados por caracteres y obligatorio para los archivos de longitud fija. La sintaxis es la siguiente:

Coln = nombre_columna tipo [Width #]

Parámetro Descripción
nombre_columna Nombre del campo. Es importante destacar que, si el nombre del campo de la tabla original contiene espacios en blanco incrustados, éste se deberá de escribir necesariamente entre comillas dobles, y sólo en éste caso.
   
tipo Los tipos de datos pueden ser:
  Tipo de datos Microsoft Jet Tipo de datos ADO / ODBC
  Bit Bit
  Byte Byte
  Currency Currency
  DateTime Date
  Double Float
  Long Long
  Memo LongChar
  Short Integer
  Single Single
  Text Char
   
ancho La palabra Width, la cual indica que el siguiente número especifica el ancho del campo. Es opcional para los archivos delimitados por caracteres, y obligatorio para los archivos de longitud fija.
   
# Número entero que especifica el ancho del campo el cuál es obligatorio si se especifica Width.

El siguiente ejemplo define tres campos de la tabla mediante la opción del número de columna Coln, utilizando para ello los tipos de datos de Microsoft Jet:

Col1 = IdCliente Long
Col2 = Nombre Text Width 50
Col3 = "Fecha Alta" DateTime

2.4. Juego de caracteres

Para indicarle al ISAM el juego de caracteres que tiene que utilizar, en el archivo de información de esquema estableceremos la entrada CharacterSet, la cual podrá tener como valor uno de los siguientes juegos de caracteres disponibles: ANSI, OEM y Unicode. Dicho valor, anulará el existente con idéntico nombre, y para cada archivo de texto individual, en la siguiente clave del registro de Windows:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Text

En una configuración regional de español internacional, elegir el juego de caracteres ANSI permite que aparezcan las tildes ortográficas (acentos) y la letra Ñ, las cuales perfectamente pueden existir en las cadenas de caracteres de nuestro archivo de texto:

CharacterSet = ANSI

En lugar de las palabras ANSI/OEM/Unicode, también se puede utilizar los valores numéricos 850 para el juego de caracteres OEM, 1200 para Unicode, y 1252 para el de ANSI, que sería el valor predeterminado existente en el registro de Windows para una configuración regional de Español.

2.5. Otras opciones de formato y conversión de tipos de datos

En el archivo de información de esquema Schema.ini se pueden establecer otras opciones para especificar cómo se convierten o se muestran los datos cuando sean leídos por el motor de datos Microsoft Jet. Dichas opciones son sumamente importantes si queremos presentar un formato específico de fecha, formato de número negativo, número de dígitos decimales o el símbolo de la moneda, ya que, de omitir dichas entradas, se utilizarán por defecto los valores que actualmente se encuentren establecidos en la Configuración Regional del Panel de Control de Windows. A continuación se enumeran las opciones disponibles.

Opción Descripción
CurrencyDecimalSymbol Carácter único para separar la parte entera de la fraccioriaria de un valor monetario:
Ejemplo : CurrencyDecimalSymbol = ,
CurrencyDigits Valor numérico que especifica el número de digitos decimales que se utilizará para representar una cantidad monetaria:
Ejemplo: CurrencyDigits = 2
CurrencyNegFormat Uno de los siguientes valores con la representación del simbolo monetario que se haya establecido como valor en la opción CurrencySymbol:
  Valor Representación en dólares USA  
  0 -$1  
  1 -$1  
  2 $-1  
  3 $1-  
  4 (1$)  
  5 -1$  
  6 1-$  
  7 1$-  
  8 (Predeterminado) -1 $  
  9 -$ 1  
  10 1 $-  
  11 $ 1-  
  12 $ -1  
  13 1- $  
  14 ($ 1)  
  15 (1 $)  
  Ejemplo: CurrencyNegFormat = 8
CurrencyPosFormat Cualquiera de los siguiente valores:
  Valor Descripción  
  0 $1 (sin espacio de separación)  
  1 1$ (sin espacio de separación)  
  2 $ 1 (un espacio de separación)  
  3 1 $ (un espacio de separación)  
  Ejemplo: CurrencyPosFormat = 3
CurrencySymbol Indica el simbolo de moneda o texto de la misma, que se utilizará en los valores monetarios incluidos en el archivo de texto. Los españoles pueden indicar el símbolo del euro.
Ejemplo: CurrencySymbol = $
CurrencyThousandSymbol Carácter único para separar los miles de un valor monetario:
Ejemplo: CurrencyThousandSymbol = .
DateTimeFormat El formato de cadena utilizado para las fechas y horas. Necesariamente hay que especificar ésta opción si todos los campos de fecha/hora se tratan con el mismo formato. Todos los formatos de Microsoft Jet son compatibles, excepto A.M. y P.M.
Ejemplo: DateTimeFormat = dd/mm/yyyy
DecimalSymbol Carácter único para separar la parte entera de la fraccionaria de un valor numérico:
Ejemplo: DecimalSymbol = ,
NumberDigits Valor numérico que especifica el número de digitos decimales que se utilizará para representar una cantidad numérica:
Ejemplo: NumberDigits = 2
NumberLeadingZeros Valor boolean que indicará si los valores numéricos decimales menores que 1 y mayores que -1 deben contener ceros a la izquierda (TRUE) o no (FALSE).
Ejemplo: NumberLeadingZeros = TRUE

2.6. Crear un archivo Schema.ini con el Administrador de orígenes de datos ODBC

Mediante el Administrador de Orígenes de datos ODBC, incluido en el Panel de Control de Windows, podemos crear y configurar un origen de datos DSN para trabajar con los archivos de texto que tengamos en una carpeta en particular, utilizando el controlador ODBC de texto.

Para ello, creamos un nuevo DSN eligiendo el driver Microsoft Text Driver (*.txt;*.csv), mostrándose a continuación el cuadro de diálogo Configuración de ODBC de texto. Una vez aquí, escribimos el nombre del origen de datos, una pequeña descripción y desmarcamos la casilla de verificación Usar directorio actual, lo que hará que se habilite el comando Seleccionar directorio... Pulsamos sobre dicho botón y seleccionamos el directorio donde se encuentren nuestros archivos de texto que contienen los datos con los que vamos a trabajar.

Una vez seleccionado el directorio, pulsamos sobre el botón Opciones para que se nos amplíe el cuadro de diálogo de Configuración de ODBC de texto. Observaremos la lista de extensiones permitidas para los archivo de texto, teniendo la oportunidad de añadir y eliminar extensiones a las ya existentes, una vez que desmarquemos la verificación de Predeterminada(*.*).

Pulsamos sobre el botón Definir formato..., para que se nos abra el cuadro de diálogo Definir formato de texto. En este nuevo cuadro de diálogo, podemos ver una lista de todos los archivos existentes en la carpeta que cumplen con la extensión especificada.

Si seleccionamos la opción default, podremos establecer una configuración por defecto para todos los archivos de texto que estén en la carpeta seleccionada; si no hay archivos de texto, se ignorará las opciones seleccionadas. Igualmente, si seleccionamos el nombre de un archivo de texto, podemos establecer una configuración individual para dicho archivo de texto. Una vez especificadas la opciones de configuración, pulsamos sobre el botón Estimar para que surtan efecto las mismas. Si hemos especificado Encabezado nombre columna, al aceptar la configuración, inmediatamente veremos los campos, nombre y tipos de datos que conforman nuestro archivo de texto, teniendo la oportunidad de agregar, modificar y eliminar campos de dicho archivo de texto.

Una vez aceptados todos los cambios, se generará en la carpeta seleccionada, un archivo de esquema Schema.ini, con las configuraciones elegidas para cada uno de los archivos de texto que se encuentren incluidos en la carpeta.

2.7. Ejemplos de archivos de información de esquema Schema.ini

En un mismo archivo de configuración Schema.ini pueden existir varias configuraciones para importar/exportar distintos archivos de texto, siempre y cuando aquéllas estén delimitadas por sus respectivas secciones, que indicarán a su vez, los nombres de los archivos de texto con los que vamos a trabajar.

El ejemplo siguiente muestra la configuración de un archivo de ancho fijo:

[Poliza.txt]
ColNameHeader=False
Format=FixedLength
MaxScanRows=25
CharacterSet=OEM
Col1=COL1 Char Width 2
Col2=COL2 Char Width 21
Col3=COL3 Char Width 11
Col4=COL4 Integer Width 11
Col5=COL5 Single Width 7
Col6=COL6 Char Width 16
Col7=COL7 Single Width 5
Col8=COL8 Char Width 12

A continuación se muestra la configuración de un archivo delimitado:

[Clientes.txt]
ColNameHeader=True
CharacterSet=ANSI
Format=Delimited(|)
Col1=IdCliente Integer
Col2=Apellidos Char Width 30
Col3=Nombre Char Width 50
Col4=NIF Char Width 9
Col5=Domicilio Char Width 50
Col6=CodPostal Char Width 50
Col7=Localidad Char Width 50
Col8=Telefono Char Width 50
Col9=FechaNto Date
Col10=FechaAlta Date
Col11=Activo Bit
Col12=FechaBaja Date
Col13=Causa Char Width 50

Por último, un ejemplo que muestra los distintos parámetros que se pueden establecer en el archivo de esquema Schema.ini:

[Ejemplo.txt]
ColNameHeader=True
Format=TabDelimited
MaxScanRows=25
CharacterSet=ANSI
DateTimeFormat=dd/mm/yyyy
CurrencySymbol=Euro
CurrencyPosFormat=9
CurrencyThousandSymbol=.
CurrencyDecimalSymbol=,
DecimalSymbol=,
NumberDigits=2
NumberLeadingZeros=True

 
     
     
 

3. El delimitador de texto y la opción TextDelimiter

Como se ha visto anteriormente, la opción Format especifica el carácter que utiliza nuestro archivo de texto para delimitar los campos que se incluyen en el mismo, y en principio, su valor puede ser cualquier carácter a excepción de las comillas dobles ('').

El delimitador de texto o cualificador de texto (que es el nombre que utiliza el asistente para exportación de texto de Microsoft Access), es el carácter que utilizamos para delimitar el valor contenido en un campo de tipo alfanumérico de nuestro archivo de texto, por tanto deberemos tener especial cuidado en no confundir ambos delimitadores cuando lo utilicemos en el archivo de información de esquema Schema.ini.

El carácter de delimitador de texto por defecto son las comillas dobles ("), de ahí que la opción Format no pueda tomar dicho valor, ya que obtendríamos el siguiente error: El separador de campos de la especificación de archivo de texto coincide con el separador decimal o el delimitador de texto.

Pero puede ocurrir que nos veamos en la imperiosa necesidad de trabajar con un archivo de texto cuyos campos están delimitados por comillas dobles, o bien, estamos utilizando delimitadores de texto no estándar, como la comilla simple (') o la coma (,), con valores de campos de texto que además incluyen comillas simples o comas, como por ejemplo nombres ingleses o domicilios de clientes.

Ante tales dificultades, la única solución que nos queda, a fin de evitar el mensaje de error mencionado anteriormente, es incluir la opción TextDelimiter en el archivo Schema.ini, cuyo valor será el carácter que nos servirá para definir el delimitador de texto, y por tanto, poder optar por otro valor distinto al predeterminado de las comillas dobles. Veamos un ejemplo.

Imaginad que tenemos la siguiente línea de texto, cuyos campos están separados por comas (Format), y se utiliza la comilla simple como delimitador de texto (TextDelimiter):

'Martínez Flores, Javier','Av. Concha Espina, 34 - 4º B','Madrid','28016'

Si no utilizamos ningún archivo Schema.ini para indicar los valores de ambos delimitadores, al importar el archivo de texto, los campos Nombre y Domicilio se han dividido, ya que al incluir los datos una coma, el ISAM lo ha tomado como si de un campo distinto se tratara:

Campo1 Campo2 Campo3 Campo4 Campo5 Campo6
'Martínez Flores Javier' 'Av. Concha Espina 34 - 4º B' 'Madrid' '28016'

En cambio, si en el archivo Schema.ini especificamos los valores correspondientes a ambos delimitadores, los datos se tomarán correctamente:

Format=CSVDelimited
TextDelimiter='

Campo1 Campo2 Campo3 Campo4
Martínez Flores, Javier Av. Concha Espina, 34 - 4º B Madrid 28016

Si la opción TextDelimiter es distinta a las comillas dobles, la opción Format puede contener dicho carácter de separación, por lo que ya estamos en condiciones de trabajar con un archivo de texto delimitado por comillas dobles (").

Por último indicar que, si no deseamos utilizar ningún tipo de carácter como símbolo delimitador de texto (comillas dobles, simples, etc.), necesariamente debemos de indicar el valor none en el parámetro TextDelimiter de nuestro archivo de información de esquema Schema.ini:

TextDelimiter=none

Para más información, consúltese el siguiente artículo de la Knowledge Base:

Los archivos de texto que utilizan delimitadores no estándar de texto no se analizan adecuadamente con el driver de texto de Microsoft

 
     
     
 

4. Abrir directamente un archivo de texto

A continuación voy a explicar varios procedimientos para abrir directamente un archivo de texto utilizando para ello las bibliotecas de acceso a datos Microsoft Data Access Object Library (DAO) y Microsoft ActiveX Data Object Library (ADO), así como el driver de texto de Conectividad Abierta de Bases de Datos (ODBC).

Resaltar que el ISAM de Texto de Microsoft Jet sólo nos permitirá añadir nuevos registros al archivo de texto, siempre y cuando el objeto Recordset se haya abierto con permisos de escritura. No podremos modificar ni eliminar datos del archivo de texto, ya que obtendremos el siguiente mensaje de error: Este ISAM no admite la actualización/eliminación de datos en una tabla vinculada. Si deseamos evitar el error, no nos queda más solución que abrir el archivo de texto en modo de sólo lectura, pero en éste caso, no podremos tampoco añadir nuevos registros.

4.1. Mediante DAO mostrando los datos en un DBGrid

Hay que utilizar el método OpenDatabase del objeto DBEngine donde se indicará la ruta, el modo de acceso (sólo lectura o lectura/escritura), y el tipo de la base de datos de origen, el cual, siempre será TEXT;. Asimismo, y a pesar de ser un valor opcional, es necesario establecer explícitamente a True/False el valor del parámetro Opciones del método OpenDatabase, ya que de lo contrario, obtendremos el error 3051 en tiempo de ejecución.

En este ejemplo, vamos a utilizar un simple control Data para que automáticamente se llene el control DBGrid, por tanto, en tiempo de diseño es necesario establecer la propiedad DataSource del control DBGrid con el nombre de un control Data, ya que el control DBGrid no admite automatización.

El ejemplo abre el archivo de texto Clientes, que se encuentra en la carperta Mis documentos, creando un objeto Recordset:

Dim db As Database
Dim rs As Recordset

' Abrimos el archivo de texto, donde indicamos el nombre de
' la carpeta, el modo compartido, el acceso de lectura/escritura,
' y el tipo de la base de datos que vamos a utilizar.
Set db = OpenDatabase ("C:\Mis documentos", True, False, "TEXT;")

' Creo el Recortdset
Set rs = db.OpenRecordset ("Clientes")

 ' Establezco el Recordset del control Data
Set Data1.Recordset = rs

4.2. Mediante ADO visualizando la información en un DataGrid

Si utilizamos la biblioteca Microsoft ActiveX Data Object, hay que especificar en la cadena de conexión la ruta de la carpeta que contiene el archivo de texto y el tipo del ISAM que se va a utilizar, mediante la propiedad Extended Properties del objeto Connection.

Tenga en cuenta que la versión del proveedor necesaria que hay que utilizar para abrir un archivo de texto mediante la biblioteca de ADO es la versión del proveedor Jet 4.0; el proveedor Jet 3.51 no soporta los drivers ISAM de Jet. Si se especifica el proveedor Jet 3.51, en tiempo de ejecución se recibirá el siguiente mensaje de error: No se pudo encontrar el ISAM instalable. Para descargar las distintas versiones de los componentes de acceso a datos de Microsoft (MDAC), visite la siguiente dirección: http://www.microsoft.com/data.

El siguiente ejemplo, abre el anterior archivo utilizando el ISAM de texto del proveedor de datos Microsoft Jet:

Dim cnn As ADODB.Connection
Dim rs As ADODB.Recordset

' Establezco la cadena de conexión con el archivo de texto
Set cnn = New ADODB.Connection
With cnn
    .Provider="Microsoft.Jet.OLEDB.4.0"
    .ConnectionString="Data Source=C:\Mis documentos;" & _
                                  "Extended Properties=TEXT;"

    ' Abro la conexión
    .Open
End With

 ' Abro el recordset
Set rs = New ADODB.Recordset

With rs
    ' Utilizamos cursores del lado cliente, para poder
    ' visualizar los datos en el control DataGrid
    .CursorLocation = adUseClient
    .CursorType = adOpenStatic
    .LockType = adLockOptimistic
End With

' Nótese que hay que indicar la extensión del archivo, de lo
' contrario, el proveedor nos devolverá un error.
rs.Open "Clientes.txt", cnn, , , adCmdTable

' Relleno el control DataGrid
Set DataGrid1.DataSource = rs

Por último indicar que el punto que separa el nombre del archivo de su extensión, se puede sustituir por el símbolo #:

Open "Clientes#txt", cnn, , adCmdTable

Si no deseamos crear un archivo de información de esquema, bien en la cadena de conexión, bien en la consulta SQL, aparte de indicar el ISAM de texto y la ruta de la carpeta, también podemos indicar los valores que se especifican en la siguiente tabla, aunque no podremos aprovechar todas las restantes opciones que se pueden especificar en el archivo Schema.ini:

HDR = Yes | No Indica si la primera fila contiene o no el nombre de los campos.
CharacterSet = ANSI | OEM | Unicode El juego de caracteres que se utilizará.
FMT = Delimited Los campos estarán delimitados por el carácter especificado en el registro de Windows.
   

Es importante resaltar que, en líneas generales, estos valores surtirán efecto siempre y cuando no haya un archivo de información de esquema en la carpeta donde se encuentre el origen de datos, porque de lo contrario, el ISAM de texto no los tendrá en cuenta, ya que prevalecerá la configuración existente en el archivo Schema.ini.

Asimismo, de no existir el archivo de información, los valores de los parámetros que no se especifiquen en la cadena de conexión, se tomarán de los existentes en el registro de Windows.

La cadena de conexión del ejemplo anterior, también se podría haber especificado de la siguiente manera:

    .ConnectionString = "Data Source=" & App.Path & ";" & _
                                    "Extended Properties=""TEXT;HDR=No;FMT=Delimited;CharacterSet=ANSI;"""

A diferencia del ejemplo anterior, obsérvese en éste último ejemplo la utilización de los pares de comillas en color rojo, ya que de no indicarse, nos encontraremos con el molesto mensaje de error No se pudo encontrar el archivo ISAM instalable.

Igualmente, hay que tener precaución en no separar con un espacio en blanco el signo de igualación (=) que sigue a continuación del nombre de la propiedad Extended Properties, para especificar el valor de ésta, ya que obtendremos otro mensaje de error, en este caso, El formato de la cadena de inicialización no cumple la especificación OLE DB, un sutil error que nos puede costar perder cierto tiempo en intentar descubrir su origen.

Si no deseamos tener problemas con las comillas dobles o los espacios en blanco a la hora de especificar los diferentes parámetros que conforman la cadena de conexión, podemos olvidarnos de la propiedad ConnectionString y asignar explícitamente los valores de las distintas propiedades de la siguiente manera:

cnn.Properties("Data Source") = App.Path
cnn.Properties("Extended Properties") = "TEXT;HDR=No;FMT=Delimited;CharacterSet=ANSI;"

4.3. Mediante ADO utilizando el driver de texto ODBC

También podemos utilizar la biblioteca de ADO junto con el driver ODBC de Texto para trabajar con los datos de nuestro archivo de texto. En éste caso, con tan sólo especificar en la cadena de conexión el nombre del conductor y el directorio donde se encuentra nuestro archivo, estaremos en condiciones óptimas de manipular el origen de datos.

objCnn.ConnectionString = "Driver={Microsoft Text Driver (*.txt; *.csv)};" & _
                                            "DBQ=C:\Mis documentos"

En lugar de indicar la palabra clave DBQ, también podemos especificar la palabra DefaultDir, la cual indicará el directorio por defecto, pero hay que tener en cuenta que, de no especificar ninguna de las dos palabras claves, el controlador ODBC de Texto se conectará al directorio actual que esté establecido como tal en el sistema operativo.

Es importante resaltar que los fallos en la conversión de tipos de campos especificados en el archivo Schema.ini tienen como resultado que se aplique un valor NULL a la columna afectada.

El siguiente ejemplo utiliza el driver ODBC de texto para devolver el número de registros de la tabla Clientes cuyo archivo de texto se encuentra en la carpeta que contiene nuestra aplicación:

Dim cnnText As ADODB.Connection
Dim rs As ADODB.Recordset

' Conexión con el archivo mediante el
' conductor (driver) ODBC para Texto
Set cnnText = New ADODB.Connection
With cnnText
    .Provider = "MSDASQL.1"
    .ConnectionString = "Driver={Microsoft Text Driver (*.txt; *.csv)};" & _
                                    "DBQ=" & App.Path & _
                                    ";Extensions=txt,csv,tab,asc;"
    .Open
End With

' Abrimos el objeto Recordset
Set rs = New ADODB.Recordset
rs.Open "SELECT COUNT (*) FROM Clientes.txt", cnnText, , , adCmdText

' Comprobamos el número de registros devueltos
MsgBox rs.Fields(0)

4.4. Utilizando ASP con un origen de datos (DSN)

Aparte de abrir un archivo de texto que esté disponible en alguna carpeta de nuestro ordenador, también podemos establecer una conexión con un archivo que esté disponible en un servidor, utilizando para ello un nombre de origen de datos (DSN).

Aunque podemos crear cualquier origen de datos mediante el Administrador de orígenes de datos ODBC del Panel de Control, en ésta ocasión vamos a crear directamente un nombre de origen de datos para abrirlo mediante una página ASP, por tanto, es necesario que tengamos instalado e iniciado en nuestro ordenador los Servicios de Internet Information Server (IIS), y que guardemos el texto de más abajo con el nombre Text.dsn, por ejemplo, en un directorio virtual con permisos para ejecutar scripts.

[ODBC]
DRIVER=Microsoft Text Driver (*.txt; *.csv)
UID=admin
UserCommitSync=Yes
Threads=3
SafeTransactions=0
PageTimeout=5
MaxScanRows=25
MaxBufferSize=512
ImplicitCommitSync=Yes
FIL=text
Extensions=txt,csv,tab,asc
DriverId=27

A continuación, guardar en el mismo directorio virtual los datos del archivo de texto, creando para ello un nuevo archivo con el nombre Datos.txt:

IdCliente;Nombre;Total
4300012;"Felipe Serrano Hervás";4250,37
4302015;"Gustavo Pérez García";7585,59
4303025;"Joaquín López Fernández";141,53
4305684;"María Carmen Castilla Lombardo";1485,77
4300054;"Juan Carlos Armenteros Ruiz";7835,58

Por último, sólo nos queda crear el archivo EjemploDSNTexto.asp, por ejemplo, para ejecutar el código Visual Basic Script:

<%
Option Explicit
Response.Expires = -1000

Response.Write("<p><b><u><font size=3 face=arial>")
Response.Write("Ejemplo de ASP</u></b></font></p>")
Response.Write("<p><b><font size=2 face=arial>")
Response.Write("Abrir un archivo de texto mediante un origen de datos DSN</b></font></p>")

Dim sDSNFile, sScriptDir
Dim sPath, sDSN
Dim sSQL, sColor
Dim cnn, rs

' Nombre del archivo DSN
sDSNFile = "Text.dsn"

' Recuperamos el directorio actual
sScriptDir = Request.ServerVariables("SCRIPT_NAME")
sScriptDir = StrReverse(sScriptDir)
sScriptDir = Mid(sScriptDir, InStr(1, sScriptDir, "/"))
sScriptDir = StrReverse(sScriptDir)

' Construimos dinámicamente el origen de datos DSN
sPath = Server.MapPath(sScriptDir) & "\"
sDSN = "FileDSN=" & sPath & sDSNFile & _
             ";DefaultDir=" & sPath & _
             ";DBQ=" & sPath & ";"

' Establecemos la conexión
Set cnn = Server.CreateObject("ADODB.Connection")
cnn.Open sDSN

' Construimos la consulta SQL de selección
sSQL = "SELECT * FROM datos.txt ORDER BY IdCliente"

' Creamos un objeto Recordset con el resultado
' de la consulta
Set rs = cnn.execute(sSQL)

' Mostramos el contenido del Recordset
Response.Write("<table style='font-family:arial; font-size:10pt;'>")
Response.Write("<tr bgcolor=black style='color:white;'><td>Id Cliente</td>")
Response.Write("<td>Nombre</td>")
Response.Write("<td align=right>Total Ventas</td>")

sColor = "aqua"
Do While NOT rs.EOF
    If sColor = "pink" Then
        sColor = "aqua"
    Else
        sColor = "pink"
    End If

    Response.Write("<tr bgcolor='" & sColor & "'>")
    Response.Write("<td>" & rs("IdCliente").Value & "</td>")
    Response.Write("<td>" & rs("Nombre").Value & "</td>")
    Response.Write("<td align=right>" & rs("Total").Value & "</td>")

    rs.MoveNext
Loop

' Cerramos el Recordset y la Conexión
rs.close
Set rs = nothing
cnn.close
Set cnn = nothing
%>

Si ejecutáis la página desde vuestro navegador, obtendréis la siguiente tabla de datos:

Ejemplo de ASP

Abrir un archivo de texto mediante un origen de datos DSN

Id Cliente Nombre Total Ventas
4300012 Felipe Serrano Hervás 4250,37
4300054 Juan Carlos Armenteros Ruiz 7835,58
4302015 Gustavo Pérez García 7585,59
4303025 Joaquín López Fernández 141,53
4305684 María Carmen Castilla Lombardo 1485,77

 
     
     
 

5. Vinculación de archivos de texto

Al igual que vinculamos tablas de bases de datos Access, también podemos vincular a nuestra base de datos un archivo de texto delimitado. Sin embargo, para que el motor de base de datos Microsoft Jet puede uilizar la información del archivo Schema.ini, deben residir en la misma carpeta el archivo de datos y el archivo de información de esquema.

Al igual que sucede cuando abrimos directamente un archivo de texto, cuando vinculamos un archivo de texto el ISAM de Microsoft Jet sólo nos permitirá añadir nuevos registros al archivo de texto, por lo que no podremos modificar ni eliminar datos del archivo de texto, ya que obtendremos el siguiente mensaje de error: Este ISAM no admite la actualización/eliminación de datos en una tabla vinculada.

5.1. Vincular con ADOX un archivo de texto a una base de datos Access

La biblioteca de ADO no permite vincular un archivo de texto a una base de datos Access. Para ello tenemos que ayudarnos de la biblioteca Microsoft ADO Ext. 2.x for DLL and Security, más conocida en los ambientes de programación por el nombre de ADOX, la cual es una extensión de los objetos y del modelo de programación de ADO. Por tanto, en nuestro proyecto no hay que olvidarse de hacer referencia a la citada biblioteca.

El siguiente ejemplo, muestra como vincular un archivo de texto, a una base de datos Access 2000:

Public Sub LinkTextWithADO

    Dim cnn As ADODB.Connection
    Dim cat As ADOX.Catalog
    Dim tbl As ADOX.Table

    ' Establezco la conexión con la base de datos Access
    Set cnn = New ADODB.Connection
    With cnn
        .ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
                                    "Data Source=C:\Mis documentos\Bd1.mdb;"
        .Open
    End With

    ' Creo un nuevo catálogo
    Set cat = New ADOX.Catalog
    cat.ActiveConnection = cnn

    ' Creo la nueva tabla
    Set tbl = New ADOX.Table
    tbl.Name = "Tabla Vinculada de Texto"
    Set tbl.ParentCatalog = cat

    ' Establezco las propiedades para crear el vínculo
    With tbl
        .Properties("Jet OLEDB:Create Link") = True
        .Properties("Jet OLEDB:Link Provider String") = "TEXT;DATABASE=" & _
                                                    App.Path & ";HDR=Yes;FMT=Delimited"
        .Properties("Jet OLEDB:Remote Table Name") = "Clientes#txt"
    End With

    ' Añado la tabla a la colección 'Tables'
    cat.Tables.Append tbl

End Sub

5.2. Utilizar DAO para vincular un archivo de texto

Para vincular un archivo de texto delimitado a una base de datos Access, hay que utilizar el método OpenDatabase para abrir la base de datos; crear un objeto TableDef, y establecer las propiedades Connect y SourceTableName del objeto TableDef para indicar el archivo de texto que se desea vincular.

En el siguiente ejemplo, vamos a vincular un archivo de texto de longitud fija, por lo que necesitaremos crear un archivo de información de esquema Schema.ini, en la misma carpeta donde se encuentren los datos, para especificar el número, nombre, tipo de dato y ancho de las columnas. En éste caso, indicaremos que la primera fila no contiene los nombres de los campos. El archivo de configuración de esquema sería así:

[Clientes fijo.txt]
ColNameHeader=False
CharacterSet=ANSI
Format=FixedLength
Col1=IdCliente Long Width 7
Col2=Nombre Text Width 35
Col3=CIF Text Width 9

El archivo Clientes fijo.txt estará compuesto por los siguientes cinco registros. Si desea probar el ejemplo, copie y pegue los datos con el mismo formato en el que aparecen aquí:

430001 CAÑADA VAZQUEZ, JOAQUIN            12111255B
430002 MENDEZ CUBILLO, LORENZO            58777000Ñ
430006 CONSTRUCCIONES EL BUENO, S.A.      A33366684
430012 MENDIETA GARCÍA, FELIPE            06254000A
430015 CARRILLO CONTRERAS, ROSARIO        55666555Z

Ya sólo nos queda, ejecutar el siguiente procedimiento:

Public Sub LinkTextWithDAO

    Dim db As Database
    Dim td As TableDef

    ' Abro la base de datos de Access
    Set db = OpenDatabase("C:\Mis documentos\Bd1.mdb")

    ' Creo un objeto TableDef
    Set td = db.CreateTableDef("Tabla de Texto Fijo vinculada")

    ' Establezco la información de conexión
    td.Connect = "TEXT;DATABASE=" & App.Path
    td.SourceTableName = "Clientes fijo#txt"

    ' Anexo el objeto TableDef para crear el vínculo
    db.TableDefs.Append td

End Sub

Si abrimos la tabla vinculada en nuestra base de datos Access, observaremos el siguiente resultado:

IdCliente Nombre CIF
430001 CAÑADA VAZQUEZ, JOAQUIN 12111255B
430002 MENDEZ CUBILLO, LORENZO 58777000Ñ
430006 CONSTRUCCIONES EL BUENO, S.A. A33366684
430012 MENDIETA GARCÍA, FELIPE 06254000A
430015 CARRILLO CONTRERAS, ROSARIO 55666555Z

 
     
     
 

6. Cómo crear y eliminar una tabla de texto

Mediante la instrucción CREATE TABLE correspondiente al Lenguaje de Definición de Datos (DDL) de SQL, podemos crear una tabla de texto de la misma forma que crearíamos una tabla en una base de datos Access. Es más, utilizando dicho comando, automáticamente se generará el archivo de información de esquema Schema.ini correspondiente, y en la misma carpeta donde hayamos creado el archivo de texto. De querer crear un archivo de texto delimitado, en mi opinión es la forma más fácil de generar el archivo Schema.ini, porque en principio, los parámetros del mismo serán los que aparezcan en el registro de windows. Por el contrario, si deseamos crear un archivo de texto de longitud fija, necesitaremos crear de antemano el archivo Schema.ini para especificar el ancho de las columnas.

La sintaxis de la instrucción CREATE TABLE es la siguiente:

CREATE TABLE Nombre_Tabla (Campo1 Tipo (tamaño), Campo2 Tipo (tamaño), ...)

A continuación vamos a generar un archivo de texto de tres campos, utilizando la biblioteca de ADO:

Dim cnn As ADODB.Connection

' Establecemos la conexión
Set cnn = New ADODB.Connection
With cnn
    .Provider = "Microsoft.Jet.OLEDB.4.0"
    .ConnectionString = "Data Source=" & App.Path
    .Properties("Extended Properties") = "TEXT;"
    .Open
End With

' Creamos la tabla de texto
cnn.Execute "CREATE TABLE Clientes#txt (IdCliente LONG, " & _
                    "Apellidos TEXT (50), Nombre TEXT (25))"

Si vamos a la carpeta que contiene nuestra aplicación, podemos observar que se ha generado el archivo de texto donde sólo aparecen los nombres de los campos en la primera fila. Asimismo, también podemos observar que se ha creado el archivo de información de esquema con los valores de los parámetros existentes en el registro de nuestro sistema.

Si utilizamos la biblioteca de DAO, el código sería el siguiente:

Dim db As Database

' Abrimos la base de datos
Set db = OpenDatabase(App.Path, True, False, "TEXT;")

' Creamos la tabla de texto
db.Execute "CREATE TABLE Clientes#txt (IdCliente LONG, " & _
                  "Apellidos TEXT (50), Nombre TEXT (25))"

En cuanto a cómo eliminar un archivo de texto, lo más fácil sería eliminarlo desde el Administrador de Archivos, o utilizar la instrucción Kill de Visual Basic, pero ya que estamos utilizando bibliotecas de acceso a datos, vamos a eliminarlo como eliminaríamos cualquier otra tabla de una base de datos Access.

Mediante ADO y DAO utilizaríamos el método Execute de un objeto Connection o Database, respectivamente, para ejecutar la siguiente consulta SQL:

objeto.Execute "DROP TABLE Clientes#txt"

Para los usuarios de DAO, comentar que también pueden eliminar el archivo de texto utilizando el método Delete de la colección TableDefs de un objeto Database previamente abierto:

db.TableDefs.Delete "Clientes#txt"

Tal es la vinculación existente entre el archivo de texto y su archivo de información de esquema, que al eliminar el archivo de texto, automáticamente también se elimina el archivo de información de esquema asociado, o la sección correspondiente al archivo eliminado, si el archivo Schema.ini tiene información de varios archivos de texto. Esta es la ventaja que tiene utilizar los métodos de eliminación expuestos en contraposición a utilizar la instrucción Kill.

 
     
     
 

7. Importar los datos de un archivo de texto

La verdadera importancia de los distintos formatos de ISAM del que dispone el motor Microsoft Jet, reside en la capacidad que ostenta para importar/exportar datos a distintos orígenes de datos, utilizando para ello el potente Lenguaje de Consulta Estructurado (SQL). De ésta manera podemos utilizar los datos de un simple archivo de texto para importarlo a una base de datos Access, a una hoja de cálculo Excel, o a otros tipos de base de datos de escritorio como bien puede ser, dBASE o Paradox, entre otros.

Esto es posible gracias a una variación de la instrucción SELECT, la cual nos permitirá crear una nueva tabla con los registros devueltos de la consulta, simplemente con agregar la cláusula INTO a la misma. De igual manera, para identificar el archivo de texto externo, incluiremos la cláusula IN para especificar el tipo de ISAM que vamos a utilizar (en nuestro caso TEXT;), y la ruta donde se encuentra la base de datos externa (el parámetro DATABASE).

En general, la sintaxis de la consulta de creación de tabla es la siguiente, dependiendo de la tabla que deseemos identificar.

● Para identificar una tabla de destino:

SELECT * INTO [Tabla destino] IN {ruta | ["ruta" "tipo ISAM"] | ["" [tipo ISAM; DATABASE = ruta]]}

SELECT * INTO [Nueva Tabla] IN 'C:\Mis documentos' 'TEXT;' FROM [Tabla Origen]
SELECT * INTO [Nueva Tabla] IN ''[TEXT; DATABASE=C:\Mis documentos] FROM [Tabla Origen]

● Para identificar una tabla de origen:

FROM [Tabla origen] IN {ruta | ["ruta" "tipo ISAM"] | ["" [tipo ISAM; DATABASE = ruta]]}

SELECT * INTO [Nueva Tabla] FROM [Tabla Origen] IN 'C:\Mis documentos' 'TEXT;'
SELECT * INTO [Nueva Tabla] FROM [Tabla Origen] IN ''[TEXT; DATABASE=C:\Mis documentos]

7.1. Importar los datos a una base de Access

Si tenemos una conexión abierta con una base de datos Access, podemos importar los datos de un archivo de texto creando una nueva tabla en nuestra base de datos. En éste caso, la tabla que necesitamos identificar es la tabla de origen, que corresponderá con el archivo de texto cuyos datos queremos recuperar.

A continuación, y mediante la biblioteca de ADO, vamos a crear una nueva tabla [TextImport] en nuestra base de datos Access, con los datos del archivo de texto [Clientes#txt]. Para utilizar el ejemplo con la biblioteca de DAO, simplemente necesitará ejecutar la misma consulta SQL con el método Execute de un objeto Database previamente abierto:

Dim cnn As ADODB.Connection
Dim sTablaOrigen As String

' Establezco la conexión con la base de datos actual
Set cnn = New ADODB.Connection
With cnn
    .Provider = "Microsoft.Jet.OLEDB.4.0"
    .ConnectionString = "Data Source=C:\Mis documentos\bd1.mdb"
    .Open

    ' Identificamos la tabla de origen. Obsérvese en rojo la
    ' utilización de las comillas simples
    sTablaOrigen = "''[TEXT; DATABASE=" & App.Path & "]"

    ' También podemos utilizar la siguiente sintaxis
    ' sTablaOrigen = "'" & App.Path & "' 'TEXT;'"

    ' Importamos los datos, creando una nueva tabla
    .Execute "SELECT * INTO TextImport FROM [Clientes#txt] IN " & sTablaOrigen

    ' Cerramos la conexión
    .Close
End With

Nota importante: Pongo especial énfasis en las comillas simples para que el lector observe correctamente la sintaxis utilizada, ya que es sumamente importante incluirlas para delimitar la ruta de acceso al archivo y la versión del ISAM instalable que se va a utilizar, procurando dejar un espacio en blanco entre ambos parámetros.

Es de suma importancia tener en cuenta que, si el delimitador de campos del archivo de texto no coincide con el especificado por defecto en el registro de Windows, necesariamente tendremos que especificarlo en la opción Format del archivo de información de esquema Schema.ini, a fin de que todos los campos se importen correstamente, porque de lo contrario, sólo se importará el primer campo, y tampoco lo hará de forma idónea.

7.2. Importar los datos a una hoja de cálculo Excel

En el siguiente ejemplo, vamos a utilizar nuestro archivo de texto para importar los datos a un libro de trabajo de Excel, creando de ésta manera, una nueva hoja de cálculo. Vuelvo hacer hincapié en la necesidad de tener un archivo de información de esquema para que los datos se exporten correctamente. Es más, si la primera fila del archivo de texto no contiene el nombre de los campos, necesariamente tendremos que establecer a False el valor del parámetro ColNameHeader del archivo Schema.ini si queremos que se recupere la primera fila como un registro más.

Dim sTablaOrigen As String, sChainSql As String
Dim cnn As ADODB.Connection

' Establezco la conexión con el libro de trabajo
Set cnn = New ADODB.Connection
With cnn
    .Provider = "Microsoft.Jet.OLEDB.4.0"
    .ConnectionString = "Data Source=C:\Mis documentos\Libro1.xls;"
    .Properties("Extended Properties") = "Excel 8.0;"
    .Open
End With

' Construimos la consulta SQL
sTablaOrigen = "'" & App.Path & "' 'TEXT;'"
sChainSql = "SELECT * INTO TextImport FROM [Clientes#txt] IN " & sTablaOrigen

' Creamos una hoja de cálculo en el libro de Excel
cnn.Execute sChainSql

' Cierro la conexión
cnn.Close

7.3. Importar los datos a otro archivo de texto

También nos puede interesar crear otro archivo de texto delimitado para, por ejemplo, modificar el carácter delimitador de los campos, o cualquier otro parámetro, de un archivo de texto ya existente, por lo que necesariamente tendremos que crear un archivo Schema.ini para indicar el nuevo valor que deseamos obtener en el parámetro apropiado. En ésta ocasión, vamos a utilizar la biblioteca de DAO:

Dim sTablaOrigen As String, sChainSql As String
Dim db As Database

' Establezco la conexión con el archivo de texto
' que deseamos crear, especificando la ruta y
' el tipo de ISAM
Set db = OpenDatabase(App.Path, True, False, "TEXT;HDR=Yes;FMT=Delimited;")

' Construimos la consulta SQL
sTablaOrigen = "''[TEXT; DATABASE=" & App.Path & "]"
sChainSql = "SELECT * INTO [TextImport#txt] FROM [Clientes#txt] IN " & sTablaOrigen

' Creamos el nuevo archivo de texto
db.Execute sChainSql

' Cierro la conexión
db.Close

A diferencia de los ejemplos anteriores, en éste quiero hacer la salvedad de que necesariamente tendremos que especificar una extensión para el nuevo archivo de texto, utilizando para ello un punto (.), o el símbolo #, de tal forma que quede bien definido el nombre y la extensión del archivo. Y esto es así porque de no especificar la extensión obtendremos el mensaje de error: No se puede actualizar. Base de datos u objeto de sólo lectura. Un error que nos puede acarrear un verdadero dolor de cabeza si no ponemos especial cuidado en especificar la extensión del nuevo archivo de texto. Para más información sobre el tema, puede consultar el sigiente artículo de Microsoft Knowledge Base:

Mensaje de error "No se puede actualizar. Base de datos u objeto de sólo lectura" cuando importa o exporta archivos

 
     
     
 

8. Cómo exportar datos desde el propio archivo de texto

Al igual que hemos utilizado una consulta SQL de creación de tabla para importar los datos de un archivo de texto, creando para ello una conexión con otro origen de datos distinto, ahora se trata de exportar los datos desde el propio archivo de texto, es decir, abriendo una conexión con éste último y exportando desde aquí los datos a una base de datos Access, por ejemplo. En éste caso, necesitaremos identificar la tabla de destino, la cuál se corresponderá con el archivo de texto que deseamos crear. Véase la sintaxis de la instrucción SELECT * INTO descrita en el punto número siete.

Mediante ADO, vamos a crear una tabla en nuestra base de datos Access, con los datos de un archivo de texto delimtado:

Dim cnn As ADODB.Connection
Dim sConnect As String

' Establezco la conexión con el archivo de texto
Set cnn = New ADODB.Connection
With cnn
    .Provider = "Microsoft.Jet.OLEDB.4.0"
    .ConnectionString = "Data Source=" & App.Path & _
    ";Extended Properties=""TEXT;"""
    .Open

    ' Indicamos la ruta de la base de datos
    sConnect = "'C:\Mis documentos\Bd1.mdb'"

    ' Creamos la tabla
    .Execute "SELECT * INTO [TextExport] IN " & sConnect & " FROM [Clientes#txt]"

    .Close
End With

Si en la propiedad Extended Properties no se desea escribir tantos pares de comillas dobles, se puede hacer referencia al tipo de ISAM de la siguiente manera:

cnn.Properties("Extended Properties") = "TEXT;"

A continuación, vamos a generar un archivo dBASE con los datos de nuestro archivo de texto, utilizando ésta vez, la biblioteca de DAO. Indicar que, si el nombre del archivo de dBASE es superior a ocho caracteres, no se tendrán en cuenta los caracteres que excedan de dicho número.

Dim db As Database
Dim sConnect As String

' Establezco la conexión con el archivo de texto
' que deseamos crear, especificando la ruta y
' el tipo de ISAM
Set db = OpenDatabase(App.Path, True, False, "TEXT;HDR=Yes;FMT=Delimited;")

' Construimos la consulta SQL para identificar la tabla de destino
' Obsérvese las comillas simples en rojo
sConnect = " ''[dBASE 5.0; DATABASE=" & App.Path & "]"

' Creamos el nuevo archivo de dBASE, cuyo nombre tiene más de ocho caracteres
db.Execute "SELECT * INTO [TextExport#dbf] IN " & sConnect & " FROM [Clientes#txt]"

' Cierro la conexión
db.Close

 
     
     
 

9. Cómo exportar datos a un archivo de texto

La manera más fácil de crear un archivo de texto delimitado con los datos procedentes de tablas u otros orígenes de datos, es mediante la utilización de una consulta SQL de creación de tabla. Simplemente necesitaremos establecer una conexión con el origen de datos, y exportar la tabla especificando el tipo de ISAM que vamos a utilizar y la ruta donde se creará el archivo de texto.

Si al exportar los datos no disponemos de la información del archivo de configuración de esquema Schema.ini, automáticamente se generará uno en la misma carpeta donde se haya creado el archivo de texto, el cual contiene los valores por defecto establecidos en el registro de Windows. Si necesitamos especificar o modificar algún valor, necesariamente tenemos que generar un archivo Schema.ini antes de ejecutar la consulta.

Debemos de tener especial cuidado en no olvidarnos de especificar la extensión del archivo de texto, ya que de lo contrario obtendremos el mensaje de error: No se puede actualizar. Base de datos u objeto de sólo lectura.

9.1. Exportar los datos de una tabla de Access

El ejemplo mostrará cómo exportar mediante la biblioteca de ADO una tabla de Access, creando un archivo de texto delimitado:

Dim cnn As ADODB.Connection
Dim sConnect As String

' Establezco la conexión con la base de datos actual
Set cnn = New ADODB.Connection
With cnn
    .Provider = "Microsoft.Jet.OLEDB.4.0"
    .ConnectionString = "Data Source=C:\Mis documentos\bd1.mdb"
    .Open

    ' Indico el tipo de ISAM y la ruta del archivo de texto
    sConnect = "[TEXT;DATABASE=" & App.Path & "].[TextExport#txt]"

    ' Exportamos la tabla
    .Execute "SELECT * INTO " & sConnect & " FROM Clientes"

    ' Cierro la conexión
    .Close
End With

9.2. Exportar los datos de una hoja de cálculo Excel

En ésta ocasión, el ejemplo ilustra cómo exportar desde Excel una hoja de cálculo, creando un archivo de texto delimitado, utilizando para ello la biblioteca de DAO. Al igual que utilizamos Excel como origen de datos, también podemos especificar otro tipo de ISAM disponible en nuestro sistema:

Dim sConnect As String
Dim db As Database

' Establezco la conexión con el libro de trabajo
Set db = OpenDatabase("C:\Mis documentos\Libro1.xls", False, False, "Excel 8.0; HDR=Yes;")

' Indico el tipo de ISAM y la ruta del archivo de texto
sConnect = "[TEXT; DATABASE=" & App.Path & "].[TextExport#txt]"

' Exportamos la hoja de cálculo
db.Execute "SELECT * INTO " & sConnect & " FROM [Hoja1$]"

' Cierro la base de datos
db.Close

 
     
     
 

10. Añadir registros a una tabla procedentes de un archivo de texto delimitado

Si tenemos una tabla creada en Access y queremos añadir los datos existentes en un archivo de texto delimitado, podemos insertar los datos mediante la instrucción INSERT INTO, lo que en SQL se conoce como una consulta de datos añadidos o anexados, la cual añade los nuevos registros al final de la tabla o consulta ya existente.

En las tablas origen y destino puede especificar una tabla o una consulta. Si especifica una consulta, el motor de base de datos Microsoft Jet añade los registros a cualquiera y a todas las tablas especificadas en la consulta.

Si la tabla de destino contiene una clave principal, hay que asegurarse de que se añade un valor único y distinto de Null al campo o campos de la clave principal; de lo contrario, el motor de base de datos no añadirá los registros.

También hay que tener en cuenta que, si añade registros a una tabla con un campo de tipo AutoNumérico y desea volver a numerar los registros añadidos, no incluya el campo contador en la consulta. Incluya el campo Autonumérico en la consulta sólo si desea conservar los valores originales del campo.

Por último recalcar que, si la tabla o consulta no existe en la base de datos de Access, no se podrá añadir registros, debido a la inexistencia de la misma, cosa que por otra parte, es bastante lógica.

10.1. Desde la propia base de datos Access activa

Si tenemos una conexión abierta con una base de datos Access, que ya contiene la tabla o consulta donde queremos añadir los registros del archivo de texto, solamente tendríamos que especificar la versión del ISAM a utilizar, el parámetro HDR y la ruta del archivo de texto en el parámetro DATABASE.

El siguiente ejemplo muestra como insertar un conjunto de registros en una tabla existente de Access mediante la biblioteca de ADO. El ejemplo parte de la premisa de la no existencia de un archivo de configuración Schema.ini, por lo que necesariamente tendremos que especificar en el parámetro HDR que la primera fila del archivo de texto contiene el nombre de los campos:

Dim cnn As ADODB.Connection
Dim sConnect As String, sSQL As String

sConnect = "[TEXT; HDR=Yes; DATABASE=" & App.Path & "].[Clientes#txt]"

' Construimos la consulta SQL
sSQL = "INSERT INTO TBClientes SELECT * FROM " & sConnect

' Conexión con tu base de datos Accesss
Set cnn = New ADODB.Connection
With cnn
    .Provider = "Microsoft.Jet.OLEDB.4.0;"
    .ConnectionString = "Data Source=C:\Mis documentos\Bd1.mdb"
    .Open

    ' Añadimos los registros
    .Execute sSQL, , adCmdText

    ' Cerramos la conexión
    .Close
End With

De no existir un archivo Schema.ini, el ISAM no puede conocer de antemano el nombre de las columnas, por lo que la primera fila de nuestro archivo de texto necesariamente deberá de contener los nombres de los campos, y éstos deberán de coincidir, y en el mismo orden, con los nombre de los campos de la tabla. En este supuesto, el parámetro HDR cobra especial relevancia, porque de especificar el valor No, podríamos tener problemas al añadir los registros, debido a que el motor Jet no sabría dónde insertar los mismos.

10.2. Desde el propio archivo de texto activo

Al contrario que en el punto anterior, a continuación voy a mostrar cómo se añadirían los registros en la tabla de Access, pero desde una conexión con el archivo de texto, de esta forma se observará la utilización de la cláusula IN de SQL, la cual identifica las tablas de cualquier base de datos externa a la que el motor de base de datos Microsoft Jet se puede conectar, en éste caso identificamos la tabla de destino, que se corresponderá con una tabla de la base de datos de Access. El turno ahora es para la biblioteca de DAO:

Dim sConnect As String, sChainSQL As String
Dim db As Database

' Establezco la conexión con el archivo de texto
' que deseamos crear, especificando la ruta y
' el tipo de ISAM
Set db = OpenDatabase(App.Path, True, False, "TEXT; HDR=Yes; FMT=Delimited;")

' Indicamos la ruta de la base de datos Access
sConnect = " 'C:\Mis documentos\Bd1.mdb' "

' Construimos la consulta SQL
sChainSQL = "INSERT INTO TBClientes IN " & sConnect & " SELECT * FROM [Clientes#txt]"

' Insertamos los nuevos registros
db.Execute sChainSQL

' Cierro la conexión
db.Close

 
     
     
 

11. Añadir nuevos registros a nuestro archivo de texto

Siguiendo con las posibilidades que nos brinda el Lenguje de Consulta Estructurado (SQL), vamos a ver cómo insertar nuevos registros en un archivo de texto delimitado.

Esto es útil para cuando tengamos un archivo de texto vacío, con su correspondiente archivo de información de esquema Schema.ini creado, y debidamente configurado a nuestras necesidades, y necesitemos trabajar con los datos en el propio archivo de texto, o bien, para intercambiar la información entre los distintos sistemas de gestión de bases de datos existentes en el mercado.

En el supuesto que nos ocupa, es necesario que el archivo de texto exista previamente en la carpeta especificada, y que la primera fila contenga el nombre de los campos y estén en el mismo orden que los campos del archivo o tabla cuyos registros vamos a insertar en nuestro archivo de texto. Igualmente, y a fin de evitar el oportuno error, si en la conexión con la base de datos externa se especifica el parámetro HDR, éste necesariamente tendrá que ser True, ya que de nada sirve que establezcamos a True/False el parámetro ColNameHeader en el archivo de información de esquema Schema.ini. Por supuesto, de no especificar el parámetro HDR, habrá de asegurarse que el valor FirstRowHasNames de la clave del registro de Windows HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Text, esté establecido a 01, porque de lo contrario, necesariamente tendremos que especificar el parámetro HDR=Yes.

11.1. Desde un archivo de dBASE activo

El utilizar un archivo dBASE, simplemente es para que el lector observe la capacidad de la que dispone los distintos tipos de ISAM que incluye el motor de base de datos Microsoft Jet, por lo que prácticamente podemos intercambiar información entre diferentes tipos de orígenes de datos.

A continuación, y mediante la biblioteca de ADO, vamos a establecer una conexión con un archivo dBASE, e insertar los registros devueltos por una consulta SQL, en nuestro archivo de texto:

Dim sConnect As String, sChainSql As String
Dim cnn As ADODB.Connection

' Establecemos la conexión con el archivo de dBASE,
' que será la conexión activa
Set cnn = New ADODB.Connection
With cnn
    .Provider = "Microsoft.Jet.OLEDB.4.0"
    .ConnectionString = "Data Source = " & App.Path
    .Properties("Extended Properties") = "dBASE 5.0;"
    .Open
End With

' Identificamos la tabla de destino, que será el nombre de nuestro archivo de texto
' Obsérvese el par de comillas simples en rojo
sConnect = " ''[TEXT; HDR=Yes; DATABASE=" & App.Path & "]"

' Construimos la consulta SQL
sChainSql = "INSERT INTO [Clientes#txt] IN " & sConnect & " SELECT * FROM [Clientes#dbf]"

' Insertamos los registros
cnn.Execute sChainSql, , adCmdText

' Cerramos la conexión
cnn.Close

11.2. Desde el propio archivo de texto activo

A diferencia del ejemplo anterior, a continuación vamos a insertar los registros en el archivo de texto, pero desde una conexión con éste último, por tanto, mientras que en el ejemplo anterior identificábamos la tabla de destino, en éste identificaremos la tabla de origen, que se corresponderá con el archivo dBASE. Mediante la biblioteca de DAO seria de la siguiente manera:

Dim sConnect As String, sChainSql As String
Dim db As Database

' Establezco la conexión con el archivo de texto,
' especificando la ruta y el tipo de ISAM
Set db = OpenDatabase(App.Path, True, False, "TEXT; HDR=Yes; FMT=Delimited;")

' Identificamos la tabla de origen, que será la
' ruta del archivo dBASE
sConnect = " ''[dBASE 5.0; DATABASE=" & App.Path & "]"

' Construimos la consulta SQL
sChainSql = "INSERT INTO [Clientes8#txt] SELECT * FROM [Clientes#dbf] IN " & sConnect

' Insertamos los nuevos registros
db.Execute sChainSql

' Cerramos la conexión
db.Close

 
     
     
 

12. Algunos artículos útiles de Microsoft Knowledge Base

La siguiente relación de enlaces a Microsoft Knowledge Base que cito (por no decir todos), están en inglés. He traducido los títulos de los artículos a fin de facilitar al usuario hispanohablante una referencia más rápida al contenido de los mismos. En dichos artículos el usuario podrá ampliar la información contenida en éste artículo sobre cómo manipular los datos contenidos en un archivo de texto mediante el ISAM de Texto del motor Microsoft Jet. Los artículos están ordenados de mayor a menor antigüedad en la fecha de su última actualización.

 
     
 
Artículo Tipo Descripción
550166     Lectura de un fichero de texto con Schema.ini
146220   PRB El driver de texto ODBC sólo soporta la instrucción INSERT
190186   ACC Error al actualizar un archivo de texto vinculado utilizando el Administrador de Tablas vinculadas
208404   ACC2000 Los campos de texto de longitud fija con caracteres de retorno incrustados son incorrectamente importados
234201   ACC2000 Utilizar SQL para exportar a Unicode mediante el proveedor Jet y el ISAM de texto
124657   INF El driver de texto necesita conocer el directorio para definir el formato permitido
239471     El ISAM Instalable de Texto Jet 4.0 le permite a los usuarios añadir líneas a los archivos de sistema
205439   PRB Los archivos de texto que utilizan delimitadores no estándar de texto no se analizan adecuadamente con el driver de texto de Microsoft
230265     El ejemplo ImportText.exe importa texto a Access mediante ADO, RDO, DAO, Filesys y Automatización
262537   HOWTO Abrir archivos de texto delimitado utilizando el IISAM de texto del proveedor Jet
145769   PRB La letra mayúscula "S" no se muestra cuando se usa el ISAM de texto
210001   ACC2000 Cómo crear mediante programación un archivo Schema.ini
282263   ACC2002 Ignorar el valor establecido de MaxScanRows puede provocar tipos de datos inadecuados en tablas vinculadas
199068   ACC2000 Error de Schema.ini con la acción TransferText durante la exportación
245407   ACC2000 Mensaje de error "No se puede actualizar. Base de datos u objeto de sólo lectura" cuando importa o exporta archivos
254002   FIX Importar un archivo de texto sin utilizar el archivo Schema.ini puede ocasionar que las columnas de texto se definan como Currency
268264   ACC2000 Error 3433 en tiempo de ejecución cuando importa o exporta un archivo de texto
326548   HOW TO Utilizar Jet OLE DB Provider 4.0 para conectarse a bases de datos ISAM
241477   ACC2000 Error cuando intenta utilizar Schema.ini para importar o exportar con el método TransferText
210073   ACC2000 Cómo utilizar un archivo Schema.ini para tener acceso a datos de texto
182354   PRB Jet Text IISAM Driver Drops Leading Spaces
182355   PRB El IISAM de texto Jet trunca los espacios arrastrados
187670   HOWTO Utilizar RDO y el driver de texto ODBC para abrir un archivo de texto delimitado
       
       

 
     
     
 

NOTA: El contenido de éste artículo es una recopilación de las participaciones del autor en el grupo de noticias en español de Visual Basic (microsoft.public.es.vb), así como de la información disponible en los distintos artículos que la Microsoft Knowledge Base ofrece sobre el tema en cuestión, de los cuales se hace una referencia en el apartado número doce.

La información contenida en este artículo, así como el código fuente incluido en el mismo, se proporciona COMO ESTÁ, sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo explicado, recomendado o sugerido en el presente artículo.

 
     
 

This article is provided AS IS with no warranties, and confers no rights. You assume all risk for your use.

 
   
 

Enrique Martínez Montejo - 2003