【保存版】VBAコードのきれいな書きかたをここにすべて記す【まとめ】
「あったら早く教えてほしかった...」

そんなVBAを書くときのルールまとめ。
これで書けとは言わないが、独自に会得した見やすいVBAの書きかただ。

まあブックマークで保存して、忘れたときは読み返してみてくれ。

基本的な書きかたはこの2つのルールだけ

  • インデント
  • 空白行

この基本的なルールは上記2つで成り立ってる。2つなら覚えられそうだろ?

さて、じゃあインデントから話していこうか。

基本ルール1: インデント

まず、インデントだがSub,Function,For,If,Do,Do While(Until)が出てきたらインデント。
そして、End ~,Next ~,Loopがインデント終了の合図だ。

インデントとは、文章の行頭に空白を挿入して先頭の文字を右に押しやること。

1つのグループ分けとして考えると分かりやすいかもしれん。

次のコードで言うと、Sub、Forの部分でインデントが発生してるのが分かるはずだ。

Sub mainProcess()
    
  Dim i As Long

  For i = 1 To 10
    Debug.Print i
  Next i

End Sub

それと、インデントは一番外側のインデント(上記でいうSub)を含めないで3連続までにするべき。

理想をいうなら2連続までが望ましいが。2次元配列なんかを処理するときには3連続になってしまうこともあるだろう。

ちなみに次のような感じがインデントの最大数だ。

Sub mainProcess()

  Dim i As Long
  Dim j As Long
  
  For i = 1 To 10

    For j = 1 To 100

      If j = 100 Then
        MsgBox "最後の数字です"
      Else
        Cells(j, i) = i + j
      End If

    Next j

  Next i

End Sub

4つ以上のインデントをするということ。
すなわちそれは複雑な処理にしようとしているということだ。

見にくくもなるし。まあ対処法としてはいくつかの処理を分けることだね。

基本ルール2: 空白行

「けっきょく空白」と言うくらい空白行は大事。見やすさが段違いになる。

ルールとしてはDim,複数のDimが出てきたら次の行が空白。

Sub ~ End Sub,Function ~ End Functionが出てきたら上下内側を1行空白行にする。
For ~ Next ~,If ~ End If,Do ~ Loop,Do While(Until) ~ Loopの上下が空白行に。

さっき見たプログラムで見ていくと次のようになる。

Sub mainProcess()
    
  Dim i As Long

  For i = 1 To 10
    Debug.Print i
  Next i

End Sub

ここで疑問が出てくると思う。DimとForが出てきたのに空白行が2行じゃないと。

そう、空白行は1行でOKだ。

ルール通りにやって空白行が2行になってしまう場合、空白行は1行にしていい。

ちなみにもう1つ例をだしておこう。

Sub mainProcess()

  Dim i As Long
  Dim result_number As Long

  For i = 1 To 10
    result_number = result_number + i
  Next i

  MsgBox result_number

End Sub

これをさっきの空白ルールで見ていくと、Dimごとに空白行が発生してないって思うよね。

そう、Dimが複数発生する場合はDimごとに空白行じゃなくていい。
複数のDimグループとして最後に空白行をいれること。

さて、ここまでが基本的なルールだ。
つぎは命名規則について話していこう。

VBAの命名規則

見やすく書くためには命名規則というのも必要だ。

ここでは次のような命名規則を話していく。

  • モジュール名
  • プロシージャ名(Sub, Function)
  • 引数名
  • 変数名
  • 定数名

まずはモジュール名からやっていこうか。

命名規則: モジュール名

モジュール名は次のように書いてみよう。

TestModule
単語の1文字目を大文字にしてスペースを開けないで名前をつけていこう。

ちなみに、モジュール名はできるだけ抽象的な名前にしていい。

たとえばCalcPeopleNumberってモジュール名だと「人数の計算」ってことになる。これだと具体的すぎて中身のプロシージャが1つで終わる可能性があるわけ。

