Menghapus file di VBA

121

Menggunakan VBA, bagaimana saya bisa:

  1. menguji apakah sebuah file ada, dan jika demikian,
  2. Hapus?
ZygD
sumber

Jawaban:

168

1.) Periksa di sini . Pada dasarnya lakukan ini:

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

Saya akan menyerahkan kepada Anda untuk mencari tahu berbagai penanganan kesalahan yang diperlukan, tetapi ini adalah di antara hal-hal penanganan kesalahan yang akan saya pertimbangkan:

  • Periksa apakah ada string kosong yang lewat.
  • Periksa string yang mengandung karakter ilegal dalam nama / jalur file

2.) Cara Menghapus File. Lihat ini. Pada dasarnya gunakan perintah Bunuh tetapi Anda harus mengizinkan kemungkinan file menjadi hanya-baca. Inilah fungsinya untuk Anda:

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

Sekali lagi, saya akan menyerahkan penanganan kesalahan kepada Anda dan sekali lagi ini adalah hal-hal yang akan saya pertimbangkan:

  • Haruskah ini berperilaku berbeda untuk direktori vs. file? Haruskah pengguna harus secara eksplisit menunjukkan bahwa mereka ingin menghapus direktori?

  • Apakah Anda ingin kode menyetel ulang atribut hanya-baca secara otomatis atau haruskah pengguna diberi semacam indikasi bahwa atribut hanya-baca disetel?


EDIT: Menandai jawaban ini sebagai wiki komunitas sehingga siapa pun dapat memodifikasinya jika perlu.

Onorio Catenacci
sumber
terima kasih - bagaimana jika ada dua file dengan nama yang sama yang ada akankah sub DeleteFile membunuh keduanya atau hanya satu? saran apa pun sangat dihargai.
BKSpurgeon
6
Anda tidak dapat memiliki dua file dengan nama yang sama dalam satu direktori.
Onorio Catenacci
52

Cara alternatif untuk mengkodekan jawaban Brettski, yang saya setujui sepenuhnya, mungkin saja

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

Efek yang sama tetapi lebih sedikit (yah, tidak ada sama sekali) deklarasi variabel.

FileSystemObject adalah alat yang sangat berguna dan layak digunakan. Terlepas dari apa pun, untuk penulisan file teks terkadang bisa lebih cepat daripada alternatif lama, yang mungkin mengejutkan beberapa orang. (Setidaknya dalam pengalaman saya, YMMV).

Mike Woodhouse
sumber
7
Menggunakan sintaks ini tanpa mendeklarasikan objek skrip file, harus menambahkan referensi untuk Microsoft Scripting Runtime, lain: Dim fs As New Scripting.FileSystemObject
pghcpa
5
Anda juga perlu merujuk pustaka skrip. lihat di sini: stackoverflow.com/questions/3233203/…
ekkis
Karena tidak ada variabel untuk disetel ke Tidak Ada, apakah ada risiko FileSystemObject akan tetap ada di memori, menyebabkan kebocoran atau masalah lain?
johny mengapa
Tidak, itu akan dibuang setelah "Akhiri Dengan". Karena tidak ditugaskan ke variabel, efeknya mirip dengan objek yang telah ditetapkan ke variabel yang telah disetel ke "Tidak ada".
jony
15

Saya mungkin akan dikecam karena ini, tetapi apa gunanya menguji keberadaan jika Anda hanya akan menghapusnya? Salah satu kekesalan utama saya adalah aplikasi yang menampilkan dialog kesalahan dengan sesuatu seperti "Tidak dapat menghapus file, tidak ada!"

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.

Jika file tidak ada sejak awal, misi selesai!

