デバッグが出た?


ビギナーの方からマクロの相談を受けていると、ときおり変な表現を耳にします。

このマクロなんですけど、ときどきデバッグが出るんです。
マクロを実行するとデバッグになるんです。

まぁ、何となく言ってる意味は理解できます。要するに、マクロを実行したら、途中でエラーになって止まるってことを言いたいんでしょうね。でもね、用語の使い方が間違っています。

マクロというのは、Excelに対して与える"指示・命令"です。その"指示・命令"を書くときに使うのがVBAというプログラミング言語です。正しい"指示・命令"を与えれば、Excelは期待したとおりに動作します。しかし"指示・命令"が間違っていたら、そのマクロは正しく動きません。当たり前です。そうしたマクロの"間違い"は、大別すると2種類あります。

  1. スペルミスや文法や構文などの間違い
  2. 論理的な間違い

1.は、いわゆる"書き間違い"です。VBAで使われる単語のスペルを間違えたとか、括弧が足りないとか、ピリオドのところにカンマを入力したとかのミスです。たとえば次のような。

2.は、書いてある指示は文法・構文的に正しいんだけど、それを実行しようとしたら「ああ、それは無理、できません」みたいなミスです。

Sheets("Sheet2").Select

上記は「Sheet2をアクティブシートにしろ」という命令です。文法的にも構文的にも間違ってはいません。正しいです。でも、もし、Sheet2が存在しなかったら、このコードは実行できません。こうしたミスがマクロ中に含まれていると、そこでマクロは停止します。そのように、途中でマクロが止まってしまうことをエラーと呼びます。ちなみに、1.の文法・構文的なミスによって起こるエラーのことを「コンパイルエラー」といいます。2.のように、文法・構文的には正しいけど、実行してみたら無理だったというエラーが「実行時エラー」です。

マクロの実行中にエラーが起きると、もうそのマクロは先には進めません。間違っているのですから。じゃ、先に進めなかったらどうするのかというと、われわれに与えられる選択肢は2つです。

  1. 実行しているマクロを"終了"する
  2. マクロは終了せず"一時停止状態"にして、誤りを探したり修正したりする

マクロを"終了"しても、"一時停止状態"でも、いずれにしてもコードを修正することはできます。しかし「なぜエラーになったのか?」「何が悪かったのか?」という原因を調べるには、マクロが終了していては困るときがあります。たとえば、マクロ中で使用している変数は、マクロが終了するとすべてクリアされて消えてしまいます。変数の中を調べるには、マクロが"実行中"でなければならないです。あるいは、マクロ実行中の状態が、何かの原因になっていることもあるでしょう。そんなときは、マクロを"終了"するのではなく、"一時停止状態"にして誤りを探します。このように、マクロを"一時停止状態"にして、誤りを探す作業のことをデバッグと呼びます。ちなみに、マクロが一時停止状態になると、下図のように、停止した行(次に実行される行)が黄色く反転します。また、VBEのタイトルバーに[中断]と表示されます。この"一時停止状態"を終わらせて、完全にマクロを終了するには、ツールバーの[リセット]ボタンをクリックします。

エラーはいつ起きるか

ここまでは、よろしいですか?ポイントを箇条書きでまとめます。

  • ミスには「スペルミスや文法や構文などの間違い」と「論理的な間違い」がある
  • マクロ中にミスがあるとエラーになる
  • スペルミスや文法や構文などの間違いで起きるエラーを「コンパイルエラー」と呼ぶ
  • 実行して初めて露呈する論理的な間違いで起きるエラーを「実行時エラー」と呼ぶ
  • マクロを一時停止してミスを探したり修正する作業のことをデバッグと呼ぶ
  • マクロが一時停止状態になると、コードの一部が黄色く反転する

さて、われわれがマクロを書いて、そのマクロを実行する流れの中で、いつ、どんなエラーが起きるのでしょうか。エラーが起きるタイミングは2つあります。

  1. VBEで1行分のコードを書いてEnterキーを押したとき
  2. マクロを実行したとき

1.は正確に言うと「Enterキーを押したとき」だけではなく「別の行にカーソルを移動したとき」です。このときVBEは、その1行に文法的なミスや、構文的なミスがないかどうかをチェックします。もしここで、何らかのミスがあると「コンパイルエラー」が起きます。

上図は、括弧の数が合っていません。閉じ括弧がひとつ多いです。つまり構文的に間違っています。この状態でEnterキーを押すか、カーソルを別の行に移動すると、下図のようなコンパイルエラーが起きます。

