jueves, 24 de mayo de 2012

VBA: Una macro en Excel para listar las propiedades de un archivo.

En un articulo anterior mostré la forma en que podíamos listar los archivos contenidos en una carpeta de nuestro PC. Hoy, en respuesta a un lector que necesitaba además del nombre otras serie de datos de esos ficheros, explicaré qué código es necesario para obtener ciertas propiedades o atributos de los ficheros / archivos contenidos en una carpeta.
En particulas obtendremos en nuestra Hoja de excel, las propiedades:
Nombre = .Name
Fecha creación = .DateCreated
Fecha último acceso = .DateLastAccessed
Fecha última modificación = .DateLastModified
Tipo archivo = .Type
Tamaño en bytes = .Size
Ruta corta utilizada por los programas que necesitan necesitan la convención de nomenclatura 8+3 = .shortpath
Nombre corto utilizado por los programas que necesitan la convención de nomenclatura 8+3 = .shortname
Devuelve los atributos de archivos o carpetas. Lectura o escritura, o sólo lectura, dependiendo del valor atributo = .Attributes
Ruta completa = .Path

Insertaremos en un módulo del Explorador de proyectos del Editor de VBA el siguiente código, formando nuestra macro de Excel:

Sub ListarPropiedadesFicherosCarpeta()
'www.excelforo.com
Dim Ruta As String
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Creamos el objeto FileSystemObject que
'proporciona acceso al sistema de archivos de un equipo
Set fso = CreateObject("Scripting.FileSystemObject")
'Indicamos la ruta de donde vamos a obtener
'los ficheros, en este caso D:\BancoFotos
Ruta = "D:\BancoFotos\"
'definimos dos variables que necesitaremos,
'para recuperar el nombre de la carpeta, y los ficheros que haya dentro
Set Carpeta = fso.GetFolder(Ruta)
Set ficheros = Carpeta.Files
'damos un título en negrita para la celda A1
Range("A1").Value = "Ficheros de la carpeta " & Ruta
Range("B1").Value = "Fecha creación"
Range("C1").Value = "Fecha último acceso"
Range("D1").Value = "Fecha última modificación"
Range("E1").Value = "Tipo archivo"
Range("F1").Value = "Tamaño en bytes"
Range("G1").Value = "Ruta corta"
Range("H1").Value = "Nombre corto"
Range("I1").Value = "Atributo"
Range("J1").Value = "Ruta completa"
Range("A1:J1").Font.Bold = True

'escribimos los ficheros, a partir de A2
Range("A2").Select
For Each archivo In ficheros
    'escribimos el nombre del fichero
    ActiveCell = archivo.Name
    ActiveCell.Offset(0, 1) = archivo.DateCreated
    ActiveCell.Offset(0, 2) = archivo.DateLastAccessed
    ActiveCell.Offset(0, 3) = archivo.DateLastModified
    ActiveCell.Offset(0, 4) = archivo.Type
    ActiveCell.Offset(0, 5) = archivo.Size
    ActiveCell.Offset(0, 6) = archivo.shortpath
    ActiveCell.Offset(0, 7) = archivo.shortname
    ActiveCell.Offset(0, 8) = archivo.Attributes
    ActiveCell.Offset(0, 9) = archivo.Path
    
    'bajamos una fila
    ActiveCell.Offset(1, 0).Select
Next archivo
Range("A:J").EntireColumn.AutoFit
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Limpiamos los objetos y variables definidas
Set fso = Nothing
Set Carpeta = Nothing
Set ficheros = Nothing

Application.ScreenUpdating = True
End Sub


Al ejecutar la macro en la hoja de Excel podemos ver el resultado:

