Cómo hacer una macro Excel para recorrer todos los archivos de una carpeta

Introducción

Recorrer automáticamente todos los archivos de una carpeta es una de las tareas más habituales en la automatización con Excel VBA. Este tipo de macro resulta útil cuando una empresa recibe decenas o cientos de libros con una estructura similar y necesita abrirlos, leer determinados datos, consolidar información, comprobar su contenido, cambiar formatos o generar un informe conjunto.

Contenido

Aunque la idea parece sencilla, una solución fiable debe resolver varios problemas prácticos: comprobar que la carpeta existe, verificar que el usuario dispone de permisos, decidir qué extensiones se procesarán, evitar archivos temporales creados por Excel y controlar los posibles errores al abrir libros dañados, protegidos o bloqueados por otro usuario.

En este artículo se desarrolla una estructura de macro reutilizable para recorrer archivos de una carpeta de forma controlada. El objetivo no es limitarse a mostrar un bucle básico, sino explicar cómo convertirlo en una solución adecuada para el trabajo real de un profesional, una microempresa o una pyme.

Índice

Qué significa recorrer los archivos de una carpeta con una macro

Recorrer una carpeta significa obtener, uno por uno, los nombres o las rutas de los archivos que contiene y ejecutar una operación sobre cada elemento encontrado. En VBA, este proceso suele realizarse mediante un bucle que continúa hasta que ya no quedan más archivos por revisar.

La macro puede limitarse a inventariar los documentos o puede abrir cada libro y trabajar con su contenido. Por ejemplo, podría acceder a una hoja determinada, leer una celda, copiar una tabla, comprobar una fecha o incorporar información a un libro maestro.

El patrón general del proceso es el siguiente:

  1. Obtener o solicitar al usuario la ruta de la carpeta.
  2. Comprobar que la ruta existe y es accesible.
  3. Localizar el primer archivo que cumpla los criterios establecidos.
  4. Descartar archivos temporales, ocultos o no válidos.
  5. Abrir el archivo cuando sea necesario.
  6. Ejecutar el tratamiento programado.
  7. Cerrar el archivo de forma controlada.
  8. Continuar con el siguiente archivo.
  9. Registrar los resultados y posibles incidencias.

Esta estructura puede integrarse posteriormente en una solución más amplia, como una macro para consolidar datos y preparar un informe final o un sistema para generar informes por cliente desde una plantilla de Excel.

Casos de uso habituales

Una macro que recorre archivos puede utilizarse en numerosos procesos administrativos, técnicos y comerciales. Algunos ejemplos habituales son los siguientes:

  • Consolidar hojas de ventas mensuales enviadas por distintas delegaciones.
  • Leer facturas o listados almacenados en varios libros.
  • Extraer datos de partes de trabajo.
  • Revisar si todos los archivos contienen una hoja obligatoria.
  • Comprobar que determinadas celdas están cumplimentadas.
  • Actualizar tablas, fórmulas o gráficos en varios libros.
  • Cambiar nombres de hojas o formatos de celda.
  • Generar un inventario de archivos con nombre, extensión, tamaño y fecha.
  • Exportar varios informes de Excel a PDF.
  • Separar o reorganizar información por clientes, proyectos o departamentos.

La principal ventaja es que el usuario deja de abrir manualmente cada archivo. Esto reduce tiempo, evita operaciones repetitivas y disminuye el riesgo de omitir documentos o copiar datos en una posición incorrecta.

Requisitos previos antes de crear la macro

Antes de escribir el código conviene definir con precisión qué debe hacer la automatización. Una macro que simplemente enumera archivos no necesita las mismas comprobaciones que otra que abre cien libros, modifica información y guarda los cambios.

Estructura de los archivos

Debe comprobarse si todos los documentos tienen una estructura homogénea. Es importante saber:

  • Si las hojas tienen los mismos nombres.
  • Si las columnas aparecen siempre en el mismo orden.
  • Si los encabezados se encuentran en la misma fila.
  • Si existen libros antiguos con un formato diferente.
  • Si algunos archivos pueden estar vacíos.
  • Si las hojas o libros están protegidos.

Tipos de archivo admitidos

También hay que decidir qué extensiones formarán parte del proceso. Una carpeta puede contener libros de Excel, archivos PDF, documentos de texto, imágenes y subcarpetas. La macro debe indicar expresamente qué elementos quiere procesar.

Entre las extensiones más habituales de Excel se encuentran:

  • .xlsx: libro de Excel sin macros.
  • .xlsm: libro habilitado para macros.
  • .xlsb: libro binario de Excel.
  • .xls: formato antiguo de Excel.
  • .csv: archivo de texto con datos separados por delimitadores.

