Excluindo um arquivo no VBA

Respostas:

168

1.) Confira aqui . Basicamente, faça isso:

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

Deixarei que você descubra as várias manipulações de erros necessárias, mas essas são algumas das coisas que eu consideraria:

  • Verifique se há uma sequência vazia sendo passada.
  • Verifique se há uma sequência contendo caracteres ilegais em um nome / caminho de arquivo

2.) Como excluir um arquivo. Olhe isso. Basicamente, use o comando Kill, mas você precisa permitir a possibilidade de um arquivo ser somente leitura. Aqui está uma função para você:

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

Mais uma vez, deixarei o tratamento de erros para você e, novamente, estas são as coisas que considero:

  • Isso deve se comportar de maneira diferente entre um diretório e um arquivo? Um usuário deve explicitamente precisar indicar que deseja excluir um diretório?

  • Deseja que o código redefina automaticamente o atributo somente leitura ou o usuário receba algum tipo de indicação de que o atributo somente leitura está definido?


EDIT: Marcando esta resposta como wiki da comunidade, para que qualquer pessoa possa modificá-la, se necessário.

Onorio Catenacci
fonte
obrigado - e se houver dois arquivos com o mesmo nome, o DeleteFile sub- matará os dois ou apenas um? qualquer conselho muito apreciado.
BKPargeon
6
Você não pode ter dois arquivos com o mesmo nome em um diretório.
Onorio Catenacci
52

Uma maneira alternativa de codificar a resposta de Brettski, com a qual eu concordo totalmente, pode ser

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

Mesmo efeito, mas menos (bem, nenhuma) declarações de variáveis.

O FileSystemObject é uma ferramenta realmente útil e vale a pena ser amigável. Além de qualquer outra coisa, para escrever arquivos de texto, às vezes pode ser mais rápido que a alternativa herdada, o que pode surpreender algumas pessoas. (Pelo menos na minha experiência, YMMV).

Mike Woodhouse
fonte
7
Usando esta sintaxe sem declarar um objeto de arquivo script, deve adicionar referência para Microsoft Scripting Runtime, outra coisa: Dim fs As New Scripting.FileSystemObject
pghcpa
5
você também precisa fazer referência à biblioteca de scripts. veja aqui: stackoverflow.com/questions/3233203/…
ekkis
Como não há variável para definir como Nothing, existe o risco de o FileSystemObject permanecer na memória, causando um vazamento ou outro problema?
johny why
Não, ele será descartado após o "Finalizar com". Como não está atribuído a uma variável, o efeito é semelhante ao objeto ter sido atribuído a uma variável que foi definida como "Nothing".
jony
15

Provavelmente serei inflamado por isso, mas qual é o sentido de testar a existência se você apenas deseja excluí-lo? Um dos meus principais ódios de estimação é um aplicativo que gera uma caixa de diálogo de erro com algo como "Não foi possível excluir o arquivo, ele não 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.

Se o arquivo não existir em primeiro lugar, missão cumprida!

JohnFx
fonte
4
Você levanta um bom argumento, mas, como a maioria das coisas, acho que depende do contexto e, às vezes, simplesmente ter uma função "Arquivo existe" é útil, além da exclusão.
Onorio Catenacci
3
+1: talvez o usuário do aplicativo deseje ser perguntado antes de remover um arquivo: por exemplo, o uso ActiveWorkbook.SaveCopyAsnão pode substituir, portanto, você deve primeiro remover o arquivo existente com o mesmo nome de arquivo.
Joël
mas você nunca deve usar On Error Resume Next, ou pelo menos me disseram: D É claro que esse conselho é ridículo e sua resposta está correta.
johny why
A Len(dir(...))parte não é ÚNICA para verificar a existência. É também verificar se o arquivo está escondido porque um arquivo oculto irá retornar uma string vazia, mesmo se ele existe (e você não será capaz de excluí-lo): Dir(hiddenFile) = "". Portanto, a parte SetAttr FileToDelete, vbNormaleloquentemente cuida disso para você.
precisa saber é o seguinte
11

O seguinte pode ser usado para testar a existência de um arquivo e excluí-lo.

Dim aFile As String
aFile = "c:\file_to_delete.txt"
If Len(Dir$(aFile)) > 0 Then
     Kill aFile
End If 
Rich Adams
fonte
3
Eu sei que essa pergunta e resposta são antigas, apenas pensei em acrescentar que o uso de Len () para testar seqüências de caracteres (e funções que retornam seqüências de caracteres) parece ser mais rápido do que as comparações de seqüências de caracteres literais no VBA.
JimmyPena
7
A razão pela qual Len()(e LenB(), que é ainda mais rápido) é mais rápida que a comparação de cadeias é que, na memória, as cadeias VB são precedidas pelo seu comprimento. Len / LenB apenas puxa o comprimento desse local de memória, eles não precisam percorrer a string para saber seu comprimento. Por outro lado, o uso da comparação de strings tem muito mais trabalho a fazer. Além disso, evite usar ""no VB, pois ele sempre aloca uma nova string. Use em vbNullStringvez disso, pois é uma constante e não usa mais memória.
Renaud Bompuis
7

No VB é normalmente Direncontrar o diretório do arquivo. Se não estiver em branco, ele existe e, em seguida, use-o Killpara se livrar do arquivo.

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

defina uma referência para a biblioteca Scripting.Runtime e use o FileSystemObject:

Dim fso as New FileSystemObject, aFile as File

if (fso.FileExists("PathToFile")) then
    aFile = fso.GetFile("PathToFile")
    aFile.Delete
End if
Brettski
fonte
I usar o método FileSystemObject também, como Mate é possível excluir arquivos / pastas com diacritis
mauek Unak
Este é o método que eu uso. Alguém que implementa isso deseja usar a verificação de erros e DisplayAlerts = false. (O arquivo não vai apagar se ele está em uso, de modo que deve ter interceptação de erro)
Gregg Burns,
3

Aqui está uma dica: você está reutilizando o nome do arquivo ou planeja fazer algo que exija a exclusão imediatamente?

Não?

Você pode fazer com que o VBA inicie o comando DEL "C: \ TEMP \ scratchpad.txt" / F no prompt de comando de forma assíncrona usando o VBA.Shell:

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

Observe as aspas duplas (caractere ASCII 34) em torno do nome do arquivo: Suponho que você tenha um caminho de rede ou um nome de arquivo longo contendo espaços.

Se for um arquivo grande ou estiver em uma conexão de rede lenta, o recurso ignorar é o caminho a seguir. Claro, você nunca consegue ver se isso funcionou ou não; mas você retoma seu VBA imediatamente e há momentos em que isso é melhor do que esperar pela rede.

Nilo
fonte
Esta é uma ótima alternativa, se assíncrono é o que você deseja.
johny why
2

Você pode definir uma referência para a biblioteca Scripting.Runtime e, em seguida, usar o FileSystemObject. Possui um método DeleteFile e um método FileExists.

Veja o artigo do MSDN aqui .

Darrel Miller
fonte