エラーになった上図をよく見てください。まず、コンパイルエラーになると「文法・構文的に間違っている行」が赤色になります。そして、VBEが「ねぇねぇ、ここが違うんじゃね?」と、ミスっている箇所(とVBEが判断した箇所)が選択されます。だから、まずは選択されているところをチェックします。ただ、このVBEによる判断は、VBAのプログラミング的な判断で行われます。したがって、必ずしも"本当にミスをしている箇所"が選択されるとは限りません。典型的なのは、End IfやNextを書き忘れたときのコンパイルエラーです。その件に関して詳しい解説は「VBAのコンパイルエラー「If ブロックに対応する End If がありません。」」をご覧ください。また「VBAのコンパイルエラー」に、主なコンパイルエラーの原因と対処法を解説していますので、そちらもご覧ください

さて、上図のエラー画面では、表示されたダイアログボックスに[OK]ボタンと[ヘルプ]ボタンだけしかありません。ちなみに[ヘルプ]ボタンをクリックしても、何の助けにもなりませんからクリックしない方がいいです。この[ヘルプ]ボタンというのは、今は使われていない昔の仕組みです。つまり、われわれに許されていることは[OK]ボタンをクリックしてダイアログボックスを閉じることだけです。ああ、ダイアログボックスの右上[×]ボタンも同じことですよ。では、上図の状態で、[OK]ボタンをクリックするとどうなるでしょう。

何も起きません。ただダイアログボックスが閉じられるだけです。この"何も起きない"ということを、よく覚えておいてください。

さて、エラーが起きるタイミングはもうひとつあります。

  1. VBEで1行分のコードを書いてEnterキーを押したとき
  2. マクロを実行したとき

2.の「マクロを実行したとき」です。マクロを実行したときに起きるエラーは「コンパイルエラー」または「実行時エラー」のいずれかです。先の「VBEで1行分のコードを書いてEnterキーを押したとき」に起きるコンパイルエラーでは、1行分のコードに間違いがあるかどうかしかチェックしていません。でも、その行だけを見たら正しい記述でも、マクロ全体で考えたら間違っているということもあります。ですから、マクロを実行するときに、もう一度マクロ全体の文法・構文的な間違いをチェックするんです。

上図は"Sheets"のスペルが間違っています。"e"が多いです。まぁ、こんな間違いをすることは、あまりないでしょうね。"GReeeeN"じゃねーんだから!でも実は、この1行、文法・構文的には合っているんです。スペルをミスっているのに、なぜこれが正しいと判断されるかの理由に関しては、奥が深い話ですから考えないでください。いずれにしても、この1行のコードだけを見たら、間違いとは言えないんです。だから、Enterキーを押しただけではコンパイルエラーになりません。さて、このマクロを実行すると、次のようになります。

先の「VBEで1行分のコードを書いてEnterキーを押したとき」と同じ画面です。ここでも、われわれは[OK]ボタンをクリックするしかありません。ここで[OK]ボタンをクリックすると

マクロが"一時停止状態"になります。違いが分かりますか?今度のエラーが起きたのは、もうマクロが実行しているんです。コードを書いてEnterキーを押しただけではありません。だから、自動的にマクロが"一時停止状態"になります。同じ画面でも、その違いを理解してください。

さあ、残るエラーはあとひとつです。文法・構文的には正しいけど、マクロを実行してみたら「ああ、それは無理、できません」という"実行時エラー"です。

上図のコードは正しいです。間違っていません。でも、もし、このブックにSheet2が存在しなかったら。次のようになります。

出ました!www デバッグが出ましたwww

みなさん、この状態のことを「デバッグが出た」とか「デバッグになる」などと言うようです。まぁ、確かに、デバッグ(と表示されているボタン)が(画面上に)出たんですけどね。よろしいですか?デバッグというのは、マクロを"一時停止状態"にして、間違いを探す作業のことです。この[デバッグ]ボタンは、「デバッグ(という作業)をするために、マクロを"一時停止状態"にします」という意味です。ここで[デバッグ]ボタンをクリックすると

上図のように"一時停止状態"になります。[終了]ボタンをクリックすると、"一時停止状態"にはならず、ただマクロを終了します。

揚げ足を取るつもりはありませんし、別に正確な表現を強いるつもりもありません。ただ「デバッグが出た」「デバッグになる」は、明らかにおかしい表現です。この場合でしたら、普通に「(マクロを実行したら)エラーになる」あるいは「エラーで止まる」と言ってください。