VBA(Excel)

Excelマクロで起きるエラーを減らす方法

スポンサーリンク

こんにちは。システム担当の父親、KATSUです。
Excel歴20年、Access歴10年ですが、ブログは65記事を書いた程度です。


早速ですが、Excelでマクロを作るとき、エラーに悩まされたことはないでしょうか?

職場の上司や同僚からマクロの作成を頼まれて作ったはいいけど、「実行時エラーというのが出てくるんだけど、何とかならないの?」とのクレームが…。

本当は時間をかけて作ったのだから、感謝の声を聞きたかったけど、真逆の結果になってしまうと悔しいですよね?

今回は、Excel VBAで発生するエラーの処理方法と考え方について書きました。

この記事を書いている私は、約10年前にExcel VBAを使い始め、入力や集計作業の効率化を進めてきました。

この10年間は、上司や同僚にマクロを作り感謝されてきましたが、多くのエラーや失敗も起こして迷惑をかけたこともありました。

特にVBAを独学し始めたころは、配布した後に毎日エラーが発生し、本当に悔しい思いをしたのを覚えています。

今では配布後のエラーはほとんどなく、快適にツールを使ってくれています。

今回はエラーへの対処方法を紹介しますが、エラー発生に困っているあなたにとって役に立つところがきっと見つかると思います。

エラーを処理するために使える4つの方法

VBAで発生するエラーは、下のように様々なものがあります。

  • 単純に文法が間違っているもの
  • 選択した範囲やオートシェイプが存在しない
  • 変数の型が違う
  • 0で割り算された場合

しかし、発生したエラーはコードを書き直せば無くせるのですが、実戦投入前にどれだけ見つけきれるかがポイントです。

エラーの種類によっては打ち手が変わりますので、整理しておくことが必要です。

難易度の低い順に並べると、

  • 変数の宣言を強制
  • 運用前にはコンパイルを実行
  • マクロを止めずにエラーコードのみを表示
  • 防げないエラーはその時だけスルーする

といった4項目になります。

上の2項目は必ずおこなってほしいこと、下の2項目は運用前につぶせなかったエラーをどのように対処するかといったことになります。

気を付けてこれらのことを実践していけば、今までに比べて必ずエラーを減らせるようになります。

更に、今回の記事を書くために調査したところ、使えそうな例もありましたので、併せて紹介していきます。

エラー処理1-変数の宣言を強制しておく

VBAの初期設定では、変数の宣言が強制されていません。

宣言していなくても変数が使えますので、思わぬ不具合を起こすリスクがあります。

解決する方法は、プロシージャの初めに「Option Explicit」と書くことです。

しかし、毎回書くのは面倒くさいですよね?書き忘れることもあるでしょう。

早速ツールメニューのオプションを選択しましょう。

「変数の宣言を強制する」という項目があります。

初期設定ではチェックされていませんので、必ずチェックを入れておきましょう。

チェックを済ませておけば、次から新しいプロシージャを作ったマクロを作った時には、必ず「Option Explicit」が表示されるようになります。

一度チェックを入れておけば、変数宣言を強制する一文を都度書かなくて済みます。

エラー処理2-運用前には必ずコンパイルを実行

マクロを実行する前には、デバッグメニューの「VBAProjectのコンパイル」を実行しましょう。

実行すると全てのコンパイルエラーを知らせてくれます。

コンパイルエラーとは単純に文法が間違っていることによって起きるエラーで、どちらかというと初心者の方が陥り易いエラーです。

コンパイルを運用前に実行することで、隠れているコンパイルエラーを全て無くすことができます。

実行時エラーを全て無くせなくても、コンパイルエラーだけは解消して運用を開始しておきたいものです。

エラー処理3-マクロを止めずにエラー番号を表示する

下のコードはデータ型のエラーを発生させます。

Sub Er_Hdl1()
'整数型変数に文字列を使うエラー
    Dim i As Integer
    i = "みかん"
End Sub

エラーが発生すると、対象の箇所でプログラムが止まり、エラー番号と内容が表示されます。

エラーが起こった場合は「終了」「デバッグ」「ヘルプ」の3つのボタンが表示されます。

VBAの知識が無い人にとってはどのように操作したらよいか分からず、混乱してしまいます。

プログラムを停止させずにエラー内容を表示させるというのも、使用者を混乱させないひとつの選択です。

下のコードでは、「On Error Goto」でエラー処理コードErに飛ぶようになっています。

Sub Er_Hdl2()
'整数型変数に文字列を使うエラー(On Error Goto あり)
    Dim i As Integer
    On Error GoTo Er
    i = "みかん"
    Exit Sub  'エラーがない場合はここで終了
Er:
    'エラー発生時は以下に飛ぶ
    MsgBox ("番号" & Err.Number & "のエラーが発生しました." & vbCrLf & _
    Err.Description)
End Sub

実行すると、エラー内容と「OK」ボタンのみを表示にしますので、目にしても混乱しません。

「On Error Goto」を使う場合は、エラー処置用コードの上に「Exit Sub」を忘れないようにしましょう。