Acción que se realizará

Debe especificarse si la macro solo leerá los libros o también los modificará. Esta decisión afecta al modo de apertura, al cierre de cada archivo y a la necesidad de realizar copias de seguridad.

Cuando el proceso todavía se realiza manualmente, puede ser útil analizar primero qué tareas de Excel deberían automatizarse y cuáles conviene mantener bajo supervisión humana.

Cómo seleccionar la carpeta que se va a procesar

La ruta puede escribirse directamente en el código, almacenarse en una celda de configuración o seleccionarse mediante una ventana de exploración. Para una herramienta que utilizarán distintos usuarios, normalmente resulta más práctico mostrar un selector de carpetas.

Función para seleccionar una carpeta

Private Function SeleccionarCarpeta() As String

```
Dim selector As FileDialog

Set selector = Application.FileDialog(msoFileDialogFolderPicker)

With selector
    .Title = "Seleccione la carpeta que desea procesar"
    .AllowMultiSelect = False

    If .Show = -1 Then
        SeleccionarCarpeta = .SelectedItems(1)
    Else
        SeleccionarCarpeta = vbNullString
    End If
End With

Set selector = Nothing
```

End Function

La función devuelve la ruta elegida. Si el usuario cancela la ventana, devuelve una cadena vacía. La macro principal debe comprobar esta situación antes de continuar.

Ruta fija almacenada en una celda

Otra posibilidad consiste en guardar la carpeta en una hoja de configuración:

rutaCarpeta = ThisWorkbook.Worksheets("Configuracion").Range("B2").Value

Esta alternativa es útil cuando la carpeta cambia ocasionalmente y se quiere evitar modificar el código VBA. Sin embargo, conviene validar siempre el valor de la celda antes de comenzar.

Métodos disponibles en VBA para recorrer archivos

VBA permite recorrer archivos principalmente mediante la función Dir o mediante FileSystemObject. Ambos métodos son válidos, pero tienen características diferentes.

Función Dir

Dir forma parte de VBA y no requiere activar referencias adicionales. Es rápida y suficiente para muchos procesos sencillos.

Su funcionamiento básico consiste en solicitar el primer archivo que cumpla un patrón y llamar después repetidamente a Dir() sin argumentos para obtener los siguientes.

nombreArchivo = Dir(rutaCarpeta & "\*.xlsx")

Do While nombreArchivo <> vbNullString
Debug.Print nombreArchivo
nombreArchivo = Dir()
Loop

FileSystemObject

FileSystemObject ofrece objetos específicos para carpetas y archivos. Facilita el acceso a propiedades como el tamaño, la fecha de modificación o el tipo de archivo, y resulta cómodo cuando se quieren recorrer subcarpetas.

Dim sistemaArchivos As Object
Dim carpeta As Object
Dim archivo As Object

Set sistemaArchivos = CreateObject("Scripting.FileSystemObject")
Set carpeta = sistemaArchivos.GetFolder(rutaCarpeta)

For Each archivo In carpeta.Files
Debug.Print archivo.Name
Next archivo

Qué método conviene utilizar

Para una macro sencilla que busque archivos por extensión, Dir suele ser suficiente. Cuando se necesitan propiedades adicionales, una estructura orientada a objetos o un recorrido recursivo por subcarpetas, FileSystemObject puede resultar más claro.

Macro completa para recorrer todos los archivos de una carpeta

El siguiente ejemplo utiliza Dir, permite seleccionar una carpeta, procesa varios formatos de Excel, descarta archivos temporales y evita abrir el propio libro que contiene la macro.

Option Explicit

