単調な作業はVBAにやらせよう
VBAで自動化するのって正直どうかと思うんですが、どこの部署に行ってもExcelが入っている&下手に開発環境を導入しようとすると手続きがめんどくさいという理由でなかなか手放せずにいます。
別に自動化して褒められようとか残業を減らそうとか、そんな崇高な趣味はございません。本でも読みながらぼーっとする時間が増えたらそれで十分でございます。
まずは第一歩として、ファイル一覧を作るマクロを書いてみます。
とりあえずVBA起動
Excel開いてAlt-F11
。
マクロはSheet1に直接書いちゃってもいいし、標準モジュールを挿入してそこに書いてもいいです。動けばいいので。
Scripting.FileSystemObjectを読み込む
ファイルシステムの読み書きを行うライブラリです。
詳しい説明は割愛。
Scripting.FileSystemObjectの用法としては、以下の書き方を多く見かけるような気がします。
Dim FS As Object
Set FS = CreateObject("Scripting.FileSystemObject")
が、 Ctrl-SPACE
でコード補完が使えなかったりめんどくさいので、参照設定を追加してしまった方が断然ラクです。
' ツール(T) > 参照設定(R) > Microsoft Scripting Runtime
Dim FS As New Scripting.FileSystemObject
指定されたフォルダにあるファイルを返すサブルーチンを書いてみる
検索結果は複数件返ってくるので、FileオブジェクトのCollectionにしてみます。
VBAは日本語で書くのがマイブーム。
Option Explicit
Private Sub ファイル検索(検索フォルダ As Scripting.Folder, 検索結果 As Collection)
Dim ファイル As Scripting.File
For Each ファイル In 検索フォルダ.Files
検索結果.Add ファイル
Next ファイル
End Sub
サブルーチンを呼び出す処理を書いてみる
まあ、最初なので贅沢は言いません。
マクロ実行時に Alt-F8
する必要があったり、検索フォルダのパスがソースにべた書きだったり、結果の出力先がデバッグ(イミディエイトウィンドウ)だったりしてもいいんです。気にしたら負けです。
前述のModule1に追記します。
Public Sub Main()
Dim FS As New Scripting.FileSystemObject
Dim 検索フォルダ As Scripting.Folder
Dim 検索結果 As New Collection
Dim ファイル As Scripting.File
Set 検索フォルダ = FS.GetFolder("C:\Users\xxx\Documents")
Call ファイル検索(検索フォルダ, 検索結果)
For Each ファイル In 検索結果
Debug.Print ファイル.Path
Next ファイル
End Sub
フォルダの指定は、ファイルサーバーとかのネットワークパスでも大丈夫(どちらかというとそっちの用途の方が多いんじゃないかな?)。
イミディエイトウィンドウ(Ctrl-G
)にファイルパスがずらーっと出てきましたかね?
(ちょっと改良)サブフォルダにあるファイルも一覧化したい
ファイル検索を再帰呼び出ししちゃいましょう。
検索フォルダ配下にリバースポイント(ジャンクションポイント、シンボリックリンク)があった場合、そのサブフォルダを参照しようとすると 実行時エラー '70': 書き込みできません。
というエラーが発生するので除外しました。
Private Sub ファイル検索(検索フォルダ As Scripting.Folder, 検索結果 As Collection)
Dim フォルダ As Scripting.Folder
Dim ファイル As Scripting.File
' リバースポイントのサブフォルダを参照するとエラーになるので除外する
If 検索フォルダ.Attributes And Alias Then Exit Sub
For Each ファイル In 検索フォルダ.Files
検索結果.Add ファイル
Next ファイル
For Each フォルダ In 検索フォルダ.SubFolders
Call ファイル検索(フォルダ, 検索結果)
Next フォルダ
End Sub
まあ、ファイル一覧だけならVBA書くまでもないですが
コマンドプロンプト開いて dir /s
で一発ですがね。
「複数のファイルをいっぺんに処理したい」という要件が大半なので、基本の基本として覚えておいても損はないと思いますね。