ほんの10年くらい前まではほとんど無かったのに、ここ数年ぐらいの間に『VBAコーディング規約』に関する記事がかなり増えています。プログラマ向けのコーディング規約自体は昔からあるのですが、VBAに特化したコーディング規約が現れ出したのは最近のことと思われます。
もともと、VBA開発はプログラマに人気がないというかむしろ嫌われていて、少しでも携わったことのある人なら「コードが汚い」「設計書や仕様書などのドキュメントがない」などのいわゆるVBAあるあるを経験したことがあると思います。
もちろん、プロの職業プログラマによるVBA開発の現場ではきれいなコードときちんとしたドキュメントが作成されていると思いますが、それ以外のほとんどの現場では、ExcelやVBAに少し詳しいだけのアマチュアプログラマがひとりで作っている場合が多いです。
なので、プロの現場のようなプログラマ同士のディスカッションやコードのブラッシュアップ、仕様書の作成などが行われることなく開発されます。まぁそれを「開発」と呼ぶかどうかはびみょーですが、自分の経験でも申し訳程度の改修履歴が残ってるぐらいが関の山で、他人が作ったVBAツールの保守・改修は極めて骨の折れる作業と言わざるを得ません。逆に、人が書いたコードを修正する経験を通して、コーディングルールというものがいかに重要かを学ぶのです。
ここ最近のVBAコーディング規約記事の増加は、上記のようなVBA開発の闇の部分を改善しようという機運の高まりなのかどうかはわかりませんが、日本中の多くのアマチュアプログラマがきれいなコードを書き、本格的とまでは言わないものの後々引き継ぐ人が苦労しなくて済むような要件定義、仕様書、設計書ぐらいは残すことができるようになれば、IT市場の裾野が広がることは間違いありません。それがひいては強い日本復活の一翼を担うことになるでしょう。今の日本企業に本当に必要なのは、年収1千万円のプログラマではなく、会社の「利益」を1億円増やすことのできるプログラマ「チーム」なのです。
ということで、自分もVBAコーディング規約の記事をいろいろ読んで自分なりにまとめてみました。
命名ルール
- システムハンガリアンは使わない(例:strUserName や intAge などはダメ)
- ローカル変数はキャメル(例:parentFolderPath)
- Public変数はパスカル(例:ParentFolderPath)
- 定数は大文字スネーク(例:PARENT_FOLDER_PATH)
- Subプロシージャ名および Functionプロシージャ名は動詞+名詞のパスカル(例:GetUserName)
- プロシージャのスコープがPrivateの場合は動詞+名詞のキャメル(例:getUserName)
- Subプロシージャおよび Functionプロシージャのパラメータ変数(仮引数)は小文字スネーク(例:parent_folder_path)
- クラスのメンバ変数は小文字スネーク(例:parent_folder_path)
- Propertyプロシージャ名は名詞のパスカル(例:FolderPath)
- Propertyプロシージャのパラメータ変数(仮引数)は arg
- モジュール名はパスカルスネーク(例:Export_Module)
- 一次元配列の変数名の最後は Ary、二次元配列の変数名の最後は Arry で終わる(例:listAry、dataArryなど)
- コレクションの変数はsで終わる(例:users)
- 列挙体名は先頭に小文字のeをつける(例:eClm)
- Excel表の列番号は列挙体にし、メンバ変数も日本語にする(例:担当者ID = 1)
- 日本語をローマ字にした変数は使わない(例:mitsumoriBangou はダメ)
- それをするくらいならむしろ日本語の変数名にする(例:Dim 見積No As String)
プロシージャのルール
- 変数の宣言を強制(Option Explicit)する
- 変数の型は明示する(例:Dim userName As String)※Variant型はしなくてもよい
- 変数の宣言は1行1変数 ⇒ 複数の変数を1行にまとめて宣言しない
- 複数の変数をプロシージャの冒頭でまとめて宣言しない ⇒ それぞれ使う直前に宣言する
- 変数はなるべく明示的に初期化を行う
- 整数にInteger型は使わない ⇒ Long型にする
- 同じコードを2度書かない ⇒ 関数化する
- プロシージャには必ず次のコメントをつける ⇒ どのような機能か/どのような引数をとるか/どのような戻り値を返すか
- ひとつのプロシージャは、コメント、空行を含めて20行程度にする ⇒ どれだけ長くても50行まで
- コードの1行は80文字程度 ⇒ 長くなる場合は半角スペースとアンダーバー[( &) _]で改行する
- 1行の長さが短めでコード全体の見通しがよくなるなら「:」を使って1行につなげてもよい
- 自作プロシージャの呼び出しは Call を使用する
- マジックナンバーは使わない ⇒ 必ず変数または定数にする
- ハードコーディング(固有の値--リテラル--を直接コード中に書くこと)は極力避ける
- 引数は原則値渡し ⇒ ByVal
- 配列や大きな文字列は参照渡しにする ⇒ ByRef省略
- 参照渡しの引数を(ポインタのように)戻り値として使う場合は参照渡しであることを明示する(例:ByRef user_id As String)
- プロシージャの引数が5個以上になるようならクラスにすることを検討してみる
- 文字の結合にプラス演算子(+)は使わない ⇒ アンバサンド演算子(&)を使う
- 規定のプロパティは使用しない ⇒ 必ず Value をつける
- クラスモジュールを使用した場合は、Class_Initializeで全てのメンバ変数の初期化を行う
- クラスモジュールのメンバ変数のスコープは原則Privateとし、Propertyプロシージャでアクセサにする
<参考記事>
VBA コーディングガイドライン
VBAのコーディングルール
ハンガリアン記法
VBA ローカル変数は使用する直前で宣言する
【ExcelVBA】Integer型とLong型の使い分けは?処理速度が速いのは?