Public Sub RecorrerArchivosDeCarpeta()

    Dim rutaCarpeta As String
    Dim nombreArchivo As String
    Dim rutaCompleta As String
    Dim libroOrigen As Workbook
    Dim numeroProcesados As Long
    Dim numeroErrores As Long

    On Error GoTo GestionErrorGeneral

    rutaCarpeta = SeleccionarCarpeta()

    If Len(rutaCarpeta) = 0 Then
        MsgBox "No se ha seleccionado ninguna carpeta.", vbInformation
        Exit Sub
    End If

    If Dir(rutaCarpeta, vbDirectory) = vbNullString Then
        MsgBox "La carpeta seleccionada no existe o no está disponible.", vbExclamation
        Exit Sub
    End If

    If Right$(rutaCarpeta, 1) <> "\" Then
        rutaCarpeta = rutaCarpeta & "\"
    End If

    Application.ScreenUpdating = False
    Application.EnableEvents = False
    Application.DisplayAlerts = False
    Application.StatusBar = "Buscando archivos..."

    nombreArchivo = Dir(rutaCarpeta & "*.*")

    Do While nombreArchivo <> vbNullString

        rutaCompleta = rutaCarpeta & nombreArchivo

        If EsArchivoProcesable(nombreArchivo) Then

            If StrComp(rutaCompleta, ThisWorkbook.FullName, vbTextCompare) <> 0 Then

                Application.StatusBar = _
                    "Procesando: " & nombreArchivo

                Set libroOrigen = Nothing

                On Error Resume Next
                Set libroOrigen = Workbooks.Open( _
                    Filename:=rutaCompleta, _
                    UpdateLinks:=0, _
                    ReadOnly:=True, _
                    AddToMru:=False, _
                    Notify:=False)
                On Error GoTo GestionErrorArchivo

                If Not libroOrigen Is Nothing Then

                    ProcesarLibro libroOrigen, nombreArchivo

                    libroOrigen.Close SaveChanges:=False
                    Set libroOrigen = Nothing

                    numeroProcesados = numeroProcesados + 1

                Else
                    numeroErrores = numeroErrores + 1
                End If

            End If

        End If

SiguienteArchivo:
        On Error GoTo GestionErrorGeneral
        nombreArchivo = Dir()

    Loop

SalidaControlada:

    On Error Resume Next

    If Not libroOrigen Is Nothing Then
        libroOrigen.Close SaveChanges:=False
        Set libroOrigen = Nothing
    End If

    Application.StatusBar = False
    Application.DisplayAlerts = True
    Application.EnableEvents = True
    Application.ScreenUpdating = True

    On Error GoTo 0

    MsgBox _
        "Proceso finalizado." & vbCrLf & vbCrLf & _
        "Archivos procesados: " & numeroProcesados & vbCrLf & _
        "Archivos con error: " & numeroErrores, _
        vbInformation

    Exit Sub

GestionErrorArchivo:

    numeroErrores = numeroErrores + 1

    RegistrarIncidencia _
        nombreArchivo, _
        Err.Number, _
        Err.Description

    Err.Clear
    Resume SiguienteArchivo

GestionErrorGeneral:

    MsgBox _
        "No ha sido posible completar el proceso." & vbCrLf & _
        "Error " & Err.Number & ": " & Err.Description, _
        vbCritical

    Resume SalidaControlada

End Sub

Private Function SeleccionarCarpeta() As String

    Dim selector As FileDialog

    Set selector = Application.FileDialog(msoFileDialogFolderPicker)

    With selector
        .Title = "Seleccione la carpeta que desea procesar"
        .AllowMultiSelect = False

        If .Show = -1 Then
            SeleccionarCarpeta = .SelectedItems(1)
        Else
            SeleccionarCarpeta = vbNullString
        End If
    End With

    Set selector = Nothing

End Function

Private Function EsArchivoProcesable( _
    ByVal nombreArchivo As String) As Boolean

    Dim extension As String
    Dim posicionPunto As Long

    EsArchivoProcesable = False

    If Len(nombreArchivo) = 0 Then Exit Function

    If Left$(nombreArchivo, 2) = "~$" Then Exit Function

    If Left$(nombreArchivo, 1) = "." Then Exit Function

    posicionPunto = InStrRev(nombreArchivo, ".")

    If posicionPunto = 0 Then Exit Function

    extension = LCase$(Mid$(nombreArchivo, posicionPunto + 1))

    Select Case extension
        Case "xlsx", "xlsm", "xlsb", "xls"
            EsArchivoProcesable = True
    End Select

End Function

Private Sub ProcesarLibro( _
    ByVal libroOrigen As Workbook, _
    ByVal nombreArchivo As String)

    Dim hojaOrigen As Worksheet
    Dim hojaDestino As Worksheet
    Dim siguienteFila As Long

    Set hojaDestino = ThisWorkbook.Worksheets("Resultado")

    If ExisteHoja(libroOrigen, "Datos") Then

        Set hojaOrigen = libroOrigen.Worksheets("Datos")

        siguienteFila = _
            hojaDestino.Cells(hojaDestino.Rows.Count, "A").End(xlUp).Row + 1

        hojaDestino.Cells(siguienteFila, "A").Value = nombreArchivo
        hojaDestino.Cells(siguienteFila, "B").Value = hojaOrigen.Range("B2").Value
        hojaDestino.Cells(siguienteFila, "C").Value = hojaOrigen.Range("B3").Value
        hojaDestino.Cells(siguienteFila, "D").Value = hojaOrigen.Range("B4").Value

    Else

        RegistrarIncidencia _
            nombreArchivo, _
            0, _
            "El libro no contiene la hoja Datos."

    End If

