次に、ファイルやフォルダの操作を行うメソッドを見ていこう。まずは、フォルダの作成の例からご覧にいれよう。
Option Explicit
Dim objFSO
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
Dim strNewFolderName
strNewFolderName = "新しいフォルダ"
'もし、フォルダが存在しない場合は作成する
If Not objFSO.FolderExists(strNewFolderName) Then
objFSO.CreateFolder strNewFolderName
MsgBox _
objFSO.GetAbsolutePathName(strNewFolderName) & vbCrLf & _
"を作成しました。"
'もしフォルダが存在する場合は何もしない
Else
MsgBox "すでに" & vbCrLf & _
objFSO.GetAbsolutePathName(strNewFolderName) & vbCrLf & _
"が存在します。"
End If
Set objFSO = Nothing
このスクリプトを実行すると、カレント・ディレクトリに「新しいフォルダ」という名前のフォルダが作成されるが、その前にFolderExistsメソッドでフォルダの存在を確認してからCreateFolderメソッドを使ってフォルダを作成するのがセオリーである(フォルダがすでに存在しているとエラーになるため)。
カレント・ディレクトリは13回で解説したとおり、通常はスクリプトの存在するフォルダであるが、WshShellオブジェクトのCurrentDirectoryプロパティを変更したり、.vbsファイルへのショートカットで「作業ディレクトリ」を別のフォルダに指定したりすると、ほかのフォルダがカレント・ディレクトリになる。確実にスクリプトの存在するフォルダの場所に新しいフォルダを作りたい場合は、先ほどの問題に挙げたようなコードを使用するとよい。
さて、ここからは既存のファイルやフォルダの操作メソッドを紹介する。
既存のフォルダやファイルを移動、コピー、削除するメソッドがあるが、使い方は似通っているので1つのスクリプトを例に取り上げ、一部を変えることでまとめて紹介しよう。
Option Explicit
Dim objFSO
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
objFSO.MoveFile "*.txt", "新しいフォルダ\"
Set objFSO = Nothing
これは、MoveFileメソッドを用いてカレントに存在する拡張子.txtのファイルをすべて子フォルダの「新しいフォルダ」に移動するスクリプトである。このようにワイルドカードが使えるのが特徴である。もちろん、“a.txt”のように単一のファイルを指定することもできる。また、すべてのファイルを移動したい場合は“*.*”を指定する。送り先をフォルダで指定する場合は、例のように末尾に“\”を付ける。また、送り先に同名のファイル名がある場合はエラーが発生する。エラーが発生する可能性がある場合はFileExistsメソッドを使って確認するか、On Error Resume Nextステートメントを用いてエラーをトラップする必要がある。
送り先にファイル名を指定する場合は末端に\を付けず、
objFSO.MoveFile "a.txt","新しいフォルダ\a.txt"
のようにする。この場合、ワイルドカードは使えない。
ここまですべて相対パスで表記を行っているが、もちろん絶対パス表記でも可能である。
objFSO.MoveFile "C:\script\*.txt", "C:\script\新しいフォルダ\"
同様に、フォルダを移動するMoveFolderメソッドも存在する。使い方はMoveFileメソッドと同じである。フォルダの中身(サブフォルダやファイル)ごと移動する。ワイルドカードも使用可能である。
MoveFileメソッドとMoveFolderメソッドは、ファイルやフォルダのリネームにも応用できる。例えば、カレント・ディレクトリにある「新しいフォルダ」を「New Folder」にリネームするには
objFSO.MoveFolder "新しいフォルダ", "New Folder"
のようにする。なお、鋭い方はお気付きかもしれないが、FileSytemObjectオブジェクトでは半角スペースを含むパスを、さらにダブル・クオーテーション記号を使って囲む必要がない(連載第12回「WshShellオブジェクトを利用する(1)――1.Runメソッド」参照)。この点はWshShellオブジェクトのRunメソッドと異なるので注意が必要である。
これも厳密にはFileExists/FolderExistsメソッドでリネーム先ファイルやフォルダの存在確認をする必要がある場合がある。また、例えば「a.txt」を「b.txt」にリネームする場合、MoveFileメソッドを使うことは可能だが、「b.txt」という名前の「フォルダ」が存在するとエラーになってしまうので注意が必要だ。これはMoveFolderメソッドや、後で述べるCopyFile/CopyFolderメソッドでも同様である。あるファイル名と同名のフォルダ名が存在するとうまく動作しない。
次にCopyFileメソッドおよびCopyFolderメソッドを用いたファイルやフォルダのコピーであるが、これもMoveFile/MoveFolderメソッドとほとんど使い方は同じである。ただしこれらのメソッドには省略可能な第3の引数が存在し、コピー先(第2引数)にファイルやフォルダがすでにある場合上書きするかどうかをブール値(TrueかFalse)で指定する。Trueにすると上書きする。Falseの場合、もし同名ファイルやフォルダがあった場合エラーが発生する。省略時はTrue(上書きする)である。
例えば、カレント・ディレクトリの子フォルダ「新しいフォルダ」に、カレント・ディレクトリのすべての.txtファイルをコピーするには次のようにする。
objFSO.CopyFile "*.txt", "新しいフォルダ\"
同名ファイルを上書きしないようにするには、
objFSO.CopyFile "*.txt", "新しいフォルダ\", False
とする。この場合、同名ファイルが存在するとエラーが発生するので、On Error Resume Nextステートメントを用いてエラーをトラップする必要がある。
CopyFolderメソッドも同様で、カレント・ディレクトリの「新しいフォルダ」をコピーして「新しいフォルダ2」と名付けるには、
objFSO.CopyFolder "新しいフォルダ", "新しいフォルダ2"
のようにする。この場合、「新しいフォルダ」の中身ごと「新しいフォルダ2」にコピーされる。コピー先の末尾に\を付けると、そのフォルダの下に新しくフォルダがコピーされる。
CopyFolderメソッドは少し注意が必要で、例えばカレント・ディレクトリに「新しいフォルダ」のほかに、すでに「新しいフォルダ2」があるとき、
objFSO.CopyFolder "新しいフォルダ", "新しいフォルダ2"
とすると、「新しいフォルダ」直下のファイルとフォルダが、「新しいフォルダ2」の直下にコピーされる。この際、第3引数がFalseだと同名ファイル/フォルダがあるとエラーになる。True(デフォルト)だと上書きする。
ファイルやフォルダを削除するDeleteFileメソッド、DeleteFolderメソッドも存在する。カレント・ディレクトリにある「新しいフォルダ」の中のファイルをすべて削除するには、
objFSO.DeleteFile "新しいフォルダ\*.*"
とする。このようにワイルドカードが使用可能だが、もちろん、
objFSO.DeleteFile "a.txt"
のように単一のファイルを削除することも可能だ。
DeleteFolderメソッドはフォルダを中身ごと削除する。
objFSO.DeleteFolder "新しいフォルダ"
とするとカレント・ディレクトリにある「新しいフォルダ」が削除される。
これらのメソッドには省略可能な第2引数が存在し、Trueを指定すると読み取り専用ファイル/フォルダも強制的に削除する。デフォルトはFalseで、読み取り専用ファイル/フォルダを削除しようとするとエラーになる。
なお、これらのメソッドを使って削除したファイルやフォルダはごみ箱に移動されるのではなく、完全に消去され復元が不可能であるので、使用には十分注意してもらいたい。
さて、ここで1つ例題を出そう。あるフォルダの中に含まれているファイルとフォルダを、その親フォルダに移動する、すなわち、感覚的にはフォルダの中身を抽出する動作をしたいことがあるのではないだろうか(階層を深く作りすぎたので、整理したい場合や、.ZIPファイルを解凍した際、トップレベルが単一のフォルダになっていたので、そのフォルダの中身の階層を1つ引き上げたい場合など)。そのスクリプトがこれまでの知識で記述可能だ。書いてみよう。
マーカーで隠れたところを選択してチェックしてみよう。
※ファイル:ExtractFilesAndFolders.vbs
Option Explicit
Dim objFSO
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
Dim strArgument, strTargetPath
'すべてのコマンドライン・オプションに対して繰り返す
For Each strArgument In WScript.Arguments
'もし、それがフォルダならば
If objFSO.FolderExists(strArgument)Then
'親フォルダ・パスを取得
strTargetPath = objFSO.GetParentFolderName(strArgument)
'親フォルダ・パスの後ろに\を付ける
strTargetPath = objFSO.BuildPath(strTargetPath, "\")
If MsgBox(strArgument & "の中身を" & strTargetPath & _
"に移動しますか?",vbYesNo) = vbYes Then
'フォルダの中のファイルを親フォルダに移動
objFSO.MoveFile objFSO.BuildPath(strArgument,"*.*"), _
strTargetPath
'フォルダの中のフォルダを親フォルダに移動
objFSO.MoveFolder objFSO.BuildPath(strArgument,"*"), _
strTargetPath
MsgBox "移動しました"
End If
End If
Next
Set objFSO = Nothing
このスクリプトの使い方は、エクスプローラでフォルダをスクリプト(ExtractFilesAndFolders.vbs)にドロップすると、その中身が親フォルダに抽出される。
今回はFileSystemObjectオブジェクト直下のクラスのうち、ファイル/フォルダ情報を取得するものとファイル/フォルダを操作するものを取り上げた。だが今回取り上げたメソッドだけだと、実際にどんなファイルやフォルダがあるかをあらかじめ知っていないとコーディングできないことに気付くだろう。また、最終更新日時などの情報も取得したいところである。次回は、これらがファイルやフォルダなどをインスタンスとして扱うことで可能になることを示す。
Copyright© Digital Advantage Corp. All Rights Reserved.