Visual Basic s(y por ende, VBA)iempre se caracterizó por ser una herramienta muy poderosa a la hora de operar con archivos de texto. Las operaciones de lectura/escritura en dichos archivos se realizan a una velocidad impresionante y su uso, en términos generales y para las rutinas de baja/mediana complejidad, es muy sencillo.
Debemos reconocer que también a los TXT se los mira con cierta "desconfianza", llevando esto a ignorar su verdadero potencial. Ejemplo: hace un par de años en el trabajo me encargaron ciertas labores informáticas, las cuales incluían el manejo de un par de millones de registros. Bueno, pensé, o utilizo MySql o bien divido semejante info en varias bases de datos de Access y se terminó el problema. Al requerir algunos de los citados programas... no, no hay licencias disponibles, como así tampoco no es posible utilizar otro tipo de soft. Entonces, los TXT vinieron en mi ayuda.
como soy un "windows' boy" irremediable, utilizo al querido Bloc de Notas, pero existen cientos de alternativas, como por ejemplo el excelente NotePad ++ (open source) ideal para programadores.
[+/-] Ver el resto / Ocultar
El tema posee su parte teórica y debemos repasarla, para una mejor comprensión de todos aquellos que no acostumbran utilizar este tipo de almacenamiento de datos.Comencemos.
Existen distintas formas (modos) de acceder a los archivos de texto plano (.txt). El método que utilizaremos dependerá en gran medida de la estructura que tengan los datos dentro del TXT y/o los requerimientos de nuestra aplicación. Al hablar de estructura, nos estamos refiriendo a la forma en que los datos se encuentran ordenados dentro del mismo. Y van unos ejemplos para clarificar, ya que disponemos de tres Modos para abrir un archivo:
En general al sintaxis del código a emplear es la siguiente:
Open RutaDelArchivo For Modo As #NumeroDeArchivo
-----instrucciones-----
Close #NumeroDeArchivo
Open: instrucción de apertura
RutaDelArchivo: directorio en donde se encuentra o guardaremos nuestro TXT
Modo: Secuencial (Input / Output / Append) – Aleatorio – Binario
NumeroDeArchivo: un número entero entre 1 y 255. Si abrimos un archivo con #2, debemos cerrarlo con Close #2, y así sucesivamente.
SECUENCIAL: VBA lee al archivo línea por línea. Se comienza por la primera y debemos recorrer todas hasta llegar a la última; de allí que se llame Secuencial. Según la instrucción que utilicemos en la sintaxis, estaremos definiendo si la apertura será de lectura o escritura. Veamos esas 3 instrucciones involucradas dentro del modo Secuencial:
a) Input: lectura. Si el archivo no existe, arroja error (no se puede leer algo que no existe).
b) Output: escritura. Sobrescribe cualquier dato existente en el archivo. Si el archivo no existe, lo crea.
c) Append: escritura. No sobrescribe, agrega los datos luego de la última línea. Si el archivo no existe, lo crea.
Llevando los tres items anteriores a la práctica, nos quedaría:
a)
c)
En a) leemos una sola línea de texto. En b) y c) escribimos, también, una sola línea de texto. Si la lectura (instrucción Input) de nuestro archivo incluyera varias líneas (de hecho, puden ser cientos, miles o millones), el código sería el que describo a continuación. Se encontrarán con la palabra EOF (end of file = final del archivo), que puede ser True (llegó al final) o False (aún no llegó al final). Por ello el bucle dice “While Not EOF” (mientras no se llegue al final del archivo). También verán como empiezo a enviar datos desde el archivo de texto a Excel:
Vamos a suponer ahora que tenemos cierta información en el rango A1:A100, y deseamos llevarla a un archivo de texto:
Recordemos que con Output sobrescribimos, así que si existían datos dentro de ese archivo.... chau. Para agregar info a un archivo el procedimiento es exactamente igual, pero cambiamos a Output por Append:
Hasta aquí vimos y aplicamos ejemplos muy básicos sobre el modo Aleatorio, en sus tres variantes Input, Output y Append. Pueden copiar el código e incluirlo dentro de un módulo en VBA para practicar y probar alternativas.
Realizaré a continuación un ejemplo un tanto mas complejo: tomaremos un archivo de texto con un par de líneas, en donde cada campo se encuentra separado por un “;” (punto y coma), lo cual es una estructura de almacenamiento bastante común. Como siempre aclaro, existe mas de una forma de encarar cualquier código, mi intención es mostrar los pasos comunes y aplicar en el ejemplo otras cosas, a los fines de que luego puedan aprovecharlo en cualquier proyecto.
Así como trajimos datos a Excel, otra función muy útil es la de llevar los datos de nuestras planillas a un TXT, que luego será muy fácil de migrar a una base de datos, como Access o MySql.
El procedimiento arriba codificado es extremadamente útil para realizar back-ups rápidos y efectivos de nuestros datos.
Existen distintas formas (modos) de acceder a los archivos de texto plano (.txt). El método que utilizaremos dependerá en gran medida de la estructura que tengan los datos dentro del TXT y/o los requerimientos de nuestra aplicación. Al hablar de estructura, nos estamos refiriendo a la forma en que los datos se encuentran ordenados dentro del mismo. Y van unos ejemplos para clarificar, ya que disponemos de tres Modos para abrir un archivo:
En general al sintaxis del código a emplear es la siguiente:
Open RutaDelArchivo For Modo As #NumeroDeArchivo
-----instrucciones-----
Close #NumeroDeArchivo
Open: instrucción de apertura
RutaDelArchivo: directorio en donde se encuentra o guardaremos nuestro TXT
Modo: Secuencial (Input / Output / Append) – Aleatorio – Binario
NumeroDeArchivo: un número entero entre 1 y 255. Si abrimos un archivo con #2, debemos cerrarlo con Close #2, y así sucesivamente.
SECUENCIAL: VBA lee al archivo línea por línea. Se comienza por la primera y debemos recorrer todas hasta llegar a la última; de allí que se llame Secuencial. Según la instrucción que utilicemos en la sintaxis, estaremos definiendo si la apertura será de lectura o escritura. Veamos esas 3 instrucciones involucradas dentro del modo Secuencial:
a) Input: lectura. Si el archivo no existe, arroja error (no se puede leer algo que no existe).
b) Output: escritura. Sobrescribe cualquier dato existente en el archivo. Si el archivo no existe, lo crea.
c) Append: escritura. No sobrescribe, agrega los datos luego de la última línea. Si el archivo no existe, lo crea.
Llevando los tres items anteriores a la práctica, nos quedaría:
a)
Open “C:\Mis Documentos\archivoBlog.txt” for Input as #1 ‘en Variable leo y almaceno la línea de texto: Line Input #1, Variable Close #1
b)
Open “C:\Mis Documentos\archivoBlog.txt” for Output as #1 ‘llevo al archivo los datos que tengo en Variable Print #1, Variable Close #1
c)
Open “C:\Mis Documentos\archivoBlog.txt” for Append as #1 ‘llevo al archivo los datos que tengo en Variable Print #1, Variable Close #1
En a) leemos una sola línea de texto. En b) y c) escribimos, también, una sola línea de texto. Si la lectura (instrucción Input) de nuestro archivo incluyera varias líneas (de hecho, puden ser cientos, miles o millones), el código sería el que describo a continuación. Se encontrarán con la palabra EOF (end of file = final del archivo), que puede ser True (llegó al final) o False (aún no llegó al final). Por ello el bucle dice “While Not EOF” (mientras no se llegue al final del archivo). También verán como empiezo a enviar datos desde el archivo de texto a Excel:
Open “C:\Mis Documentos\archivoBlog.txt” for Input as #1 While Not Eof(1) ‘leo la línea de texto y la almaceno en Variable Line Input #1, Variable ‘llevo a Variable a una celda de la planilla Cells(x,1).value = Variable X = x + 1 Wend Close #1
Vamos a suponer ahora que tenemos cierta información en el rango A1:A100, y deseamos llevarla a un archivo de texto:
Open “C:\Mis Documentos\archivoBlog.txt” for Output as #1 For x = 1 to 100 Variable = Cells(x,1).value Print #1, Variable Next x Close #1
Recordemos que con Output sobrescribimos, así que si existían datos dentro de ese archivo.... chau. Para agregar info a un archivo el procedimiento es exactamente igual, pero cambiamos a Output por Append:
Open “C:\Mis Documentos\archivoBlog.txt” for Append as #1 For x = 1 to 100 ‘almaceno el valor de la celda Variable = Cells(x,1).value ‘y la envío al archivo: Print #1, Variable Next x Close #1
Hasta aquí vimos y aplicamos ejemplos muy básicos sobre el modo Aleatorio, en sus tres variantes Input, Output y Append. Pueden copiar el código e incluirlo dentro de un módulo en VBA para practicar y probar alternativas.
Realizaré a continuación un ejemplo un tanto mas complejo: tomaremos un archivo de texto con un par de líneas, en donde cada campo se encuentra separado por un “;” (punto y coma), lo cual es una estructura de almacenamiento bastante común. Como siempre aclaro, existe mas de una forma de encarar cualquier código, mi intención es mostrar los pasos comunes y aplicar en el ejemplo otras cosas, a los fines de que luego puedan aprovecharlo en cualquier proyecto.
Sub MigarTxt_a_Excel() 'declaro las variables de uso local: Dim Texto, C, Matrix() As String Dim NumArch, Fila, X As Integer 'con FreeFile obtengo el nro de archivo disponible. 'esto generalmente se usa cuando manejamos varios 'archivos al mismo tiempo y no sabemos cual asignar 'al nuevo que vamos a abrir: NumArch = FreeFile Fila = 0 'abro en modo Secuencial, con la instrucción Input (lectura) Open "R:\Compartido\texto1.txt" For Input As NumArch 'lo recorro desde el inicio, hasta que VBA detecte el 'EOF (end of file=final de archivo) While Not EOF(NumArch) 'almaceno la primer línea en Texto Line Input #1, Texto 'como cada campo está separado unívocamente por un 'punto y coma, aprovecho para volcar esa línea de 'texto a una matriz Matrix() = Split(Texto, ";") Fila = Fila + 1 'con un simple bucle For... recorro la matriz y 'coloco cada campo en una celda distinta For X = 0 To UBound(Matrix()) Cells(Fila, (X + 1)) = Matrix(X) Next X Wend 'cierro el archivo Close #NumArch 'borro la matriz Erase Matrix() 'y aviso que terminó el proceso: MsgBox "migración finalizada", vbInformation End Sub
Así como trajimos datos a Excel, otra función muy útil es la de llevar los datos de nuestras planillas a un TXT, que luego será muy fácil de migrar a una base de datos, como Access o MySql.
Sub MigarExcel_a_TXT() 'declaro las variables de uso local: Dim Texto As String Dim NumArch, X As Integer 'con FreeFile obtengo el nro de archivo disponible. 'esto generalmente se usa cuando manejamos varios 'archivos al mismo tiempo y no sabemos cual asignar 'al nuevo que vamos a abrir: NumArch = FreeFile 'abro en modo Secuencial, con la instrucción Output '(escritura, sobrescribiendo cualquier dato existente: Open "R:\Compartido\texto1.txt" For Output As NumArch 'concateno en Texto a la fila de la planila de 'cálculos, separando cada campo con un ";" For X = 1 To 6 Texto = Cells(X, 1) & ";" & Cells(X, 2) _ & ";" & Cells(X, 3) & ";" & Cells(X, 4) _ & ";" & Cells(X, 5) & ";" & Cells(X, 6) 'lo guardo en el TXT Print #NumArch, Texto Next X 'cierro el archivo Close #NumArch 'y aviso que terminó el proceso: MsgBox "exportación finalizada", vbInformation End Sub
El procedimiento arriba codificado es extremadamente útil para realizar back-ups rápidos y efectivos de nuestros datos.
Vimos como trabajar con una estructura en la cual sus campos está delimitados por un punto y coma ( ; ).
Pero muchos programas generan archivos de texto con otros formatos (también muy utilizados), en donde cada campo tiene una longitud fija de caracteres y ningún carácter especial separa sus campos. Si bien a este tipo de archivos no es aconsejable abrirlos mediante el modo Secuencial, valga la siguiente experiencia personal por si en algún momento deben lidiar con ellos: la utilización de la Función Mid(), con la cual es posible extraer “partes” de una cadena de texto.
Sintaxis: Mid(cadena, posición inicial, longitud)
Ejemplos:
1) Texto = Mid(“que frio se vino este invierno”, 1, 8)
El resultado sería almacenar “que frío” dentro de Texto, ya que a partir del primer carácter (1) extiendo 8 caracteres.
2) Texto = Mid(“que frío se vino este invierno”, 13, 4)
El resultado sería almacenar “vino” dentro de Texto, ya que a partir del carácter 13 extiendo 4.
Entonces, si el TXT tiene los siguientes campos (fecha, legajo, horas trabajadas) sin separadores, como en este ejemplo:
Pero muchos programas generan archivos de texto con otros formatos (también muy utilizados), en donde cada campo tiene una longitud fija de caracteres y ningún carácter especial separa sus campos. Si bien a este tipo de archivos no es aconsejable abrirlos mediante el modo Secuencial, valga la siguiente experiencia personal por si en algún momento deben lidiar con ellos: la utilización de la Función Mid(), con la cual es posible extraer “partes” de una cadena de texto.
Sintaxis: Mid(cadena, posición inicial, longitud)
Ejemplos:
1) Texto = Mid(“que frio se vino este invierno”, 1, 8)
El resultado sería almacenar “que frío” dentro de Texto, ya que a partir del primer carácter (1) extiendo 8 caracteres.
2) Texto = Mid(“que frío se vino este invierno”, 13, 4)
El resultado sería almacenar “vino” dentro de Texto, ya que a partir del carácter 13 extiendo 4.
Entonces, si el TXT tiene los siguientes campos (fecha, legajo, horas trabajadas) sin separadores, como en este ejemplo:
1201104578309
1201103358408
1201104875310
1201103568909
y partiendo de la premisa que todos poseen la misma longitud, podría volcar esos datos a Excel con estas líneas de código, las cuales deberán estar incluidas dentro del respectivo bucle:
Tampoco desmerezcamos mucho a estos archivos par buscar información dentro de ellos. Obviamente que no poseerá la velocidad y practicidad de una base de datos.... pero se defiende bastante. Si vamos al primer ejemplo (en donde migramos a Excel los registros del TXT), incorporando una simple línea podríamos sólo volcar aquellas líneas que cumplan con cierta condición:
Si bien describí un proceso muy repetitivo y, desde ya, no tiene punto de comparación con el manejo de una base de datos, merece un análisis en su defensa. Los procesadores están especialmente diseñados para realizar este tipo de trabajos (tareas repetidas) y no necesitamos ningún tipo de librería adicional: nos olvidamos de ODBC y sus orígenes de datos, bases de datos, conexiones, recordsets, sentencias SQL, etc, etc, todos objetos y rutinas que lógicamente también insumen recursos de nuestro ordenador. Y en la mayoría de los casos, la PC en donde se ejecutará nuestra macro deberá contar con las mencionadas librerías y demás, o nos veremos en la obligación de incorporarlas, para que todo funcione bien.
Por otra parte hablamos de archivos de texto plano, sin formato, que ocupan el menor de los espacios posibles en nuestro disco. Y luego son muy fáciles de migrar a cualquier base de datos.
Desventajas? Si. Los registros son viables de ser corrompidos con facilidad y la apertura del archivo también es muy sencilla, mediante cualquier editor de texto básico. Y, con lo visto hasta ahora... ¿cómo modifico un dato cualquiera del TXT, como por ejemplo el apellido o número de legajo? Por que no olvidemos que antes de abrir el archivo indico que operación efectuaré sobre el: lectura o escritura. Y si estoy leyendo, no puedo escribir... y viceversa. El procedimiento sería por demás de engorroso: ir leyendo el archivo de origen y copiándolo en otro, cuando encuentro el apellido o legajo en cuestión envío al archivo copia el nuevo dato, cierro ambos archivos y elimino el original, para finalizar renombrando la copia. Parece un galimatías, y lo es. Muy complicado. Entonces: fácil lectura, escritura y búsqueda de datos. Casi imposible modificar registros ya existentes.
Para lograr esto viene en nuestro auxilio el otro Modo de apertura: Aleatorio (random), el cual trataré en otro post, dada la complejidad y lo extenso del tema.
1201103358408
1201104875310
1201103568909
y partiendo de la premisa que todos poseen la misma longitud, podría volcar esos datos a Excel con estas líneas de código, las cuales deberán estar incluidas dentro del respectivo bucle:
‘leo la cadena de texto del archivo: Line Input #1, Texto ‘y con Mid() voy tomando partes de ese texto: Cells(x,1) = mid(texto, 1, 6) ‘la fecha Cells(x,2) = mid(texto, 7, 5) ‘el legajo Cells(x,3) = mid(texto, 12, 2) ‘horas trabajadas
Tampoco desmerezcamos mucho a estos archivos par buscar información dentro de ellos. Obviamente que no poseerá la velocidad y practicidad de una base de datos.... pero se defiende bastante. Si vamos al primer ejemplo (en donde migramos a Excel los registros del TXT), incorporando una simple línea podríamos sólo volcar aquellas líneas que cumplan con cierta condición:
‘cargo en la matriz la linea de texto Matrix() = Split(Texto, ";") ‘recorro la matriz: For X = 0 To UBound(Matrix(1)) ‘y solo vuelco a Excel si el segundo campo ‘(apellido) es igual a PELLEGRINI If Trim(Matrix(1)) = “PELLEGRINI” Then Cells(Fila, (X + 1)) = Matrix(X) End if Next X
Si bien describí un proceso muy repetitivo y, desde ya, no tiene punto de comparación con el manejo de una base de datos, merece un análisis en su defensa. Los procesadores están especialmente diseñados para realizar este tipo de trabajos (tareas repetidas) y no necesitamos ningún tipo de librería adicional: nos olvidamos de ODBC y sus orígenes de datos, bases de datos, conexiones, recordsets, sentencias SQL, etc, etc, todos objetos y rutinas que lógicamente también insumen recursos de nuestro ordenador. Y en la mayoría de los casos, la PC en donde se ejecutará nuestra macro deberá contar con las mencionadas librerías y demás, o nos veremos en la obligación de incorporarlas, para que todo funcione bien.
Por otra parte hablamos de archivos de texto plano, sin formato, que ocupan el menor de los espacios posibles en nuestro disco. Y luego son muy fáciles de migrar a cualquier base de datos.
Desventajas? Si. Los registros son viables de ser corrompidos con facilidad y la apertura del archivo también es muy sencilla, mediante cualquier editor de texto básico. Y, con lo visto hasta ahora... ¿cómo modifico un dato cualquiera del TXT, como por ejemplo el apellido o número de legajo? Por que no olvidemos que antes de abrir el archivo indico que operación efectuaré sobre el: lectura o escritura. Y si estoy leyendo, no puedo escribir... y viceversa. El procedimiento sería por demás de engorroso: ir leyendo el archivo de origen y copiándolo en otro, cuando encuentro el apellido o legajo en cuestión envío al archivo copia el nuevo dato, cierro ambos archivos y elimino el original, para finalizar renombrando la copia. Parece un galimatías, y lo es. Muy complicado. Entonces: fácil lectura, escritura y búsqueda de datos. Casi imposible modificar registros ya existentes.
Para lograr esto viene en nuestro auxilio el otro Modo de apertura: Aleatorio (random), el cual trataré en otro post, dada la complejidad y lo extenso del tema.
- Obtener enlace
- Correo electrónico
- Otras aplicaciones
Etiquetas
Macros
Etiquetas:
Macros
- Obtener enlace
- Correo electrónico
- Otras aplicaciones
Hola. Agradezco tu dedicación y la claridad con que lo explicas.
ResponderEliminarMi reto es, a partir de tu explicación, conseguir extraer datos de un TXT y exportarlos a otro TXT, preferiblemente sin tener que pegar los datos previamente a una hoja de Excel. El TXT origen contiene varias veces una cadena de texto determinada pero ésta se encuentra en líneas que no siguen ningún patrón. Un ejemplo:
me levanto
trabajo
duermo 8 horas
me levanto
salgo a correr
trabajo
duermo 7 horas
me levanto
trabajo
voy al cine
duermo 7 horas
(Aclaro que como todos los días y que normalmente hago algunas cosas más, pero esto es sólo un ejemplo)
Pretendo crear un archivo de texto con una sola columna que contenga las horas que voy durmiendo:
8
7
7
En fin, voy a ello.
Un saludo.
bien luis, de primera el tema que planteas y es totalmente factible de ser realizado.
ResponderEliminarcomienzo a trabajar en un post al respecto, así te lo explico claramente.
apenas lo termine te aviso. gracias x tus palabras.
aquí terminé el post con tu consulta:
ResponderEliminarhttp://damianexcel.blogspot.com/2010/12/interactuar-con-dos-archivos-de-texto.html
al final encontrarás el link al archivo, con el ejemplo.