End Sub

Private Function ExisteHoja( _
    ByVal libro As Workbook, _
    ByVal nombreHoja As String) As Boolean

    Dim hoja As Worksheet

    ExisteHoja = False

    For Each hoja In libro.Worksheets
        If StrComp(hoja.Name, nombreHoja, vbTextCompare) = 0 Then
            ExisteHoja = True
            Exit Function
        End If
    Next hoja

End Function

Private Sub RegistrarIncidencia( _
    ByVal nombreArchivo As String, _
    ByVal numeroError As Long, _
    ByVal descripcionError As String)

    Dim hojaLog As Worksheet
    Dim siguienteFila As Long

    Set hojaLog = ThisWorkbook.Worksheets("Registro")

    siguienteFila = _
        hojaLog.Cells(hojaLog.Rows.Count, "A").End(xlUp).Row + 1

    hojaLog.Cells(siguienteFila, "A").Value = Now
    hojaLog.Cells(siguienteFila, "B").Value = nombreArchivo
    hojaLog.Cells(siguienteFila, "C").Value = numeroError
    hojaLog.Cells(siguienteFila, "D").Value = descripcionError

End Sub

El ejemplo presupone que el libro de la macro contiene dos hojas llamadas Resultado y Registro. También presupone que los libros de origen deberían incluir una hoja llamada Datos.

La parte incluida en el procedimiento ProcesarLibro es solo un ejemplo. Debe sustituirse por las operaciones concretas de cada proyecto.

Explicación detallada del código

Option Explicit

La instrucción Option Explicit obliga a declarar las variables antes de utilizarlas. Esto evita errores provocados por nombres mal escritos y mejora la fiabilidad de la macro.

Selección y validación de la carpeta

La función SeleccionarCarpeta muestra una ventana para que el usuario elija el directorio. Después, la macro comprueba que la ruta no esté vacía y que el directorio exista.

También se añade una barra invertida al final cuando sea necesaria. Sin esta normalización, la concatenación de la carpeta y el nombre del archivo podría generar una ruta incorrecta.

Búsqueda inicial

La instrucción siguiente inicia la búsqueda:

nombreArchivo = Dir(rutaCarpeta & "*.*")

El patrón *.* permite examinar todos los nombres. Posteriormente, la función EsArchivoProcesable decide cuáles deben abrirse.

Bucle principal

El bucle continúa mientras Dir devuelva un nombre:

Do While nombreArchivo <> vbNullString
    ' Tratamiento del archivo
    nombreArchivo = Dir()
Loop

La llamada posterior a Dir() no debe incluir argumentos. Su función es devolver el siguiente archivo correspondiente a la búsqueda iniciada previamente.

Exclusión del propio libro

Si el archivo que contiene la macro está guardado dentro de la carpeta procesada, conviene impedir que intente abrirse a sí mismo:

If StrComp(rutaCompleta, ThisWorkbook.FullName, vbTextCompare) <> 0 Then

ThisWorkbook representa el libro donde está guardado el código, mientras que ActiveWorkbook representa el libro activo en ese momento. Confundir ambos objetos puede provocar que la macro escriba datos en un archivo equivocado.

Apertura en modo de solo lectura

El parámetro ReadOnly:=True reduce el riesgo de modificar accidentalmente los documentos de origen. También resulta conveniente desactivar la actualización de vínculos mediante UpdateLinks:=0.

Procedimiento independiente para procesar cada libro

Separar el tratamiento en un procedimiento denominado ProcesarLibro mejora la claridad y facilita las ampliaciones. La macro principal se ocupa del recorrido y el procedimiento secundario contiene la lógica de negocio.

Esta división es especialmente importante cuando el procesamiento incluye múltiples comprobaciones, transformaciones de datos o generación de informes.

Cómo evitar los archivos temporales que abre Excel

Cuando un libro está abierto, Excel suele crear en la misma carpeta un archivo temporal cuyo nombre comienza por ~$. Por ejemplo, al abrir Ventas.xlsx puede aparecer temporalmente un archivo llamado ~$Ventas.xlsx.

Este archivo sirve para gestionar información relacionada con el bloqueo y la edición del documento. No debe tratarse como un libro normal.

La comprobación más habitual es la siguiente:

If Left$(nombreArchivo, 2) <> "~$" Then
    ' El archivo puede continuar en el proceso
End If

En el ejemplo completo, esta validación se encuentra dentro de la función EsArchivoProcesable:

