Hojas de cálculo en Excel - página principal

Listar los archivos de un directorio

Hoy trataré de explicar, como obtener el nombre de todos los ficheros existentes en un directorio. Esto nos puede servir para muchas cosas, por ejemplo, para saber existe o no determinado fichero, o para grabar un fichero y que no se grabe con el mismo nombre de otro ya existente. Con independencia de la utilidad que queramos darle, estoy seguro que nos puede ser útil en más de una ocasión.

Para que este macro funcione, tendremos que tener grabado el fichero en nuestro disco duro. El código para devolvernos los ficheros existentes en la misma carpeta donde hayamos grabado el fichero, es el que aparece a continuación. El nombre de los ficheros, lo imprimiremos en la propia hoja de cálculo, aunque podemos imprimirlos en un combobox, por ejemplo:


Sub ficheros_del_directorio()
'Si hay errores, que continúe
On Error Resume Next
'Ocultamos el procedimiento
Application.ScreenUpdating = False
'Creamos el objeto FileSystemObject
Set fso = CreateObject("Scripting.FileSystemObject")
'Informamos de la ruta de donde vamos a obtener
'los ficheros, en este caso, el mismo directorio
'donde tengamos grabado este fichero con el macro

ruta = ActiveWorkbook.Path
'definimos dos variables que necesitaremos,
'para recuperar el nombre de la carpeta, y
'los ficheros que haya dentro

Set directorio = fso.GetFolder(ruta)
Set ficheros = directorio.Files
'escribimos un encabezado en la celda A6
Range("A6").Select
ActiveCell = "Ficheros del directorio:"
'lo ponemos en negrita y subrayado
ActiveCell.Font.Bold = True
ActiveCell.Font.Underline = xlUnderlineStyleSingle
'escribimos los ficheros, a partir de A7
Range("A7").Select
For Each archivo In ficheros
'escribimos el nombre del fichero
ActiveCell = archivo.Name
'bajamos una fila
ActiveCell.Offset(1, 0).Select
Next
'Limpiamos los objetos
Set fso = Nothing
Set directorio = Nothing
Set ficheros = Nothing
'Mostramos el procedimiento
Application.ScreenUpdating = True
End Sub

Si lo que deseamos es escribir los ficheros del directorio, pero sin incluir el nombre del fichero activo, es decir, del fichero desde donde estamos ejecutando el macro -porque por supuesto, al estar en el directorio, se listará-, entonces deberemos cambiar el bucle For Each anterior, por este otro que os incluyo a continuación, y que incorpora un condicional (el resto del código es el mismo, así que me ahorro el copiar y pegar). Esto solo nos servirá si el directorio del cual consultamos los ficheros, es el mismo donde tenemos guardado el fichero que ejecuta el macro, es decir, si se trata del mismo path:

For Each archivo In ficheros
'escribimos el nombre del fichero
If archivo.Name <> ActiveWorkbook.Name Then
ActiveCell = archivo.Name
'bajamos una fila
ActiveCell.Offset(1, 0).Select
End If
Next

Si lo que deseamos es listar solo los nombres de los subdirectorios existentes en el directorio donde tenemos guardado el fichero activo, entonces el macro que tendremos que utilizar, será este:

Sub subdirectorios_del_directorio()
'Si hay errores, que continúe
On Error Resume Next
'Ocultamos el procedimiento
Application.ScreenUpdating = False
'Creamos el objeto FileSystemObject
Set fso = CreateObject("Scripting.FileSystemObject")
'Informamos de la ruta de donde vamos a obtener
'los ficheros, en este caso, el mismo directorio
'donde tengamos grabado este fichero con el macro

ruta = ActiveWorkbook.Path
'definimos dos variables que necesitaremos,
'para recuperar el nombre de la carpeta, y
'los subdirectorios que haya dentro

Set directorio = fso.GetFolder(ruta)
Set subdirectorios = directorio.subfolders
'escribimos un encabezado en la celda C6
Range("C6").Select
ActiveCell = "Subdirectorios del directorio:"
'lo ponemos en negrita y subrayado
ActiveCell.Font.Bold = True
ActiveCell.Font.Underline = xlUnderlineStyleSingle
'escribimos los subdirectorios
ActiveCell.Offset(1, 0).Select
For Each subdirectorio In subdirectorios
'escribimos el nombre del subdirectorio
ActiveCell = subdirectorio.Name
'bajamos una fila
ActiveCell.Offset(1, 0).Select
Next
'Limpiamos los objetos
Set fso = Nothing
Set directorio = Nothing
Set subdirectorios = Nothing
'Mostramos el procedimiento
Application.ScreenUpdating = True
End Sub

