第18回 FileSystemObjectオブジェクトを利用する(3):基礎解説 演習方式で身につけるチェック式WSH超入門(1/2 ページ)
Files/Foldersコレクションを使えば、サブフォルダの内容を再帰的に走査して処理できる。ドライブの情報を取得する方法についても解説。
諸事情のため、およそ1年間の休載期間をいただきました。連載の続きをお待ちいただいた読者諸氏に深くおわび申し上げます。この連載も、今回を含めてあと2回ですので、最後までよろしくお願いいたします。
前回は、FileSystemObjectオブジェクトから呼び出し可能なオブジェクトである、ファイルを表すFileオブジェクト、フォルダを表すFolderオブジェクトについて取り上げた。そして、それぞれに共通のメンバを紹介し、ファイル/フォルダのプロパティの取得と設定、メソッドを用いたファイル・システム操作について述べた。
今回は、フォルダを表すFolderオブジェクトからその配下にあるファイルの集合を表すFilesコレクション、サブフォルダの集合を表すFoldersコレクションを取得し、これらのコレクションから各要素を取り出し利用する方法を述べる。また、ドライブを表すDriveオブジェクトについて述べ、現在利用可能なドライブの集合を表すDrivesコレクションについても取り上げる。
FilesとFoldersコレクション
■連載目次
第1回 WSHを始めよう
第2回 VBScript基本(1)文字列の入出力
第3回 VBScript基本(2)計算と分岐処理
第4回 関数を使いこなす:文字列、数値、日付
第5回 データ型について理解を深めよう
第6回 VBScriptの配列を極める
第7回 Subプロシージャで処理を定義
第8回 Functionプロシージャで関数を定義
第9回 VBScriptのオブジェクトを使いこなす
第10回 WScriptオブジェクト(1)
第11回 WScriptオブジェクト(2)
第12回 WshShellオブジェクト(1)
第13回 WshShellオブジェクト(2)
第14回 WshShellオブジェクト(3)
第15回 WshNetworkオブジェクト
第16回 FileSystemObjectオブジェクト(1)
第17回 FileSystemObjectオブジェクト(2)
第18回 FileSystemObjectオブジェクト(3)
第19回 TextStream/Dictionaryオブジェクト
あるフォルダには、ファイルや、サブフォルダが含まれることがある。これらを取得するにはFolderオブジェクトのFilesプロパティ、SubFoldersプロパティを用いる。それぞれ、Filesコレクション(Fileオブジェクトのコレクション)、Foldersコレクション(Folderオブジェクトのコレクション)を返す。
これらのプロパティを使って、スクリプトが存在するフォルダに含まれるサブフォルダと、ファイルの一覧を列挙するスクリプトをご覧にいれよう。
例えば次のようなフォルダを対象とする。
※ファイル:dir.vbs
Option Explicit
'FileSystemObjectオブジェクト変数の宣言とインスタンスの代入
Dim objFSO
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
'出力メッセージを保持する変数宣言
Dim strMessage
strMessage = ""
'親フォルダのパスと親フォルダのFolderオブジェクトを格納する変数宣言
Dim strParentFolder, objParentFolder
'スクリプトが存在するフォルダの親フォルダのパスを取得
strParentFolder = objFSO.GetParentFolderName(WScript.ScriptFullName)
'親フォルダを表すFolderオブジェクトを取得して代入
Set objParentFolder = objFSO.GetFolder(strParentFolder)
'1つのサブフォルダおよびサブフォルダのセットを表すオブジェクト変数を宣言
Dim objSubFolder, objSubFolders
'FolderオブジェクトのSubFoldersプロパティを参照し、Foldersコレクションを得る
Set objSubFolders = objParentFolder.SubFolders
'サブフォルダのFolderオブジェクトを列挙
For Each objSubFolder In objSubFolders
'サブフォルダのフォルダ名を取得
strMessage = strMessage & objSubFolder.Name & vbCrLf
Next
Set objSubFolder = Nothing
Set objSubFolders = Nothing
'1つのファイルおよびファイルのセットを表すオブジェクト変数を宣言
Dim objFile, objFiles
'FolderオブジェクトのFilesプロパティを参照し、Filesコレクションを得る
Set objFiles = objParentFolder.Files
'フォルダに存在するファイルのFileオブジェクトを列挙
For Each objFile In objParentFolder.Files
'ファイル名を取得
strMessage = strMessage & objFile.Name & vbCrLf
Next
Set objFile = Nothing
Set objFiles = Nothing
'サブフォルダとファイル名の一覧を表示
MsgBox strMessage
Set objFSO = Nothing
このスクリプトをサブフォルダやファイルが存在するフォルダで実行すると、例えば次のような結果が得られる。
このように、実際にファイル・システムに存在するサブフォルダとファイルが一覧として出力されることがお分かりいただけると思う。
まずこのスクリプトではFolderオブジェクトに存在するSubFoldersプロパティを用いサブフォルダを表すFolderオブジェクトのセットを格納したFoldersコレクションを取得している。取得した値はコレクションなのでFor〜Each〜Nextステートメント(第6回参照)で列挙できる。その1つ1つの要素、すなわちサブフォルダを表すFolderオブジェクトを取得し、そのNameプロパティを参照することでフォルダの名前を取得している。
同じことをファイルに対しても行っている。違いは、FolderオブジェクトのFilesプロパティが、ファイルを表すFileオブジェクトのセットを格納したFilesコレクションを返すことである。
ここではNameプロパティを参照したが、もちろんほかのプロパティやメソッドの使用(前回参照)も可能だ。
この2つのプロパティ(Files、SubFolders)は、非常によく使われるので、よく覚えておいてもらいたい。
ちなみにこの2つのプロパティ以外にも、FolderオブジェクトにはあってFileオブジェクトにはないプロパティがある。それはIsRootFolderプロパティである。これは、そのFolderオブジェクトが表すフォルダがルート・フォルダ(C:\など)ならTrue、そうでないならFalseを返す読み取り専用のプロパティである。
再帰呼び出しを用いたファイル・フォルダの列挙
ここでひとつ応用を兼ねた例題を出そう。最初に挙げたスクリプトでは1階層、つまりあるフォルダの直下にあるサブフォルダと、直下にあるファイルしか列挙できなかった。しかし、実際はサブフォルダの配下にまたファイルやフォルダが存在することもある。こうした場合、あるフォルダに含まれるすべてのファイル一覧を取得したいというケースがよくある。それには再帰呼び出し(第8回参照)という手段を用いる。この場合、フォルダを引数に取るプロシージャAを用意する。Aでは引数のフォルダ内のファイル一覧を出力して、サブフォルダをそれぞれAに渡すという形で再帰呼び出しを行う。Aは繰り返し最下の階層まで実行される。以上を踏まえて、あるフォルダに含まれるフォルダとファイルの一覧をフルパスで出力するスクリプトを組んでみてもらいたい。
マーカーで隠れたところを選択してチェックしてみよう。
※ファイル:recursiveDir.vbs
Option Explicit
Dim objFSO
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
Dim strMessage
strMessage = ""
Dim strParentFolder, objParentFolder
strParentFolder = objFSO.GetParentFolderName(WScript.ScriptFullName)
Set objParentFolder = objFSO.GetFolder(strParentFolder)
'親フォルダを表すFolderオブジェクトをプロシージャSearchFolderに渡す
Call SearchFolder(objParentFolder)
'Folderオブジェクトを引数に取り、そのフォルダに含まれるサブフォルダ、ファイルを
'列挙するSubプロシージャ。引数にはFolderオブジェクトを取る
Sub SearchFolder(objFolder)
'引数に与えられたフォルダのパスを取得する
strMessage = strMessage & objFolder.Path& vbCrLf
'1つのファイルおよびファイルのセットを表すオブジェクト変数を宣言
Dim objFile, objFiles
'FolderオブジェクトのFilesプロパティを参照し、Filesコレクションを得る
Set objFiles = objFolder.Files
'フォルダに存在するファイルのFileオブジェクトを列挙
For Each objFile In objFiles
'ファイルパスを取得
strMessage = strMessage & objFile.Path & vbCrLf
Next
Set objFile = Nothing
Set objFiles = Nothing
'1つのサブフォルダおよびサブフォルダのセットを表すオブジェクト変数を宣言
Dim objSubFolder, objSubFolders
'FolderオブジェクトのSubFoldersプロパティを参照し、Foldersコレクションを得る
Set objSubFolders = objFolder.SubFolders
'サブフォルダに対して、SubプロシージャSearchFolderを再帰呼び出しする
For Each objSubFolder In objSubFolders
Call SearchFolder(objSubFolder)
Next
Set objSubFolder = Nothing
Set objSubFolders = Nothing
End Sub
MsgBox strMessage
Set objFSO = Nothing
以上のスクリプトを実行すると、例えば次のような結果が得られる。
このように、あるフォルダ(ここではスクリプトの存在するフォルダ)の配下に存在するすべてのフォルダとファイルを列挙することができた。このスクリプトは最初に取り上げたスクリプトのコアの部分をプロシージャ化し、再帰呼び出しを行っているだけで、基本は最初のスクリプトと同じなので、理解もそれほど困難ではないかと思われる。
再帰呼び出しを用いたファイル・フォルダの列挙はよく使うのでこの手法も覚えておくとよい。
また、ここではスクリプトの存在するフォルダに対して実行するようにしたが、第10回で述べたように、フォルダをスクリプト・ファイルにドロップをして、ドロップしたフォルダに対して処理を行うようにもすることができる。もちろん、文字列リテラルを用いて任意のフォルダに対して処理を行うことも可能だ。余裕があれば、各自挑戦してみてもらいたい。
Copyright© Digital Advantage Corp. All Rights Reserved.