Lesson14 ファイル・フォルダ・ドライブの操作
FileSystemObjectのオブジェクト1
-Folder,File,Driveオブジェクト・Folders,Files,Drivesコレクション-
注意: このLessonは未完成です。
前回は、FileSystemObjectオブジェクトを使って、基本的なファイル操作の方法について述べましたが、今回は、FileSystemObjectオブジェクトから派生するオブジェクト(Folderオブジェクト・Fileオブジェクト・Driveオブジェクト)、およびコレクション(Foldersコレクション・Filesコレクション・Drivesコレクション)を取り上げて、より複雑なファイル操作の方法についてふれたいと思います。なお、このLessonに関しても、VBSランゲージリファレンスを併用してごらんになることをおすすめします。
では、まずこれらのオブジェクト・コレクションがどういうものか、それぞれ説明していきましょう。
・Fileオブジェクト
文字通り、ファイルを表すオブジェクトです。基本的に一つのファイルから一つのFileオブジェクトが取得できます。Fileオブジェクトは、ファイルの名前、サイズ、更新日時などのプロパティをもち、移動、コピーなどのメソッドをもっています。このオブジェクトは、FileSystemObjectオブジェクトのGetFileメソッドなどで取得できます。
・Filesコレクション
あるフォルダに含まれる、すべてのファイルのFileオブジェクトを含んだコレクションです。Itemプロパティで、各Fileオブジェクトを参照できます。
・Folderオブジェクト
フォルダを表すオブジェクト。このオブジェクトも、一つのフォルダから一つ取得できます。プロパティ・メソッドはFileオブジェクトと同じものを持ち、それに加えて、当該フォルダ直下のすべてのファイルを含んだFilesコレクション、すべてのサブフォルダを含んだFoldersコレクションを参照できるプロパティがあります。このオブジェクトは、FileSystemObjectオブジェクトのGetFolderメソッドなどで取得できます。
・Foldersコレクション
あるフォルダに含まれる、すべてのサブフォルダのFolderオブジェクトを含んだコレクションです。Itemプロパティで、各Folderオブジェクトを参照できます。
・Driveオブジェクト
ドライブを表すオブジェクト。ボリュームラベル・空き容量など、ドライブの情報を格納したプロパティを持っています。ドライブのルートフォルダをFolderオブジェクトとして取得するプロパティもあります。このオブジェクトは、FileSystemObjectオブジェクトのGetDriveメソッドなどで取得できます。
・Drivesコレクション
コンピュータにつながれたすべてのドライブ(ネットワークドライブ含む)のDriveオブジェクトを含んだコレクション。Itemプロパティで、各Driveオブジェクトを参照できます。FileSystemObjectオブジェクトのDrivesプロパティで取得できます。
次に、これらのオブジェクト・コレクションがどのようなプロパティ・メソッドを持ち、どのような機能をはたすか、オブジェクトごとに分類してみましょう。
1.Fileオブジェクト・Folderオブジェクトに共通のプロパティ・メソッド
Name プロパティ | ファイル名 |
ShortName プロパティ | DOSでのファイル名 |
Path プロパティ | パス |
ShortPath プロパティ | DOSでのパス |
ParentFolder プロパティ | 親フォルダのパス |
Drive プロパティ | ドライブのパス |
DateCreated プロパティ | 作成日時 |
DateLastAccessed プロパティ | アクセス日 |
DateLastModified プロパティ | 更新日時 |
Size プロパティ | サイズ(バイト) |
Type プロパティ | ファイルタイプ名 |
Attributes プロパティ | 属性 |
Copy メソッド | コピー |
Delete メソッド | 削除 |
Move メソッド | 移動 |
2.Fileオブジェクトのメソッド
OpenAsTextStream メソッド | テキストファイルとして開き、 TextStreamオブジェクトを返す |
3.Folderオブジェクトのプロパティ
IsRootFolder プロパティ | ルートフォルダならTrueを返す |
Files プロパティ | そのフォルダにあるすべてのFileオブジェクトを 含んだFilesコレクションを返す |
SubFolders プロパティ | そのフォルダにあるすべてのFolderオブジェクトを 含んだFoldersコレクションを返す |
4.Driveオブジェクトのプロパティ
DriveLetter プロパティ | ドライブレター(アルファベット一文字) |
DriveType プロパティ | ドライブの種類(HDD,CD-ROM,RAM,Removable,Network) |
FileSystem プロパティ | ファイルシステム(FAT,FAT32,NTFS,CDFS) |
IsReady プロパティ | ドライブが準備できていたらTrueを返す |
VolumeName プロパテ | ボリュームラベル |
ShareName プロパティ | ネットワークでの共有名 |
SerialNumber プロパティ | シリアルナンバー |
AvailableSpace プロパティ | 空きディスク領域(バイト) |
FreeSpace プロパティ | 空きディスク領域(バイト) |
TotalSize プロパティ | ドライブの容量 |
RootFolder プロパティ | ドライブのルートフォルダのFolderオブジェクトを返す |
5.Filesコレクション・Foldersコレクション・Drivesコレクションに共通のプロパティ・メソッド
Count プロパティ | オブジェクトの数Filesコレクションなら、含まれるFileオブジェクトの数。 |
Item プロパティ | オブジェクトを返す。引数にはファイル名(フォルダ名)を指定可。 |
Add メソッド | 新しいFolderオブジェクトを作成し、それを含んだ Foldersコレクションを新たに返す(Foldersコレクションのみ) |
それではこれから実際のコード例を見ていきましょう。最初は、Fileオブジェクト・Folderオブジェクトを取得し、その各プロパティを表示するスクリプトです。
On Error Resume Next Dim path Dim n,s,p,h,r,d,z,y,t,c,a,m Set Fs = WScript.CreateObject("Scripting.FileSystemObject") '1.FileSystemObjectオブジェクト作成 Set arg=WScript.Arguments '2.WshArgumentsオブジェクトを取得。 If arg.Count=0 Then '3.もしオプションがついていなければ path=InputBox("情報を表示したいファイル・フォルダ名を入力してください。") Else '4.オプションがついていれば、一つ目のオプションをパスとして読み込む path=arg(0) End If If Fs.FileExists(path) Then '5.もし、与えられたパスがファイルなら Set f=Fs.GetFile(path) '6.fというオブジェクト変数にFileオブジェクト代入 ElseIf Fs.FolderExists(path) Then '7.もし、与えられたパスがフォルダなら Set f=Fs.GetFolder(path) '8.fというオブジェクト変数にFolderオブジェクト代入 If f.IsRootFolder Then '9.ルートフォルダを指定するといろいろ不都合が出るので除外 MsgBox "ルートフォルダは指定できません。" WScript.Quit End If Else '10.パスが存在しない場合、終了 MsgBox "このパスは実在しません。" WScript.Quit End If n=f.Name '11.名前 s=f.ShortName '12.DOSでの名前(8+3) p=f.Path '13.パス h=f.ShortPath '14.DOSでのパス r=f.ParentFolder '15.親フォルダのパス d=f.Drive '16.ドライブのパス z=f.Size '17.サイズ(バイト) y=f.Type '18.ファイルの種類 t=attr(f.Attributes) '19.属性。attrファンクションを呼び出している c=f.DateCreated '20.作成日時。(不明)である場合はエラーが発生する。 a=f.DateLastAccessed '21.アクセス日。(不明)である場合はエラーが発生する。 m=f.DateLastModified '22.更新日時。(不明)である場合はエラーが発生する。 MsgBox n & vbCrLf & "(" & p & ")" & vbCrLf & vbCrLf & _ "種類 : " & y & vbCrLf & _ "場所 : " & r & vbCrLf & _ "サイズ : " & FormatNumber(z,0) & "バイト" & vbCrLf & vbCrLf & _ "MS-DOS ファイル名 : " & s & vbCrLf & "(" & h & ")" & vbCrLf & vbCrLf & _ "作成日時 : " & c & vbCrLf & _ "更新日時 : " & m & vbCrLf & _ "アクセス日 : " & a & vbCrLf & vbCrLf & _ "属性 : " & t,,n & "のプロパティ" '23.FormatNumber関数は、小数点を切り捨てたり、カンマ(,)をつけてくれる便利な関数 Function attr(num) '24.数字が与えられると、その属性を返す。 If (num And 1)=1 Then attr=attr & "読み取り専用 " If (num And 2)=2 Then attr=attr & "隠しファイル " If (num And 4)=4 Then attr=attr & "システム " If (num And 16)=16 Then attr=attr & "フォルダ " If (num And 32)=32 Then attr=attr & "アーカイブ " End Function
いきなり長めのスクリプトですが、要点を順番に見ていきましょう。
1.のFileSystemObject作成は前のLesson13ですでにやりました。
2.〜4.ではWshArgumentsオブジェクトを作成して、コマンドラインオプションを読み込んでいます。これも解説済みですね。もしファイル名が指定されていなければ、InputBoxを表示して入力させるようにしています。
5.、7.でFileExistsメソッド・FolderExistsメソッドを使って、指定された文字列がファイルのパスなのか、フォルダのパスなのかを確認しています。
そして、6.で、もしファイルならGetFileメソッドにそのパスを引数として指定し、Fileオブジェクトを取得しています。Fileオブジェクトはfというオブジェクト変数に入りました。8.では同様にGetFolderメソッドで、Folderオブジェクトを取得しています。どちらも同じ変数名fを使っていますが、これは、Fileオブジェクト・Folderオブジェクトで共通のプロパティを後で使用するためです。
9.では、FolderオブジェクトのIsRootFolderプロパティを使って、取得したFolderオブジェクトがルートフォルダ(C:\など)でないかどうか、確認しています。もしルートならTrueが返るので、その場合は終了します。なぜこの処理が必要かというと、後でFolderオブジェクトの様々なプロパティを参照するとき、ルートフォルダだとエラーが返されたりする事が多いからです。
11.〜21.までは、Fileオブジェクト・Folderオブジェクト共通のプロパティを参照し、それぞれ変数に代入しています。それぞれのプロパティの返す値はとくに解説は必要ないでしょう。
ただし、ファイルやフォルダの属性(隠しファイル、読みとり専用など)を取得する、Attributesプロパティを解釈するには少々面倒な手順が必要になります。そこで、このスクリプトではAttributesプロパティが返す整数を、具体的な属性名に変換するためのattrファンクション(24.)を記述し、それを19.で参照するようにしています。このファンクションに関する解説はここではしないことにしておきます。なお、逆にAttributesプロパティを設定するのは簡単で、その例は次のサンプルスクリプトをご覧ください。
最後に、23.で得られた情報をMsgBoxで表示させています。なお、ここで登場するFormatNumber関数は、与えられた数字を整形して文字列として返す、便利な関数です。引数など詳細はランゲージリファレンスをどうぞ。
今度は、Fileオブジェクト・Folderオブジェクトのプロパティを設定するスクリプトです。下のスクリプトは、ファイルの名前と属性を変更するものです。
On Error Resume Next Dim path Set Fs = WScript.CreateObject("Scripting.FileSystemObject") Set arg=WScript.Arguments '1.WshArgumentsオブジェクトを取得。 If arg.Count=0 Then '2.もしオプションがついていなければ path=InputBox("属性を変更したいファイル・フォルダ名を入力してください。") Else '3.オプションがついていれば、一つ目のオプションをパスとして読み込む path=arg(0) End If If Fs.FileExists(path) Then '4.もし、与えられたパスがファイルなら Set f=Fs.GetFile(path) '5.fというオブジェクト変数にFileオブジェクト代入 ElseIf Fs.FolderExists(path) Then '6.もし、与えられたパスがフォルダなら Set f=Fs.GetFolder(path) '7.fというオブジェクト変数にFolderオブジェクト代入 If f.IsRootFolder Then '8.ルートフォルダを指定するといろいろ不都合が出るので除外 MsgBox "ルートフォルダは指定できません。" WScript.Quit End If Else '9.パスが存在しない場合、終了 MsgBox "このパスは実在しません。" WScript.Quit End If nname=InputBox ("新しい名前を入力してください。現在の名前は" & f.Name & "です。",,f.Name) If nname="" Then WScript.Quit '10.キャンセルを押したら終了 If AvailableName(nname) Then '11.ファイル名に使えない文字を使っていなければ If nname<>f.Name Then f.Name=nname '12.もし現在の名前と違う名前が指定されたら、指定された名前に変える If Err.Number=70 Then '13.エラー番号が70なら MsgBox "書き込みできませんでした。",vbCritical WScript.Quit ElseIf Err.Number=58 Then '14.エラー番号が58なら MsgBox "すでに同名のファイルが存在しています。",vbCritical WScript.Quit End If Else MsgBox "次の文字はファイル名に使用できません。" & vbCrLf & "\ / : , ; * ? "" < > |",vbCritical WScript.Quit End If If MsgBox("属性を変更しますか?",vbYesNo)=vbYes Then attr=0 If MsgBox ("読み取り専用属性をつけますか?",vbYesNo)=vbYes Then attr=attr+1 If MsgBox ("隠しファイル属性をつけますか?",vbYesNo)=vbYes Then attr=attr+2 If MsgBox ("システム属性をつけますか?",vbYesNo)=vbYes Then attr=attr+4 If MsgBox ("アーカイブ属性をつけますか?",vbYesNo)=vbYes Then attr=attr+32 f.Attributes=attr '15.属性変更。属性は各値の和を指定する。 End If Function AvailableName(str) '16.ファイル名に使えない文字が入っていたらFalse、入ってなければTrueを返す tmpstr=Split("\ / : , ; * ? "" < > |"," ") '17.Split関数で、使えない文字の入った一次元配列を作成 For Each I In tmpstr If InStr(str,I)<>0 Then AvailableName=False '18.一つでも入っていたら、その時点でFalseを返してFunction終了 Exit Function Else AvailableName=True End If Next End Function
今度も長めですが、というかこのLessonはこんなのばっかりですががんばって行きましょう。
1〜9までに関しては、前のサンプルと同じなので省略します。
9.以降でまず、新しいファイル名を指定するためのインプットボックスを表示させ、nnameという変数に代入しています。
10.から14.までで、入力されたファイル名(nname)が妥当なものであるかをチェックしています。まず、10.で、InputBoxでキャンセルを押した場合は終了させるようにしています。
11.で、後に記述しているAvailableNameプロシージャを呼び出して、入力された文字列に、ファイル名として使用してはいけない文字が入っていないかどうかを調べています。
12.では、もとのファイル名と異なっているかどうかを判断しています。13.、14.ではエラー番号を調べてエラーを表示させるようにしています。
15.でいよいよ属性変更しています。FileオブジェクトのAttributesプロパティに、属性を表す数値の和を代入すると、属性を変更することができます。たとえば、読みとり専用属性は、1なので、1を指定すると読みとり専用属性がつき、隠しファイル(2)も同時に指定したい場合は、1+2=3を指定すればよいのです。このスクリプトでは、各属性をつけるかどうか、MsgBoxでユーザーに問い合わせ、「はい」と答えると、その属性を表す整数をattrという変数に加え、最後にこのattrという変数の値をAttributesプロパティに入れることで属性変更しています。ちなみにattr=0の場合は無属性のファイルになります。
最後にAvailableNameファンクション(16.)を見ておきましょう。
17.で、Split関数を使って、「ファイル名としては使ってはいけない文字」が格納された、一次元配列を作っています。(別にArray関数でも作れますが、
"
をいっぱい記述しなければならないので面倒ですね。)
For Each...Nextステートメント中で、配列の各値が、指定の文字列(str)に含まれていないかInStr関数で調べ、入っていれば(すなわちInStr関数が0以外の値を返せば)、AvailableName=Falseにして、Exit
Functionでこのプロシージャを終了させています。どの文字も含まれていなかった場合は、この行は実行されないので、AvailableName=Trueを返すことになります。
次は、Filesコレクション(Fileオブジェクトの集合)、Foldersコレクション(Folderオブジェクトの集合)を用い、再帰呼び出しを使ったファイル名検索スクリプトです。
Dim filename Dim str Set Fs = WScript.CreateObject("Scripting.FileSystemObject") filename=InputBox("検索するファイル名を入力してください。") Set arg=WScript.Arguments '1.WshArgumentsオブジェクトを取得。 If arg.Count=0 Then '2.もしオプションがついていなければ path=InputBox("検索したいフォルダ名を入力してください。") Else '3.オプションがついていれば、一つ目のオプションをパスとして読み込む path=arg(0) End If If Fs.FolderExists(path) Then '4.もし、与えられたパスがフォルダなら Call RecursibleSearch(path) '5.RecursibleSearchプロシージャを呼ぶ Else '6.パスが存在しない場合、終了 MsgBox "このパスは実在しません。" WScript.Quit End If MsgBox str,,filename & "を含むパスの検索結果" Sub RecursibleSearch(folderspec) '7.引数としてフォルダのパスを指定する Set fol = Fs.GetFolder(folderspec) '8.Folderオブジェクト取得 If InStr(fol.Path,filename)>0 Then '9.もしこのフォルダのパスに、検索文字列があれば str=str & fol.Path & "<dir>" & vbCrLf End If Set flc = fol.Files '10.FilesプロパティはFilesコレクションを返す For Each fl1 in flc '11.FilesコレクションのすべてのFileオブジェクトについて繰り返す If InStr(fl1.Path,filename)>0 Then '12.ファイルのパスに検索文字列があれば str=str & fl1.Path & vbCrLf End If Next Set sfc = fol.SubFolders '13.SubFoldersプロパティは、サブフォルダのFoldersコレクションを返す For Each sf1 in sfc '14.FoldersコレクションのすべてのFolderオブジェクトについて繰り返す Call RecursibleSearch(sf1.Path) '15.再帰呼び出し Next End Sub
1.〜6.まではこれまでのスクリプトと同様なので、省略します。
5.で、指定されたフォルダのパス(path)を引数として、RecursibleSearchプロシージャを呼び出しています。
ところで、FoldersコレクションにはAddメソッドというのがあり、その例も書かないとだめだがまだ未完成だぞ
どんどん行きましょう。次は、Drivesコレクションと、Driveオブジェクトの使用例です。
Dim l,n,p,t,r,b,y,v,a,s Set Fs = WScript.CreateObject("Scripting.FileSystemObject") Set drvs=Fs.Drives 'Drivesプロパティは、Drivesコレクションを返す MsgBox drvs.Count & "個のドライブが見つかりました。情報を表示します。" 'Countプロパティはドライブの総数 For Each I In drvs 'すべてのDriveオブジェクトに対して繰り返す l=I.DriveLetter 'ドライブレター(アルファベット一文字) n=I.ShareName 'ネットワークでの共有名 p=I.Path 'ドライブのパス Select Case I.DriveType 'ドライブの種類 Case 0 t="不明" Case 1 t="リムーバブルドライブ" Case 2 t="ハードディスク" Case 3 t="ネットワークドライブ" Case 4 t="CD-ROM" Case 5 t="ラムドライブ" End Select If I.IsReady Then 'IsReadyプロパティがTrueなら、ドライブは準備できている r="(このドライブは準備ができています)" '以下の各プロパティは、IsReadyがFalseの時参照しようとするとエラーになる b=I.SerialNumber 'シリアルナンバー。Hex(b)で16進形式のNOが得られる。 y=I.FileSystem 'ファイルシステムの種類。FAT,FAT32,NTFS,CDFSが返される v=I.VolumeName 'ボリュームラベル a=I.AvailableSpace '空き領域(バイト)。FreeSpaceプロパティも同じ値を返す s=I.TotalSize '総容量(バイト)。AvailableSpaceもそうだが、2GB以上の領域は認識しない。 Else r="(このドライブは準備ができていません)" b="" y="" v="" a=0 s=0 End If MsgBox "ドライブ" & l & vbCrLf & vbCrLf & _ "ボリュームラベル : " & v & vbCrLf & "種類 : " & t & vbCrLf & vbCrLf & _ "ファイルシステム : " & y & vbCrLf & "シリアルNO : " & b & vbCrLf & _ "パス : " & p & vbCrLf & "共有名 : " & n & vbCrLf & vbCrLf & _ "使用領域 : " & FormatNumber((s-a)/1048576,0) & "MB" & vbCrLf & _ "空き領域 : " & FormatNumber(a/1048576,0) & "MB" & vbCrLf & _ "容量 : " & FormatNumber(s/1048576,0) & "MB" & vbCrLf & vbCrLf & r _ ,,"(" & l & ":)のプロパティ" '1MB=1024KB=1048576バイト(1024*1024) Next
・・・・・・・解説はまだなんだ
Driveオブジェクトを使った例をもう一つどうぞ
Set Fs = WScript.CreateObject("Scripting.FileSystemObject") drvl=InputBox ("ドライブレター(アルファベット一文字)を入力してください。") If drvl="" Then WScript.Quit drvl=UCase(drvl) '大文字に変換 If (65<=Asc(drvl) And Asc(drvl)<=90) And Len(drvl)=1 Then 'もし、与えられた文字列の文字コードが65以上90以下(アルファベットの大文字)で、 'かつ一文字だったら If Fs.DriveExists(drvl) Then 'もし、そのドライブが存在したら Set drv=Fs.GetDrive(drvl) 'GetDriveメソッドでDriveオブジェクトを取得 If drv.IsReady Then 'ドライブが準備されていたら Set fol=drv.RootFolder 'RootFolderプロパティで、ドライブのルートフォルダをFolderオブジェクトとして取得 'Set fol=Fs.GetFolder(drv.Path) でも同じ。 MsgBox drvl & "ドライブには、" & fol.Files.Count+fol.SubFolders.Count & "個のオブジェクトがあります。" 'Filesコレクション、FoldersコレクションのCountプロパティを足すことで、ルート直下の 'ファイルとフォルダの総数を表示する。 Else MsgBox drvl & "ドライブは準備されていません。" End If Else MsgBox drvl & "ドライブは存在しません。" End If Else MsgBox "ドライブレターはアルファベット一文字です!" End If
・・・・・・・・・解説はまだなのよ
Fileオブジェクト・Folderオブジェクトのメソッドを使って、ファイル操作をする例を紹介します。
この例はまだ作ってないぞ。
tempフォルダ掃除スクリプトなどありきたりのものは作りたくないのですが…。
できればVBSのDate型の値を扱う関数を織り込んだスクリプトにしたいと思います。
さて、オブジェクト・コレクションを取得するには、どのオブジェクトの、どのプロパティ・メソッドを使用するかをまとめた表を最後に載せておきます。
たとえば「Fileオブジェクトを取得するには、FileSystemObjectオブジェクトのGetFileメソッドか、FilesコレクションのItemプロパティを使う」ということが、この表からわかるようになっています。
取得するオブジェクト・コレクション | オブジェクト・コレクション | プロパティ・メソッド |
---|---|---|
Fileオブジェクト | FileSystemObjectオブジェクト | GetFileメソッド |
Filesコレクション | Itemプロパティ | |
Folderオブジェクト | FileSystemObjectオブジェクト | GetFolderメソッド |
FileSystemObjectオブジェクト | CreateFolderメソッド | |
FileSystemObjectオブジェクト | GetSpecialFolderメソッド | |
Foldersコレクション | Itemプロパティ | |
Driveオブジェクト | RootFolderプロパティ | |
Driveオブジェクト | FileSystemObjectオブジェクト | GetDriveメソッド |
Drivesコレクション | Itemプロパティ | |
Filesコレクション | Folderオブジェクト | Filesプロパティ |
Foldersコレクション | Folderオブジェクト | SubFoldersプロパティ |
Foldersコレクション | Addメソッド | |
Drivesコレクション | FileSystemObjectオブジェクト | Drivesプロパティ |
このLessonでは、ファイルやフォルダのオブジェクトを使って、ファイルの情報取得やファイル操作をおこなう方法について述べました。次回は、TextStreamオブジェクトを使って、テキストファイルを読み書きする話をしたいと思います。