Hace unos días escribí un post sobre cómo importar archivos txt delimitados por caracteres, y quedaba pendiente para otro post (este), importar archivos txt pero de ancho fijo.
Pues bien, siguiendo con el ejemplo anterior, ahora lo que tenemos es una archivo de texto de ancho fijo, previamente definido especificando el ancho de cada campo de texto. Vemos el archivo:
A simple vista ya podemos ver las diferencias con el archivo de la entrada anterior, efectivamente los datos están alineados y con una distancia específica entre cada cadena de texto. Para tratar e importar el archivo a Excel, vamos a usar la misma macro que el ejemplo anterior, pero con algunas modificaciones importantes:
Sub Import_TXT_Anchofijo()
'Definimos variables a utilizar
Dim Filtro As String
Dim nFichero As Integer
Dim sCadena As Variant
Dim i As Double
nFichero = FreeFile
'indicamos que tipo de archivo que vamos a seleccionar (txt)
Filtro = " TXT(*.TXT),"
'buscamos el archivo
txt = Application.GetOpenFilename(Filtro)
'si existe fichero comenzamos la instrucción, de lo contrario el proceso no se 'inicia
If txt <> Empty Then
'mediante un bucle do while recorremos todas las líneas de información del txt
Open txt For Input As nFichero
i = 0
Do While Not EOF(nFichero)
Line Input #nFichero, datos
i = i + 1
sCadena = datos
'definimos la longitud del ancho de cada información e indicamos en que columna se 'debe insertar
'la fila ya viene determinada con la longitud del fichero txt (i) que hemos 'definido al principio
'con la función Mid indicamos los campos a extraer y la con la función Trim 'eliminamos espacios en blanco
'que se nos puedan haber olvidado por error.
With Sheets(1)
.Cells(i, 1) = Trim(Mid(sCadena, 1, 3))
.Cells(i, 2) = Trim(Mid(sCadena, 4, 29))
.Cells(i, 3) = Trim(Mid(sCadena, 33, 20))
.Cells(i, 4) = Trim(Mid(sCadena, 53, 10))
.Cells(i, 5) = Trim(Mid(sCadena, 63, 8))
.Cells(i, 6) = Trim(Mid(sCadena, 71, 16))
.Cells(i, 7) = Trim(Mid(sCadena, 87, 21))
End With
Loop
'por último cerramos el proceso.
Close nFichero
End If
End Sub
Como podéis observar, una vez que seleccionamos el archivo txt, y aislamos la cadena de texto (sCadena) ya podemos extraer cada una de las palabras o caracteres con la función Mid. Por ejemplo, el primer campo tiene 3 espacios de ancho, por ello extraemos desde el punto 1 hasta el tercer carácter: Mid(sCadena, 1, 3)
Para reforzar la función, aplicaremos Trim que es otra función (espacios o recortar) que elimina los espacios en blanco al principio y final del texto, solucionando así si por error introducimos un espacio vacío.
Normalmente cuando tratamos archivos de ancho fijo, tenemos las especificaciones para realizar la importación, en caso de no tenerlas es necesario verificar con suma atención los anchos. En el INE, por ejemplo, todos los archivos que os descarguéis de ancho fijo vienen con un archivo Excel con las especificaciones definidas.
Y ahora ya tenemos toda la información necesaria para importar cualquier tipo de archivo txt, espero que os haya resultado de interés:
Descarga el archivo de ejemplo pulsando en: IMPORTAR TXT DE ANCHO FIJO
Descarga el archivo TXT de ejemplo pulsando en: ARCHIVO TXT ANCHO FIJO
Sera casualidad, pero ya son varios los artículos que publicas que justamente tratan el problema con el que me estoy enfrentando. Lo de importar archivos TXT me ha venido como anillo al dedo, justamente ahora esta planteando como hacerlo y ya me lo has dado resuelto.
La macro como siempre sencilla, muy bien explicada y muy util.
Gracias por tu tiempo.
Adolfo
Muchas gracias Adolfo 🙂 Perfecto que te sirva de ayuda! Últimamente también trato con bastante archivo txt y me parecía una buena idea desarrollar un post sobre el tema.
Lo dicho, muchas gracias! Saludos
buenas tardes amigo, me ha servido de mucho tu codigo lo he modificado un poco a mis necesidades, te queria preguntar existe manera, de seleccionar varios txt al mismo tiempo y que estos se extraigan cada uno en un mismo libro pero en diferentes hojas colocandoles a cada una el nombre del txt. la macro que estoy usando es la siguiente:
Sub Import_TXT_Anchofijo()
‘Definimos variables a utilizar
Dim Filtro As String
Dim nFichero As Integer
Dim sCadena As Variant
Dim i As Double
nFichero = FreeFile
‘indicamos que tipo de archivo que vamos a seleccionar (txt)
Filtro = » TXT(*.TXT),»
‘buscamos el archivo
txt = Application.GetOpenFilename(Filtro)
‘si existe fichero comenzamos la instrucción, de lo contrario el proceso no se ‘inicia
If txt Empty Then
‘mediante un bucle do while recorremos todas las líneas de información del txt
Open txt For Input As nFichero
i = 0
Do While Not EOF(nFichero)
Line Input #nFichero, datos
i = i + 1
sCadena = datos
‘definimos la longitud del ancho de cada información e indicamos en que columna se ‘debe insertar
‘la fila ya viene determinada con la longitud del fichero txt (i) que hemos ‘definido al principio
‘con la función Mid indicamos los campos a extraer y la con la función Trim ‘eliminamos espacios en blanco
‘que se nos puedan haber olvidado por error.
With Sheets(1)
.Cells(i, 1) = (Mid(sCadena, 1, 35))
.Cells(i, 2) = (Mid(sCadena, 136, 20))
.Cells(i, 3) = (Mid(sCadena, 156, 22))
.Cells(i, 4) = (Mid(sCadena, 176, 21))
End With
Loop
‘por último cerramos el proceso.
Close nFichero
End If
End Sub
Hola:
Tendría que programarlo para que llevara la información a cada hoja.
De todas formas si te sirve que se consoliden todos los datos en una única hoja, te paso este post:
https://excelsignum.com/2017/09/16/consolidar-varios-archivos-csv-o-txt-usando-conexion-de-datos-externos-y-vba/
En los próximos días trataré de programar lo que preguntas.
Saludos.
Gracias amigo estare a la espera de tu colaboracion, ya que por la continuidad o cantidad de TXT, me son necesarios en una hoja cada uno, en esta ultima macro que me indicas esta definido por tabulacion, y lo necesitaba de ancho fijo, tratare de ver como adaptarlo.
Buenos días,
Primero quiero agradecer ya que he aprendido mucho con ustedes y me me han servido muchas de sus macros.
Hoy quisiera que me ayudaran con un código para abrir un TXT que está delimitado por ancho fijo, y que me de la opción de cambiar la delimitación de los campos ya que en mi trabajo tengo que abrir muchos TXT pero tienen diferente largo, a ver si me hice entender, cuando abra el TXT que me pregunte la delimitación de los campos de alguna forma, se me ocurre seleccionando un rango de celdas que contengan el largo de cada columna.
Les agradecería muchísimo, gracias.
Hola Fabián, lo que comentas, si lo he entendido bien, de hacer referencia a los largos de campo de una hoja excel, ¿no es lo mismo que modificarlos en el código?, Sería para evitar realizar la modificación en el código y realizar directamente haciendo referencia a una hoja?
Sería un tema a estudiar. Esta macro está pensada para procesos estandarizados, donde cada x tiempo has de importar los mismos txt. No obstante, me gustaría que explicases un poco más la problemática que tienes.
Para vincular el ancho de campo a una hoja, solo tienes que hacer referencia a la hoja en la función Mid, por ejemplo, aquí:
(Mid(sCadena, 1, 3))
se podría hacer referencia a(Mid(sCadena, sheets(1).cells(1,1), sheets(1).cells(1,2)))
donde en la hoja 1 en las celdas a1 y a2 tendrías los valores 1 y 3 respectivamente.De esta forma, con una plantilla base podrías ir modificando los anchos de cada campo, simplemente modificándolos en la hoja y no en el código.
Saludos.
Hola Segu,
Gracias por tu pronta respuesta,
Es exactamente lo que tú dices la maro es para un proceso estándar porque siempre se importar el mismo txt, pero en mi caso tengo un aproximado de 30 archivos txt con diferentes largos y quiera tener un solo proceso para todos donde solo tenga que cambiar el dato, un ejemplo de la fila 1 la cual tendrá en cada columna (celda) el largo que necesito en el momento para el txt que quiero abrir, pues estos largos si están definidos en el layout de cada txt.
Este es el uso que quisiera implementar.
Mil gracias.
Hola Fabián,
Entonces, entiendo que esos 30 TXT forman parte de un proceso (mensual, diario, etc) que has de abrirlos uno por uno y volcar la información en una hoja (u hojas). Suponiendo que el nombre de los TXT no cambie en cada mes (que debería sea así). Una forma sería modificar la macro, eliminando el getopen y la referencia al filtro txt y escribir directamente la ruta, es proceso lo repites por tantos txt tengas que importar, (30 o los que sean)
Sub Import_TXT_Anchofijo()
Dim Filtro As String, nFichero As Integer, sCadena As Variant, i As Double
nFichero = FreeFile
txt = "C:\Users\tuarchivo.txt"
If txt Empty Then
Open txt For Input As nFichero
i = 0
Do While Not EOF(nFichero)
Line Input #nFichero, datos
i = i + 1
sCadena = datos
With Sheets(1)
.Cells(i, 1) = Trim(Mid(sCadena, 1, 3))
.Cells(i, 2) = Trim(Mid(sCadena, 4, 29))
End With
Loop
Close nFichero
End If
Call (y la macro)
Call (y la macro)
Call (y la macro)
....
End Sub
Una vez que los tengas referenciados a una carpeta o a varias, luego solo tendrás que utilizar una de esas macros y justo antes de End Sub haces un Call a cada macro, de forma que ejecutaras todo el proceso a la vez. Es un proceso sencillo, podrás determinar las especificaciones de cada TXT en su macro y controlar los posibles errores, además podrás vincular cada exportación a una pestaña.
Espero que así lo puedas lo solucionar. Saludos.
Hola Segu
Muchas gracias por esta ayuda.
Sin embargo, estoy teniendo un problema, ya que el txt que necesito importar no esta separado, es decir, los caracteres vienen todos agrupados por linea de datos, por lo que las lineas de códigos .Cells(i, 1) = Trim(Mid(sCadena no están funcionando.
Me puedes indicar como corregir esto?
Desde ya muchas gracias por tu ayuda
Hola Darwin,
No tendría que ser un problema que los datos del .txt estén todos juntos, de echo es lo habitual (en ancho fijo con ceros o con espacios) y con con caracteres. Por ello, me resulta extraño que no te funcione correctamente.
Por otra parte, si se trata de un archivo de texto de ancho fijo seguramente en algún lugar tendrás las especificaciones para la importación, de no ser así habría que hacerlas.
Para responderte más concretamente necesitaría ver el txt y también el resultado esperado de la importación. Esto lo puedes hacer enviando a excelsignum@yahoo.es el txt (un ejemplo de prueba) y en excel el resultado de cómo debería quedar (por ejemplo, la primera linea del txt).
Saludos.
Muy práctica tu Macro! Qué debería hacer para importar un archivo .txt con un header? Digamos que el archivo tiene un encabezado de 30 líneas y quisiera que esas líneas se omitan, o se carguen juntas, y recién después en la línea 31 comenzara a ejecutarse el código de tu macro?
Desde ya, muchas gracias por tu tiempo,
M.
Hola Marcelo:
O bien comienzas a importar desde la línea 30 o bien importas todo a Excel y ahí eliminas el encabezado. Esas serías las alternativas.
Saludos.
Espectacular la Macro! mi único problema es que son muuuchos registros, y me tarda como 8min en promedio en procesarme el archivo =S
Hola Faq:
8 minutos es bastante, pero supongo que tiene que ver con el volumen de la información. Puedes intentar con esta macro que importa también TXT según especificaciones:
https://excelsignum.com/2017/04/21/trabajar-con-grandes-bases-de-datos-en-excel-parte-1-importar-la-informacion/
Te podría servir.
Muy buena la macro me ha servido mucho
pero hay forma de ingresar varios archivos .txt y que se agrupen en una sola hoja
esa es mi duda
gracias
Hola Juan Diego:
Sí lo puedes hacer, se trataría que incluir en un loop tantas consultas como necesites y pasarlas a la hoja. Pero sí es posible.
Saludos.
SI pero en el loop a la hora de cargar los .txt no los va a sobrescribir ?
esas es mi duda
si me puedes ayudar
No debería, cuando lo programas, una variable tiene que decirte siempre en todo momento donde está el final de los datos para grabar la nueva información y no sobreescribir, en este post es la variable «i» la que realizar este trabajo. Aunque no es lo mismo aquí podrás ver un ejemplo:
https://excelsignum.com/2017/09/16/consolidar-varios-archivos-csv-o-txt-usando-conexion-de-datos-externos-y-vba/
En concreto: Destination:=.Range(«A» & uFila)) es donde se indica el lugar a pegar los nuevos datos.
Si tengo tiempo, intento escribir un post con ese mismo ejemplo para varios archivos o consultas.
Saludos
gracias , si me ayudaria mucho
es para un proyecto de curso y aun no se
como agregar varios archivos de txt con ancho fijo y se carguen en una hoja
Cuando tenga un momento intento ayudarte,. Saludos.
Buenos días profe, como estas?
Tengo que leer 500 archivos de texto fijo y consolidarlos en una misma hoja, pero no se como recorrer la carpeta que contiene los archivos. te agradezco mucho me puedas dar respuesta mil gracias
Tienes en la web multitud de ejemplo para consolidar archivos. Usa el buscador.
Un ejemplo es este: https://excelsignum.com/2017/09/16/consolidar-varios-archivos-csv-o-txt-usando-conexion-de-datos-externos-y-vba/
Saludo.s