Mutable_Yunの業務改善ブログ

業務改善や生産性向上のブログです。自動化の手段として、VBAやRPAの勉強に役立つ解説をしています。

VBA 中級者から上級者へ⑤ デバッグを効率化する簡単なコツ

今回は中級から上級へのステップアップを果たすスピードが爆上がりするデバッグを上達する方法を解説します。<誤解を招かない表現に修正 on 2019/11/01>
エクセルVBA中級者から上級者へのステップアップ① 中級を卒業するためのステップで解説したように、中級と上級の違いは経験と思いやりでした。思いやりとはエラーを出さない事とユーザーが使い易いことでしたね。

デバッグとはプログラムの挙動を確認することであり、エラーを回避する処理をする為に必要な行為です。この記事で、簡単にできるデバッグのコツを学んで、素早くデバッグができるようになれば上級者への仲間入りです。

この記事は中級です。
レベルについてはExcel VBAの実力(レベル)を定義してみる 初心者~三段をご参照ください。

目次

デバッグとは

まずはWikipediaでデバッグを検索します。以下の枠内、Wikipedia引用。(2019/10/26時点)

デバッグ(debug)とは、コンピュータプログラムや電気機器中のバグ・欠陥を発見および修正し、動作を仕様通りのものとするための作業である。サブシステムが密結合であると、1箇所の変更が別の箇所でのバグを作り出すので、バグの修正がより困難となる。

仕様とは「こういう風に動いて欲しい」という要求を実現する方法のことです。自分だけの便利ツールを作っている段階では余り気にしなくてもいいのですが、人に使ってもらうツールやシステムを作るときは仕様を意識するようにしましょう。

サブシステムや密結合はVBAにおける開発で今のところ気にしなくてもOKです。

仕様についてより詳しく深掘りしたい方は- 非エンジニアのプログラミングに要求仕様書は必要かをご参照下さい。

VBEの機能が充実&VBAは高級言語なのでデバッグは楽。使えるモノは使うスタイル

VBEとは、VBAを記述するためのエディタで、これまで皆さんがVBAのコードを記述していた所です。VBEはコードを記述する為だけの機能ではありません。Windowsのメモ帳とは違います。デバッグの機能もバッチリついています。

さらに私たちにとってありがたいことに、VBEのデバッグ機能に恵まれているだけで無く、VBAはデバッグがしやすい、高級言語だと言うことです。高級言語とはざっくり言うと、やりたいことを書けばいい、と言う事です。セルA1に「こんにちは」と書き込むのはたった一行で済みますよね。そういうことです。本来であれば、「こんにちは」と書き込む作業はどのPCのどのメモリ領域を使って「こんにちは」と書き込むと言う計算をするのか、と言ったパソコン側の事情をくみ取って書いてあげなければいけないのですが、VBAではそのようなことはエクセルアプリケーションがやってくれます。ありがたいことです。中級から上級にステップアップする段階では、VBAを使っている私たちは恵まれた環境でプログラムを書かせてもらっているんだな、くらいの理解でOKです。

使えるモノは使っていきましょう。←これが一番言いたいこと

プログラミングの効率改善を目指すならデバッグの効率も目指す

VBAを勉強していると言う事は何らかの自動化ツールやシステムを作っているか作ろうとしていると言うことですよね。それならプログラミングの工程も効率を改善していきましょう、と言う事です。

よくプログラミングの世界で言われているのは、仕様を固めるのが3割、プログラムを書くのが3割、デバッグが4割、と言う事です。全体の4割がデバッグでコーディングより大きいんですよね。しかし、今回取り扱うのはそのデバッグでは無く、「プログラムを書くのが3割」に含まれているデバッグです。リリース前のテストの前にやるデバッグではありません。

下記の2点が大事です。

  1. 不具合が起き得る場合を想定して、それに対して不具合を起こさない、と予め決める事
  2. 決められたテストにたどりつくためにコーディングミスによる不具合を起こさないこと

ほとんどの場合、開発者が自分なりに行うテストはリリース前のテストでは一発では通りません。だったらテストまでできるだけ早くたどり着きたい。つまり2の「コーディングミスによる不具合を起こさないこと」が大事です。コーディングのミスがなくてもテストで通らないなら、開発工程はプログラミングミスなくさっさと終わらせて、早くテストフェーズに移りたいと言う事です。

つまりコーディング中の自分のミスによるエラーを速攻で撲滅していく必要があります。よって、ここで解説しているデバッグはテストで不具合が出たときに再度合格するためのデバッグでは無く、「一通り開発は終わった」というテストに至るまでの、コーディング中のデバッグの事です。プログラミング作業中の不具合の撲滅なので、先述の「デバッグ4割」では無く「プログラミング」の中に含まれるデバッグです。

やっとこのブログで解説する内容が明確になりました。

デバッグのコツ

ここから具体的なコツと実際に使う技を解説します。

細かく部分ごとに実行する

プログラムは長くなると不具合箇所の特定が難しくなります。エラーそのものが出ている場所では無く、その場所のコードを実行している前提が既に想定外になっている可能性があるからです。

初めのうちは1行ごとに実行してもいいと思います。慣れてきたら、If文やFor文などブロックごとですね。

スニペットという考え方と結合テスト

スニペットはよく使うひとかたまりのプログラムのことです。
エクセルVBA中級者から上級者へのステップアップ③ ブックを開く周辺で、ブックを開く時の周辺のエラー対策をしました。この講座で作成したプログラムはエクセルデータを入力する事が頻発するエクセルVBAのプログラミングでは何回も使いそうですよね。

このように、よく使うひとまとまりの部分をスニペットと言います。違うところだけ微修正するだけで使えるので開発速度が爆上がりします。イメージとしてはスニペット部分を一つのサブプロシージャにして、それをつなげていくイメージですね。(クラスは初段レベルなので今は知らなくてOKです)