JohnFx
sumber
4
Anda meningkatkan poin yang baik tetapi, seperti kebanyakan hal, saya pikir itu akan tergantung pada konteks dan terkadang hanya memiliki fungsi "File Exists" berguna selain dari penghapusan.
Onorio Catenacci
3
+1: mungkin pengguna aplikasi ingin ditanyai sebelum menghapus file: misalnya, menggunakan ActiveWorkbook.SaveCopyAstidak dapat menimpa, jadi Anda harus menghapus file yang sudah ada dengan nama file yang sama terlebih dahulu.
Joël
tetapi Anda tidak boleh menggunakan On Error Resume Next, atau begitulah saya telah diberitahu: D Tentu saja, itu nasihat yang konyol, dan jawaban Anda benar.
johny mengapa
Bagian Len(dir(...))ini TIDAK HANYA untuk memeriksa keberadaan. Hal ini juga memeriksa apakah file tersebut HIDDEN karena file yang tersembunyi akan mengembalikan string kosong bahkan jika itu ada (dan Anda tidak akan dapat menghapusnya): Dir(hiddenFile) = "". Oleh karena itu, bagian tersebut dengan SetAttr FileToDelete, vbNormalfasih menangani ini untuk Anda.
elektrykalAJ
11

Berikut ini dapat digunakan untuk menguji keberadaan file, dan kemudian menghapusnya.

Dim aFile As String
aFile = "c:\file_to_delete.txt"
If Len(Dir$(aFile)) > 0 Then
     Kill aFile
End If 
Rich Adams
sumber
3
Saya tahu pertanyaan dan respons ini sudah lama, hanya berpikir saya akan menambahkan bahwa menggunakan Len () untuk menguji string (dan fungsi yang mengembalikan string) tampaknya lebih cepat daripada perbandingan string literal di VBA.
JimmyPena
7
Alasan bahwa Len()(dan LenB(), yang bahkan lebih cepat) lebih cepat daripada perbandingan string adalah karena dalam memori, string VB didahului oleh panjangnya. Len / LenB hanya menarik panjang dari lokasi memori itu, mereka tidak perlu mengulang melalui string untuk mengetahui panjangnya. Di sisi lain, menggunakan perbandingan string memiliki lebih banyak pekerjaan yang harus dilakukan. Selain itu, hindari penggunaan ""di VB karena selalu mengalokasikan string baru. Gunakan vbNullStringsebagai gantinya karena ini adalah konstanta dan tidak menggunakan lebih banyak memori.
Renaud Bompuis
7

Di VB biasanya Diruntuk menemukan direktori file. Jika tidak kosong maka itu ada dan kemudian gunakan Killuntuk menyingkirkan file tersebut.

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

setel referensi ke pustaka Scripting.Runtime dan kemudian gunakan FileSystemObject:

Dim fso as New FileSystemObject, aFile as File

if (fso.FileExists("PathToFile")) then
    aFile = fso.GetFile("PathToFile")
    aFile.Delete
End if
Brettski
sumber
Saya menggunakan metode FileSystemObject juga, karena Kill tidak dapat menghapus file / folder dengan diakritis
mauek unak
Ini adalah metode yang saya gunakan .. Seseorang yang mengimplementasikan ini ingin menggunakan pemeriksaan kesalahan dan DisplayAlerts = false. (File tidak akan dihapus jika sedang digunakan, jadi harus memiliki perangkap kesalahan)
Gregg Burns
3

Berikut tipnya: apakah Anda menggunakan kembali nama file, atau berencana melakukan sesuatu yang memerlukan penghapusan segera?

Tidak?

Anda bisa mendapatkan VBA untuk mengaktifkan perintah DEL "C: \ TEMP \ scratchpad.txt" / F dari command prompt secara asinkron menggunakan VBA.Shell:

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

Perhatikan tanda kutip ganda (karakter ASCII 34) di sekitar nama file: Saya berasumsi bahwa Anda memiliki jalur jaringan, atau nama file panjang yang berisi spasi.

Jika itu file besar, atau itu pada koneksi jaringan yang lambat, api-dan-lupakan adalah cara yang tepat. Tentu saja, Anda tidak pernah bisa melihat apakah ini berhasil atau tidak; tetapi Anda segera melanjutkan VBA Anda, dan ada kalanya ini lebih baik daripada menunggu jaringan.

Nil
sumber
Ini adalah alternatif yang bagus, jika asinkron adalah yang Anda inginkan.
johny mengapa
2

Anda dapat mengatur referensi ke perpustakaan Scripting.Runtime dan kemudian menggunakan FileSystemObject. Ini memiliki metode DeleteFile dan metode FileExists.

Lihat artikel MSDN di sini .

Darrel Miller
sumber