和風スパゲティのレシピ

日本語でコーディングするExcelVBA

FileSystemObjectとは - Dir関数群との違い

ExcelVBAにおいてファイル・フォルダを便利に操作するために、
FileSystemObjectという名前の拡張機能が用意されています。


このFileSystemObjectを初めて使う方に向けて、

  • どんな機能なのか
  • どんな時に使うのか

をまずは簡単に説明していきます。


長いコードはまったく出てきませんので、
読み物と思って、気楽に読んでみてください。

◇ FileSystemObject入門シリーズ
【1】FileSystemObjectとは - Dir関数群との違い(本記事)
【2】参照設定と変数宣言
【3】ファイル一覧の取得
【4】すべての下層フォルダの取得
【5】FileSystemObjectって何が便利なの?

FileSystemObjectとは

FileSystemObject(以下FSOと略します)とは、
ファイル・フォルダを操作するための便利機能集です。


FSOを使わずにファイル・フォルダを操作する機能と言えば、

  • ファイル・フォルダを検索するDir関数
  • ファイルをコピーするFileCopyステートメント
  • ファイルを削除するKillステートメント
  • フォルダを作成するMkDirステートメント

などがあり、20種類ほどが用意されています。


例えば「新規フォルダを作る」場合は、

MkDir 作りたいフォルダのパス

このコードを実行すればよいです。


さてこの「新規フォルダを作る」処理ですが、
FSOにも同じ処理を行う「CleateFolderメソッド」が用意されており、

FSO.CreateFolder 作りたいフォルダのパス

このコードで全く同じ結果が得られます。


まずはこの点、
Dir関数群でできることは大抵FSOでも実行でき、構文も大体同じになる
ということを抑えてください。


FileSystemObjectとは、

  • Dir関数群でできる処理は似た書き方で実行できる
  • その上でDir関数群にできない処理ができたり、より簡潔に書けたりする

こんなものだと思っておけばOKです。

FileSystemObjectを使うメリット

それではこのFSOがDirシリーズに勝る点を列挙していきます。

中身のファイルごとフォルダを処理することができる。

FSOの中で最も実効性がある長所はフォルダごと何かをするのが得意なことです。

FSOのメソッドには、

  • フォルダごとコピーするCopyFolderメソッド
  • フォルダごと移動するMoveFolderメソッド
  • フォルダごと削除するDeleteFolderメソッド

が用意されており、中身もまるごとコピー/移動/削除することが可能です。


このうちコピーと削除はDir関数群に代替手段がありませんので、
FSOでしか出来ない処理ということになります。
※ 移動だけはNameステートメントで実行できます。


ググると有無を言わさずFSOの記事が並ぶので、
FSOを知るきっかけの処理だったという方も多そうですね。

フォルダ内のフォルダ(サブフォルダ)を取得するのが簡単

Dir関数はフォルダ内の「ファイル」を探すのは難なくこなしますが、
フォルダ内の「フォルダ」を探すのがちょっと苦手です。


対してFSOはファイル取得とフォルダ取得をほぼ同じコードで実行できるため、
フォルダ内のフォルダを取得する場合はFSOの力を借りる方がはるかに楽です。


ここまでを合わせると、

  • FSOはフォルダごと何かをするのが得意
  • FSOはフォルダ内のフォルダを取得するのが得意

ということなので、「フォルダ操作ならFSO」と思ってしまっていいでしょう。

まずはこの長所を抑えておいてください。

環境依存文字の対応範囲が広い

続いてFSOには「環境文字の対応範囲が広い」という特長があります。

具体的には

  • DirシリーズはShift-JIS限定
  • FSOはUnicode(UTF-16)にも対応

という感じなのですが、この辺はよくわからなければ無視してください。


簡単に言うとVBAで入力したら?になる文字はDir関数だとエラーになります。


頻出文字としては、フォルダ名やファイル名に丸数字を使っていた場合

  • ①~⑳はDirでもFSOでもどちらでもOK
  • ㉑~㊿はFSOでないと動かない

という違いが出てきます。


