リスト1●指定したExcelファイルを開くマクロ(エラー・トラップがないもの)
リスト1●指定したExcelファイルを開くマクロ(エラー・トラップがないもの)
[画像のクリックで拡大表示]
リスト2●リスト1にエラー・トラップを加えたマクロ
リスト2●リスト1にエラー・トラップを加えたマクロ
[画像のクリックで拡大表示]
図1●VBAの実行時エラーのメッセージ。エラー・トラップが機能していない
図1●VBAの実行時エラーのメッセージ。エラー・トラップが機能していない
[画像のクリックで拡大表示]
図2●VBAの「オプション」ダイアログ
図2●VBAの「オプション」ダイアログ
[画像のクリックで拡大表示]
リスト3●表示するメッセージに,ErrオブジェクトのDescriptionプロパティを利用したマクロ(エラー・ハンドラ部分の一部)
リスト3●表示するメッセージに,ErrオブジェクトのDescriptionプロパティを利用したマクロ(エラー・ハンドラ部分の一部)
[画像のクリックで拡大表示]
図3●リスト3のエラー発生時に表示されるメッセージ。Descriptionプロパティの内容が表示されている
図3●リスト3のエラー発生時に表示されるメッセージ。Descriptionプロパティの内容が表示されている
[画像のクリックで拡大表示]

今月の相談

「マクロを作って配布したのですが,あるユーザーだけエラー・トラップが機能しません。マクロに問題があるのでしょうか?それともユーザーのExcelやパソコンに何か問題があるのでしょうか?」

 確かに一人だけうまく動かないというのは変ですよね。でも,それほど深刻な問題ではありません。実は,やっかいなことにVBAにはエラー・トラップを働かせないオプション設定があるのです。VBAプログラマは,このオプションの存在をよく覚えておきましょう。

エラー・トラップは必須

 この連載の第1回(2005年3月号)で説明したように,エラー・トラップは,Excelにあまり詳しくないユーザーにマクロを使わせる場合には必須のテクニックです。作業中(マクロの実行中)に,ユーザーの予期せぬ動作によりエラーが発生することがよくあります。そうした場合に,一般ユーザーには意味不明なVBAのエラー・メッセージ(実行時エラー)が表示されてしまうと,ユーザーはパニックに陥ってしまいます。エラー・トラップを各所に施して,エラー発生時にうまく処理を中断するなどの工夫が必要なのです。

 さて,エラー・トラップが機能しないとは,どういうことでしょうか?実例で見てみましょう。リスト1[拡大表示]は,指定したブックを開くだけの単純なマクロです。エラー・トラップをしかけていませんので,このままでは開こうとするファイルが存在しないと実行時エラーになります。

 ファイルがいつのまにか移動していたり,削除されたりすることは日常茶飯事です。このようなケースを想定して対策を行うのはプログラマとして当然です。リスト2[拡大表示]は,開こうとするファイルが存在しない場合,エラー・トラップによって,メッセージボックスを表示するようにしたものです。

リスト1●指定したExcelファイルを開くマクロ(エラー・トラップがないもの)

Sub test1()
    Dim myFileName As String

    myFileName = "C:\123.xls"
    Workbooks.Open (myFileName)
End Sub

リスト2●リスト1にエラー・トラップを加えたマクロ

Sub test2()
    Dim myRes As Integer
    Dim myFileName As String

    myFileName = "C:\123.xls"
    On Error GoTo ErrHandler1
        Workbooks.Open (myFileName)
    On Error GoTo 0
Exit Sub

ErrHandler1:
    myRes = MsgBox("指定のファイルがみつかりません。" & _
        他のファイルを指定しますか", vbYesNo + vbQuestion)

    Select Case myRes
        Case vbYes
            myFileName = Application.GetOpenFilename( _
                "Excel ファイル(*.xls), *.xls")
            If myFileName = "False" Then
                MsgBox "処理を中断します", vbInformation
                Exit Sub
            Else
                Resume
            End If
        Case vbNo
            MsgBox "処理を中断します", vbInformation
    End Select
End Sub

 (2)のステートメントにエラー・トラップを仕掛けています(1)(3)。ここでエラーが発生すると,処理は(4)のラベルにジャンプします。(5)のメッセージ・ボックスを表示して,ファイルを探すかどうかを確認します。ユーザーが「はい」をクリックすると,「ファイルを開く」ダイアログを表示して,選択されたファイルを取得します(6)。そして(7)のResume(エラーが発生したステートメントから処理を続行する)ステートメントにより,再度ファイルを開こうとします。

VBAのオプションに注意

 ところが,図1[拡大表示]のようにエラー・メッセージが表示されてしまうことがあります。前述の通り,これはVBAのオプション設定に原因があります。VBE(Visual Basic Editor)を開いて[ツール]-[オプション]でダイアログボックスを開き,[全般]タブをクリックします。図2[拡大表示]のように[エラートラップ]オプションの[エラー発生時に中断]が選択されていると,エラー・トラップは無効になります。[エラー処理対象外のエラーで中断]をクリックして,[OK]ボタンをクリックするとエラー・トラップが有効になります。

 このオプションを変更することは滅多にありません。本来,VBAプログラムのデバッグなどを目的としたオプションですから,一般ユーザーが触れることはないでしょう。また,[再計算]のオプションのように,Excelファイルに保存されるオプションではないので,もらったファイルを開くことで変更されるといったこともありません。しかし,VBAを利用しているユーザーが,適当にオプションを変更した後で戻すのを忘れてしまうということはあるようです。

エラー・メッセージの手抜きをする方法

 ついでに,エラー・トラップに関して役に立つTipsを一つ紹介しておきましょう。プログラムのあちこちにエラー・トラップをしかける場合,エラー・トラップ内で表示させるメッセージ(説明など)をいちいち記述するのは面倒だなと思っている方はいませんか?そんなあなたにピッタリのテクニックがあります。

 それは,ErrオブジェクトのDescriptionプロパティを利用する方法です。マクロ実行中にエラーが発生すると,VBAはErrオブジェクトのDescriptionプロパティにエラー・メッセージをセットします。このプロパティを利用すれば,エラー・メッセージを長々と文字列で記述する必要はありません。

 リスト3[拡大表示]の(1)を見てください。MsgBoxの第1引数(メッセージの内容)に,Err.Descriptionと改行コード(Chr(13))と“他のファイルを指定しますか”という文字列を連結して指定しています。このマクロを実行してエラーが発生すると,図3[拡大表示]のように指定したファイルが存在しないという趣旨の説明文が表示されます。

リスト3●表示するメッセージに,ErrオブジェクトのDescriptionプロパティを利用したマクロ(エラー・ハンドラ部分の一部)

ErrHandler1:
    myRes = MsgBox(Err.Description & Chr(13) & Chr(13) & _
        Chr(13) & "他のファイルを指定しますか", _
        vbYesNo + vbQuestion)

    ~略~
End Sub

 最後の一文を除いた部分が,ErrオブジェクトのDescriptionプロパティで取り出した文字列です。メッセージがやや冗長になるきらいもありますが,ユーザーには少なくとも指定したファイルがないことは伝わるでしょう。皆さんもうまく活用してみてください。

古庄 潤