If Left$(nombreArchivo, 2) = "~$" Then Exit Function

Excluir los archivos temporales evita errores de apertura, mensajes inesperados y registros duplicados. También conviene descartar nombres que comiencen por punto cuando la carpeta pueda contener archivos ocultos generados por otros sistemas.

Cómo filtrar los tipos de archivo que se van a procesar

No todos los archivos de una carpeta deben abrirse con Excel. La macro debe identificar la extensión y admitir únicamente los formatos previstos.

Procesar una sola extensión

Cuando solo se quieren recorrer archivos .xlsx, puede aplicarse el filtro directamente en Dir:

nombreArchivo = Dir(rutaCarpeta & "*.xlsx")

Procesar varias extensiones

Si se quieren admitir varios formatos, resulta más flexible recorrer los nombres y evaluarlos mediante una función:

Select Case extension
    Case "xlsx", "xlsm", "xlsb", "xls"
        EsArchivoProcesable = True
End Select

Precauciones con archivos CSV

Los archivos CSV pueden abrirse desde Excel, pero requieren un tratamiento específico. La interpretación de separadores, fechas, decimales, codificación de caracteres y ceros iniciales puede variar según la configuración regional.

Cuando los datos contienen códigos como 000123, Excel podría convertirlos automáticamente en números y eliminar los ceros iniciales. Para procesos críticos, puede ser preferible importar el archivo mediante QueryTables, Power Query o una lectura controlada como texto.

Archivos con extensiones engañosas

La extensión ayuda a filtrar, pero no garantiza que el archivo sea válido. Un documento puede estar dañado, haber sido renombrado incorrectamente o no ser realmente un libro de Excel. Por este motivo, la apertura debe quedar protegida mediante control de errores.

Cómo abrir y procesar cada libro

Una vez identificado un archivo válido, la macro puede abrirlo y ejecutar la operación prevista. La apertura debería utilizar argumentos explícitos para evitar comportamientos inesperados.

Set libroOrigen = Workbooks.Open( _
    Filename:=rutaCompleta, _
    UpdateLinks:=0, _
    ReadOnly:=True, _
    AddToMru:=False, _
    Notify:=False)

UpdateLinks

El valor 0 evita actualizar vínculos externos durante la apertura. Esto reduce esperas, avisos y riesgos cuando los libros hacen referencia a archivos que ya no existen o no están disponibles.

ReadOnly

La apertura en modo de solo lectura protege los documentos originales. Si la macro debe modificar y guardar cada libro, este parámetro tendrá que cambiarse, pero será recomendable trabajar previamente con una copia de seguridad.

AddToMru

El valor False impide que cada libro abierto por la macro se incorpore a la lista de documentos recientes de Excel.

Cierre del archivo

Después del tratamiento, el libro debe cerrarse expresamente:

libroOrigen.Close SaveChanges:=False

Si la macro solo lee datos, SaveChanges:=False es la opción más segura. Cuando se guardan cambios, conviene determinar con claridad si se sobrescribe el archivo, se crea una copia o se genera una nueva versión.

No utilizar Select ni Activate cuando no sea necesario

Una macro robusta debe trabajar directamente con variables de objeto:

valor = libroOrigen.Worksheets("Datos").Range("B2").Value

Es preferible evitar una secuencia como esta:

libroOrigen.Activate
Worksheets("Datos").Select
Range("B2").Select
valor = Selection.Value

El acceso directo es más rápido, más legible y menos dependiente de la ventana o la hoja que estén activas.

Permisos sobre el directorio

Que una carpeta sea visible en el Explorador de archivos no significa necesariamente que la macro pueda realizar todas las operaciones previstas. Los permisos pueden afectar a la lectura, apertura, modificación, creación o eliminación de documentos.

Permiso de lectura

Para inventariar o abrir documentos, el usuario necesita al menos acceso de lectura. Si no dispone de él, la función Dir podría no devolver archivos o la apertura podría generar un error.

Permiso de escritura

Si la macro debe guardar cambios, renombrar archivos, crear informes o escribir un registro dentro de la misma carpeta, también será necesario disponer de permiso de escritura.

Carpetas de red

En unidades de red pueden intervenir permisos del servidor, credenciales, desconexiones temporales, rutas compartidas y bloqueos establecidos por otros usuarios.

Una ruta con letra de unidad, como Z:\Informes\, puede funcionar en un ordenador y no existir en otro. En entornos compartidos suele ser más estable utilizar una ruta UNC:

\\Servidor\RecursoCompartido\Informes\

OneDrive, SharePoint y carpetas sincronizadas

