
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.