あとは、頻出ではないけど人によっては超頻出になってしまうのが、
𠮷田さんみたいにShift-JISで書けない職員が近くにいる場合です。

その人用のフォルダや、「_𠮷田更新.xlsx」みたいな接尾語がアウトになります。


このようなフォルダ・ファイルを扱う場合はFSOを使いましょう。



以上がざっくりとしたFileSystemObjectの特長です。

実務的には、

  • フォルダごとコピー・移動・削除したい
  • フォルダの中のフォルダを取得したい
  • Dirでエラーになる環境依存文字に遭遇した

こんなときにFSOを使えばよいということになります。

まずはこれを覚えてください。


実はもう一つ重要な特長があるのですが、
結構難しい話になるため後回しにします。


次はデメリットから説明していきますね。

FileSystemObjectを使うデメリット

使う準備(変数宣言と参照設定)が必要

冒頭で「フォルダを作成」するコードとして紹介した、

FSO.CreateFolder 作りたいフォルダのパス

このコードの先頭には、「FSO」という記述があります。


この「FSO」はFileSystemObject型の変数で、
FSOの入力選択肢
こんな風にFSOの各メソッドを選んで入力することができます。


「.」から使う機能を選べるという点で、
WorksheetFunctionの仲間だと思っておけばOKです。
WorksheetFunctionの入力選択肢



さてWorksheetFunctionはVBAの標準機能なのですが、
FSOは標準機能ではないため自分で変数を宣言する必要があります。


例えば「フォルダを作成する」場合は、

Dim FSO As New FileSystemObject

FSO.CreateFolder 作りたいフォルダのパス

このように実行コードの前に変数宣言が必要になります。


しかもこの変数宣言に加えてもう一つ、
FSOが入った拡張機能の有効設定をONにする作業も必要です。


FSOを使う場合は、この2つの手間が発生します。

この方法は別記事にて解説していますので後ほどリンクしますね。


さてこの手間をデメリットとしてあげましたが、
実際は慣れると10秒かかりませんので身構えなくてOKです。
 

Dim FSO As New FileSystemObject

このコードの意味を理解する必要はありませんので呪文だと思えばいいですし、
入力も「New F」まで打てばあとは選択肢がでます。


この変数宣言をかなりハードルに感じている方もたまに見受けますが、
やってみると大した作業ではないことがわかります。

逆にこの準備を手間に感じてFSOを敬遠していると、
かえって大変なコードを書く羽目になりますのでご注意ください。

ファイルの部分一致検索が少し面倒

FSOの機能面として「○○ができない」というのはほぼありませんが、
強いて言うならファイルの存在判定にワイルドカード*が使えません。

「Dir関数で1行で書けるけどFSOだとForEachが必要」なことがたまにあります。


ただ、Dir関数も1行にできない(Do Whileが必要な)場合はそんなに差はありません。

FSOを使って「ForEach+Like演算子」を書く方が楽なこともあるくらいです。


これもそんなに気にするデメリットではないと思います。

ファイル検索が遅い

1000を超えるファイルを検索するときにようやく差が出てくる程度の話ですが、
FSOはDir関数に比べてファイルの検索が数倍遅いです。


「数倍」と評しましたが、普段はそんなに気にする必要はありません。

どちらも十分高速なため、4倍だったとしても0.1秒と0.4秒とかの差になって、
実際は体感できる差にはならないからです。


ただ、いつか巨大なフォルダ・ファイル群を相手にするときには、
気にしなければいけない差になることがあります。

この性質も、心の片隅にでも置いておいてください。




以上がFileSystemObjectのメリット・デメリット一覧です。


まとめると、

◇ FileSystemObjectを使うメリット

  • フォルダごとコピー・移動・削除が得意
  • フォルダ内のフォルダを探すのが得意
  • 環境依存文字の対応範囲が広い

◇ FileSystemObjectを使うデメリット

  • 使う準備が必要(慣れれば数秒)
  • ファイル検索に*が使えない(ForEach+Likeで代替できる)
  • ファイル検索が遅い(普通の規模なら気づかない程度)

