【簡単Excelマクロ・VBA】ファイルを削除する方法|Kill / FileSystemObject|ファイル操作 #010
いつもありがとうございます。
ノンプログラマー向け「Excelマクロ・VBA解説シリーズ」へようこそ。
本稿では、ファイルを削除する方法を解説いたします。
ファイルの削除は、私たちノンプログラマーが特に気をつけなければいけない操作です。
なぜなら、ファイル削除のコーディングをミスすると、例えば、誤って共有サーバーのファイルを消去してしまったりする可能性があるということです。
これはマクロとして致命的な欠陥です。
そのため、ファイルを削除するコードを実装するときは、細心の注意を払ってコーディングし、しっかりとテストしてからリリースしましょう。
ことばの意味
- ノンプログラマー
プログラミングを本職としない人たちのことです。 - マクロ
VBAを使って作成される「機能」のことです。 - VBA
Visusal Basic for Application の略で、プログラミング言語のことです。
関連記事
VBAにおけるファイル操作の全体像
VBAにおける「ファイル操作」の全体像は以下の記事で解説しております。
本稿では「ファイル操作」の一部である「ファイルを削除する方法」を解説いたします。
VBAでファイルを削除する方法
ファイルの削除には2つの方法がある
VBAでファイルを削除するには以下の2つの方法があります。
- kill ステートメントを使う方法
- FileSystemObject を使う方法
ことばの意味
- ステートメント
VBAの中で何らかの固有の働きをするものを定義したものの呼称です。VBAには、Ifステートメント、For...Next ステートメント、Withステートメント、Sub ステートメントなど、様々なステートメントがあります。例えば、Subステートメントは、コードの始まりを定義するステートメントです。
使い分けは以下のようにすると良いでしょう。どちらを使うか迷う場合は、さまざまな状況に対応できる FileSystemObject を使っておけば問題ないでしょう。
- 単純にファイルを削除したいだけなら Killステートメントを使う
- 柔軟なファイル操作が必要である場合には FileSystemObject 使う
解説します。
Kill ステートメントは、ファイルを削除することに特化したVBAの標準のステートメントです。特徴はシンプルで高速であるということです。
一方、FileSystemObject は、Microsoft Scripting Runtime という Microsoft が提供するライブラリを使ってファイルシステムを操作するためのオブジェクトです。多機能であり、文脈に応じて柔軟なコードを実装することができます。
ことばの意味
- オブジェクト
特定の役割を持つ道具のようなものです。
Killステートメントと FileSystemObject ができること、できないことを簡単にまとめると下表のようになります。
操作 | Kill ステートメント | FileSystemObject |
---|---|---|
単一ファイルの削除 | できる | できる |
複数ファイルの削除 | できる | できる |
サブディレクトリの操作 | できない | できる |
ファイルの存在確認 | できない | できる(FileExists メソッドで可能) |
フォルダの存在確認 | できない | できる(FolderExists メソッドで可能) |
ファイルのコピー | できない | できる(CopyFile メソッドで可能) |
ファイルの移動 | できない | できる(MoveFile メソッドで可能) |
ファイルの削除 | できない | できる(DeleteFolder メソッドで可能) |
エラーハンドリング | できない(標準のコードでエラーハンドリング実装が必要) | できる(内臓のエラーハンドリング機能がある) |
Killステートメントでファイルを削除する方法
Killステートメントでファイルを削除する基本構文
Killステートメントの基本構文は以下の通りです。
ことばの意味
- 構文・・・プログラミング言語の文法のことです。
Kill filepath
ここで filepath
はファイルのパスです。
「単一のファイルの削除」と、ワイルドカードを使用した「複数ファイルの一括削除」する方法があります。
' 単一ファイルの削除
Kill "your_directory/your_file.xlsx"
' 複数ファイルの一括削除(ワイルドカード使用)
Kill "your_directory/*.xlsx"
尚、"ワイルドカード"とは、特定の文字やパターンを表現するための特別な文字のことです。
上記のコードで使用している " * "(アスタリスク)は、「0文字以上の任意の文字列」を表します。つまり、上記の例において "*.xlsx" は、拡張子”.xlsx”のすべてのファイルを意味しています。
即ち Kill "your_directory/*.xlsx"
は、すべての xlsxファイルを削除せよ、という命令になります。
Killステートメントで単一ファイルを削除する方法
単一ファイルを削除する例を以下に示します。この例では、「ファイルを削除する.xlsm」にマクロを記録し、同階層にある "ファイル1.xlsx" を削除します。
Sub Sample()
' ファイルを削除する
Kill ThisWorkbook.Path & "\ファイル1.xlsx"
End Sub
Killステートメントで複数ファイルを一括削除する方法
複数ファイルの一括削除の例を以下に示します。この例では、「ファイルを削除する.xlsm」にワイルドカードを使用したマクロを記録し、同階層にあるすべての xlsx ファイルを一括削除します。
Sub Sample2()
' ファイルを削除する
Kill ThisWorkbook.Path & "\*.xlsx"
End Sub
Killステートメントでファイルを削除する際の基本的なエラーハンドリングの追加
基本的な使い方は前述した通りですが、実際には、これではプログラムの堅牢性に欠けます(ロバスト性が低い)。
ことばの意味
- ロバスト性
プログラムが、さまざまな状況や予期しない条件の下でも安定して正しく動作し続ける能力のことです。具体的には、予期しない入力やエラーが発生した際にも、適切に処理できる能力のことです。
つまり Kill filepath
のみのコードの実装では、 マクロ実行環境のばらつきによってエラーが発生する可能性が高まります。
もし指定したファイルが存在しなかった場合は、以下のようなエラーが発生しマクロが中断されます。
実際のコードでは、最低限、ファイルを削除する前にファイルの存在を確認するコードは実装しておくことが推奨されます。
以下に、ファイルの存在確認をしてから削除するコードを示します。このコードであれば、指定したディレクトリ内に xlsx ファイルがひとつも存在しない場合でもエラーは発生しません。
Sub Sample4()
' 変数宣言
Dim file_path As String
Dim file_name As String
Dim full_path As String
' 指定されたディレクトリ内の xlsx ファイルを検索
file_path = ThisWorkbook.Path & "\*.xlsx"
file_name = Dir(file_path)
' すべの xlsx ファイルに対して繰り返し処理
Do While file_name <> ""
' ファイルのフルパスを取得
full_path = ThisWorkbook.Path & "\" & file_name
' ファイル削除
Kill full_path
' 次のファイル名の取得
file_name = Dir()
Loop
解説します。
' 変数宣言
Dim file_path As String
Dim file_name As String
Dim full_path As String
冒頭のこの部分は変数の宣言をしています。変数は Dim 変数 As データ型
の構文で宣言します。
これによって各変数は As 以降で指定したデータ型のデータを格納することができるようになります。
尚、String
は文字列を格納するためのデータ型です。
' 指定されたディレクトリ内の xlsx ファイルを検索
file_path = ThisWorkbook.Path & "\*.xlsx"
file_name = Dir(file_path)
ThisWorkbook.Path
は現在のExcelファイルが保存されているディレクトリのパスを表します。つまり、"ファイルを削除する.xlsm" が保存されているディレクトリのパスを表します。
ThisWorkbook.Path & "*.xlsx"
は、現在のExcelファイルが保存されているディレクトリ内のすべての ".xlsx" ファイルのことを表します。
つまり、変数 file_path
には、現在のディレクトリ内のすべての ".xlsx" ファイルを表す文字列が格納されます。
file_name = Dir(file_path)
file_name = Dir(file_path)
の Dir関数は、指定されたパスに一致する最初のファイル名を返す関数です。
この場合は、file_path
に一致する最初の ".xlsx" ファイルを表す文字列が格納されます。
このコードにより指定のディレクトリ内にある ".xlsx" ファイルの名前を取得できます。
' すべの xlsx ファイルに対して繰り返し処理
Do While file_name <> ""
' ファイルのフルパスを取得
full_path = ThisWorkbook.Path & "\" & file_name
' ファイル削除
Kill full_path
' 次のファイル名の取得
file_name = Dir()
Loop
Do While file_name <> ""
は、file_name (ファイル名を表す文字列)が"空"でない間、処理を繰り返しなさいという命令です。これはつまり、Dir 関数が返すファイル名がある限り繰り返し処理を続けるということです。
full_path = ThisWorkbook.Path & "\" & file_name
は、 file_name に 現在のExcelファイル("ファイルを削除する.xlsm")が保存されているパスを "&" で結合してフルパスとし、変数 full_path に格納しています。
ようやく登場しました。Kill full_path
が、ファイルを削除するコードです。変数 full_path に格納されているパスのファイルを削除します。
実は次がポイントです。file_name = Dir()
は、Dir関数を再度呼び出して、次のファイル名を取得するコードです。 つまり、前回の Dir で見つかったファイルの、次のファイルを取得します。
そして 16行目の Do While ステートメントに戻ります。これの繰り返しです。
file_name
が空でなければ Do While 以降のコードを再度実行し、空であればそこで処理終了になります。
もし 12行目、つまり初回の file_name が空であれば、Do While ステートメントの中身のコードは一度も実行されません。これはつまり、指定したディレクトリに ".xlsx" ファイルがひとつも存在しなくてもエラーは発生しないということです。
以上が、ファイルの存在確認をしてから削除する方法です。
Killステートメントでファイルを削除する際の予期しないエラーへの対応
上述の、ファイルの存在を確認してから削除する方法だけでも悪くはないですが、もうひと手間加えるとさらにコードが堅牢になり、玄人らしくなります。
例えば、環境のばらつきの一例として 、file_name
で指定したファイルが開かれていたとします。この場合はどうなるでしょう。
以下のようなエラーが発生して、処理が止まります。
このような事態に対処するためには以下のようにコードを記述します。コードを追加した部分をハイライトします。
Sub Sample5()
' 変数宣言
Dim file_path As String
Dim file_name As String
Dim full_path As String
' エラーハンドリングを設定
On Error GoTo ErrorHandler
' 指定されたディレクトリ内の xlsx ファイルを検索
file_path = ThisWorkbook.Path & "\*.xlsx"
file_name = Dir(file_path)
' すべての xlsx ファイルに対して繰り返し処理
Do While file_name <> ""
' ファイルのフルパスを取得
full_path = ThisWorkbook.Path & "\" & file_name
' ファイル削除
Kill full_path
' 次のファイル名の取得
file_name = Dir()
Loop
' エラーハンドリングを終了
On Error GoTo 0
' 正常にプロシージャーを終了
Exit Sub
ErrorHandler:
MsgBox "エラー番号 " & Err.Number & " が発生しました: " & Err.Description, vbCritical
'必要に応じて、ここに処理を追加してください。
' 例)次の処理に進める
'Resume Next
End Sub
このコードでは、file_name
で指定したファイルが開かれていた場合、以下のエラーメッセージを出します。
この場合は、ErrorHandler の部分に、メッセージボックスの表示しか記述していないため、ここで処理は止まります。
しかし、例えば、例示したような次の処理に進めるコード(Resume Next)を書けば、このエラーが発生しているファイルはスキップして次のファイルに進みます。
以上が予期しないエラーへの対応方法です。
FileSystemObject でファイルを削除する方法
Microsoft Scripting Runtime の参照設定の追加
FileSystemObject を使用するためには、まずはじめに Microsoft Scripting Runtime を参照設定を追加しておく必要があります。
「ツール」-->「参照設定」と進み、Microsoft Scripting Runtime にチェックを入れ「OK」を押下します。
このひと手間が FileSystemObject を使う際のデメリットであるともいえますが、一度設定してしまえば以降は設定の必要はありません。
FileSystemObject でファイルを削除する基本構文
FileSystemObject でファイルを削除する基本構文は以下の通りです。
FileSystemObject.DeleteFile(filepath)
ここで filepath は削除したいファイルのパスです。
FileSystemObject で単一ファイルを削除する方法
単一ファイルの削除の例を以下に示します。Kill ステートメントの解説の時と同様に "ファイルを削除する.xlsm"にマクロを記録し、同階層にある "ファイル1.xlsx" を削除する例です。
Sub Sample6()
' 変数宣言
Dim fso As FileSystemObject
Dim filepath As stiring
' FileSystemObject を作成して変数に代入
Set fso = New FileSystemObject
' ファイルパスを変数に代入
filepath = ThisWorkbook.Path & "\ファイル1.xlsx"
' ファイルを削除する
fso.DeleteFile filepath
End Sub
FileSystemObject で複数ファイルを一括削除する方法
複数ファイルの一括削除の例を以下にします。Kill ステートメントの解説の時と同様に "ファイルを削除する.xlsm"にワイルドカードを使用したマクロを記録し、同階層にある xlsx ファイルをすべて削除する例です。
Sub Sample7()
' 変数宣言
Dim fso As FileSystemObject
Dim filepath As String
' FileSystemObject を作成して変数に代入
Set fso = New FileSystemObject
' ファイルパスを変数に代入
filepath = ThisWorkbook.Path & "\*.xlsx"
' ファイルを削除する
fso.DeleteFile filepath
End Sub
Kill ステートメントと同様にワイルドカードを使用して一括削除することができます。
FileSystemObject でファイルを削除する場合の基本的なエラーハンドリング
Kill ステートメントの場合と同じく、実際のコードではプログラムに最低限の堅牢性(ロバスト性)を持たせるため、指定したフォルダ内にファイルが存在しない場合でもエラーが発生しないようにしてくことが推奨されます。
以下に、ファイルが存在しない場合でもエラーがでないコードを例示します。
単一ファイルの削除にエラーハンドリングを実装する方法
FileSystemObject 方式のファイルの削除において、ファイルの存在を確認してから削除するコードを以下に示します。コードを追加した部分をハイライトします。
Sub Sample8()
' 変数宣言
Dim fso As FileSystemObject
Dim file_path As String
' FileSystemObject を作成して変数に代入
Set fso = New FileSystemObject
' ファイルパスを変数に代入
file_path = ThisWorkbook.Path & "\ファイル1.xlsx"
' ファイルが存在するか確認し、削除する
If fso.FileExists(file_path) Then
fso.DeleteFile file_path
End If
End Sub
このコードでは、18行目でファイルの存在を確認しています。
ファイルが存在していれば、20行目でファイルを削除します。
ファイルが存在してなければ、20行目はスキップされますので、エラーは発生しません。
複数ファイルの一括削除にエラーハンドリングを実装する方法
ファイルパスにワイルドカードを使用して filepath = ThisWorkbook.Path & "*.xlsx"
とし、fso.DeleteFile filepath
とするとファイルを一括削除できますが、ファイルの存在を確認する fso.FileExists(file_path)
メソッドにはワイルドカードが使えません。
そこで考え方を変え、FileSystemObject の機能を使ってフォルダ内のファイルをイテレーションし(ひとつずつ繰順番に処理し)、削除する方法に変更します。
ことばの意味
- イテレーション・・・一つずつ繰り返し処理していくことです。
Sub Sample9()
' 変数宣言
Dim fso As FileSystemObject
Dim folder_path As String
Dim folder As folder
Dim file As file
' FileSystemObjectを作成して変数に代入
Set fso = New FileSystemObject
' フォルダのパスを変数に代入
folder_path = ThisWorkbook.Path & "\"
' フォルダオブジェクトを変数 folder に代入
Set folder = fso.GetFolder(folder_path)
' フォルダ内のファイルをイテレーションする(フォルダ内のファイルを一つずつ順番に処理する)
For Each file In folder.Files
' 削除するファイルの拡張子を .xlsx げ限定する ※用途にに応じて修正してください
If LCase(fso.GetExtensionName(file.Name)) = "xlsx" Then
' ファイルを削除する
file.Delete
End If
Next file
' オブジェクトの解放
Set folder = Nothing
Set fso = Nothing
End Sub
ポイントを解説します。
' フォルダオブジェクトを変数 folder に代入
Set folder = fso.GetFolder(folder_path)
20行目で、ファイルの入っているフォルダーを FileSystemObject のオブジェクトとして取得します。
' フォルダ内のファイルをイテレーションする(フォルダ内のファイルを一つずつ順番に処理する)
For Each file In folder.Files
For Each ステートメントでフォルダ内のファイルをひとつずつ順番に処理していきます。ここが一番のポイントです。
For...Each ステートメントを使うことによって、Folder.Files が "空" であっても、For Each ループ内の処理が実行されないだけです。
つまり、エラーは発生しません。
わざわざファイルの存在を確認するコードを実装する必要が無いのです。
尚、For...Each ステートメントの使い方はこちらの記事で解説しておりますので、もしよろしければご覧ください。
' ファイルを削除する
file.Delete
そして、ファイルを削除します。Folder.Files が空である場合、当然ここもスキップされます。
FileSystemObjectでファイルを削除する際の予期しないエラーへの対応
予期しないエラーへの対処方法は、Kill ステートメントで解説した方法と同様です。
おわりに
ご覧いただきありがとうございました。
本稿では、「ファイル操作」の中の「ファイルを削除する方法」を解説いたしました。
お問い合わせやご要望等ございましたら、「お問い合わせ/ご要望」またはコメントにて、ご連絡いただければ幸いでございます。
皆様の人生がより一層素晴らしいものになるよう、少しでもお役に立てれば幸いでございます。
なお、当サイトでは様々な情報を発信しております。もしよろしければ、トップページもご覧いただけると幸いでございます。
筆者の記事関連経験
- VBA使用経験約20年
実務に使用するマクロを多数作成してきました。 - Python 3 エンジニア認定基礎試験
経済産業省が定めたガイドライン「ITスキル標準(ITSS)」に掲載されている民間資格です。
VBAプログラミングスキルアップのための参考情報
ここでは参考図書を紹介いたしますが、これらに限らず自分に合うものを選ぶことが重要だと考えております。皆様の、より一層のご成功を心よりお祈りしております。
VBAプログラミングのスキルアップ
学習用としてもハンドブックとしても役立つ便利な書籍がこちらです。価格はやや高めですが、その内容は非常に充実しています。相応のスキルを身に付けるためには、こうしたしっかりとした書籍を一冊持っておくと良いでしょう。
入門書に関しては、どの書籍も大きな違いはありません。あまり迷うことに時間をかけるよりは、手頃なものを一冊選んでみると良いでしょう。VBAの入門書は数多く出版されていますので、興味がある方はぜひチェックしてみてください。
甲乙つけがたい場合、私はインプレス社の「いちばんやさしい」シリーズを選ぶことが多いです。
\チェックしてみよう/
\チェックしてみよう/
\チェックしてみよう/
VBAのプログラミング能力を客観的に証明したい場合には「VBAエキスパート試験」があります。この試験はVBAの知識を公式に認定するものです。VBAの総合的な能力獲得を目指す方に適しています。以下の公式テキストが販売されております。
プログラミングの一般教養
「独学プログラマー」というプログラミングの魅力を解説した書籍があります。これはVBAではなくPythonを題材としていますが、プログラミングの基本的な知識や思考法、仕事の進め方まで幅広く学べます。
こちらの記事でも紹介しております。もしよろしければご覧ください。