Access

Cómo eliminar las carpetas en VBA usando la API FSO, RMDIR y Windows

Eliminar carpetas mediante programación es una tarea común en la administración de archivos y la automatización. En este artículo, exploraremos varios métodos diferentes para eliminar las carpetas utilizando Visual Basic para aplicaciones (VBA):

  • Rmdir
  • FileSystemObject (FSO)
  • API de Windows

Rmdir

VBA proporciona un comando incorporado llamado RMDIR para eliminar directorios. Este método es fácil de usar y no requiere ninguna creación de objetos adicional o declaraciones de API.

Uso básico de RMDIR

La sintaxis básica para RMDIR es sencilla:

Sub DeleteFolderWithRmDir()
    RmDir "C:\Path\To\Your\Folder"
End Sub

Tal comando eliminará el directorio especificado Si está vacío. Si el directorio no está vacío, se producirá un error de tiempo de ejecución y no se realizará la eliminación.

Por lo tanto, para ser realmente útil, necesitaría hacer una función recursiva que se llame a sí mismo en cada archivo y subcarpeta.

Además, es importante tener en cuenta que la instrucción RMDIR omite el contenedor de reciclaje del sistema que no proporciona medios de recuperación si se ha producido un error.

FileSystemObject (FSO)

Para eliminar una carpeta específica con FSO, puede usar el método DeleteFolder, en su forma más simple, se vería algo así como:

Sub FSO_DeleteFolder()
    Dim FSO As Object
    Set FSO = CreateObject("Scripting.FileSystemObject")
    FSO.DeleteFolder "C:\Path\To\Your\Folder", True
    Set FSO = Nothing
End Sub

Para hacerlo más útil, lo he transformado ligeramente en una función reutilizable como:

'---------------------------------------------------------------------------------------
' Procedure : FSO_DeleteFolder
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : 
' Purpose   : Delete a folder and any subfolders
'               *** Does not go to the recycle bin ***
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - 
' Req'd Refs: Late Binding  -> None required
'             Early Binding -> Microsoft Scripting Runtime
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sFolder   : Path of the directory to delete
' sErrorMsg : Returned error message, if the function fails
'
' Usage:
' ~~~~~~
' FSO_DeleteFolder("C:\Temp\Reporting190517", sErrorMsg)
'   Returns -> True/False
'              sErrorMsg will contain any messages if the function fails
'
' Revision History:
' Rev       Date(yyyy-mm-dd)        Description
' **************************************************************************************
' 1         2019-03-21
' 2         2025-03-23              Updated header to new format
'                                   Added Early/Late Binding CCD
'---------------------------------------------------------------------------------------
Function FSO_DeleteFolder(ByVal sFolder As String, _
                          Optional ByRef sErrorMsg As String) As Boolean
On Error GoTo Error_Handler
    #Const FSO_EarlyBind = False    'True => Early Binding / False => Late Binding
    #If FSO_EarlyBind = True Then
        Dim oFSO              As Scripting.FileSystemObject

        Set oFSO = New FileSystemObject
    #Else
        Dim oFSO              As Object

        Set oFSO = CreateObject("Scripting.FileSystemObject")
    #End If

    If oFSO.FolderExists(sFolder) Then
        oFSO.DeleteFolder sFolder, True
        DoEvents
        If Not oFSO.FolderExists(sFolder) Then
            FSO_DeleteFolder = True
        Else
            sErrorMsg = "Could not delete the specified directory."
        End If
    Else
        sErrorMsg = "Folder not found."
    End If

Error_Handler_Exit:
    On Error Resume Next
    Set oFSO = Nothing
    Exit Function

Error_Handler:
    If Err.Number = 70 Then
        sErrorMsg = "Permission denied." & _
                    "Possibly a file is open and locking the folder deletion" & _
                    ", user doesn't have deletion permissions, ..."
    Else
        MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
               "Error Source: FSO_DeleteFolder" & vbCrLf & _
               "Error Number: " & Err.Number & vbCrLf & _
               "Error Description: " & Err.Description & _
               Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
               , vbOKOnly + vbCritical, "An Error has Occurred!"
    End If
    Resume Error_Handler_Exit