53 comentarios:

  1. estimado, te dejo este pequeño aporte de macro con conexion ADO y base de datoa ACCESS es una especie de control de stock, miralo y me comentas.

    http://dl.dropbox.com/u/30570853/Control%20de%20Stock%20(2)%20Aporte.zip

    Saludos desde Chile

    ResponderEliminar
    Respuestas
    1. Hola roro1981,
      ¿tienes alguna duda al respecto? o simplemente quieres que lo miré?
      Un cordial saludo

      Eliminar
    2. hola roro1981, me gustaria ver este aporte, ya que manejo un control de inventario, y esto me puede ser util.

      de antemano gracias

      Eliminar
  2. Excelente!, mil gracias por tu ayuda!

    ResponderEliminar
  3. hola excelforo me gustaria tu opinion al respecto, saludos

    ResponderEliminar
    Respuestas
    1. Hola roro1981,
      sin duda, me parece un buen fichero con una muy práctica programación VBA; aprovechando los recursos de ADODB connection.
      La verdad no he trabajado nunca con macros en este sentido (si con conexiones a través del estándar), pero me parece muy buena la idea.
      Y, de verdad, la parte del código de carga:
      Set rst = New ADODB.Recordset
      Sql = "SELECT * FROM productos where codigo='" & TextBox1 & "'"
      With rst
      .CursorLocation = adUseClient
      .CursorType = adOpenKeyset
      .LockType = adLockOptimistic
      .Open Sql, cnn, , , adCmdText
      End With

      donde aprovechas una parte del formulario para formar la Query mediante SQL en la base de datos Access, me parece superinteresante.
      Me parece que no te llego ni a la suela de los zapatos!!
      UN saludo y gracias por la lección!!

      Eliminar
  4. estimado: no es mi intención vanaglorearme de lo que he aprendido en macros solo busco la opinión de los mejores para poder ir hacia arriba en mis conocimientos.

    Saludos desde Chile

    ResponderEliminar
    Respuestas
    1. Hola roro1981,
      nada más lejos de mi intención insunuar tal cosa, todo lo contrario, admiro a los que son capaces de interpretar y utilizar todos los recovecos de Excel y sus macros.
      Un atento saludo!!

      Eliminar
  5. Si deseo obtener mas informacion. ej.
    Asunto
    Autor
    Organización
    Guardado por

    Y si mediante codigo VBA puedo modificar uno de ellos.

    Gracias por su ayuda.

    ResponderEliminar
    Respuestas
    1. Buenas Javier,
      lamentablemente la instrucción Getfolder(ruta).files no lee todas las propiedades de los ficheros; además de los explicados en la entrada otras propiedades que también entiende serían:
      .files
      .isrotfolder
      .subfolder
      .parentfolder
      .drive
      Slds

      Eliminar
    2. Hola como podría desplegar el autor, gracias

      Eliminar
    3. Hola,
      como indico en este comentario al usuario Javier, la instrucción Getfolder(ruta).files no lee todas las propiedades de los ficheros...
      y el author es una de ellas.
      Lo siento
      Slds

      Eliminar
    4. Hola, gracias por tu valioso aporte, yo necesito desplegar el campo Titulo, puedes ayudarme. Gracias.

      Eliminar
    5. Hola,
      puedes emplear

      Sub TituloArchivo()
      Dim oApp As New Excel.Application
      Dim oWB As Workbook
      Set oWB = ActiveWorkbook
      Dim titulo As String
      titulo = oWB.BuiltinDocumentProperties("Title")
      MsgBox titulo
      End Sub

      Saludos

      Eliminar
    6. Gracias me refería al campo de las propiedades del fichero (Titulo) Gracias

      Eliminar
    7. Sí, correcto...
      eso es lo que hace la pequeña macro

      Un saludo

      Eliminar
  6. hola una pregunta com debería modifcar para que buscará tambien en subcarpetas.
    Gracias de antemano.

    ResponderEliminar
    Respuestas
    1. Hola Carlos,
      existe una propiedad .Subfolders que te devolvería todas las carpetas contenidas en una carpeta especificada.
      Tendrías que añadirlo a
      Set Carpeta = fso.GetFolder(Ruta).Subfolders

      debería funcionar...
      Slds

      Eliminar
    2. Hola! estoy intentando tener un excel con informacion de mis carpetas y su tamaño a tiempo real por un tema de organizacion. Intente usar este macro y le sume el .Subfolders y no hubo caso...
      Apreciaria mucho que puedieras actualizar este post con la ruta completa :) (no me manejo mucho en macros)
      Gracias de antemano

      Eliminar
    3. Hola,
      subiré un post al blog dando respuesta.
      Un cordial saludo

      Eliminar
    4. Muchas gracias! espero con ansias tu post :)

      Eliminar
  7. perdona, pero al crear la macro, la ejecuto y no me crea el objeto, sino que se abre la ventana de macros, como si me pidiera ejecutar una..¿Podrás ayudarme?. Yo realmente lo que quiero es cambiar el atributo de fecha de creacion de un fichero, ya que al crearlo con FileCopy me coge los valores del fichero que copio. Si no te importa, y si me puedes ayudar, enviame un correo a pcandidomsn (arr o ba) hot mail.com (todo junto XD)
    Muchas Gracias

    'Creamos el objeto FileSystemObject que
    06.'proporciona acceso al sistema de archivos de un equipo
    07.Set fso =(CreateObject"Scripting.FileSystemObject")

    ResponderEliminar
    Respuestas
    1. Hola!,
      este código no abre ningún objeto, lo crea como parte de la programación, y es normal que al querer ejecutar macros, y presionar Alt+F8 se abra la venta de macros para seleccionar cuál queremos ejecutar.
      De todas formas este ejemplo sólo lista las propiedades del libro (fichero). En próximos días subiré una entrada al blog explicando cómo editar/modificar esas propiedades del documento.
      Slds

      Eliminar
  8. ROR01981 Excelente tu ejemplo a conexion MACRO VBA-ACCES, favor puedes realizar un ejemplo con SQL, y favor puedes realizar solo un ejecutable para que no se abra con excel.

    ResponderEliminar
    Respuestas
    1. Gracias Paul Condo,
      intentaré subir un post al respecto.
      Slds!!

      Eliminar
  9. Hice una macro en excel que inserta imágenes desde un directorio, en grupos de 50 (50 por vez) de productos de un almacén. En windows me funciona bien, pero en Mac no inserta las imágenes. Sólo las inserta cuando antes se han insertado manualmente en cualquier hoja, de una en una. Pienso que es un problema de permisos de acceso desde excel a la carpeta que contiene las imágenes.
    Me gustaría que alguien me ayude en eso. No sé cómo hacerlo. Gracias.

    ResponderEliminar
    Respuestas
    1. Hola, buenos días.
      Puede ser lo que indicas o también que la programación en Mac es, en muchos casos diferente.
      Quizá en un blog específico de Excel para Mac te den la solución
      Slds

      Eliminar
  10. La macro me parece muy interesante, pero desconozco los nombres de todas las propiedades, con lo que solo puedo obtener las que aparecen en la macro, pero hay muchas mas, ¿alguien me podría ayudar en poder obtener los nombres de las diferentes propiedades de los ficheros .jpg?

    ResponderEliminar
    Respuestas
    1. Hola Juan,
      no siempre hay por que emplear las propiedades de .FileSystemObject, a veces, si quieres ser muy preciso o completo se emplea .BuiltinDocumentProperties, que es más preciso.
      Puedes listar las propiedades así:

      For Each p In ActiveWorkbook.BuiltinDocumentProperties
      Cells(rw, 1).Value = p.Name
      rw = rw + 1
      Next

      En ocasiones también se emplea .GetDetailsOf

      Saludos

      Eliminar
    2. Muchas gracias por tu repuesta, ante todo informarte de que no soy experto en macros de estos niveles, asi que he intentado utilizar .BuiltinDocumentProperties y he conseguido una lista de propiedades, pero no se como conseguir una lista con las imágenes de una carpeta y su fecha de captura y el modelo con el que se hizo la captura.

      Eliminar
    3. De las 2 propuestas, la que mas se ajusta a mis necesidades es la segunda, en esencia es exactamente lo que necesito, aunque necesitaría poder incluir en la lista de propiedades a recuperar de los ficheros la fecha de captura de la imagen, así como el modelo de cámara utilizado, datos estos que en la visualización con el explorer son seleccionables.

      Eliminar
  11. se pueden sacar los datos EXIF de esta forma?

    ResponderEliminar
    Respuestas
    1. Hola Elioth
      qué tal estás?, un placer saludarte igualmente.

      Creo que los datos Exif están relacionados con el mundo de la fotografía e imágenes... y en todo caso, las propiedades que se pueden listar responden únicamente a las propiedades del fichero concreto, por lo que no creo posible acceder al interior del archivo/imagen par recuperar cierto tipo de propiedades.
      Cordiales saludos

      Eliminar
  12. Saludos, ten geniales como siempre tus Artículos.

    ResponderEliminar
  13. Hola! tiene alguna formula para tomar las dimensiones del archivo? para imagenes. Gracias!

    ResponderEliminar
  14. Buenas noches.

    Es posible que esta macro traiga tambien los nombres del creador y el autor de cada archivo?

    De ser asi como sería la macro?

    Gracias!

    ResponderEliminar
    Respuestas
    1. Hola!
      para otro tipo de propiedades si quieres ser muy preciso o completo se emplea .BuiltinDocumentProperties, que es más preciso.
      Puedes listar las propiedades así:

      For Each p In ActiveWorkbook.BuiltinDocumentProperties
      Cells(rw, 1).Value = p.Name
      rw = rw + 1
      Next

      En ocasiones también se emplea .GetDetailsOf

      Saludos

      Eliminar
  15. hola, estoy haciendo un archivo que me permita modificar las propiedades de archivos mp3, es decir que tengo que accesar a propiedades como Año de la cancion, Album, Interprete, Titulo, como se hace?

    ResponderEliminar
    Respuestas
    1. Hola,
      es bastante complejo...necesitarías librerías/referencias de un editor de audio (mp3), y casi seguro emplear parte del código en módulos de clase ... usando algunas API...
      Saludos

      Eliminar
  16. Bs dias
    Volviendo sobre el tema "listar imágenes de una carpeta y su fecha de captura ¿como es posible que si windows tiene la informacion de fecha de captura de la imagen no la pueda leer la macro o por lo menos esa macro?
    Seguro llego tarde pido disculpas..

    ResponderEliminar
    Respuestas
    1. Hola Pedro
      hasta done yo sé, esto funciona con librerías cargadas en Excel... si quien creó la librería de código no incluyó todas las propiedades, nosotros no podemos disponer de ellas (aunque exista la funcionalidad).
      Salvo mejor opinión, claro.

      Un saludo!!

      Eliminar
  17. Hola Ismael
    Entonces tu haces la macro usando la libreria que interesa que empaqueta informacion del explorador.
    La pregunta es ¿como ampliar la funcionalidad de esta libreria ?
    Tan potente es esta programación ?
    Muchas Gracias

    ResponderEliminar
  18. Vuelvo para decir que el parametro Fecha última modificación se corresponde en principio a la fecha de captura asi que ya tenemos listados de archivos con la fecha de captura.
    Lo tenia delante y no lo veia...
    saludos

    ResponderEliminar
    Respuestas
    1. Me alegro ya tengáis resuelto este pequeño entuerto
      ;-)

      Las librerías en principio no se pueden tocar (salvo mejor opinión)
      Saludos

      Eliminar
  19. Buenas. Como hago para que el Tamaño de archivo salga en KB. También quiero aplicar un filtro por hora de creación.. Me explico... tengo una carpeta que cada hora se genera uno nuevo archivo. Solo quiero tomar la información del archivo de las 8 am y no los demás..

    ResponderEliminar
    Respuestas
    1. Hola!
      para obtener el dato en Kb simplemente divide por 1024 el resultado de la propiedad .Size
      ActiveCell.Offset(0, 5) = archivo.Size/1024

      En cuanto al filtro aplica para cada archivo un condicional
      ...
      If TimeValue(archivo.DateCreated) = TimeSerial(8, 0, 0) Then
      ...

      Saludos

      Eliminar
  20. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  21. Hola! Tengo la necesidad de obtener el propietario de los archivos Pdf. ¿Cómo lo puedo hacer?

    Gracias

    ResponderEliminar

Nota: solo los miembros de este blog pueden publicar comentarios.