Excel VBAで関数を綺麗に!リファクタリングで複雑なコードを読みやすくする方法
生徒
「先生、自分で作ったVBAのプログラムが長くなりすぎて、どこで何をしているのか自分でも分からなくなってしまいました。もっとスッキリさせる方法はありますか?」
先生
「それはプログラミングをしていると必ずぶつかる壁ですね。実は『リファクタリング』という魔法のテクニックを使えば、中身の動きは変えずに、驚くほど読みやすいコードに書き換えることができるんですよ。」
生徒
「リファクタリング……?なんだか難しそうですが、初心者の私でもできますか?」
先生
「もちろんです!まずは複雑な処理を小さな部品に分けることから始めましょう。具体的な手順を丁寧に解説しますね。」
1. リファクタリングとは何か?
Excel VBAのリファクタリングとは、プログラムが実行される「結果」はそのままに、プログラムの「中身(構造)」を整理整頓して読みやすく、修正しやすくすることを指します。例えるなら、散らかった部屋の荷物を整理して、どこに何があるか一目でわかるようにする作業に似ています。
最初は「動けばいい」と思って書いたコードも、時間が経つと自分でも解読不能になることがあります。これを放置すると、後で少し修正したいと思ったときに、思わぬバグ(間違い)を発生させる原因になります。プログラミングの初心者こそ、この整理術を身につけることで、上達のスピードが劇的に上がります。この記事では、特に「関数」や「プロシージャ」を読みやすくするテクニックに絞って学んでいきましょう。
2. 長すぎるプロシージャを分割するメリット
一つのプロシージャ(Sub や Function)の中に、何十行も、時には何百行もコードを詰め込んでいませんか?このように「何でも屋」になってしまった巨大なプログラムを、私たちはスパゲッティコードと呼んだりします。糸が絡まり合って、端っこがどこかわからない状態のことです。
これを解決する最大の方法は「処理を分ける」ことです。一人の担当者が「電話対応もして、郵便も出して、掃除もする」のは大変ですが、それぞれに専用の担当者がいればスムーズに進みますよね。VBAでも同じように、特定の仕事だけを担当する小さな関数をたくさん作ることで、全体の流れが「目次」のように読みやすくなります。また、一度作った小さな関数は、他のプログラムでも使い回せるという大きな利点もあります。
3. 関数分割の基本手順をマスターしよう
まずは、一つの大きな処理から、特定の計算や作業を行っている部分を抜き出して、別の関数にしてみましょう。例えば「消費税を計算する」という処理がプログラムのあちこちに登場する場合、それを独立した関数にします。以下のコードは、リファクタリング前の「ごちゃごちゃした」状態の例です。
Sub TotalCalculationBefore()
' 合計金額を計算してメッセージを出すだけの処理だが、計算式が混ざっている
Dim price As Long
Dim taxIncluded As Long
price = 1000
' ここで直接計算している(後で消費税率が変わったら修正が大変!)
taxIncluded = price * 1.1
MsgBox "合計金額は " & taxIncluded & " 円です。"
End Sub
このコードを、計算部分を独立させてリファクタリングしてみます。計算を担当する「専門家」を作るイメージです。
' 消費税計算の専門家(関数)を作る
Function CalculateTax(ByVal price As Long) As Long
CalculateTax = price * 1.1
End Function
' メインの処理はスッキリ
Sub TotalCalculationAfter()
Dim price As Long
price = 1000
' 計算は専門の関数にお任せする
MsgBox "合計金額は " & CalculateTax(price) & " 円です。"
End Sub
このように分けることで、メインの処理(TotalCalculationAfter)を読んだだけで「あ、ここでは税金を計算して表示しているんだな」という意図がすぐに伝わるようになります。
4. 意味のある名前を付ける技術
リファクタリングにおいて、最も大切で最も難しいのが名前付けです。変数名に a や b、data1 といった名前を使っていませんか?これでは、一ヶ月後の自分が見たときに、その中身が何だったか思い出せません。
良い名前を付けるコツは、その変数や関数が「何であるか」を具体的に説明することです。「金額」なら Amount、「最終行」なら LastRow、「名前を確認する」なら CheckUserName といった具合です。パソコンが理解できることよりも、人間が理解できることを優先しましょう。VBAでは日本語の変数名も使えますが、将来的なことを考えると、英単語を組み合わせた名前を付ける習慣をつけておくと、プロのコードに一歩近づけます。
5. 条件分岐のネストを解消してスッキリさせる
If 文の中にまた If 文があり、さらにその中に……という状態をネスト(入れ子)が深いと言います。右にどんどんインデント(字下げ)がズレていくコードは、非常に読みにくいです。これを解消するテクニックとして「ガード節」という考え方があります。
ガード節とは、ダメな条件を最初に見つけて、さっさと処理を終わらせてしまう手法です。以下の例を見てみましょう。まずは読みにくいネストされたコードです。
Sub ProcessDataBefore(ByVal val As Integer)
If val > 0 Then
If val < 100 Then
' ここで本来のメイン処理を行う
MsgBox "有効な数値です。"
End If
End If
End Sub
これをガード節を使ってリファクタリングすると、以下のようになります。メインの処理が一番左側の列に来るため、読みやすさが格段に上がります。
Sub ProcessDataAfter(ByVal val As Integer)
' 範囲外ならすぐに抜ける(ガードをかける)
If val <= 0 Then Exit Sub
If val >= 100 Then Exit Sub
' メインの処理をインデントせずに書ける
MsgBox "有効な数値です。"
End Sub
このように、例外的なパターンを先に追い出すことで、本筋のプログラムを一直線に読むことができるようになります。これは実務で非常に多用されるテクニックです。
6. マジックナンバーを排除して定数を使おう
プログラムの中に * 0.08 や Range("A1:A10") のように、生の数字や文字を直接書いていませんか?これらをマジックナンバーと呼びます。書いた瞬間は分かっていても、後で見たときに「この 0.08 って何の数字だっけ?」となってしまいます。
こうした値には Const(定数)を使って名前を付けてあげましょう。例えば、Const TAX_RATE = 0.1 と定義しておけば、後で消費税が 15% に上がったときも、定義場所を一箇所直すだけで全てのプログラムに反映されます。修正漏れを防ぐという意味でも、非常に重要なリファクタリングポイントです。
7. 複雑な条件式を変数に格納する
If (A = 1 Or B = 2) And Not C = 3 Then のような、長くて複雑な条件式は一目見ただけでは理解できません。これを解決するには、条件の結果(True か False)を一度、分かりやすい名前の変数に入れてしまう方法が有効です。
Sub CheckCondition()
Dim isTargetUser As Boolean
' 複雑な条件に名前を付けて、何を確認しているか明確にする
isTargetUser = (Range("A1").Value = "会員" And Range("B1").Value >= 20)
If isTargetUser Then
MsgBox "キャンペーン対象者です。"
End If
End Sub
このように、条件そのものに「これは対象ユーザーかどうかの判定です」という名前を付けることで、コード自体が説明書のような役割を果たすようになります。これを説明変数と呼びます。
8. コメントに頼りすぎないコードを目指す
「このコードは読みにくいから、横に説明文(コメント)をたくさん書こう」と考えるのは、リファクタリングの観点からは少し惜しい考え方です。本当に良いコードは、コメントがなくても「名前」や「構造」を見ただけで意味が伝わるものです。
コメントは、コードでは表現できない「なぜこの処理が必要なのか」という理由を書くために残しておきましょう。「何をしているか」を説明するコメントが多い場合は、その部分の変数名や関数名が適切でないサインかもしれません。リファクタリングを繰り返していくと、自然とコメントが少なくなり、それでいて誰よりも分かりやすいプログラムが書けるようになります。
9. 繰り返しの処理を一箇所にまとめる
プログラムの中で、似たような記述を何度もコピー&ペーストしていませんか?コピペは非常に危険です。一箇所間違いが見つかったとき、すべてのコピペ先を直して回る必要があり、必ずと言っていいほど修正漏れが発生します。
同じ動きをする部分は、引数(ひきすう:関数に渡すデータ)を使って汎用的な一つの関数にまとめましょう。データの種類が違っても、処理の手順が同じなら一つの部品で対応できます。このように「重複をなくす」ことは、リファクタリングにおいて最も強力な武器になります。無駄なコードが削ぎ落とされ、筋肉質なプログラムに生まれ変わります。