だから、Peopleってモジュール名にすれば抽象的になるから「人」に関するプロシージャをいくつか入れられるよね。

モジュール名について詳しく知りたいならVBAモジュールを分ける意味はたった1つ【具体例あり】を見るといい。

命名規則: プロシージャ名(Sub, Function)

プロシージャ名(Sub, Function)は次のように書いてみよう。

Sub mainProcess()

End Sub

Function getPeopleNumber() As Long

End Function
最初の単語はすべて小文字、次の単語から1文字目を大文字にして名前をつけていこう。

ちなみに、プロシージャ名は具体的な名前にするべき。

なぜかって言うと次のようなことになるからだ。

  • 処理が複雑になる
  • インデントが5連続、6連続にもなる可能性がある
  • コードの変更が困難、やりづらい
  • 使いまわしできない、その場限りのコードができる
  • 処理を詰め込みすぎて1プロシージャで100行、200行になる

と、あげればキリがないが...

たとえば、さっき出てきたcalcPeopleNumber。これは人数の計算だ。人数の計算だけなら処理もシンプルに保てるし他にも転用できる可能性がある。

peopleという名前にしたらどうだろう?
人数の計算、年齢の計算も入れられる。人の名前も。人に関するすべての処理が書けることになる。

じゃあ他で人数の計算だけほしい、またはコード変更したいってなったら、膨大なコード量から探す作業が発生する。

はっきりいってムダな時間でしかない。抽象的な名前はやめよう。

ちなみに、プロパティにも次のようにプロシージャ名のルールが適用される。

Property Get saveFileName() As String

End Property 

プロシージャ名についてもっと詳しく知りたいなら【VBA】そろそろSubプロシージャ名のつけ方を知ろうか【教える】を見るといい。

命名規則: 引数名・変数名

Sub mainProcess(Byval test_number As Long)

End Sub
Dim import_file_name As String
import_file_name = "test.xlsx"
単語はすべて小文字、単語と単語はアンダーバー( _ )でつなげて名前をつけていこう。

ちなみに、引数、変数名はできるだけ名前でどんな変数なのか分かるようにしておくべき。

理由としてはムダなコメントが増えるからだ。しかも大量に。

たとえば次のように変数名があったとする。

Dim a As String
a = "test.xlsx" 'インポート用のファイル名

これだとaという変数がでてくるたびにコメントをつけないとバグの原因になったり、最悪コードを読むのが不可能になるわけ。

それを次のようにすると、コメントもいらないし、他で出てきたときも分かるはずだ。

Dim import_file_name As String
import_file_name = "test.xlsx"

まあ簡単にいえば引数、変数名は分かる名前にしとけってこと。
aなんて名前つけてると、あとで大変になるのはキミ。少なくとも予想できる名前にしよう。

命名規則: 定数名

Const IMPORT_FILE_NAME = "test.xlsx"
単語はすべて大文字、単語と単語はアンダーバー( _ )でつなげて名前をつけていこう。

定数名は保存するフォルダ名の変数に入れるときにでも定数を使ってもいいだろう。

ちなみに定数名も引数、変数名同様、意味のある名前にすべきだ。
ただ、単語は4語ほどに制限すること。あまりにも長い名前だと逆にコードが読みにくくなるからだ。

まとめ: このルールでやれば見やすくきれいなVBAコードだ

ざっくり説明したが、説明した通りにVBAを書けば少なくとも昨日よりはるかに上回るきれいなコードが書けるはず。

そして、記事はどんどん追記していく。少しでもこの記事を参考にしてくれれば幸いだ。
VBAがきれいに書けるやつを少しでも増やしたいからな。

ちなみに、このルールは少しPythonの書きかたを参考にしている。
Pythonに興味があれば【超簡単】Pythonインストールして開発環境をつくる方法【Windows】から始めてみるといい。

VBAツール一覧