【簡単Excelマクロ・VBA】ファイル・フォルダの一覧を取得する|アプリ事例 #003
いつもありがとうございます。
ノンプログラマー向けの「Excelマクロ・VBAアプリ事例解説シリーズ」へようこそ。
本稿では、「ファイル・フォルダの一覧を取得するアプリ」の解説をいたします。
皆さんは、フォルダ内のファイルやフォルダの一覧を取得したいときはありませんか。
例えば、ファイルの整理をするときなどです。マクロを作成する方は、全ファイルを逐次的に操作する際などにファイルの一覧を取得することがあるでしょう。
VBAで自分に合ったアプリを作成し、仕事量は半分に、成果は2倍にしていきましょう。
初心者でも理解しやすいように、分かりやすく解説していきます。ぜひご覧ください。
ことばの意味
- ノンプログラマー
プログラミングを主な仕事にしていない人たちのことです。 - マクロ
VBAを使って作成される「機能」のことです。 - VBA
Visusal Basic for Application の略で、プログラミング言語のことです。
関連記事
VBAでファイル・フォルダの一覧を取得する方法
アプリの仕様
指定したフォルダ内の全てのファイルとフォルダを、Excelシートに出力します。
前提条件
下図のように、マクロが記述される「ファイル・フォルダの一覧を取得する.xlsm」と同じ階層に、ファイルやフォルダが格納されている「フォルダ」が存在しているものとします。
「フォルダ」の中身は、下図のようになっています。
Excelシートの設計
取得したファイルとフォルダを表示するためのExcelシートを準備します。下図のようなシートを作成しましょう。
コードの実装
フォルダ内の全てのファイルとフォルダをExcelシートに出力するコードと、その実行結果を以下に示します。
Sub ListFolderContentsToSheet()
' 使用ライブラリ
' Microsoft Scripting Runtime (FileSystemObject を使用)
' 変数宣言
Dim thiswb As Workbook ' 現在のワークブック
Dim thiswb_ws1 As Worksheet ' 現在のワークブックの1つ目のワークシート
Dim fso As FileSystemObject ' ファイルシステムオブジェクト(フォルダやファイル操作用)
Dim source_folder As String ' ソースとなるフォルダのパス
Dim source_file As Object ' 各ファイルを表すオブジェクト
Dim sub_folder As Object ' 各フォルダを表すオブジェクト
Dim row_idx As Long ' 行のインデックス(書き込み用の行番号)
Dim serial_num As Long ' 通し番号を保持する変数
' ワークブックとワークシートを変数に代入
Set thiswb = ThisWorkbook
Set thiswb_ws1 = thiswb.Worksheets(1)
' FileSystemObjectのインスタンスを生成し変数に代入
Set fso = New FileSystemObject
' ソースフォルダを変数に代入
source_folder = ThisWorkbook.Path & "\フォルダ"
' ワークシートの初期化(内容と書式をクリア)
thiswb_ws1.Rows("3:" & thiswb_ws1.Rows.Count).Clear
' 行番号と通し番号の初期値を設定
row_idx = 3 ' 行番号
serial_num = 1 ' 通し番号
' フォルダ内の全フォルダを書き込む
For Each sub_folder In fso.GetFolder(source_folder).SubFolders
thiswb_ws1.Cells(row_idx, 1) = serial_num ' 通し番号をA列に追加
thiswb_ws1.Hyperlinks.Add _
Anchor:=thiswb_ws1.Cells(row_idx, 2), _
Address:=sub_folder.Path, _
TextToDisplay:=sub_folder.Name ' フォルダ名にハイパーリンクを設定
row_idx = row_idx + 1
serial_num = serial_num + 1 ' 通し番号をインクリメント
Next sub_folder
' フォルダ内の全ファイルを書き込む
For Each source_file In fso.GetFolder(source_folder).Files
thiswb_ws1.Cells(row_idx, 1) = serial_num ' 通し番号をA列に追加
thiswb_ws1.Hyperlinks.Add _
Anchor:=thiswb_ws1.Cells(row_idx, 2), _
Address:=source_file.Path, _
TextToDisplay:=source_file.Name ' ファイル名にハイパーリンクを設定
thiswb_ws1.Cells(row_idx, 3) = Round(source_file.Size / 1024, 2) & " KB" ' ファイルサイズをC列に移動して表示
row_idx = row_idx + 1
serial_num = serial_num + 1 ' 通し番号をインクリメント
Next source_file
' C列を右揃えに設定
thiswb_ws1.Columns("C:C").HorizontalAlignment = xlRight
' オブジェクトを開放
Set source_file = Nothing
Set sub_folder = Nothing
Set fso = Nothing
End Sub
解説していきます。
' 使用ライブラリ
' Microsoft Scripting Runtime (FileSystemObject を使用)
これはコードの一部ではありませんが、この コードを実行するために必要なライブラリをコメントとして記載しています。このMicrosoft Scripting Runtime
を使用することで、FileSystemObject
というオブジェクトを操作することができるようになります。つまり、ファイルやフォルダに関する情報を取得したり操作したりすることができます。
ことばの意味
- オブジェクト
特定の役割を持つ道具のようなものです。 - ライブラリ
特定の機能をもったコードの集合体です。ソフトウェア作成における部品のようなものです。新しいアプリケーションを作成する際、ライブラリを使用することで、プログラマーは複雑なコードを自分で書く必要がなくなります。
ライブラリの参照設定は以下の手順で行うことができます。
VBE画面から「ツール」--> 「参照設定」を開きます。
Microsoft Scripting Runtime
にチェックを入れて、「OK」を押します。なお、これらのライブラリを初めて設定する場合、上位には表示されていません。アルファベット順に従ってリストの下の方に表示されていますので、慌てずに探してください。
以上で、ライブラリの参照設定は終了です。
' 変数宣言
Dim thiswb As Workbook ' 現在のワークブック
Dim thiswb_ws1 As Worksheet ' 現在のワークブックの1つ目のワークシート
Dim fso As FileSystemObject ' ファイルシステムオブジェクト(フォルダやファイル操作用)
Dim source_folder As String ' ソースとなるフォルダのパス
Dim source_file As Object ' 各ファイルを表すオブジェクト
Dim sub_folder As Object ' 各フォルダを表すオブジェクト
Dim row_idx As Long ' 行のインデックス(書き込み用の行番号)
Dim serial_num As Long ' 通し番号を保持する変数
ここでは、コード内で使用する変数が宣言されています。変数は Dim 変数名 As データ型
の構文で宣言します。これにより、各変数は As
以降で指定したデータ型のデータを格納できるようになります。
' ワークブックとワークシートを変数に代入
Set thiswb = ThisWorkbook
Set thiswb_ws1 = thiswb.Worksheets(1)
ここでは、オブジェクト変数 thiswb
と thiswb_ws1
に、それぞれワークブックオブジェクトとワークシートオブジェクトを代入しています。なお、ThisWorkbook
は現在のワークブック、つまりこのコードが記述されているワークブックを指します。
' FileSystemObjectのインスタンスを生成し変数に代入
Set fso = New FileSystemObject
ここでは、FileSystemObject
を新しく作成し、そのオブジェクトを fso
という変数に代入しています。FileSystemObject
は、ファイルやフォルダを操作するためのオブジェクトで、これを使うことでフォルダ内のファイルリストを取得したり、ファイルの存在確認、コピー、削除などの操作が可能になります。
' ソースフォルダを変数に代入
source_folder = ThisWorkbook.Path & "\フォルダ"
ここでは、source_folder
という変数に、ソースとなるフォルダのパスを代入しています。ThisWorkbook.Path
は、現在実行中のワークブックが保存されているフォルダのパスを取得します。これに "\フォルダ"
を追加することで、ThisWorkbookと同階層にある「フォルダ」という名前のフォルダを指定しています。
' ワークシートの初期化(内容と書式をクリア)
thiswb_ws1.Rows("3:" & thiswb_ws1.Rows.Count).Clear
ここでは、ワークシートの初期化を行っています。thiswb_ws1.Rows("3:" & thiswb_ws1.Rows.Count).Clear
というコードにより、3行目から最終行までのすべての行の内容と書式がクリアされます。これにより、前回の処理結果や不要なデータを削除し、新しいデータをクリーンな状態で書き込む準備が整います。
' 行番号と通し番号の初期値を設定
row_idx = 3 ' 行番号
serial_num = 1 ' 通し番号
ここでは、行番号と通し番号の初期値を設定しています。row_idx = 3
によって、データを書き込む開始行を3行目に指定しています。serial_num = 1
は、通し番号の初期値を1に設定しています。これにより、データが3行目から書き込まれ、各項目には通し番号が1から順に割り振られるようになります。
' フォルダ内の全フォルダを書き込む
For Each sub_folder In fso.GetFolder(source_folder).SubFolders
thiswb_ws1.Cells(row_idx, 1) = serial_num ' 通し番号をA列に追加
thiswb_ws1.Hyperlinks.Add _
Anchor:=thiswb_ws1.Cells(row_idx, 2), _
Address:=sub_folder.Path, _
TextToDisplay:=sub_folder.Name ' フォルダ名にハイパーリンクを設定
row_idx = row_idx + 1
serial_num = serial_num + 1 ' 通し番号をインクリメント
Next sub_folder
ここでは、指定したフォルダ内のすべてのサブフォルダをワークシートに書き込む処理を行っています。
For Each sub_folder In fso.GetFolder(source_folder).SubFolders
で、source_folder
内のすべてのサブフォルダを取得し、sub_folder
というオブジェクトで順番に処理しています。thiswb_ws1.Cells(row_idx, 1) = serial_num
では、現在の行(row_idx
)のA列に、通し番号を書き込んでいます。thiswb_ws1.Hyperlinks.Add
の部分では、B列にフォルダ名を表示し、フォルダ名にハイパーリンクを設定しています。Address
にフォルダのパス、TextToDisplay
にフォルダ名が表示されるようにしています。row_idx = row_idx + 1
で、次の行に移動し、serial_num = serial_num + 1
で通し番号を1つ増やして、次のフォルダが次の行に書き込まれるようにしています。serial_num = serial_num + 1
は、通し番号を1つ増やす操作です。これを「インクリメント」と呼びます。次のアイテムが処理されるたびに通し番号が順に増えていきます。
このループは、すべてのサブフォルダが処理されるまで続きます。
' フォルダ内の全ファイルを書き込む
For Each source_file In fso.GetFolder(source_folder).Files
thiswb_ws1.Cells(row_idx, 1) = serial_num ' 通し番号をA列に追加
thiswb_ws1.Hyperlinks.Add _
Anchor:=thiswb_ws1.Cells(row_idx, 2), _
Address:=source_file.Path, _
TextToDisplay:=source_file.Name ' ファイル名にハイパーリンクを設定
thiswb_ws1.Cells(row_idx, 3) = Round(source_file.Size / 1024, 2) & " KB" ' ファイルサイズをC列に移動して表示
row_idx = row_idx + 1
serial_num = serial_num + 1 ' 通し番号をインクリメント
Next source_file
ここでは、指定したフォルダ内のすべてのファイルをワークシートに書き込む処理を行っています。
For Each source_file In fso.GetFolder(source_folder).Files
で、source_folder
内のすべてのファイルを取得し、source_file
というオブジェクトで順番に処理しています。thiswb_ws1.Cells(row_idx, 1) = serial_num
では、現在の行(row_idx
)のA列に通し番号を書き込んでいます。thiswb_ws1.Hyperlinks.Add
の部分では、B列にファイル名を表示し、そのファイル名にハイパーリンクを設定しています。Address
にファイルのパス、TextToDisplay
にファイル名が表示されるようにしています。thiswb_ws1.Cells(row_idx, 3) = Round(source_file.Size / 1024, 2) & " KB"
では、ファイルサイズをKB単位でC列に表示します。source_file.Size
で取得したサイズをKBに変換し、Round
関数で小数点以下2桁に丸めています。row_idx = row_idx + 1
で次の行に移動し、serial_num = serial_num + 1
で通し番号を1つ増やします。
このループは、フォルダ内のすべてのファイルが処理されるまで続きます。
' C列を右揃えに設定
thiswb_ws1.Columns("C:C").HorizontalAlignment = xlRight
ここでは、ワークシートのC列に対して右揃えの設定を行っています。
' オブジェクトを開放
Set source_file = Nothing
Set sub_folder = Nothing
Set fso = Nothing
ここでは、使用したオブジェクトを解放しています。
この操作は必須ではありませんが、 コーディングの良い習慣として、使用が終わったオブジェクトは開放することが推奨されます。これにより、メモリの無駄な消費を防ぐことができます。
以上で解説は終了です。
おわりに
ご覧いただきありがとうございました。
本稿では、「ファイル・フォルダの一覧を取得するアプリ」の紹介いたしました。
お問い合わせやご要望等ございましたら、「お問い合わせ/ご要望」またはコメントにて、ご連絡いただければ幸いでございます。
皆様の人生がより一層素晴らしいものになるよう、少しでもお役に立てれば幸いでございます。
尚、当サイトでは様々な情報を発信しております。もしよろしければ、トップページもご確認いただけると幸いでございます。
筆者の記事関連経験
- VBA使用経験約20年
実務に使用するマクロを多数作成してきました。 - Python 3 エンジニア認定基礎試験
経済産業省が定めたガイドライン「ITスキル標準(ITSS)」に掲載されている民間資格です。
VBAプログラミングスキルアップのための参考情報
ここでは参考図書を紹介いたしますが、これらに限らず自分に合うものを選ぶことが重要だと考えております。皆様の、より一層のご成功を心よりお祈りしております。
VBAプログラミングのスキルアップ
学習用としてもハンドブックとしても役立つ便利な書籍がこちらです。価格はやや高めですが、その内容は非常に充実しています。相応のスキルを身に付けるためには、こうしたしっかりとした書籍を一冊持っておくと良いでしょう。
入門書に関しては、どの書籍も大きな違いはありません。あまり迷うことに時間をかけるよりは、手頃なものを一冊選んでみると良いでしょう。VBAの入門書は数多く出版されていますので、興味がある方はぜひチェックしてみてください。
甲乙つけがたい場合、私はインプレス社の「いちばんやさしい」シリーズを選ぶことが多いです。
\チェックしてみよう/
\チェックしてみよう/
\チェックしてみよう/
VBAのプログラミング能力を客観的に証明したい場合には「VBAエキスパート試験」があります。この試験はVBAの知識を公式に認定するものです。VBAの総合的な能力獲得を目指す方に適しています。以下の公式テキストが販売されております。
プログラミングの一般教養
「独学プログラマー」というプログラミングの魅力を解説した書籍があります。これはVBAではなくPythonを題材としていますが、プログラミングの基本的な知識や思考法、仕事の進め方まで幅広く学べます。
こちらの記事でも紹介しております。もしよろしければご覧ください。