Si lo que deseamos es listar los nombres de los subdirectorios y los ficheros existentes en el directorio donde tenemos guardado el fichero activo, entonces el macro que tendremos que utilizar, será este:

Sub ficheros_y_subdirectorios_del_directorio()
'Si hay errores, que continúe
On Error Resume Next
'Ocultamos el procedimiento
Application.ScreenUpdating = False
'Creamos el objeto FileSystemObject
Set fso = CreateObject("Scripting.FileSystemObject")
'Informamos de la ruta de donde vamos a obtener
'los ficheros, en este caso, el mismo directorio
'donde tengamos grabado este fichero con el macro

ruta = ActiveWorkbook.Path
'definimos dos variables que necesitaremos,
'para recuperar el nombre de la carpeta, y
'los subdirectorios y ficheros que haya dentro

Set directorio = fso.GetFolder(ruta)
Set subdirectorios = directorio.subfolders
Set ficheros = directorio.Files
'escribimos un encabezado en la celda D6
Range("D6").Select
ActiveCell = "Subdirectorios del directorio:"
'lo ponemos en negrita y subrayado
ActiveCell.Font.Bold = True
ActiveCell.Font.Underline = xlUnderlineStyleSingle
'escribimos los subdirectorios
ActiveCell.Offset(1, 0).Select
For Each subdirectorio In subdirectorios
'escribimos el nombre del subdirectorio
ActiveCell = subdirectorio.Name
'bajamos una fila
ActiveCell.Offset(1, 0).Select
Next
'a continuación escribimos los ficheros
'pero antes, escribiremos el encabezado

ActiveCell = "Ficheros del directorio:"
'lo ponemos en negrita y subrayado
ActiveCell.Font.Bold = True
ActiveCell.Font.Underline = xlUnderlineStyleSingle
'pasamos a la siguiente fila
ActiveCell.Offset(1, 0).Select
For Each archivo In ficheros
'escribimos el nombre del fichero
ActiveCell = archivo.Name
'bajamos una fila
ActiveCell.Offset(1, 0).Select
Next
'Limpiamos los objetos
Set fso = Nothing
Set directorio = Nothing
Set subdirectorios = Nothing
Set ficheros = Nothing
'Mostramos el procedimiento
Application.ScreenUpdating = True
End Sub


Desde aquí podéis descargar el fichero de excel, con el ejemplo que os presento en este artículo.



35 comentarios:

Anónimo dijo...

Muy bueno codigo
os agradesco

FMS

Javier Marco dijo...

Muchas gracias por tu comentario.

Un saludo.

Wingor dijo...

Estimado: Usted es un FENOOOOOOOMENO. Estoy inmensamente agradecido

Javier Marco dijo...

Muchas gracias por tu comentario, pero de fenómeno nada, que todavía me queda mucho por aprender de excel :-)

Anónimo dijo...

hola,

como hago para tambien trae la fecha de modificacion del archivo ??

me ayudaria bastante.

gracias

Javier Marco dijo...

Pues para el primer ejemplo, el de listar los ficheros del directorio (el macro que se ejecutar al pulsar el primer botón de esa hoja de cálculo, es decir, el botón que hay más a la izquierda de todo, de esos 4 que hay), donde pone:

For Each archivo In ficheros
'escribimos el nombre del fichero
ActiveCell = archivo.Name
'bajamos una fila
ActiveCell.Offset(1, 0).Select
Next

Tienes que cambiarlo por esto otro (para que te escriba en la celda de la derecha, la fecha de modificación del fichero):

For Each archivo In ficheros
'escribimos el nombre del fichero
ActiveCell = archivo.Name
'escribimos la fecha de modificación, a la derecha
ActiveCell.Offset(0, 1) = FormatDateTime(archivo.DateLastModified, vbShortDate)
'bajamos una fila
ActiveCell.Offset(1, 0).Select
Next

Daniel dijo...

Hola Javier, soy Daniel (de Chile)..después de haber visto tus comentarios de macros, sin duda me puedes ayudar..necesito hacer una macro que me permita ir llenando una b.datos a partir de un formulario...mas especificamente, tengo una hoja en la cual ingreso datos de personas (formulario de ingreso), y en otra hoja necesito ir guardando los datos, formando asi una b.datos...necesito de tu conocimiento, es urgente, gracias y saludos...

-=(ANDRES)=- dijo...

Javier: Como siempre un excelente codigo con gran aplicación, gracias por tu gran aporte.
Por otro lado no se si será posible, pero necesito una Macro que me Liste las unidades de Red activas del PC., por ej. que la salida sea simplemente:
C:
D:

