変数名・プロシージャ名を命名する際の共通の制約事項
変数名・プロシージャ名に関しては、ExcelVBAで以下の制約事項があり、この範囲内で命名する必要があります。
使用可能な文字の制約
使用可能な文字 | 半角英数字、全角英数字、漢字、ひらがな、カタカナ、「_(半角アンダーバー)」 |
---|---|
使用できない文字 | スペースなどの記号、上記以外の文字 |
※上記以外の制約として、変数名・プロシージャ名を命名する際、先頭の文字に半角数字を使用することはできません。
文字数の制約
変数名・プロシージャ名は、半角255文字以内で命名する必要があります。
使用できる名称の制約
一般的に予約語と呼ばれますが、ExcelVBAが提供しているメソッド名、プロパティ名、関数名、ステートメント名、引数名などは、変数名・プロシージャ名として使用することはできません。
同一名称の変数名・プロシージャ名を複数使用の制約
例えば以下のように、同じ適用範囲で同一名称の変数名・プロシージャ名を複数使用することはできません。
- 同一プロシージャ内で、同一名称の変数名を複数使用する。
- 同一ワークブック内で、同一名称のプロシージャ名を複数使用する。
大文字・小文字の区別の制約
ExcelVBAにおいては、大文字・小文字の区別はありません。
[emalabo式] 変数名のネーミングルール
emalabo式では、変数名のネーミングルールに以下の3つのルールを採用しています。
- ハンガリアン記法
- スネークケース
- 小文字で統一する
この3つについて、詳しく解説します。
ハンガリアン記法
ハンガリアン記法の解説
Wikipediaには、ハンガリアン記法について、以下のように記述されています。
プログラマがプログラムのソースコードを書く際に変数名やクラス名などの識別子に特別な接頭文字ないし接尾文字をつけることで、他の人がその識別子を見たときに識別子の使用方法・データ型情報・スコープなどが分かるようにするための命名法である。
ハンガリアン記法という名称は考案者チャールズ・シモニーがハンガリー出身であることに由来する。
この記事によると、初期のWindowsやWord、Excelの開発ではハンガリアン記法が用いられ、成功を収めましたが、現在は批判されることが多く、Microsoftでも.NET Framework以降の開発では使用していないということです。
この「現在は批判されることが多く」という記述についてWikipediaには、具体的にいつ頃から、どのような内容の批判をされているか、というところまでの記述がないため、実際に私がこの命名法を使用してみた感想と対比できないところは残念です。
ハンガリアン記法については、ネット上にも様々な記事が掲載されており、賛否両論あるようですが、私が実際にこの命名法を使用して100本以上のExcelマクロを開発してきて、デメリットと考えられる点は少ないのに対して、多くの点でメリットを享受することができることが分かっております。
以上のことから、emalabo式のネーミングルールでは、ハンガリアン記法を採用することにします。
[emalabo式] ハンガリアン記法を用いたネーミングルールと具体例
ハンガリアン記法を用いたemalabo式の変数名ネーミングルールでは、基本的にそれぞれのデータ型に対応した接頭文字を割り当てます。
変数名のネーミングは、基本的に以下のルールに従って命名します。
- 変数名:「接頭文字」+「変数を表す英単語」
emalabo式の主なデータ型に対する変数のネーミング例は、以下の通りです。
データ型 | 接頭文字 | 具体的な変数の例 | 変数名の例 |
---|---|---|---|
Workbook変数 | wb_ | Excel形式の入力ファイル | wb_inputfile |
Worksheet変数 | ws_ | wb_inputfileの中にあるワークシート | ws_inputfile |
String型 | str_ | メールアドレス | str_mailaddress |
Long型 | num_ | Forループ文の行のカウンター | num_row |
Forループ文の列のカウンター | num_col | ||
Date型 | dt_ | 今日の日付 | dt_today |
Variant型 | var_ | 全ての型の戻り値をセットする変数 | var_ret |
Boolean型 | flag_ | エラーフラグ | flag_error |
ハンガリアン記法が有効に機能するケース一覧
変数名にデータ型の接頭文字を付ける、emalabo式のハンガリアン記法が有効に機能するケースは、以下のようなものがあります。
発生する局面 | どのように機能するか |
---|---|
マクロを実行すると、「型が一致しません」というエラーが出力される。 | 一般的にこのエラーは、関数からの戻り値をセットする変数が、戻り値をセットできない型であることが多く、戻り値をセットする変数の型が、関数の戻り値の型を許容するかどうか、変数の接頭文字で判別できるケースがしばしばあります。 |
変数の型とメソッドやプロパティの組合せに問題がある場合に、自動メンバー表示に出てこない場合やマクロ実行時にエラーとなる。 例) ws_inputfile.Close | 左の例で挙げた「ws_inputfile.Close」は、一見正しいように見えますが、ws_inputfileはワークブック変数ではなく、ワークシート変数であり、ワークシート変数はCloseすることができないので、自動メンバー表示には表示されず、手動で入力してマクロを実行すると、エラーが発生します。 ワークブック変数とワークシート変数は最初は紛らわしいため、接頭文字が「wb_」か「ws_」のいずれかに注意を払うことにより、このエラーに素早く対応できるようになると思います。 |
Forループ文で、カウンターとして使用する変数に、「i」や「j」を用いてコーディングしてしまったが、時間が経過してプログラムを見返した時、このカウンターの役割を思い出すのに時間が掛かってしまった。 | Forループ文のカウンター変数として「i」や「j」を用いる方は多いと思いますが、以下の理由によりお勧めしません。 「i」や「j」がカウンターだということはすぐに分かりますが、何をカウントする変数なのか、把握するのが難しい場合がある。 カウンターを「i」や「j」でコーディングした後、これを別の変数名に置換したいと思った場合、プログラム全体の一括置換では多数の誤変換が発生するため、カウンター変数を1つ1つ置換するしかなく、非常に手間が掛かる。 そもそも「i」や「j」といった1文字のカウンター変数が主流になっているのは、大昔のFORTRANというプログラミング言語の名残でしかなく、これに固執する理由は現在ではなくなっている。 私が上記の表で例示した変数名にする必要もないですが、他の変数名と同様にカウンター変数も分かりやすいものにすべきだと考えております。 更に、カウンター変数の命名時に接頭文字を付けると、Forループ文が以前とは比較にならないくらい分かりやすいものとなる、と思います。 |
スネークケース
主要な3つの表記法の解説
プログラミング言語などで変数名を命名する際の表記法として、現在主なものとして以下の3つがあります。
表記法の名称 | 表記法の解説 |
---|---|
キャメルケース (Camel Case) | キャメルケースは、複数の単語を組み合わせて新しい単語を作る際に使用される表記法です。 最初の単語は小文字で始まり、その後の各単語は大文字で始まります。 例えば、firstName や isAvailable のようになります。 キャメルケースという名称は、大文字が「らくだのこぶ」のように見えることから名付けられました。 この表記法は、JavaやJavaScriptなどのプログラミング言語でよく使用されます。 |
スネークケース (Snake Case) | スネークケースは、複数の単語を「_(アンダーバー)」で結びつける表記法です。 全ての文字は小文字で書かれます。 例えば、first_name や is_available のようになります。 スネークケースという名称は、見た目が「蛇(snake)」のように見えることから名付けられました。 この表記法は、PythonやRubyなどのプログラミング言語やデータベースのカラム名などでよく使用されます。 |
ケバブケース (Kebab Case) | ケバブケースは、複数の単語を「-(ハイフン)」で結びつける表記法です。 全ての文字は小文字で書かれます。 例えば、first-name や is-available のようになります。 ケバブケースという名称は、串刺し料理の「ケバブ」のように見えることから名付けられました。 この表記法は、URLやHTMLのクラス名でよく使用されます。 |
3つの表記法の比較
ExcelVBAでの使用を想定した場合の各表記法の比較は以下の通りです。
表記法の名称 | 表記法の特徴 |
---|---|
キャメルケース | ExcelVBAでは、変数名の大文字・小文字を区別しないため、採用不可。 |
スネークケース | ExcelVBAにおいて問題となる点がないため、emalabo式ではこれを採用。 |
ケバブケース | ExcelVBAでは、変数名に「-(ハイフン)」を使用することができないため、採用不可。 |
小文字で統一する
スネークケースの解説にもありましたので繰り返しになりますが、変数名は基本的に小文字で統一します。
[emalabo式] 上記の3つのルール以外の個人的なネーミングルール
基本的には上記の3つのルールに準拠して変数名を命名していただければ、分かりやすく統一感のある変数名となり、可読性やメンテナンス性が大幅に向上すると思いますが、個人的にはこれに追加して以下のルールを設けております。
個人的ルール | ルールの解説 |
---|---|
変数名に使用する単語は英単語を使用する | 変数名に使用する単語は、基本的に英単語を使用することとします。 なお、以下の2つは禁止とします。 日本語をそのままローマ字に変換したもの。 日本語の2バイトコードの使用。 |
接頭文字以降の英単語には、変数名の用途として分かりにくい単語や数字の濫用は控える | 変数名にはその変数の用途を表す端的な単語を付けるべきではあるが、そのような単語を考えるのを端折って、以下のような汎用的な単語や数字、またその両方の組合せで命名する方がいますが、可読性やメンテナンス性を向上させるためのネーミングルールが意味をなさなくなるため、絶対に止めましょう。 【よく使用されるNGな例】tmp、temp、i、j、k、tmp1、tmp2、等 |
スネークケースを使用するのは、接頭文字とそれ以降の英単語の間のみとする | 個人的に接頭文字を目立たせることにより、変数のデータ型を識別しやすくするため、接頭文字以降の英単語について、複数の英単語の組合せとする場合は、そこは「_(アンダーバー)」を使用せず、単語同士を直接結び付けることにします。 |
上記の表の3つ目のルールはスネークケースに準拠しているわけではないため、ご自身の好みで採用/不採用を決めていただければと思いますが、1つ目と2つ目のルールは一般的だと思いますので、準拠していただいた方がいいのではないかと思います。
[emalabo式] プロシージャ名のネーミングルール
emalabo式では、変数名のネーミングルールに以下の3つのルールを採用しています。
- PowerShellのコマンドレットのネーミングルールに準拠
- ただしExcelVBAの制約により、以下の2点についてPowerShellのコマンドレットのネーミングルールを一部変更する
- 「-(ハイフン)」の代わりに「_(アンダーバー)」を使用する
- 大文字は使用せず、全て小文字とする
PowerShellについての解説
PowerShell(パワーシェル)は、コマンドプロンプトの後継アプリに相当するようなものとなっています。
PowerShellでは、基本的にはコマンドプロンプトのコマンドも受け付けますが、PowerShell独自の高機能なコマンド(これをコマンドレットと呼びます)が多数提供されています。
Windows11では、PowerShellのアイコンはWindowsツールに存在します。
PowerShellのコマンドレットについての解説
PowerShellのコマンドレットは、以下の構文で作成されています。
- PowerShellのコマンドレット:「動詞(現在形)の英単語」+「-(ハイフン)」+「名詞(単数形)の英単語」
代表的なコマンドレットの例を以下に列挙します。
コマンドレット | コマンドレットの成り立ち | コマンドレットの機能 |
---|---|---|
Get-Help | 「取得する」+「-(ハイフン)」+「ヘルプ」 | ヘルプを出力する |
Get-Command | 「取得する」+「-(ハイフン)」+「コマンド」 | コマンドレットの一覧を出力する |
Get-Childitem | 「取得する」+「-(ハイフン)」+「子供のアイテム」 | カレントフォルダの内容を出力する (「dir」と同等) |
Write-Host | 「書く」+「-(ハイフン)」+「ホスト」 | ホスト(コンソール)に文字列情報を 出力する |
Restart-Computer | 「再起動する」+「-(ハイフン)」+「コンピューター」 | PCを再起動する |
プロシージャ名のネーミングルールをPowerShellのコマンドレット準拠にする理由
プロシージャ名のネーミングルールについては、変数名と同様に分かりやすいものを容易に作ることができる、という目的を達成するために色々と検討しましたが、以下の点においてPowerShellのコマンドレットのネーミングルールは、他のルールと比較して優れていると考え、採用することにしました。
- 変数名のように、プロシージャ名にはデータ型を持っていないので、変数名とは別のネーミングルールを採用する必要があった。
- PowerShellのコマンドレットは、ネーミングルールが分かれば、コマンドからそれが何を実行するのかを推測しやすいため、これをマクロの開発で実際に適用し、検証してみた。
- マクロの開発で実際に使用してみて、作成するプロシージャが何をするのかを把握していれば、このネーミングルールを用いてプロシージャ名を命名するのはそれほど困難ではなく、プロシージャが何を実行するのかを把握するのも容易だった。
プロシージャ名とPowerShellのコマンドレットのネーミングルールの相違点
ExcelVBAの制約により、プロシージャ名のネーミングルールはPowerShellのコマンドレットのネーミングルールから以下の点を変更しています。
変更点 | 変更理由 |
---|---|
「-(ハイフン)」の代わりに 「_(アンダーバー)」を使用する | ExcelVBAでは、「-(ハイフン)」を使用できないため、 代わりに「_(アンダーバー)」を使用する |
大文字は使用せず、全て小文字とする | ExcelVBAでは大文字と小文字を区別しないため、 全て小文字とする |
プロシージャ名のネーミングルールを用いたプロシージャ名の具体例
実際の業務で想定されるプロシージャの処理内容から、上記のネーミングルールで私なりにプロシージャ名を作成してみましたので、ご参考になれば幸いです。
プロシージャの処理の内容 | プロシージャ名の例 |
---|---|
1つのExcelファイルを複数のExcelファイルに分割する | split_excelfile |
複数のExcelファイルを1つのExcelファイルにマージする | merge_excelfile |
Excelファイルのフォーマット変換を行う | transform_excelfileformat |
社員番号からメールアドレスを取得する | get_mailaddress |
zipファイルを作成し、所定のフォルダに格納する | make_zipfile |
[emalabo式] 変数に関するコーディングルール
変数についてコーディングする際は、以下の点に留意しましょう。
- コードの最初に「Option Explicit」を必ず出力する設定をして、変数を使用する際は、必ず事前に宣言するようにしましょう。
なお、「Option Explicit」を必ず出力する設定は、以下の操作を行ってください。
VBEのメニューで「ツール」をクリック
→ プルダウンメニューから「オプション」をクリック
→「変数の宣言を強制する」の選択肢のチェックボックスにチェックを入れる - 変数の宣言は、プロシージャ名の直後に、そのプロシージャ内で使用する全ての変数をまとめて宣言しましょう。
- 変数を宣言する際、基本的にはデータ型に「Variant」は使用しないようにしましょう。
「Variant」を使用しない方がいい理由は、以下の2つが挙げられます。- 「Variant」は全てのデータ型を受け入れることが可能なため、例えば本来はDate型として使用する変数がVariant型であったりすると、そこにLong型やString型の値を入れようとした場合、適切なデータ型で宣言していれば値を入れるタイミングでエラーになるところがエラーにならず、それ以降の処理でエラーとなることが想定されるため、エラーを突き止めるのに困難が予想される。
- 「Variant」で宣言すると、そこで宣言された変数が具体例に何の変数として使用しようとしているか明示的に分からないため、第三者が把握しづらい。
- 例外的に、以下のようなケースでは変数のデータ型を「Variant」にせざるを得ないことがあります。
例)
Match関数の戻り値は、検索値が見つかった場合は数値を戻しますが、検索値が見つからなかった場合はエラー値である「#N/A 」を戻すため、戻り値をセットする変数を宣言する際は、数値とエラー値の両方の値を想定する必要があり、データ型を「Variant」にせざるを得ない。 - オブジェクト変数を宣言する際のデータ型はなるべく「Object」は使用せず、そのオブジェクト変数に対して最適なデータ型で宣言するようにしましょう。
例)ワークブック変数を宣言する場合
:Dim wb_inputfile as Workbook
:Dim wb_inputfile as Object
「Object」を使用しない方がいい理由は、以下の2つが挙げられます。- 「Object」を使用すると、自動メンバー表示ができないため。
- 「Object」で宣言すると、そこで宣言されたオブジェクト変数が具体例に何のオブジェクト変数として使用しようとしているか明示的に分からないため、第三者が把握しづらい。
- 整数の変数を宣言する際は、「Integer」ではなく「Long」で宣言しましょう。
上記の理由は、「現在のExcelシートの最大行数」>「Integerの最大値」のためです。
現在のExcelシートの最大行数 | 1,048,576行 |
---|---|
Integerが取り扱うことができる数値の範囲 | -32,768 ~ 32,767 |
Longが取り扱うことができる数値の範囲 | -2,147,483,648 ~ 2,147,483,647 |
[emalabo式] プロシージャに関するコーディングルール
プロシージャを作成する際は、以下の点に留意して、第三者が読んでも分かりやすいプログラムを目指しましょう。
以下の点を留意するだけでも、バグの発生率や可読性、メンテナンス性は格段に向上すると思います。
- プロシージャが長くなりすぎると、一般的に分かりづらいプログラムとなるため、その場合はプロシージャを分割して、親プロシージャから子プロシージャをCallするようにしましょう。
- 子プロシージャを作成する際、戻り値を返さないプロシージャはsubプロシージャ、戻り値を返すプロシージャはfunctionプロシージャを作成するようにしましょう。
- 親プロシージャから子プロシージャに引数を渡す際は、参照渡し(ByRef)or 値渡し(ByVal)のどちらにするか、留意しましょう。(逆に設定すると、場合によっては想定通りに動作しない場合があります。)
- 第三者がプログラムを読んで、処理の内容を把握しやすくするために、適宜コメントを記述するようにしましょう。
- プログラムを記述する際は、適切にインデント(Tabキーによる段落の作成)するようにしましょう。
通常のステートメントでは1つのインデント、IF文やForループ文などの条件分岐処理や繰り返し処理が発生したら、その配下のステートメントには更に1つインデントを増やしましょう。
IF文などは、ネストの追加・削除が発生することにより、その配下の大量のステートメントを全てインデントする必要が発生する場合がありますが、そのまま放置せず、インデントの追加・削除を確実に実施しましょう。
オブジェクト変数の解放について
コーディングルールから少し外れますが、書籍やネット上の記事で、オブジェクト変数の解放を明示的に行う必要があるかどうか、「必要」という記事と「不要」という記事の両方を見かけます。
オブジェクト変数の解放は、以下の構文となります。
- Set オブジェクト変数 = Nothing
結論から申し上げますと、オブジェクトを解放することにより、ExcelがPCに確保しているメモリを解放することになるので、一般的にはメモリ使用量は減ると考えられますが、その一方でオブジェクトが確保しているメモリの容量は、現在ではPCのメモリの残容量を逼迫させるほどのものではないので、一般的には解放不要と考えられます。
私自身、この数年間で1度もオブジェクト変数を解放するコードを書いていませんが、それが原因でトラブルが発生した記憶はありません。
ただし、全ての場合においてオブジェクトの解放が不要かと問われると、私には断言できないため、詳細に調査が実施されている以下の記事をご参照ください。
[次の記事]