自分で書いたはずのマクロなのに、半年後に見返したら何をしているコードか分からず、修正に何時間もかかってしまった経験はありませんか?
会社の後輩と勉強がてら様々なExcelの記事を見ながらつぎはぎでコードを書いていったら
非常に読みづらいものが完成してしまい絶賛困り中です・・・。
動けばよいという書き方を続けていると、担当者の異動や引き継ぎのたびにマクロがブラックボックス化していきます。この記事では、あとから読んでも改修しやすい「保守性の高いVBA」を書くための基本的な作法を、図解を交えて解説します。
「動けばOK」なコードが引き継ぎで問題になる理由
Excel VBAは比較的自由度が高く、変数名を1文字にしても、処理をすべて1つのプロシージャに詰め込んでも、とりあえず動くマクロは書けてしまいます。しかし、この「動けばOK」なコードは、書いた本人が忘れた頃や、別の担当者が引き継いだときに大きな負債になります。変数の意味が読み取れない、どこで何をしているのか追えない、少し仕様を変えたいだけなのに影響範囲が分からない、といった問題が典型例です。
保守性とは、簡単に言えば「あとから見て理解しやすく、安全に直しやすい」という性質のことです。保守性を意識してマクロを書いておけば、担当者が変わっても業務が止まらず、修正のたびにヒヤヒヤすることもなくなります。実際、現場でよくあるのは「作った本人が退職・異動してしまい、誰もコードを直せずマクロごと使われなくなる」というケースです。せっかく自動化して業務効率を上げたのに、属人化によってその効果が数年で失われてしまうのはもったいないことです。
読み手が迷わない「名前」と「コメント」の付け方
保守性を上げる第一歩は、変数名・プロシージャ名を具体的にすることです。aやtmpではなく、lastRowやcustomerNameのように、値の意味がひと目でわかる名前を付けます。プロシージャ名も同様に、Sub Macro1()ではなくSub 顧客名簿_重複削除()のように、何をする処理なのかが名前だけで伝わるようにしましょう。
コメントは「コードが何をしているか」ではなく、「なぜそう書いたか」を書くのが効果的です。たとえば' 0件のとき除算エラーになるため事前にチェックのように、コードを読むだけでは分からない理由を残しておくと、あとから読む人がその意図を壊さずに済みます。下の図は、名前とコメントを工夫する前後で、同じ処理がどれだけ読み取りやすくなるかを比較したものです。

処理を「意味のかたまり」でプロシージャに分ける
もう1つの重要なポイントが、1つのプロシージャに処理を詰め込みすぎないことです。データの読み込み、加工、書き込み、通知といった処理をすべて1つのSubに書いてしまうと、どこか1箇所を直したいだけでも全体を読み解く必要が出てきます。
意味のまとまりごとに小さなプロシージャへ分割し、それぞれに役割がわかる名前を付けておくと、修正したい箇所だけをピンポイントで見つけられるようになります。次の図は、すべてを1つにまとめた処理と、役割ごとに分割した処理を比較したイメージです。

分割する際は、Sub データ読み込み()からSub データ加工()を呼び出す、というように親プロシージャから子プロシージャを順番に呼び出す形にすると、全体の流れも追いやすくなります。
実際のコードで比較すると違いがより分かりやすくなります。すべてを1つにまとめた場合は次のようになりがちです。
Sub 月次処理()
'(読み込み・加工・書き込み・通知の処理が延々と続く)
End Sub
これを役割ごとに分けると、次のように全体の流れが一目で追えるようになります。
Sub 月次処理()
Call データ読み込み
Call データ加工
Call 結果書き込み
Call 完了通知
End Sub
実務で保守性を保つための習慣
コードの書き方に加えて、日々の運用でも保守性を保つ工夫ができます。まず、変数は必ずDimで型を宣言し、モジュールの先頭にOption Explicitを書いておきましょう。こうしておくと、変数名のスペルミスをコンパイル時に検出でき、実行してから原因不明のバグに悩まされることがなくなります。
また、マジックナンバー(意味の説明がない数値の直書き)も避けたいポイントです。If Cells(i, 3).Value > 10000 Thenのような書き方ではなく、Const 発注基準額 As Long = 10000のように定数として名前を付けておけば、基準額が変わったときも定数を1箇所直すだけで済みます。
エラー処理も保守性に直結します。On Error Resume Nextで例外をすべて握りつぶしてしまうと、一見エラーなく動いているように見えて、実は途中の処理が失敗していたということが起こりえます。想定外のエラーが起きた場所と原因が分かるように、On Error GoToでエラー発生時の処理を明示しておくと、トラブル発生時の調査が格段に楽になります。インデント(字下げ)を揃えることも地味に重要で、Ifブロックやループの範囲が視覚的にひと目で分かるだけで、コードの見通しは大きく変わります。
最後に、修正した日付と内容、担当者名をモジュールの先頭にコメントとして残しておく習慣も、引き継ぎ時の安心材料になります。名前・コメント・分割・エラー処理・インデントという、どれも決して難しくない小さな工夫の積み重ねが、半年後・1年後の自分やチームを助けてくれます。

コメント