Gracias!
Saludos.

Javier Marco dijo...

Prueba esto:

Sub leer_discos()
'Si hay errores, que continúe
On Error Resume Next
'Ocultamos el procedimiento
Application.ScreenUpdating = False
'Creamos el objeto FileSystemObject
Set fso = CreateObject("Scripting.FileSystemObject")
'buscamos las unidades
Set discos = fso.drives
For Each unidades In discos
'escribimos el nombre de la unidad
uni = uni & " " & unidades
Next
'Mostramos las unidades
respuesta = MsgBox("las unidades que tenemos son: " & uni)
'Limpiamos los objetos
Set fso = Nothing
Set directorio = Nothing
Set ficheros = Nothing
'Mostramos el procedimiento
Application.ScreenUpdating = True
End Sub

Saludos

-=(ANDRES)=- dijo...

Javier:

Muchas gracias. Yo había encontrado una solución pero muy poco eficiente (preguntaba por todo el abecedario). La solución que me entregas tu funciona perfecto.
Muchas gracias y sigue así!

Saludos

Javier Marco dijo...

Me alegro que te haya funcionado :-)

Gerion dijo...

Javier, muchas gracias. Creo que deberías dedicarte profesionalmente a esto.

Javier Marco dijo...

Gracias por el comentario, pero no creo que pudiera ganarme la vida con esto :-)

pablo dijo...

Estimado
Felicitaciones. La macro funciona perfecto.

Anónimo dijo...

Buenas, Javier. Lo cierto es que tu Blog lo he añadido en mis favoritos porque me ayuda muchísimo con las macros que hago. Pero en este caso me queda una duda, en mi caso tengo un archivo en el que cada semana tengo que incorporar datos nuevos desde otro archivo de excel que me envían, cada envío tiene un nombre diferente, y había pensado en crear una rutina en la que me muestre el listado de archivos y yo solo decirle de cual escoger. ¿Cómo puedo hacer algo así? ¿Sería adecuado usar un formulario? Muchas gracias

Javier Marco dijo...

Se me ocurre que puedes guardar ese fichero que te envían, en una carpeta exclusiva para ese fichero o para ese tipo de envíos. Como solo tendrás un archivo, tema resuelto, porque borrarías los antiguos, o los mandarías a otra carpeta. Si tuvieras varios archivos en esa carpeta, puedes buscar el más actual, por la fecha de creación (se supone que el más actual, es aquel con el que querrás trabajar, pues lo has guardado en esa carpeta para eso). Para saber la fecha del fichero, mírate esta entrada del blog donde hablo de la fecha de creación y modificación de un fichero excel. Para saber obtener datos de otro fichero excel, mírate esto qe habla precisamente de eso, de como leer datos de otro fichero excel.

Saludos, y gracias por tu comentario.

Un cielo Asturiano en Peru dijo...

Hola amigos,
os pido ayuda para hacer una variante de este programa.
desearia que esa lista fuera ampliada en el caso de archivos musicales, con el nombre del fichero. el interprete, el peso kb y el album a que pertenece.

jlb dijo...

Excelente amigo, bendiciones por tu colaboracion, primera vez que hago un Macro y funciona de maravilla, sigue adelante

Jose dijo...

Excelente blog, un saludo desde Colombia. Me preguntaba si existe una manera de listar todos los archivos de un directorio que contenga subdirectorios en varios niveles, es decir, una carpeta que contiene carpetas y a su vez estas contienen otras carpetas con archivos. Muchas gracias.

Rodrigo Tufiño dijo...

Excelente!!!

Me ayudaste con algo que necesitaba para mi trabajo. Con una llamada recursiva y modificando un poco el código permite recorrer todos los subdirectorios ;)

Anónimo dijo...

hola, gracias por todos tus valiosos apuntes y en especial en estas macros que me han ayudado muchisimo en mi trabajo, la verdad esta macro me fue muy productivo, yo lo pude modificar cuando necesitaba aparte de alistar los archivos de excel, me leyera un dato en especifico, entonces le hice esta modificacion a una parte del dato:

Dim auxWB As Workbook
Dim auxWS As Worksheet
Dim Valor

'escribimos los ficheros
ActiveCell.Offset(1, 0).Select
For Each archivo In ficheros
'escribimos el nombre del fichero
If archivo.Name <> ActiveWorkbook.Name Then
ActiveCell = archivo.Name
'bajamos una fila

ActiveCell.Offset(0, 1).Select

Set auxWB = Workbooks.Open(Filename:=archivo, Origin:=xlWindows)

Valor = auxWB.Worksheets(1).Range("E2").Value

