他人が読みやすいVBAを書くには、変数名・処理の分割・コメント・With構文・インデントの5つを意識するだけで大きく変わります。動けばいいという考え方から一歩踏み出すことで、引き継ぎやトラブル対応のときに「このコードは何をしているのか」をすぐに把握できるようになります。
この記事では、次の5つの工夫を具体的なコード例とともに解説します。
- 工夫①:見ただけで役割がわかる変数名を使う
- 工夫②:処理をSubやFunctionで分割する
- 工夫③:コメントは「なぜ」を書く
- 工夫④:With構文とSetで無駄な繰り返しを減らす
- 工夫⑤:インデントと改行で見た目を整える
工夫①:見ただけで役割がわかる変数名を使う
変数名は略しすぎず、役割がわかる名前にするのが基本です。
悪い例
Dim a As Long
a = Cells(Rows.Count, 1).End(xlUp).Row
良い例
Dim lastRow As Long
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
a では何を表しているか読んだだけではわかりません。lastRow にするだけで「A列の最終行を入れている変数」だとすぐに伝わります。
命名の目安として、次のような基準が参考になります。
| 用途 | 良い変数名の例 | 避けたい名前 |
|---|---|---|
| 最終行 | lastRow | r、x |
| ループカウンター | i(慣例として許容) | aa、cnt1 |
| シート参照 | salesSheet、ws | s、sh1 |
| ファイルパス | filePath | fp、p |
工夫②:処理をSubやFunctionで分割する
1つのSubにすべての処理を詰め込むと、どこで何をしているのかが追いにくくなります。目的ごとにSubを分けて、メインのSubから呼び出す形にすると、全体の流れが一目でわかります。
分割前
Sub RunAll()
' 既存データを削除する処理(20行)
' データを取り込む処理(30行)
' 書式を整える処理(20行)
End Sub
分割後
Sub RunAll()
Call ClearData ' 既存データを削除
Call ImportData ' データを取り込む
Call FormatData ' 書式を整える
End Sub
Sub ClearData()
' 削除処理
End Sub
Sub ImportData()
' 取り込み処理
End Sub
Sub FormatData()
' 書式処理
End Sub
RunAll だけ見れば処理の流れが把握でき、詳細を確認したいときは個別のSubを見ればいい構造になります。バグが出たときの調査も、どのSubに問題があるかを絞り込みやすくなります。
工夫③:コメントは「なぜ」を書く
コメントはコードの内容をそのまま日本語にするのではなく、「なぜそれをするのか」を書くのが効果的です。
コードの繰り返しになっているだけのコメント(避けたい)
' 行を削除する
Rows("2:" & lastRow).Delete
意図が伝わるコメント(良い例)
' 前月分のデータを削除して今月分を新たに入れ直す
Rows("2:" & lastRow).Delete
コードを見れば「行を削除している」ことは誰でもわかります。コメントには「なぜ削除するのか」を書くことで、後から見た人が文脈を理解できます。
ただし、コメントを書きすぎると逆に読みにくくなります。処理の意図が名前だけで伝わる場合はコメントを省略し、背景や理由が必要なところだけに絞るのがベストです。
工夫④:With構文とSetで無駄な繰り返しを減らす
同じオブジェクトに対して何度も処理するとき、毎回フルパスで書くとコードが冗長になります。With構文や Set を使ってまとめましょう。
With構文なし(繰り返しが多い)
Worksheets("売上").Range("A1").Value = "日付"
Worksheets("売上").Range("B1").Value = "担当者"
Worksheets("売上").Range("C1").Value = "金額"
Worksheets("売上").Range("A1:C1").Font.Bold = True
With構文あり(すっきりする)
With Worksheets("売上")
.Range("A1").Value = "日付"
.Range("B1").Value = "担当者"
.Range("C1").Value = "金額"
.Range("A1:C1").Font.Bold = True
End With
また、シートやブックを変数に入れておくと、参照が明確になり修正も1か所で済みます。
Dim salesSheet As Worksheet
Set salesSheet = Worksheets("売上")
salesSheet.Range("A1").Value = "日付"
工夫⑤:インデントと改行で見た目を整える
コードの読みやすさは、見た目の整え方でも大きく変わります。
悪い例
If a = 1 Then b = 2
For i = 1 To 10: Cells(i, 1).Value = i: Next i
良い例
If a = 1 Then
b = 2
End If
For i = 1 To 10
Cells(i, 1).Value = i
Next i
意識するポイントは3つです。
If・For・Withの中身は必ずインデント(Tab1つ)を入れる- 処理のブロックが変わるところで1行空ける
- 1行に複数の処理を詰め込まない(コロン区切りは避ける)
VBEのエディタでは、Tabキーでインデント、Shift+Tabで戻りができます。コードを書き終えたら一度全体を見渡して、ブロックの境目が視覚的にわかるかを確認する習慣をつけましょう。
まとめ
- 変数名は 役割が伝わる名前(
lastRow、filePathなど)にする - 長い処理は Subで分割 して
Callで呼び出す形にする - コメントは コードの繰り返しではなく「なぜ」 を書く
With構文とSetで同じオブジェクトへの参照をまとめる- インデントと改行 でブロックの境目を視覚的に見せる
これら5つはどれも「今日から使える」工夫です。一度に全部やろうとせず、まず変数名だけ・コメントだけと、1つずつ取り入れていくのがおすすめです。
よくある質問
変数名はローマ字でも大丈夫?
動作上は問題ありません。ただし、英語の方が読み手に意図が伝わりやすく、VBAの予約語(Row・Sheetなど)との組み合わせも自然になるため、lastRow・filePath のような英語表記が一般的です。チーム内でルールが統一されていれば、ローマ字でも支障ありません。
Subをどの単位で分割するのが適切?
「1つのSubで1つの目的を果たす」を目安にすると判断しやすくなります。処理が30行を超えてきたら分割を検討するサインとして意識するといいでしょう。また、複数の場所から同じ処理を呼び出すなら、共通化してSubにまとめる価値があります。
With構文の中でネストしても大丈夫?
大丈夫です。Withの中に別の With を入れることもできます。ただし、2重・3重のネストになると読みにくくなるため、内側のオブジェクトは Set で変数に入れる方がスッキリすることもあります。
コメントを書きすぎるとどんな問題がある?
コードの量より説明文の方が多くなると、本質的な処理の流れが埋もれてしまいます。また、コードを修正したときにコメントの更新を忘れると、コードと説明が食い違って逆に混乱を招く原因になります。コメントは「これは補足が必要だ」と思った場所だけに絞るのが現実的です。
インデントはTabとスペースのどちらを使うべき?
VBEのデフォルトではTabキーがインデントに使われます。VBA専用のエディタであれば混在による表示崩れは起きにくいため、Tabのまま使うのが一般的です。設定は「ツール→オプション→タブ幅」で変更できます(デフォルトは4)。