Los archivos almacenados en servicios sincronizados pueden aparecer en el Explorador sin estar descargados físicamente. La macro podría provocar su descarga o fallar si el recurso no está disponible sin conexión.

También pueden producirse conflictos de sincronización cuando la macro modifica muchos libros en poco tiempo. En estos casos, conviene probar el proceso con una copia local antes de utilizar la carpeta definitiva.

Carpetas protegidas del sistema

No es recomendable utilizar como directorio de trabajo ubicaciones protegidas de Windows, carpetas de instalación o directorios para los que el usuario necesite privilegios administrativos.

Prueba práctica de escritura

Cuando la macro necesita guardar resultados en una carpeta, puede realizarse una prueba creando y eliminando un archivo temporal controlado. Esta comprobación permite detectar la falta de permisos antes de procesar todos los documentos.

Control de errores durante el recorrido

En una carpeta real es habitual encontrar algún archivo problemático. La macro no debería detener todo el proceso porque un único documento esté dañado, protegido o bloqueado.

Errores posibles

  • El archivo está siendo utilizado por otro usuario.
  • El libro está protegido por contraseña.
  • El documento está dañado.
  • La extensión no coincide con el contenido real.
  • Falta una hoja obligatoria.
  • La estructura de columnas es diferente.
  • Existen vínculos externos no disponibles.
  • La ruta supera limitaciones del sistema.
  • La conexión con la unidad de red se interrumpe.
  • El usuario pierde acceso a la carpeta durante el proceso.

Continuar con el siguiente archivo

El código debe distinguir entre un error general, que impide continuar, y un error asociado a un archivo concreto. En este último caso, lo habitual es registrar la incidencia y pasar al documento siguiente.

Restaurar siempre la configuración de Excel

Si la macro desactiva eventos, avisos o actualización de pantalla, debe restaurarlos incluso cuando se produce un error:

Application.StatusBar = False
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True

Dejar EnableEvents desactivado puede provocar que otras macros de eventos dejen de ejecutarse. Por eso es importante disponer de una salida controlada.

Evitar On Error Resume Next de forma indiscriminada

On Error Resume Next puede ser útil para una operación muy concreta, pero no debería permanecer activo durante todo el procedimiento. De lo contrario, la macro podría ignorar fallos importantes y continuar con datos incompletos.

Cómo recorrer también las subcarpetas

La función Dir puede utilizarse para recorrer carpetas, pero una solución recursiva suele resultar más clara con FileSystemObject. El siguiente ejemplo visita una carpeta y todas las que contiene.

Option Explicit

Public Sub RecorrerCarpetaYSubcarpetas()

    Dim rutaInicial As String
    Dim sistemaArchivos As Object

    rutaInicial = SeleccionarCarpeta()

    If Len(rutaInicial) = 0 Then Exit Sub

    Set sistemaArchivos = CreateObject("Scripting.FileSystemObject")

    RecorrerCarpetaRecursiva _
        sistemaArchivos.GetFolder(rutaInicial), _
        sistemaArchivos

    Set sistemaArchivos = Nothing

    MsgBox "Recorrido finalizado.", vbInformation

End Sub

Private Sub RecorrerCarpetaRecursiva( _
    ByVal carpetaActual As Object, _
    ByVal sistemaArchivos As Object)

    Dim archivo As Object
    Dim subcarpeta As Object
    Dim extension As String

    For Each archivo In carpetaActual.Files

        If Left$(archivo.Name, 2) <> "~$" Then

            extension = LCase$(sistemaArchivos.GetExtensionName(archivo.Name))

            Select Case extension
                Case "xlsx", "xlsm", "xlsb", "xls"
                    Debug.Print archivo.Path
            End Select

        End If

    Next archivo

    For Each subcarpeta In carpetaActual.SubFolders
        RecorrerCarpetaRecursiva subcarpeta, sistemaArchivos
    Next subcarpeta

End Sub

La recursividad debe utilizarse con precaución. Si la carpeta inicial contiene miles de archivos o una estructura muy profunda, el proceso puede tardar bastante tiempo.

También conviene definir si existen subcarpetas que deben excluirse, como directorios de copias de seguridad, históricos, documentos rechazados o resultados generados por la propia macro.

Mejoras de rendimiento para procesar muchos archivos

Cuando se recorren pocos documentos, las diferencias de rendimiento apenas se perciben. Sin embargo, al trabajar con cientos o miles de libros, cada apertura, cálculo y escritura puede aumentar notablemente el tiempo total.

Desactivar temporalmente funciones de Excel

Puede resultar útil desactivar la actualización de pantalla, los eventos y los avisos:

Application.ScreenUpdating = False
Application.EnableEvents = False
Application.DisplayAlerts = False

Controlar el modo de cálculo

Si los libros contienen muchas fórmulas, puede considerarse el cálculo manual durante el proceso:

Dim modoCalculoAnterior As XlCalculation

modoCalculoAnterior = Application.Calculation
Application.Calculation = xlCalculationManual

' Proceso

Application.Calculation = modoCalculoAnterior

Debe restaurarse siempre el modo anterior al finalizar, incluso cuando se produzca un error.

Leer rangos completos en matrices

Copiar celda por celda es lento. Cuando se necesita procesar una tabla, suele ser mejor cargar el rango en una matriz:

Dim datos As Variant

datos = hojaOrigen.Range("A2:F1000").Value

Después, la información puede analizarse en memoria y escribirse en bloques.

Evitar abrir archivos innecesarios

Antes de abrir un documento, pueden evaluarse su extensión, nombre, fecha o tamaño. Si el nombre indica que ya fue procesado o pertenece a un periodo fuera del análisis, puede descartarse previamente.

Mostrar el progreso

La propiedad Application.StatusBar permite informar al usuario del archivo actual:

Application.StatusBar = "Procesando: " & nombreArchivo

Para procesos largos, también puede mostrarse el número de archivo, el total estimado y el porcentaje completado.

No guardar repetidamente el libro maestro

Guardar el libro de resultados después de cada archivo reduce el riesgo de pérdida de información, pero puede ralentizar mucho el proceso. Una solución intermedia consiste en guardar cada cierto número de documentos o al terminar cada bloque.

Registro de resultados e incidencias

Una macro empresarial no debería limitarse a mostrar un mensaje final. Es recomendable crear una hoja de registro que permita saber qué documentos se trataron y cuáles quedaron pendientes.

Datos que conviene registrar

  • Fecha y hora del procesamiento.
  • Nombre del archivo.
  • Ruta completa.
  • Extensión.
  • Estado del proceso.
  • Número de registros importados.
  • Descripción del error.
  • Tiempo empleado.
  • Usuario que ejecutó la macro.

Evitar procesamientos duplicados

El registro también puede utilizarse para comprobar si un archivo ya fue tratado. No obstante, basarse únicamente en el nombre puede ser insuficiente, porque un documento podría haberse sustituido por otra versión con el mismo nombre.

Para un control más riguroso pueden compararse:

  • Nombre completo.
  • Ruta.
  • Tamaño.
  • Fecha de última modificación.
  • Una huella o identificador calculado externamente.

Separar resultados y errores

En procesos amplios puede ser conveniente utilizar una hoja para los datos consolidados y otra para las incidencias. Esto facilita la revisión y evita mezclar información operativa con mensajes técnicos.

Errores habituales al crear este tipo de macro

Procesar el archivo temporal de Excel

No excluir los nombres que comienzan por ~$ provoca intentos de apertura innecesarios y errores evitables.

Intentar abrir el libro que contiene la macro

Si el libro maestro se encuentra dentro de la carpeta, debe excluirse comparando su ruta con ThisWorkbook.FullName.

Suponer que todas las hojas existen

Una referencia directa a una hoja inexistente detendrá la ejecución. Conviene comprobar primero que el libro contiene la estructura esperada.

Usar ActiveWorkbook sin control

El libro activo cambia cuando se abren documentos. Por ello, es más seguro guardar cada referencia en variables como libroOrigen y utilizar ThisWorkbook para el libro de la macro.

No cerrar libros cuando ocurre un error

Si el código salta directamente al gestor de errores, un archivo puede quedar abierto. La salida controlada debe comprobar si existe un objeto de libro pendiente y cerrarlo.

Desactivar eventos y no restaurarlos

Un fallo durante la ejecución puede dejar Excel con eventos, cálculo o actualización de pantalla desactivados. Todas estas propiedades deben restaurarse en una sección final común.

Guardar cambios sin copia de seguridad

Modificar automáticamente cientos de libros sin una copia previa puede ocasionar una pérdida difícil de revertir. Las primeras pruebas deben realizarse siempre sobre archivos duplicados.

No controlar vínculos externos

La apertura de libros con vínculos puede mostrar avisos, ralentizar el proceso o actualizar datos que no deberían cambiar. El parámetro UpdateLinks:=0 ayuda a evitarlo.

Mezclar el recorrido con toda la lógica de negocio

Incluir cientos de líneas dentro del mismo bucle dificulta el mantenimiento. Es preferible separar la selección de carpeta, validación, apertura, procesamiento, registro y cierre en procedimientos específicos.