End Function

que a su vez se puede usar simplemente haciendo:

Sub FSO_DeleteFolder_Test()
    Dim sErrorMsg As String
    
    If Not FSO_DeleteFolder("C:\Path\To\Your\Folder", sErrorMsg) Then
        Debug.Print sErrorMsg
    End If
End Sub

De manera similar a la declaración de RMDIR, lo único que en algún momento puede ser un inconveniente utilizando el enfoque FSO es que el contenido de la eliminación de derivación del contenedor de reciclaje del sistema no proporciona medios de recuperación si se ha producido un error.

API de Windows

Otra técnica poderosa para la eliminación de carpetas es emplear API de Windows, en este caso la API ShFileOperation.

Sí, es un poco más complejo, pero también ofrece más potencia y opciones. Dos puntos principales se destacan como una justificación para su uso:

  • Elimina carpetas no vacías. No hay necesidad de rutinas recursivas.
  • Ofrece la capacidad de enviar el contenido eliminado al contenedor de reciclaje del sistema.

Aquí hay una muestra de cómo se puede implementar:

#If VBA7 Then
    Private Declare PtrSafe Function SHFileOperation Lib "shell32.dll" Alias "SHFileOperationA" (lpFileOp As SHFILEOPSTRUCT) As Long

    Private Type SHFILEOPSTRUCT
        hWnd                      As LongPtr
        wFunc                     As Long
        pFrom                     As String
        pTo                       As String
        fFlags                    As Integer
        fAnyOperationsAborted     As Boolean
        hNameMappings             As LongPtr
        lpszProgressTitle         As String
    End Type
#Else
    Private Declare Function SHFileOperation Lib "shell32.dll" Alias "SHFileOperationA" (lpFileOp As SHFILEOPSTRUCT) As Long

    Private Type SHFILEOPSTRUCT
        hWnd                      As Long
        wFunc                     As Long
        pFrom                     As String
        pTo                       As String
        fFlags                    As Integer
        fAnyOperationsAborted     As Boolean
        hNameMappings             As Long
        lpszProgressTitle         As String
    End Type
#End If

' Constants for SHFileOperation
Private Const FO_DELETE       As Long = &H3          ' Delete operation
Private Const FOF_NOCONFIRMATION As Integer = &H10    ' No confirmation dialog
Private Const FOF_SILENT      As Integer = &H4      ' No progress dialog
Private Const FOF_ALLOWUNDO   As Integer = &H40    ' Allow undo (send to Recycle Bin)

' Returned Result Values (there are more!)
' 
Private Const ERROR_FILE_NOT_FOUND As Long = 2        ' File not found
Private Const ERROR_PATH_NOT_FOUND As Long = 3        ' Path not found
Private Const ERROR_ACCESS_DENIED As Long = 5         ' Access denied
Private Const ERROR_SHARING_VIOLATION As Long = 32
Private Const ERROR_CANCELLED_BY_USER As Long = 1223  ' Operation canceled by the user


