Visual Basic 6.0 テクニック
VB6対応

 

Visual Basic 中学校 > VB6 テクニック >

14.デバッグの方法

 

今回はデバッグがテーマです。デバッグとはプログラムのバグやエラーを取り除く作業を指しています。VBを解説している本や雑誌の多くはデバッグについてはあまり触れていないのが現状ですから、VBをそこそこ使いこなしている人でもデバッグのことをよくしらなかったりします。

 

今回解説すること

・イミディエイトウィンドウの活用方法

・条件付で実行を中断する方法

・実行中にデバッグモードに移行する方法

など

 

 

1.イミディエイトウィンドウの活用

 

.実行が停止している状態でロードされているフォームの一覧を見るにはどうしたらいいでしょうか?

.イミディエイトウィンドウに次のように入力してEnterキーを押せばその時点でロードされているフォームの一覧が表示されます。

for kk=0 to forms.count-1 : ? forms(kk).name : next

 

解説

イミディエイトウィンドウは1行分の命令しか実行できないのですが行継続文字( : )を使うことによりループ処理を実行させることも可能です。この方法でオブジェクトのプロパティの一覧を見たりもできます。

 

2.Errオブジェクト以外でエラー情報を保持するオブジェクト

 

.よくエラーで「ODBC--呼び出しが失敗しました。」と出るのですがどういうことでしょうか?もっと詳細な原因はわからないのでしょうか。
 

.イミディエイトウィンドウで次のように入力してEnterキーを押せばさらに詳細なエラー情報を参照することができます。

? dbengine.Errors(0)

 

解説

エラーが発生した場合、VBはErrオブジェクトの情報しか自動で表示しませんがErr以外のオブジェクトがエラーについての詳細を把握している場合があり、その場合は自分でそれらの情報を取得しなければなりません。

上の例は DAOを使用している場合の例です。DAOのErrorオブジェクトはDAO経由で発生したエラーの詳細を把握しています。またADOにも同様のErrorオブジェクトが存在しています。この他にも名前は違うかもしれませんが独自のエラー情報を把握しているオブジェクトが存在する可能性があるので外部のライブラリを参照している場合はオブジェクトの一覧に一通りは目を通しておいたほうがよいかもしれません。

なお、この例で古いバージョンのDAOでは「ODBC--呼び出しが失敗しました。」ではなく、「カーソルは宣言されませんでした。」と表示します。

 

3.メッセージボックス表示中に一時停止する

 

.メッセージボックスを表示している行を突き止めるにはどうしたらよいでしょうか。

.メッセージボックス表示中に [Ctrl] + [Pause] (または [Ctrl] + [Break])を押します。

 

解説

[Ctlr] + [Pause] ([Ctlr] + [Break]以下同じ)はプログラムの実行中に一時停止できる便利なコマンドです。

メッセージボックスの表示中でも作動するのでメッセージボックスがあちこちにあるプログラムでは重宝するかもしれません。この他にもちろん、通常の検索を利用してメッセージボックスを表示する箇所を突き止める方法もありますが、[Crlt] + [Pause] の方が直接的で確実です。

 

4.無限ループを停止する

 

.無限ループを停止するにはどうしたらよいでしょうか。

.[Crlt] + [Pause] (または [Ctrl] + [Break])を押します。

 

5.関数・プロシージャの呼び出し履歴

 

.ある関数にブレイクポイントをおいてその関数が呼ばれたら一時停止状態になるようにしているのですが、一時停止状態になったときにその関数がどこから呼ばれたか調べるにはどうしたらよいでしょうか。

.呼び出し履歴ウィンドウを見ればわかります。

 

解説

呼び出し履歴ウィンドウを開くには[表示]メニューの[呼び出し履歴]をクリックします。

呼び出し履歴ウィンドウは関数が呼ばれた順番に下から並んでいます。具体的にどの行から呼び出されたか知るにはさらに呼び出し履歴ウィンドウの項目をダブルクリックすればその行にジャンプするのでわかります。

該当行にはインジケータ領域(ブレイクポイントやブックマークを表示する左のほうにある部分)に緑の三角が表示されます。

 

6.On Error Goto のエラー発生行を突き止める

.現在 On Error Goto を使ってエラー処理をしているのですが、エラーが発生してエラールーチンに処理が移ったところでブレイクポイントを設置して一時停止しています。このとき、どの行でエラーが発生したのか知るにはどうしたらよいでしょうか。