Cuándo conviene encargar un desarrollo a medida

Una macro básica puede ser suficiente cuando todos los archivos son homogéneos y el tratamiento consiste en leer unas pocas celdas. Sin embargo, el proyecto se complica cuando existen múltiples formatos, hojas opcionales, libros protegidos, rutas de red, reglas de validación o grandes volúmenes de información.

Un desarrollo a medida puede resultar recomendable cuando:

  • Los archivos proceden de distintos clientes o departamentos.
  • Existen varias versiones de la plantilla.
  • Los datos deben normalizarse antes de consolidarlos.
  • Es necesario generar un registro detallado y recuperable.
  • La macro debe reanudar el proceso después de una interrupción.
  • Los libros contienen vínculos, fórmulas, tablas o gráficos complejos.
  • Se necesita mantener la confidencialidad entre departamentos.
  • La solución será utilizada por varios empleados.
  • Un error podría afectar a facturación, contabilidad o información contractual.

En estos casos no basta con que el código funcione durante una prueba. Debe ser mantenible, comprensible, controlable y capaz de gestionar las excepciones reales del proceso.

También conviene documentar correctamente las entradas, salidas, tiempos máximos y reglas de negocio. Para preparar el encargo puede consultarse el artículo sobre qué información necesita un programador para crear una macro Excel.

Conclusión

Crear una macro para recorrer todos los archivos de una carpeta es relativamente sencillo, pero convertirla en una herramienta fiable requiere algo más que un bucle con la función Dir. La solución debe comprobar la carpeta, filtrar extensiones, ignorar archivos temporales, excluir el libro de la macro, abrir documentos de forma segura y continuar cuando aparece un archivo problemático.

También es importante distinguir entre leer y modificar documentos, controlar los permisos de la carpeta, evitar actualizaciones de vínculos y registrar los resultados. Estas medidas reducen el riesgo de pérdida de información y permiten saber exactamente qué ocurrió durante la ejecución.

La mejor estructura consiste en separar el recorrido de archivos de la lógica específica del proceso. De este modo, la misma base puede reutilizarse para consolidar datos, validar libros, actualizar informes, generar documentos independientes o automatizar otras tareas repetitivas de Excel.

Preguntas frecuentes

¿Qué función de VBA permite recorrer los archivos de una carpeta?

La función Dir permite obtener archivos que coinciden con un patrón. Se llama una primera vez con la ruta y después se utiliza Dir() sin argumentos para recuperar los siguientes archivos.

¿Cómo se evita procesar los archivos temporales de Excel?

Los archivos temporales de Excel suelen comenzar por ~$. La macro debe comprobar los dos primeros caracteres del nombre y excluir esos documentos antes de intentar abrirlos.

¿Puede la macro recorrer archivos XLSX, XLSM y XLSB?

Sí. Puede obtener la extensión de cada archivo y admitir varios formatos mediante una estructura Select Case. También puede incluir el formato antiguo .xls cuando sea necesario.

¿Es necesario abrir cada libro para leer sus datos?

En la mayoría de las macros VBA convencionales, sí. No obstante, existen alternativas como ADO, Power Query o conexiones externas que pueden leer determinados datos sin abrir visualmente cada libro.

¿Cómo se evita que la macro abra su propio libro?

Debe compararse la ruta completa del archivo encontrado con ThisWorkbook.FullName. Si ambas rutas coinciden, el archivo debe excluirse.

¿Qué ocurre si un libro está protegido por contraseña?

La apertura puede mostrar una solicitud de contraseña o producir un error. La macro debe registrar la incidencia y continuar con el siguiente archivo, salvo que se haya diseñado expresamente para gestionar contraseñas autorizadas.

¿Se pueden recorrer también las subcarpetas?

Sí. Puede utilizarse un procedimiento recursivo con FileSystemObject para visitar la carpeta inicial y todas sus subcarpetas.

¿La macro necesita permisos especiales?

Necesita permiso de lectura para localizar y abrir los archivos. Si además debe guardar cambios, crear informes, mover documentos o escribir registros en la carpeta, también necesitará permiso de escritura.

¿Conviene abrir los archivos en modo de solo lectura?

Sí, cuando la macro únicamente consulta o copia información. El modo de solo lectura reduce el riesgo de modificar accidentalmente los documentos originales.

¿Qué debe hacerse antes de probar una macro que modifica muchos archivos?

Debe crearse una copia de seguridad completa y realizar las primeras pruebas en una carpeta duplicada. No es recomendable ejecutar directamente una macro nueva sobre los únicos archivos disponibles.

Scroll al inicio