'---------------------------------------------------------------------------------------
' Procedure : API_DeleteFolder
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : 
' Purpose   : Delete a folder and any subfolders
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - 
' Req'd Refs: Late Binding  -> none required
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sFolder   : Path of the directory to delete
' bSendToRecycleBin : Whether or not the deleted folder/contents should be placed in the
'                       system Recycle Bin or simply permanently deleted
' sErrorMsg : Returned error message, if the function fails
'
' Usage:
' ~~~~~~
' Delete a folder and send it to the Recycle Bin
' API_DeleteFolder("C:\Temp\Reporting190517", , sErrorMsg)
'   Returns -> True/False
'              sErrorMsg will contain any messages if the function fails
'
' Delete a folder permanently and do NOT send it to the Recycle Bin
' API_DeleteFolder("C:\Temp\Reporting190517", False, sErrorMsg)
'   Returns -> True/False
'              sErrorMsg will contain any messages if the function fails
'
' Revision History:
' Rev       Date(yyyy-mm-dd)        Description
' **************************************************************************************
' 1         2019-03-21
' 2         2025-03-23              Updated header to new format
'                                   Added Early/Late Binding CCD
'---------------------------------------------------------------------------------------
Public Function API_DeleteFolder(ByVal sFolder As String, _
                                 Optional bSendToRecycleBin As Boolean = True, _
                                 Optional ByRef sErrorMsg As String) As Boolean
    Dim shFileOp              As SHFILEOPSTRUCT
    Dim lRetVal               As Long

    ' Ensure the folder path ends with a null character (required by SHFileOperation)
    sFolder = sFolder & vbNullChar & vbNullChar

    With shFileOp
        .hWnd = 0                              ' Handle to the window (0 for no UI)
        .wFunc = FO_DELETE                     ' Specify delete operation
        .pFrom = sFolder                       ' Path of the folder to delete
        .pTo = vbNullString                    ' Not used for deletion
        If bSendToRecycleBin Then
            'Send to Recycle Bin
            .fFlags = FOF_NOCONFIRMATION Or FOF_SILENT Or FOF_ALLOWUNDO
        Else
            'Do Not Send to Recycle Bin! ****
            .fFlags = FOF_NOCONFIRMATION Or FOF_SILENT
        End If
        .fAnyOperationsAborted = False         ' Tracks if the operation was aborted
        .hNameMappings = 0
        .lpszProgressTitle = vbNullString
    End With
    lRetVal = SHFileOperation(shFileOp)

    If lRetVal <> 0 Then
        Select Case lRetVal
            Case ERROR_FILE_NOT_FOUND
                sErrorMsg = "The system cannot find the file specified."
            Case ERROR_PATH_NOT_FOUND
                sErrorMsg = "The system cannot find the path specified."
            Case ERROR_ACCESS_DENIED
                sErrorMsg = "Access denied."
            Case ERROR_SHARING_VIOLATION
                sErrorMsg = "The process cannot access the file because it is being used by another process."
            Case ERROR_CANCELLED_BY_USER
                sErrorMsg = "Operation canceled by the user."
            Case Else
                sErrorMsg = "An unknown error occurred. Error code: " & lRetVal
        End Select
    Else
        API_DeleteFolder = True
    End If
End Function

Y luego simplemente lo llamas haciendo:

Sub API_DeleteFolder_Test()
    Dim sErrorMsg             As String

    If Not API_DeleteFolder("C:\Path\To\Your\Folder", , sErrorMsg) Then
        Debug.Print sErrorMsg
    End If
End Sub

También tenga en cuenta que la declaración de caso de mensaje de error es solo una lista parcialmente construida de los errores comunes, pero podría construirse aún más mientras se refiere a la URL proporcionada en el código (

Algunas palabras finales

VBA ofrece una multitud de métodos para eliminar carpetas, cada una con sus propias fortalezas/debilidades y casos de uso. El objeto del sistema de archivos (FSO) proporciona un enfoque robusto y rico en funciones, las API de Windows ofrecen control de bajo nivel y funcionalidad avanzada, y el comando RMDIR incorporado proporciona una solución VBA simple y nativa para tareas de eliminación de carpetas básicas.

Al elegir entre estos métodos, considere factores como la complejidad de su tarea, la necesidad de manejo de errores y comentarios de los usuarios, y el entorno específico en el que se ejecutará su código. Para tareas simples, rmdir podría Sea suficiente, mientras que los escenarios más complejos pueden beneficiarse del poder de las API FSO o Windows.

Como siempre, tenga cuidado al eliminar las carpetas mediante programación y asegúrese de tener un manejo de errores adecuado y salvaguardas para evitar la pérdida de datos no deseada.

Publicaciones relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Botón volver arriba