auxWB.Close SaveChanges:=False

Set auxWB = Nothing

ActiveCell = Valor

ActiveCell.Offset(1, -1).Select

End If

aqui lo que hace es leer un solo dato de excel que esta siempre en el mismo celda y bajo, el problema es que llevo ya varias semanas intentanto que me sirva para leer varios datos ejemplos todos los archivos que me aliste aparte que me leea los datos de una celda, me leea avarios y me los ponga en orden , pero no he podido, me gustaria mucho que me ayudaras, de ante mano muchas gracias

dloc_yalp dijo...

Hola una consulta necesito hacer una macro que básicamente sea un indice de varias planillas que estén dentro de un directorio es decir en una columna debe estar por ejemplo
Archivo1.xls
Archivo2.xls
Archivo3.xls
y cuando hago click en una de esos tres archivos debería abrir dicho archivo. Podrías ayudarme por favor.
Desde ya gracias.

Javier Marco dijo...

Prueba a cambiar en el primer macro, esta parte del código:

For Each archivo In ficheros
'escribimos el nombre del fichero
ActiveCell = archivo.Name
'bajamos una fila
ActiveCell.Offset(1, 0).Select
Next

Por esta otra:

For Each archivo In ficheros
'escribimos el nombre del fichero
If InStr(archivo.Name, ".xl") > 0 Then
ActiveCell = archivo.Name
ActiveSheet.Hyperlinks.Add Anchor:=ActiveCell, Address:=ActiveCell
Else
ActiveCell = archivo.Name
End If
'bajamos una fila
ActiveCell.Offset(1, 0).Select
Next

Saludos.

dloc_yalp dijo...

Ok gracias por la respuesta. Lo pruebo y te aviso.

Anónimo dijo...

EMIL:
Genial como siempre!!! Este blog se ha convertido en mi referencia de VB para Excel. Ahora estoy tratando de conseguir modificar este código para que entre en cada uno de los subdirectorios y liste a su vez los subdirectorios y archivos de cada uno de ellos partiendo de un directorio inicial... Y la verdad es que no sé como conseguirlo. ¿Alguna sugerencia? Infinitas gracias por este EXCELente blog de ayuda.

sadid montero dijo...

yo hice el comentario del dia 05 de enero del 2011, agregue algo, sin emabrgo hice una pregunta y no me la respondiste y me eliminaste

Javier Marco dijo...

Sadid, queyo sepa solo borré tu mensaje de ayer el mensaje no aportaba nada, simplemente pedía solución a tu pregunta del 5 de enero que no he visto por ningún lado.

Si los usuarios publican 2, 3, o 4 mensajes seguidos como notas aclaratorias, a veces solo publico el que aporta algo interesante, y el resto los elimino. No sé si fue ese tu caso el 5 de enero.

Saludos.

juanjo vazquez dijo...

impresionante....muchas gracias
me podriais ayudar

tengo un directorio en el que guardo facturas .xls y quiero sacar una relación en otra hoja listando archivo, fecha, nombre cliente(a7),importe(f10),y vendedor(c3)........pero no se como sacar la información de estas hojas a7,f10y c3 y las ponga en la de resumen... 2010hd2mail@gmail.com

muchas gracias

jj dijo...

muchas gracias desde toledo españa

Fernando dijo...

Son codigos de gran ayuda, muchas gracias a los que los han aportado.
Javier A.

Anónimo dijo...

buenisimas macros...y como seria MOSTRAR FICHEROS Y SUBDIRECTORIOS CON SUS FICHEROS RESPECTIVOS???????


oajala pueda ayduarme...gracias...


the_new_kornflakes@hotmail.com

Fabio Betancourth dijo...

Tambien estoy interesado en poder listar todos los archivos de una ruta, incluyendo subcarpetas.

Muchas gracias,

Virginia dijo...

Hola, Javier
Muchas gracias por el blog, me está resultando de mucha ayuda, pero tengo un problemita, que te paso a exponer:
En lugar de listar el nombre del fichero, lo que necesito listar es el contenido de una celda, siempre la misma (R30), de todos los ficheros.
¿Podrías ayudarme?
Mil gracias de antemano por tu respuesta.

Virginia dijo...

Hola, Javier

Ya lo he conseguido, combinando varias cosas de las que he visto por aquí, ha tardado en hacerse alrededor de 6 horas, pero es que eran 13.600 archivos, pero por fin ha salido.
Muchas gracias.

Juan Manuel Rodriguez de la Fuente dijo...

Hola Javier
Yo quisiera que la macro recorriese todos los subdirectorios que colgaran de el y buscara archivos que cumplieran con una extensión determinada.