在VBA中删除文件


Answers:


168

1.)在这里检查。基本上做到这一点:

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

我将留给您了解所需的各种错误处理,但这是我要考虑的错误处理内容之一:

  • 检查是否传递了空字符串。
  • 检查文件名/路径中包含非法字符的字符串

2.)如何删除文件。看这个 基本上使用Kill命令,但是您需要考虑将文件设为只读的可能性。这是为您提供的功能:

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

同样,我将把错误处理留给您,这些也是我要考虑的事情:

  • 目录和文件的行为是否应该有所不同?用户是否应该明确表示必须删除目录?

  • 您是否要让代码自动重置只读属性,还是应该向用户提供某种指示,说明已设置了只读属性?


编辑:将此答案标记为社区Wiki,以便任何人可以根据需要进行修改。


谢谢-如果存在两个同名的文件,DeleteFile子进程会杀死它们两个或一个吗?任何建议,不胜感激。
BKSpurgeon

6
目录中不能有两个具有相同名称的文件。
Onorio Catenacci

52

我否则完全同意布雷特斯基的答案的另一种编码方式可能是

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

效果相同,但变量声明更少(或者完全没有)。

FileSystemObject是一个非常有用的工具,非常值得与之友好。除了其他方面,对于文本文件编写,它有时有时可能比传统方法要快,这可能会令一些人感到惊讶。(至少以我的经验,YMMV)。


7
使用此语法而不声明文件脚本对象,必须添加Microsoft脚本运行时的引用,否则:Dim fs As New Scripting.FileSystemObject
pghcpa

5
您还需要引用脚本库。在这里看到:stackoverflow.com/questions/3233203/...
ekkis

由于没有变量设置为Nothing,是否存在FileSystemObject保留在内存中,导致泄漏或其他问题的风险?
约翰尼,为什么

不,它将在“结束于”之后被丢弃。由于未将其分配给变量,因此效果类似于将对象分配给已设置为“无”的变量。
jony

15

我可能会为此感到恼火,但是如果您要删除它,那么测试存在性的重点是什么?我主要的烦恼之一是一个应用程序引发错误对话框,显示“无法删除文件,它不存在!”之类的错误对话框。

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.

如果文件不存在,任务就完成了!


4
您提出了一个很好的观点,但是,像大多数事情一样,我认为这取决于上下文,并且有时仅具有“文件已存在”功能就很容易删除。
Onorio Catenacci

3
+1:也许在删除文件之前需要询问应用程序的用户:例如,using ActiveWorkbook.SaveCopyAs无法覆盖,因此您首先必须删除具有相同文件名的现有文件。
乔尔

但您永远不要使用On Error Resume Next,否则就被告知:D当然,这是荒谬的建议,您的回答是正确的。
约翰尼,为什么

Len(dir(...))零件并非仅用于检查是否存在。它还检查,如果该文件是隐藏的,因为一个隐藏的文件将返回即使它存在一个空字符串(你将无法将其删除): Dir(hiddenFile) = ""。因此,该部分SetAttr FileToDelete, vbNormal雄辩地为您解决了这一问题。
elektrykalAJ

11

以下内容可用于测试文件是否存在,然后将其删除。

Dim aFile As String
aFile = "c:\file_to_delete.txt"
If Len(Dir$(aFile)) > 0 Then
     Kill aFile
End If 

3
我知道这个问题和答案很老,只是想补充一下,使用Len()测试字符串(以及返回字符串的函数)似乎比VBA中的文字字符串比较要快。
JimmyPena 2011年

7
Len()(和LenB(),甚至更快)比字符串比较要快的原因是,在内存中,VB字符串的长度位于其前面。Len / LenB只是从该内存位置拉出长度,而不必遍历字符串即可知道其长度。另一方面,使用字符串比较还有很多工作要做。另外,避免""在VB中使用它,因为它总是分配一个新字符串。请vbNullString改用它,因为它是一个常量并且不占用更多内存。
Renaud Bompuis 2014年

7

在VB中通常Dir可以找到该文件的目录。如果不是空白,则表示存在,然后用于Kill删除文件。

test = Dir(Filename)
If Not test = "" Then
    Kill (Filename)
End If

6

设置对Scripting.Runtime库的引用,然后使用FileSystemObject:

Dim fso as New FileSystemObject, aFile as File

if (fso.FileExists("PathToFile")) then
    aFile = fso.GetFile("PathToFile")
    aFile.Delete
End if

我也使用FileSystemObject方法,因为Kill无法删除带有
腹膜炎的

这是我使用的方法。实现此目的的某人想使用错误检查和DisplayAlerts = false。(如果文件正在使用中,则不会删除,因此必须具有错误陷阱)
Gregg Burns

3

提示:您是重用文件名,还是打算做一些需要立即删除的文件?

没有?

您可以使VBA从命令提示符异步触发命令DEL“ C:\ TEMP \ scratchpad.txt” / F使用VBA.Shell:

Shell“ DEL”&chr(34)&strPath&chr(34)&“ / F”,vbHide

请注意文件名周围的双引号(ASCII字符34):我假设您具有网络路径,或包含空格的长文件名。

如果文件很大,或者网络连接速度很慢,那么“一劳永逸”便是解决之道。当然,您永远也看不到它是否有效。但是您立即恢复VBA,有时这比等待网络更好。


如果您想要使用异步,这是一个很好的选择。
约翰尼,为什么

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.