それぞれではちゃんとエラー無く想定通り動くのに、つなげると失敗することがあります。多くは変数が原因です。「そんな変数ありません」とか「想定外のインデックスです」とか。あとは、グローバル変数が思わぬところで既に使われている、などです。エクセルブックをシステムとして使っていて、機能の拡張をし続けている場合は要注意です。

スニペットを有効活用していくためにはどこからでもアクセス可能なグローバル変数は極力減らしていくべきです。サブプロシージャも、今後はPrivate Subと書くようにしましょう。使い回しで効率を上げるからこそ、思わぬエラーを減らす努力が必要です。(ちなみに標準プロシジャの上手な使い方は、エクセルVBA 上級者から初段へのステップアップ② 標準モジュールの役割を理解して処理の流れにこだわるで解説しています。)

慣れてくると単にSubと書くのが気持ち悪いくらいです。これまでは、サンプルプログラムのプロシージャ名は単に Sub Hoge()のように書いていましたが、今後は特に理由が無い限りPrivate Subを使っていきましょう。

さらに上達すると、スニペットの概念(=別のプログラムを作るときにコピペできる)を通り越して、そのプログラム内でスニペットを作れないか?と感じるようになります。他のプログラムでは使わないけど、このプログラムでは頻発する手順ですね。そこで出てくるのがFunctionプロシジャやSubプロシジャやFunctionプロシジャの集合体である、オブジェクト指向です。オブジェクト指向を取り入れるのは上級からのステップアップ講座で触れるので、今はそういうものがあるんだな、位でOKです。意識だけしておきましょう。今すぐオブジェクト指向に触れてみたい方は、コーディング技術に極力触れずにVBAにおけるクラスの概念だけを説明しているVBAのクラスを使う① クラスを使うためのオブジェクトとメソッドの前提知識をご覧下さい。(Ctrlを押しながらクリックするとページを変えずに新しいタブで開けます。)

具体的なデバッグの技術

デバッグに対する考え方とコツについて解説してきました。具体的な技術は他のブログでもたくさん解説されているので、ここでは検索のヒントになる情報のみ紹介していきます。

ステップイン実行

ずばりF8です。一行ずつ実行することができます。表示⇒ローカルウィンドウでローカルウィンドウを開いて変数の中身がどのように変化していくのかを観察しましょう。F8で一行ずつ実行する感覚を身に付けるためのサンプルプログラムを掲載しておきます。

Sub F8でステップイン実行して一行ずつ実行するためのプログラム()

    Dim i As Long
    Dim ans As Long
    Const initial_num = 1
    Const last_num As Long = 10
    
    
    For i = initial_num To last_num
        ans = i * i
    Next i
    
End Sub

ちょっと大切なを補足します。

F8を押して実行してみましょう。一行ずつ実行するはずなのに、一行ずつ変数と定数が定義されていくのでは無く、変数の宣言と定数の宣言部分が飛ばされて、いきなりローカルウィンドウに変数と定数が現れて、プログラムの実行はいきなりFor文の所から始まります。

これはExcelの文法的なデバッグ(本当はコンパイルと言いますが、これは覚えなくてOKです。)は一行ごとに行われているからです。Enterを押して次のプログラムを書くために、下の行に移ったらその瞬間に、間違ってたら指摘してくれてますよね。明らかな文法的な間違いはプログラムを書く時点でやってくれているのです。ありがたいですね。実はココがVBAが書きやすい理由での一つです。他のプログラミング言語では間違いが無いかのチェック(覚えなくていいコンパイルという作業)を自分で実行しなくてはいけないか、そうでなくても実行したときに初めてエラーに気づく仕様です。書くそばから明らかに誤っている文法を指摘してくれているのはありがたいことだと思います。

補足が過ぎましたが、とにかく一行ずつ実行してみましょう。変数の中身が変わっていく様子が観察できればOKで、これをデバッグに使える感覚が身につけば◎です。

Stopステートメント

強制的にプログラムを中断するのがStopステートメントです。先ほどの例ではiは10までカウントアップして終わりですが、これが1000ぐらいの数字だったらF8を押しまくらないと行けません。

そこで、For文の後にStopを書けば普通に実行して、Stopのところで止まってくれます。ピンポイントで止めて、その時の変数の中身を調べるのに向いてますね。Stopを書き加えただけですが一応プログラムを示しておきます。

Sub Stopで止めて、For文の実行後の変数の値を調べる()

    Dim i As Long
    Dim ans As Long
    Const initial_num = 1
    Const last_num As Long = 10
    
    
    For i = initial_num To last_num
        ans = i * i
    Next i
    
    Stop  'ココにStopを書き加えた。ここでiやansの中身をローカルウィンドウで確認する
    
End Sub

まとめ

具体的な技術はネットでいくらでも調べられるので、中級者が上級者になる為の考え方についてフォーカスして解説してきました。デバッグについて、この記事のまとめとネットで検索すべき単語を紹介して終わりにします。

  • VBAのデバッグが楽な理由はVBEの機能と高級言語である事
  • テスト段階では無く、プログラミング段階でのデバッグを効率化する意識が重要
  • デバッグは細かく分ける
  • スニペットの概念を知り、スニペットを使いこなすための考え方を身に付ける
  • ステップイン実行とStopステートメント

ネットにあふれていてこのブログで解説する必要が無いキーワード

  • ステップオーバー
  • ウォッチ式
  • ブレークポイント

 ⇒VBAに限って言えばブレークポイントよりもStopを使うべきだと思います

  • Debug.print

⇒要望あれば解説します。硬派なドキュメントは実行結果をMsgBoxでは無くDebug.Printを使って出力結果を検証しようとします。その理由とは。