sironekotoroの日記

Perl で楽をしたい

Excel VBAスタンダード 公式テキスト 8章 エラー処理

第三者が使用するようなマクロでは、どんなエラーが発生しても対応できるようにしておかなければなりません。エラーへの対応に必要な事は技術やテクニックではなく、優しさと思いやりです

  • むせる

8-1 エラー処理

  • 文法エラー
    • よくある括弧の付け忘れとか
    • VBEが自動的にチェックして検出してくれる
  • 論理エラー
    • コンパイルエラー
      • 実行してもエラーが出るが、メニューの「デバッグ」->「VBAProjectのコンパイル」を使うと実行時にチェックする事が出来る。
      • ただし、デバッグモードには移らない
    • 実行時エラー
      • シートが3枚しか無いのに、4枚表示させようした場合に表示される等、実行しないと分からないエラー
      • 実行しないと分からないので、エラーの原因を取り除くのに最も手間がかかる

8-2 エラーへの対応

エラーが発生したら別な処理にジャンプする

  • On Error GoTo ジャンプ先のラベル名
    • ラベルとはマクロコード上に記述するしおりのような機能
    • ラベル名:
On Error GoTo myError
Workbooks.Open "XXXX.xlsx"
MsgBox "ブックを開きました"

myError:
MsgBox "エラーが発生しました"
  • On Error GoToでジャンプさせるときは「エラーが発生しなかった」ときを想定しなくてはならない
  • 上のスクリプトのままでは、正常に終わった後にエラー表示部のスクリプトが実行されてしまう
    • 対策として、Exil SubをmyErrorの手前におく
On Error GoTo myError
Workbooks.Open "XXXX.xlsx"
MsgBox "ブックを開きました"
Exit Sub

myError:
MsgBox "エラーが発生しました"

どんなエラーが発生したか調べる

  • 発生したエラーに関する情報はErrオブジェクトに格納される
    • Numberプロパティ
      • エラーごとに決まっている「エラー番号」を返す
    • Descriptionプロパティ
      • エラーの意味を表すメッセージ(文字列)を返す
    • Clearメソッド
      • エラー情報をクリアする
Dim buf As String
On Error GoTo myError
buf = InputBox("新しいシート名は?")
Sheets("Sheet1").Name = buf
Exit Sub

myError:
    Select Case Err.Number
    Case 9
        MsgBox "Sheet1が存在しません"
    Case 1004
        If InStr(Err.Description, "次の点を確認して") > 0 Then
            MsgBox "不正な文字が含まれています"
        Else
            MsgBox "同じシートが既に存在します"
        End If
    Case Else
        MsgBox "想定しないエラーです"
    End Select
  • この中ででてくるInStr(A,B)ってのは、Aの中からBに記された文字列を検索する、というもの

発生したエラーを無視する

  • On Error Resume Next
  • 以下のマクロはセーブに失敗した場合にメッセージを出す
    • ActiveWorkbook.Savedにtrue(セーブ成功)とFalse(セーブ失敗)が格納される
On Error Resume Next
ActiveWorkbook.SaveAs "Book1.xlsm"
If ActiveWorkbook.Saved = True Then
    MsgBox "保存されました"
Else
    MsgBox "保存されませんでした"
End If

8-3 エラー対策のポイント

  • エラー発生後の修正は当然として、エラー発生前の対処も重要
  • シート名の設定に失敗する原因としていかが考えられるが、事前の対処が可能
    • ブック内にワークシートが存在しない
    • 新しいシート名が既に存在する
    • 新しいシート名に不正な文字が含まれている
  • これらのエラーに対して、エラーの発生の会費や、適切なエラーメッセージの表示をする事が大事