Eliminar un archivo en VBA

Respuestas:

168

1.) Verifique aquí . Básicamente haz esto:

Function FileExists(ByVal FileToTest As String) As Boolean
   FileExists = (Dir(FileToTest) <> "")
End Function

Te dejo que descubras los diversos errores necesarios para el manejo, pero estos son algunos de los aspectos de manejo de errores que estaría considerando:

  • Verifique si se pasa una cadena vacía.
  • Compruebe si hay una cadena que contenga caracteres ilegales en un nombre de archivo / ruta

2.) Cómo eliminar un archivo. Mira esto Básicamente, use el comando Kill, pero debe permitir la posibilidad de que un archivo sea de solo lectura. Aquí hay una función para ti:

Sub DeleteFile(ByVal FileToDelete As String)
   If FileExists(FileToDelete) Then 'See above          
      ' First remove readonly attribute, if set
      SetAttr FileToDelete, vbNormal          
      ' Then delete the file
      Kill FileToDelete
   End If
End Sub

Nuevamente, le dejaré el manejo de errores y nuevamente estas son las cosas que consideraría:

  • ¿Debería esto comportarse de manera diferente para un directorio frente a un archivo? ¿Debería un usuario tener que indicar explícitamente que desea eliminar un directorio?

  • ¿Desea que el código restablezca automáticamente el atributo de solo lectura o debe dar al usuario algún tipo de indicación de que el atributo de solo lectura está configurado?


EDITAR: Marcar esta respuesta como wiki de la comunidad para que cualquiera pueda modificarla si es necesario.

Onorio Catenacci
fuente
gracias, ¿y si existen dos archivos con el mismo nombre, el subarchivo DeleteFile los matará a ambos o solo a uno? Cualquier consejo muy apreciado.
BKSpurgeon
66
No puede tener dos archivos con el mismo nombre en un directorio.
Onorio Catenacci
52

Una forma alternativa de codificar la respuesta de Brettski, con la que estoy totalmente de acuerdo, podría ser

With New FileSystemObject
    If .FileExists(yourFilePath) Then
        .DeleteFile yourFilepath
    End If
End With

Mismo efecto pero menos (bueno, ninguna en absoluto) declaraciones variables.

FileSystemObject es una herramienta realmente útil y con la que vale la pena hacerse amigable. Además de cualquier otra cosa, para la escritura de archivos de texto, a veces puede ser más rápido que la alternativa heredada, lo que puede sorprender a algunas personas. (En mi experiencia al menos, YMMV).

Mike Woodhouse
fuente
77
Al usar esta sintaxis sin declarar un objeto de secuencia de comandos de archivo, debe agregar referencia para Microsoft Scripting Runtime, de lo contrario: Dim fs As New Scripting.FileSystemObject
pghcpa
55
También debe hacer referencia a la biblioteca de secuencias de comandos. ver aquí: stackoverflow.com/questions/3233203/…
ekkis
Dado que no hay ninguna variable para establecer en Nothing, ¿existe el riesgo de que FileSystemObject permanezca en la memoria, causando una fuga u otro problema?
johny por qué el
No, se descartará después del "Finalizar con". Como no está asignado a una variable, el efecto es similar al objeto que se ha asignado a una variable que se ha establecido en "Nada".
jony
15

Probablemente me criticarán por esto, pero ¿cuál es el punto de probar la existencia si solo lo vas a eliminar? Una de mis principales preocupaciones es una aplicación que muestra un cuadro de diálogo de error con algo como "¡No se pudo eliminar el archivo, no existe!"

On Error Resume Next
aFile = "c:\file_to_delete.txt"
Kill aFile
On Error Goto 0
return Len(Dir$(aFile)) > 0 ' Make sure it actually got deleted.

Si el archivo no existe en primer lugar, ¡misión cumplida!