下のコードを実行してみましょう。数値型の変数に正しい値を入れていますが、「Exit Sub」を抜いています。

Sub Er_Hdl3()
'Exit Subを書き忘れた場合
    Dim i As Integer
    On Error GoTo Er
    i = 2
Er:
    'メッセージが表示される
    MsgBox ("番号" & Err.Number & "のエラーが発生しました." & vbCrLf & _
    Err.Description)
End Sub

実行すると、Erコードのメッセージが表示されてしまいます。

下のコードは「Exit Sub」を正しく入れていますので、エラーが無い場合はErコードに飛ばずにプログラムが終了します。

Sub Er_Hdl4()
'変数に数値を入れてエラーを発生させない場合
    Dim i As Integer
    On Error GoTo Er
    i = 2
    Exit Sub
Er:
    'メッセージが表示されない
    MsgBox ("番号" & Err.Number & "のエラーが発生しました." & vbCrLf & _
    Err.Description)
End Sub

また、下のようにエラー処理後に条件を分岐させることで、エラーの種類毎に処理方法を変えることも可能です。

Sub Er_Hdl5()
'Erコード以下で分岐する
    Dim i As Integer
    On Error GoTo Er
    i = "みかん"
    Exit Sub
Er:
    If Err.Number = 13 Then
        MsgBox ("変数の型が違います")
    Else
        MsgBox ("番号" & Err.Number & "のエラーが発生しました." & vbCrLf & _
        Err.Description)
    End If
End Sub

エラー処理4-防ぎきれない部分だけ無視する

プログラムが複雑になってくると、どうしても防ぎきれないエラーも起こります。

そんな時は「On Error Resume Next」で以降のエラーを全て無視することが出来ます

しかし、ずっと無視するのは都合が悪いので、エラー無視を解除したい場合は「On Error Goto」で元の条件に戻すことができます。

Sub Er_Hdl6()
'エラーを特定の場所でスルーさせる
    Dim i As Integer
    On Error Resume Next
    i = "りんご"
    On Error GoTo Er
    i = "みかん"
    Exit Sub
Er:
    MsgBox ("番号" & Err.Number & "のエラーが発生しました." & vbCrLf & _
    Err.Description)
End Sub

また「On Error Goto 0」にすると、通常のエラーメッセージを表示させます。エラーを修正したい時には使えます。

Sub Er_Hdl7()
'Erコードを無効にする
    Dim i As Integer
    On Error GoTo Er
    On Error GoTo 0
    i = "みかん"
    Exit Sub
Er:
    MsgBox ("番号" & Err.Number & "のエラーが発生しました." & vbCrLf & _
    Err.Description)
End Sub

更に今回の記事のため、エラー処理について調査したのですが、以前からやりかったことを見つけられたのでついでに紹介します。

それは、エラー処理中に「Resume Next」を加えることです。

この一文を書くことで、エラー処理から抜けて、本文のエラー発生直後に戻ることができます。

Sub Er_Hdl8()
'エラー表示後に継続
    Dim i As Integer
    On Error GoTo Er
    i = "みかん"
    For i = 0 To 9
        Debug.Print i
    Next
    Exit Sub
Er:
    If Err.Number = 13 Then
        MsgBox ("変数の型が違います")
        Resume Next
    Else
        MsgBox ("番号" & Err.Number & "のエラーが発生しました." & vbCrLf & _
        Err.Description)
    End If
End Sub

エラー処理したら本文に戻れないと思い込んでいましたので、目から鱗でした。

特定のエラー番号のみを無視出来れば、マクロの品質を上げられます。

マクロ作りでエラーはつきもの

マクロを運用させた後にエラーを頻発させてしまうと、「自分はプログラミングに向いていないんじゃないだろうか…」とうんざりするのではないでしょうか?

自動化をすすめるために複雑な処理を行うと、エラーが起きるリスクも高まります。

  • 変数宣言の強制
  • 運用前のコンパイル
  • 簡単な動作確認

上の3項目を行っておけば、運用後のエラー発生の頻度をかなり下げられます。

その他の想定していないエラーが起こった場合は、気づいた時に対処すれば十分です。

世の中に出回っているソフトウェアやアプリは、職業プログラマーの人が十分な時間をかけてエラー潰しを行っています。

そのようなソフトウエアでも、初めから100%の出来でリリースされません。

リリース後に、想定外のエラー潰しや改善を行って品質を上げていきます。

ましてマクロの場合は、作る人のほとんどがノンプログラマーです。

マクロを作って職場の業務を改善する、それだけでも十分に価値があって尊い業務であると自信を持ちましょう。

まとめ

今回はVBAのエラー処理についてまとめました。

運用前の確認で、ある程度のエラーはなくすことは出来ますが、完全に無くすことは不可能です。

どうしても無くせないエラーもありますので、その時だけ無効化するのも一案です。

エラー処理の方法が分かれば、今までよりマクロ作りがもう少し楽しめるのではないでしょうか?


本日もありがとうございました。

スポンサーリンク

-VBA(Excel)