Hola a todos 🙂
Espero que todo os vaya bien!
La verdad es que llevo unas semanas con un montón de consultas y como siempre con muy poco tiempo disponible. Muchos de vosotros estáis buscando formas y métodos para hacer de vuestro trabajo una experiencia mucho más eficiente y fiable.
La programación es sin duda la forma de hacerlo!. Hoy volvemos parcialmente sobre un tema ampliamente tratado en este blog, la consolidación o agrupación de archivos de Excel (en este post tenéis acceso a las publicaciones relacionadas: AGRUPAR INFORMACIÓN DE VARIOS LIBROS EN UNA HOJA EXCEL).
Pero hoy la diferencia es que vamos a consolidar información de varios archivos CSV (archivos delimitados por comas) y que también nos va a servir para archivos de texto (TXT).
Tuve mis dudas sobre el método a utilizar, pero finalmente me he inclinado por usar en parte una de las herramientas predefinidas en Excel: Conectarse con datos externos (Importar) y hacer así la tarea un poco más rápida.
La razón de escribir este post se debe a una consulta recibida estos últimos días donde un lector preguntaba cómo podía consolidar la información de varios archivos CSV en una sola hoja de Excel, obviamente cada campo separado por comas en una columna.
Como siempre, vamos a utilizar un pequeño ejemplo: imaginad que tenemos cuatro archivos CSV:
En el que consta la información de cuatro grupos de estudiantes en los que se describe: ID, NOMBRE, CLASE, ASIGNATURAS Y CALIFICACIONES, y la coma es el delimitador de cada campo:
Pues bien, para poder realizar este trabajo, vamos a usar la siguiente macro:
Sub IMPORTAR_CSV()
'Definimos Variables
Dim Consulta As QueryTable, nArchivos As Variant, j As Long, i As Long
Dim uFila As Long, Conexiones As Object
'Seleccionamos archivos
nArchivos = Application.GetOpenFilename(FileFilter:="Text Files (*.CSV),*.CSV", _
Title:="Seleccionar archivos a importar", MultiSelect:=True)
'Si no seleccionamos nada, salimos del proceso
If IsArray(nArchivos) = False Then Exit Sub
'Dimensionamos datos
For j = LBound(nArchivos) To UBound(nArchivos)
nArchivos(j) = "TEXT;" & nArchivos(j)
Next j
For j = LBound(nArchivos) To UBound(nArchivos)
'Comprobamos la última fila con datos de la columna A
With Sheets("CONSOLIDADO")
If Application.CountA(.Range("A:A")) = 0 Then
uFila = 1
Else
uFila = Application.CountA(.Range("A:A")) + 1
End If
'Iniciamos la consulta
Set Consulta = .QueryTables.Add(Connection:=nArchivos(j), Destination:=.Range("A" & uFila))
'Indicamos parámetros de la consulta que nos interesan:
With Consulta
.Name = "Datos"
.FieldNames = True
.PreserveFormatting = True
.RefreshStyle = xlInsertDeleteCells
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileCommaDelimiter = True
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
End With
Next j
'Eliminamos todas las conexiones que hemos iniciado.
For Each Conexiones In ActiveWorkbook.Connections
Conexiones.Delete
Next Conexiones
End Sub
Como podéis observar, estamos utilizando una consulta (querytables) para importar la información y colocarla según el delimitador que tenemos, que en este caso es una coma. Si fuese punto y coma por que es un texto, bastaría sustituir en la macro:
.TextFileCommaDelimiter = True
por esto:
.TextFileSemicolonDelimiter = True
Y donde ponemos CSV en Application.GetOpenFilename
poner TXT. Pero como estamos tratando con archivos CSV, dejamos la coma.
Una vez que ejecutamos la macro, la información consolidada quedaría así:
Como podéis ver, hemos agrupado todos los archivos, según los especificado en los CSV y en el código.
OJO La parte final de la macro elimina todas las conexiones del libro y por lo tanto todas las que hemos creado para importar la información.
For Each Conexiones In ActiveWorkbook.Connections
Conexiones.Delete
Next Conexiones
Aunque lo normal es dejar las conexión por si las queremos actualizar, en este caso no tiene sentido dado que estamos consolidando informaciones de muchos ficheros y además supondría tener cientos de conexiones en la archivo, por ejemplo, en este, sin eliminarlas se verían así:
Si las queréis conservar, simplemente eliminad esa parte de la macro o dejadla como está, pero tened en cuenta que borra todas las conexiones del libro.
Sobre los parámetros, vosotros mismos podéis configurarlos, o bien consultáis en el soporte de microsoft sobre el objeto QueryTables o con el grabador de macros, grabáis una importación y añadís a la macro las especificaciones que necesitéis.
Y esto es todo, os dejo la macro para que la probéis y espero que en algún momento os sea de utilidad.
Descarga el archivo de ejemplo pulsando en: CONSOLIDAR VARIOS ARCHIVOS CSV O TXT USANDO CONEXIÓN DE DATOS EXTERNOS Y VBA
Los archivos de prueba los subo en una carpeta a Google Drive: ARCHIVOS DE EJEMPLO PARA PRUEBAS
¿Te ha resultado de interés?, puedes apoyar a Excel Signum con una pequeña donación.
¡¡Muchas gracias!!
Hola,
Como hago para indicarle la codificación, no me toma los acentos y caracteres especiales.
Saludos
Alberto
Tendrías que incluir un proceso dentro del proceso que reemplace los caracteres que indiques.
Saludos
Muchas gracias por el código. Estoy intentando importar múltiples csv con datos y fechas de unas maquinas, y tenia un montón de problemas para importarlos en formato delimitado y que las fechas no me cambiasen a formato americano.
Solo una pregunta con el código, mis ficheros csv siempre se almacenan en la misma carpeta. Hay alguna manera de automáticamente seleccionar todos los ficheros csv de una misma carpeta? He probado de añadir un directorio antes del Application.GetOpenFilename, sin éxito.
Y de verdad, muchas gracias por el código!
Intento estudiar una solución a lo que indicas, aunque requiere un desarrollo mayor. Saludos.
Gracias, como puedo hacer para obtener el nombre del archivo conjuntamente con los datos, tal como hace el Merge.
Saludos
Josep
Hola Josep:
Tendrías que colocar la referencia al name del archivo en el primer loop para que escriba el dato en la primera fila. Saludos
Perdona, no entiendo bien esta parte.
Podrías explicar como añadir dicha modificación?
Muchas gracias
Sí,
Es sencillo justo entre end With y Next J pones esto:
hNombre = Mid(nArchivos(j), InStrRev(nArchivos(j), "\", Len(nArchivos(j))) + 1, Len(nArchivos(j)))
With Sheets("CONSOLIDADO")
Fin = Application.CountA(.Range("A:A"))
.Range("F" & uFila & ":" & "F" & Fin) = Nombre
End Wit
Y ya tienes el nombre del archivo en la columna F.
Saludos.
Gracias. Es muy bueno.
Tengo una duda, en un campo (dirección) a veces a parece una coma y eso hace que a partir de la coma lo entienda como parte de otra columna, alterando así la tabla.
He probado con TextfileTabDelimiter pero no lo consigo. Como se podría solucionar?
Gracias de nuevo
No puedes si utilizas la coma como delimitador. Tendrías que modificarlo en origen.
Saludos.
como hago por favor una orientacion cuando vuelvo a acomular el mismo archivo csv. se agregan mas
y no lo reemplaza
Tienes que introducir una línea que borre la información cada vez que ejecutas la macro.Saludos