美しいマクロは「頑強性」を持っています。どんな環境でも、ユーザーがどれほど予想外の操作をしても、滅多なことでは停止しないマクロを目指しましょう。それには「○○のはず」という固定概念を払拭するのがポイントです。「ここにファイルがあるはず」「シート名は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関数は、引数に指定したファイルが存在すると、そのファイル名を返し、存在しないと空欄("")を返します。
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を返します。