ファイルの存在を調べる


美しいマクロは「頑強性」を持っています。どんな環境でも、ユーザーがどれほど予想外の操作をしても、滅多なことでは停止しないマクロを目指しましょう。それには「○○のはず」という固定概念を払拭するのがポイントです。「ここにファイルがあるはず」「シート名はSheet1のはず」などなど、固定概念が多いマクロほど思わぬトラブルを招くものです。

たとえば、次のコードは、ブックを開く簡単なマクロです。

Sub Sample1()
    Workbooks.Open "Book2.xlsx"
End Sub

シンプルですけど、これはマズイですね。「Book2.xls」にパスを指定していませんから、これでは「カレントフォルダのBook2.xls」になってしまいます。カレントフォルダは、Excelでブックを開いたり保存したりするだけでも変わりますから、Book2.xlsxが見つからない場合もあります。明示的にカレントフォルダを移動してからブックを開くのなら、次のような感じです。

Sub Sample1()
    ChDrive "C"
    ChDir "C:\Sample"
    Workbooks.Open "Book2.xlsx"
End Sub

ChDirはカレントフォルダを移動するステートメントですが、ChDirだけでは、カレントドライブは移動しません。ChDirするときは、その前にChDriveステートメントを実行して、カレントドライブも移動すると安全です。

あるいは、そもそも「Book2.xlsx」のように、パスを指定していないのがマズイのですから、ちゃんとパスを指定すればいいですね。

Sub Sample1()
    Const Path As String = "C:\Sample\"
    Workbooks.Open Path & "Book2.xlsx"
End Sub

定数として定義したパスの最後に「¥」がついている点に留意してください。

さて、開こうとしているブックのパスを指定できましたが、はたして、本当に、間違いなく、そこにBook2.xlsxが存在するのでしょうか。このように別ファイルを扱うときは、まずファイルの存在を確認するべきです。それにはDir関数を使います。

Dir関数で調べる

Dir関数は、引数に指定したファイルが存在すると、そのファイル名を返し、存在しないと空欄("")を返します。

Sub Sample2()
    If Dir("C:\Sample\Book2.xlsx") <> "" Then
        Workbooks.Open "C:\Sample\Book2.xlsx"
    Else
        MsgBox "C:\Sample\Book2.xlsx" & vbCrLf & _
               "が存在しません"
    End If
End Sub

こうした、開くファイルが特定しているような場合は、次のように定数か変数に入れておくといいですね。

Sub Sample2()
    Const Target As String = "C:\Sample\Book2.xlsx"
    If Dir(Target) <> "" Then
        Workbooks.Open Target
    Else
        MsgBox Target & vbCrLf & "が存在しません"
    End If
End Sub

Dir関数が返すのは、パスを含まないファイル名です。たとえば「Dir("C:\Sample\Book2.xlsx")」は「Book2.xlsx」を返します。この特徴を利用して、フルパスのファイル名を、パス部分とファイル名部分に分割することもできます。詳しくは、下記ページをご覧ください。

フルパスをパスとファイル名に分ける

なお、ファイルの存在確認は、FileSystemObjectのFileExistsメソッドでも可能ですが、特に理由がない限り、簡単なDir関数を使えばいいでしょう。ちなみに、FileExistsメソッドは次のようにします。

Sub Sample3()
    Const Target As String = "C:\Sample\Book2.xlsx"
    With CreateObject("Scripting.FileSystemObject")
        If .FileExists(Target) Then
        Workbooks.Open Target
    Else
        MsgBox Target & vbCrLf & "が存在しません"
        End If
    End With
End Sub

FileSystemObjectのFileExistsメソッドは、引数に指定したファイルが存在するときTrueを返します。