.Resumeを実行すると、エラーが発生した行に処理が戻るのでわかります。

 

解説

VBでは標準的に次のようなエラー処理構造を使います。

Private Sub Form_Load()

    On Error GoTo ErrorHandle

    〜メイン処理〜

    Exit Sub

ErrorHandle:

    〜エラー処理〜

End Sub

 

「メイン処理」でエラーが発生すると「エラー処理」が実行されるわけですが、「エラー処理」の実行中に「メイン処理」のどの行でエラーが発生したのか知ることはできません。(もちろん、そのための仕組み(変数など)を独自に用意していれば別です)。

特に「エラー処理」中に一時停止した場合「メイン処理」のどの行でエラーが発生したのかはとても興味のあることです。

ここで、Resumeステートメントを使うと「エラー処理」からエラー発生元である「メイン処理」に処理を返すことができるので便利です。

但し、常にResumeを使用していてはエラー処理の意味がないのでExit Subの直後にResumeを書いておいて、デバッグ時にはマウスをドラッグしてResumeを実行させればエラーが発生した行に帰ることができます、

「マウスをドラッグしてResumeを実行させる」の意味を念のためにもう少し詳しく書いておくと、「一時停止行の左側に表示されている黄色い矢印をResumeの行にドラッグして実行(F5)する」ということです。

 

7.条件つきで一時停止する

 

.変数 Name の値が "John" になった瞬間に(それがどこであれ)一時停止したいのです。そんなことはできるのですか?

.できます。

 

解説

通常のブレイクポイントでは指定した場所で必ず一時停止してしまいますが、ウォッチ式で指定したブレイクであれば、どこであれ条件が成立したとことで自動的に一時停止させることがあります。

この例では、ウォッチウィンドウを開いてから右クリックをして[ウォッチ式の追加]を選んで、式の欄に「 Name = "John" 」と入力してください。[対象]を適切に選択したらウォッチの種類のところで「式が True のときに中断」を選びます。

この設定で、[対象]で選択した範囲内で Nameの値が"John"になったときに自動的にデバッグモードに変更します。

 

8.テキストボックスの監視

 

.現在複雑な入力プログラムを開発しています。プログラムのどこかでテキストボックス txtCustomerID に "John" という文字列をセットしているようなのですがそれがどこだかわかりません。その場所を突き止めるにはどうしたらよいでしょうか?

.ウォッチ式に「 txtCustomerID.Text = "John" 」と指定して、「式が True のときに中断」を選びます。

 

解説

ウォッチ式ではコントロールの名前を直接指定することもできるのです。

 

9.通常モードとデバッグモードの違い

 

.普通に実行したときとデバッグモードでステップ実行したときとで動作が違うときがあるようなのですが・・・

.その通りです。

 

解説

通常に実行したときとステップ実行したときとではイベントの発生のタイミングが異なる場合があるようです。ときにフォーカス系のイベントで複雑な処理をしている場合にこういったことを時々体験します。

この現象は私の知る限りどうしようもありません。

ただ、ひとついえることは この現象はマイクロソフトが悪いのですが、このような現象が発生するプログラムにも問題があります。シンプルに作りましょう。

 

10.一時停止モードを使わないでデバッグする

 

.事情があって一時停止したりステップ実行したりできないのですが、途中で変数の値を確認したりしたいのです。どうすればよいでしょうか。

.確認したい位置に変数の値をファイルに書き出すロジックを追加するか、イミディエイトウィンドウに出力するロジックを追加します。

 

解説

サブクラス化を利用していたりする特殊な環境では一時停止したりすると強制終了してしまう場合があります。そんなときに変数の値を確認したりするにはもはやVBのデバッグ機能を頼ることはできません。自分でプログラムの中にデバッグ用のロジックを埋め込みましょう。

 

11.EXEファイルにすると動作が異なる場合がある

 

.完成したプログラムをEXEファイルにしたらそれまでと動作が異なるようになってしまいました。原因をつきとめようにもコンパイルする前の段階では意図したとおりに動いているのでどうしようもないように思えます。何か方法はありますか。

.「10.一時停止モードを使わないでデバッグする」と同じ方法でデバッグするしかないです。

 

解説

非常にこった作りをするとvbpで開発環境で実行しているときとコンパイルしてexeで実行している場合とで動作が異なる場合があります。この「非常にこった作り」とはメモリの内容を直接いじったりすることを指します。他にもこのような現象が発生する条件があるかもしれません。