即効テクニック

ファイル操作関連のテクニック

隠し属性ファイルを削除する

(Excel 97/2000/2002/2003/2007)
今回はファイル操作の話です。

VBAには、ファイルやフォルダを操作するためのコマンドがあります。
たとえば、新しくフォルダを作成するにはMkDir関数、既存のフォルダを削除するにはRmDir関数が用意されています。

Sub Sample1()
  ''C:\WorkフォルダにSubフォルダを作成します
  MkDir "C:\Work\Sub"
End Sub   

Sub Sample2()
  ''C:\Work\Subフォルダを削除します
  RmDir "C:\Work\Sub"
End Sub   
RmDir関数でフォルダを削除するとき、そのフォルダ内にファイルが存在すると実行時エラーが発生します。 したがって、フォルダを削除するときは、まずそのフォルダ内にファイルが存在するかどうかを確認して、もしファイルが存在したら、Killステートメントですべてのファイルを削除してから、フォルダを削除しなければなりません。
Sub Sample3()
  Dim buf As String
  Const Path = "C:\Work\Sub\"
  ''すべてのファイルを削除します
  buf = Dir(Path & "*.*")
  Do While buf <> ""
    Kill Path & buf
    buf = Dir()
  Loop
  ''フォルダを削除します
  RmDir "C:\Work\Sub"
End Sub   
しかし、これでもうまくいかないケースがあります。 削除したいフォルダ内に「隠し属性」が設定されたファイルが存在した場合です。 Dir関数には、対象のファイル属性を指定する引数もありますが、次のように定数vbHiddenを指定してもうまくいきません。
Sub Sample4()
  Dim buf As String
  Const Path = "C:\Work\Sub\"
  buf = Dir(Path & "*.*", vbHidden)
  Do While buf <> ""
    MsgBox buf
    buf = Dir()
  Loop
End Sub   
標準ファイルを表す定数vbNormalの実体は0なので、上のDir関数は
Dir(Path & "*.*", vbHidden + vbNormal)
という指定と同じ意味になるため、Dir関数は標準ファイルも返してしまいます。 また、隠し属性のファイルを特定できたとしても、Killステートメントでは隠し属性のファイルを削除することはできません。 もう、こうなれば、FileSystemObject(FSO)に頼るしかなさそうですね。 次のコードは、C:\Work\Subフォルダ内に存在する、隠し属性のファイルを含めたすべてのファイルを削除します。
Sub Sample5()
  Dim f As Object
  With CreateObject("Scripting.FileSystemObject")
    For Each f In .GetFolder("C:\Work\Sub").Files
      .DeleteFile f
    Next f
  End With
End Sub   
隠し属性のファイルを削除するには上記のコードで問題ありません。 もっとも、どうせフォルダを削除するのでしたら、そちらもFSOでやれば簡単です。 FSOのDeleteFolderメソッドは、削除するフォルダ内にファイルが存在してもそれらファイルごとフォルダを削除してくれます。 もちろん、フォルダ内に存在する隠しファイルも削除されます。
Sub Sample6()
  Dim f As Object
  With CreateObject("Scripting.FileSystemObject")
    .DeleteFolder .GetFolder("C:\Work\Sub")
  End With
End Sub   
実は、これだけではまだ不完全です。 読み取り専用属性のファイルは、そのままではFSOのDeleteFileメソッドで削除できないからです。 そんなときは、一度ファイルの属性を変更しなければなりません。