JohnFx
fuente
44
Planteas un buen punto, pero, como la mayoría de las cosas, creo que dependería del contexto y, a veces, simplemente tener una función "Archivo existe" es útil aparte de la eliminación.
Onorio Catenacci
3
+1: tal vez el usuario de la aplicación quiera que se le pregunte antes de eliminar un archivo: por ejemplo, el uso ActiveWorkbook.SaveCopyAsno puede sobrescribir, por lo que primero debe eliminar el archivo existente con el mismo nombre de archivo.
Joël
pero nunca deberías usar On Error Resume Next, o eso me han dicho: D Por supuesto, ese es un consejo ridículo, y tu respuesta es correcta.
johny por qué
La Len(dir(...))parte no es SOLAMENTE para verificar la existencia. También se comprueba si el archivo está oculto porque un archivo oculto devolverá una cadena vacía, incluso si existe (y no será capaz de eliminarlo): Dir(hiddenFile) = "". Por lo tanto, la parte SetAttr FileToDelete, vbNormalelocuentemente se encarga de esto por usted.
elektrykalAJ
11

Lo siguiente se puede usar para probar la existencia de un archivo y luego eliminarlo.

Dim aFile As String
aFile = "c:\file_to_delete.txt"
If Len(Dir$(aFile)) > 0 Then
     Kill aFile
End If 
Rich Adams
fuente
3
Sé que esta pregunta y respuesta son antiguas, solo pensé que agregaría que usar Len () para probar cadenas (y funciones que devuelven cadenas) parece ser más rápido que las comparaciones de cadenas literales en VBA.
JimmyPena
77
La razón por la que Len()(y LenB(), que es aún más rápido) es más rápido que la comparación de cadenas es que en la memoria, las cadenas VB están precedidas por su longitud. Len / LenB solo extrae la longitud de esa ubicación de memoria, no tienen que recorrer la cadena para conocer su longitud. Por otro lado, usar la comparación de cadenas tiene mucho más trabajo por hacer. Además, evite usar ""en VB ya que siempre asigna una nueva cadena. Utilice en su vbNullStringlugar, ya que es una constante y no utiliza más memoria.
Renaud Bompuis
7

En VB normalmente Dires encontrar el directorio del archivo. Si no está en blanco, entonces existe y luego se usa Killpara deshacerse del archivo.

test = Dir(Filename)
If Not test = "" Then
    Kill (Filename)
End If
Leo Moore
fuente
6

establezca una referencia a la biblioteca Scripting.Runtime y luego use FileSystemObject:

Dim fso as New FileSystemObject, aFile as File

if (fso.FileExists("PathToFile")) then
    aFile = fso.GetFile("PathToFile")
    aFile.Delete
End if
Brettski
fuente
También uso el método FileSystemObject, ya que Kill no puede eliminar archivos / carpetas con diacritis
mauek unak
Este es el método que uso. Alguien que implemente esto quiere usar la comprobación de errores y DisplayAlerts = false. (El archivo no se eliminará si está en uso, por lo que debe tener una trampa de error)
Gregg Burns
3

Aquí hay un consejo: ¿está reutilizando el nombre del archivo o planea hacer algo que requiera la eliminación de inmediato?

¿No?

Puede hacer que VBA active el comando DEL "C: \ TEMP \ scratchpad.txt" / F desde el símbolo del sistema de forma asincrónica usando VBA.Shell:

Shell "DEL" y chr (34) y strPath y chr (34) y "/ F", vbHide

Tenga en cuenta las comillas dobles (carácter ASCII 34) alrededor del nombre del archivo: supongo que tiene una ruta de red o un nombre de archivo largo que contiene espacios.

Si es un archivo grande, o está en una conexión de red lenta, disparar y olvidar es el camino a seguir. Por supuesto, nunca puedes ver si esto funcionó o no; pero reanuda su VBA de inmediato, y hay momentos en que esto es mejor que esperar a la red.

Nilo
fuente
Esta es una gran alternativa, si asynch es lo que quieres.
johny por qué el
2

Puede establecer una referencia a la biblioteca Scripting.Runtime y luego usar FileSystemObject. Tiene un método DeleteFile y un método FileExists.

Vea el artículo de MSDN aquí .

Darrel Miller
fuente