でしたね。


メリットがデメリットを大きく上回っているのを見るとわかる通り、
FileSystemObjectはとても便利な機能群です。


入門シリーズを読み進めて、是非とも勉強してみてください。

◇ FileSystemObject入門シリーズ
【1】FileSystemObjectとは - Dir関数群との違い(本記事)
【2】参照設定と変数宣言
【3】ファイル一覧の取得
【4】すべての下層フォルダの取得
【5】FileSystemObjectって何が便利なの?

 

FileSystemObjectの真のメリット

最後に、先ほど後回しにしたもうひとつのメリットを解説します。


まずは上記のメリット・デメリットをもう一度見てみましょう。

◇ FileSystemObjectを使うメリット

  • フォルダごとコピー・移動・削除が得意
  • フォルダ内のフォルダを探すのが得意
  • 環境依存文字の対応範囲が広い

◇ FileSystemObjectを使うデメリット

  • 使う準備が必要
  • ファイル検索に*が使えない
  • ファイル検索が遅い


これだけ見ると、
フォルダはFSOでやって、ファイルはDirでやればよくない?
と思った方もいるかもしれません。


実際その考えは間違いでなかったりするのですが、
FSOにはもうひとつメリットがあるのでそれを説明します。


いきなり理解しようとすると難しい話なので、
適当に流し読みしてください。


FSOを参照すると、大元のFileSystemObject型の変数に加えて、
もう2つ変数の型(種類)が追加されます。

それが、

Dim ファイル As File
Dim フォルダ As Folder

この2つの変数です。


FSO参照下では「Fileオブジェクト/Folderオブジェクト」という、
新しい型の変数が使えるようになります。


この2つの型は「オブジェクト」という名前がついている通り、
「.○○」という記述でいろいろなことができます。


例えば「ファイルを削除」する際、

FSO.DeleteFolder 削除したいフォルダのパス

と書く方法を紹介していましたが、

削除したいフォルダ.Delete

こんな風に書くこともできます。


他に「フォルダ.Copy」や「フォルダ.Move」と書くのも可能で、
それぞれイメージ通りの動きをしてくれます。



また、あるフォルダ内の全ファイルを

For Each ファイル In フォルダ.Files

と「Filesプロパティ」で取得したり、

この逆「あるファイルの親フォルダ」を、

Dim 親フォルダ As Folder
Set 親フォルダ = ファイル.ParentFolder

と「ParentFolderプロパティ」で取得することもできます。


この「.○○」で処理ができたり親子間のやり取りができたりするのって、
どこかで見たことがないでしょうか?



そう「WorksheetとRange」です。


WorksheetとRangeはともにオブジェクトですので、

  • Worksheet変数.Delete
  • Range変数.Copy

で処理を実行することができます。


また、シートとセルには親子関係がありますので、

Worksheet変数.Range
Range変数.Parent

で、お互いからお互いを取得することができます。


この「シートとセルで使えた手法をファイルやフォルダでも使えるようにする」機能がまさにFSOです。


つまり、
「フォルダとファイル」をオブジェクト化して、
「WorksheetとRange」みたいに使えるようにする。

というのが、FSOの真の役割ということですね。



このメリットは理解するのが難しく、
今までのメリットと違い、即効性がありません。

訓練しないとこの良さを引き出せない上に、習得して得られる効果は
「コードがキレイにかけることで、メンテナンス性が上がる」
といった形で出てくるものです。


ですが、このメリットを理解できるようになると、
FSOだけでなく、オブジェクトというものの理解が深まります。

プログラミングのスキル自体を上達させてくれます。


この内容は入門シリーズの最終記事
「FileSystemObjectって何が便利なの?」にて詳しく解説しています。

よろしければ読んでみてください。

◇ FileSystemObject入門シリーズ
【1】FileSystemObjectとは - Dir関数群との違い(本記事)
【2】参照設定と変数宣言
【3】ファイル一覧の取得
【4】すべての下層フォルダの取得
【5】FileSystemObjectって何が便利なの?