VBAでは、変数の命名に関して次のようなルールがあります。(以下、Excel 2007のヘルプより抜粋)
変数名には、文字 (英数字、漢字、ひらがな、カタカナ) とアンダスコア (_) を使うことができます。スペースや記号は使えません。変数名の先頭の文字は、英字、漢字、ひらがな、カタカナのいずれかでなければなりません。同一適用範囲 (スコープ) 内で同じ変数名を複数使うことはできません。また、変数名の長さは、半角で 255 文字以内でなければなりません。
つまり
ということですね。
4.は、意識する必要はないでしょう。そんな長い名前を使うことは希でしょうし、もしエラーになったとしたら短くすればいいだけの話ですから。
2.と3.は、VBEが教えてくれますので安心です。
指摘されたら別の名前に直しましょう。
1.のように、変数名には日本語(漢字・ひらがな・カタカナなど、いわゆる昔で言う2バイト文字)を使用することができます。
Dim 合計 As Long, 住所 As String
昔は「変数名やプロシージャ名に日本語(2バイト文字)を使うとエラーになったり、誤動作する」と言われていましたし、確かに、エラーや誤動作の原因になりました。Excel 95でも「マクロ記録のプロシージャ名に長音(ー)が含まれていると、操作が記録されない」という不具合がありました。しかし、最近の環境は違います。日本語を使用することで問題が生じたのは、日本語を表す2バイトのコードに、プログラム的に特別な意味を表すコードが含まれていたのが原因です。Excelを作ったアメリカの事情と、複雑な字をパソコンで扱いたいという日本の事情が、うまくマッチしていなかったんですね。しかし、最近のWindowsやExcelは、文字を「ユニコード」という文字コードで扱っています。ユニコードは、半角英数字の"A"や"1"など、すべての文字が2バイトで定義されています。なので、昔のように、日本語(2バイト文字)を扱うことで問題は生じなくなりました。なにしろ、すべての文字が2バイトなのですから。したがって、安心して変数名に日本語を使えます。
もっとも、私はめったに日本語の変数名を使いません。それは、誤動作するからではなく、日本語変換のIMEを切り替えるのが煩雑だからです。
Sub Sample24() Dim 名前 As String 名前 = InputBox("名前を入力してください") If 名前 = "" Then Exit Sub If InStr(名前, " ") > 0 Then Range("A1") = Left(名前, InStr(名前, " ") - 1) Range("B1") = Right(名前, Len(名前) - InStr(名前, " ")) End If End Sub
というようなコードを入力するとき、ひんぱんにIMEのオン/オフを切り替えるのは、プログラミングの思考が妨げられるだけでなく、IMEの切り替えを忘れて誤入力をすることが多いです。私は。ですから、個人的には、そうした理由で、日本語を使った変数名は使っていません。
変数の名前には、その変数が何を表しているか、その変数にどんな内容の値が格納されるかが分かるような名前をつけましょう。たとえば、次のコードをご覧ください。
Sub Sample25() Dim X As String, Y As String X = InputBox("名前を入力してください") Y = InputBox("住所を入力してください") '' : '' 何かの処理 '' : Range("A1") = X Range("B1") = Y End Sub
InputBoxを使って、ユーザーから名前と住所を受け取ります。それぞれを、変数Xと変数Yに入れて、後で変数に入れた値をセルに書き込んでいます。プログラム的には、何も間違っていません。しかし、
Range("A1") = X Range("B1") = Y
の部分を見て、間違いなく「セルA1に名前」「セルB1に住所」が入力されると分かるでしょうか?変数Xに何が入っているか知るには、ずっと上の、InputBoxのあたりを確認しなければなりません。もしこれが、
Range("A1") = Y Range("B1") = X
と書かれていても、それが間違っているようには見えません。では、これを次のような変数名にしたらどうでしょう。
Sub Sample26() Dim UserName As String, UserAddress As String UserName = InputBox("名前を入力してください") UserAddress = InputBox("住所を入力してください") '' : '' 何かの処理 '' : Range("A1") = UserName Range("B1") = UserAddress End Sub
「セルA1に名前」「セルB1に住所」を入力しているというのが、コードを見ただけで分かりやすくなりました。「セルA1に名前」「セルB1に住所」というルールさえ理解していれば、次のコードは間違って見えるはずです。
Range("A1") = UserAddress Range("B1") = UserName
コードの可読性を高めるために必要な考え方のひとつは、間違っているコードは、間違って見えるように書くということです。そのために「変数名に意味を持たせる」というのは、とても有効な手段です。
変数名に意味を持たせる目的は「可読性を高めるため」です。可読性を高めるのが目的なのですから、ただ単に、意味のある変数名を使えばいいのではありません。間違えてはいけない"重要な変数"が、重要に見えることも大事です。
Sub Sample27() Dim LoopCounter As Long, TemporaryString As String, UserName As String For LoopCounter = 1 To 100 If Cells(LoopCounter, 1) <> "" And InStr(Cells(LoopCounter, 1), " ") > 0 Then TemporaryString = Cells(LoopCounter, 1) UserName = Left(TemporaryString, InStr(TemporaryString, " ") - 1) Cells(LoopCounter, 2) = UserName End If Next LoopCounter End Sub
変数LoopCounterは、確かにForループで使うカウンタ変数です。名前としては間違っていません。また、変数TemporaryStringは文字列を一時的に格納する変数ですから、これもネーミングは正しいです。しかし、どちらもここでは"重要でない"変数です。重要でない変数にまで意味のある名前を付けた結果、重要な変数が埋もれてしまい、コード全体の可読性は、逆に低下しています。重要な変数が"重要に見える"ようにするには、重要でない変数の名前を簡素化するのがポイントです。次のコードと見比べてください。
Sub Sample27() Dim i As Long, tmp As String, UserName As String For i = 1 To 100 If Cells(i, 1) <> "" And InStr(Cells(i, 1), " ") > 0 Then tmp = Cells(i, 1) UserName = Left(tmp, InStr(tmp, " ") - 1) Cells(i, 2) = UserName End If Next i End Sub
後で解説するように、For Nextで使うカウンタ変数は、アルファベット小文字の「i」「j」「k」を使うのが一般的です。Cells(i, 1)というコードは、決して可読性が悪いわけではありません。であるなら、何も「変数には意味のある名前を付ける」ことにこだわって、Cells(LoopCounter, 1)とする必要はありません。可読性を高めるという目的を見失わないようにしてください。
重要な変数を目立たせるには、重要でない変数に簡素な名前を使うのがポイントです。ここでは、そうした"重要でない"変数に、一般的によく使われる変数名をご紹介します。なお、ここで紹介する変数名は、絶対的なものではなく、こういう名前を使うことが多い…というレベルです。また、私の個人的なクセや経験にもよります。
Dim buf As String buf = Range("A1")
Dim tmp As Variant tmp = Split(buf, ",") if tmp(1) = "" Then Exit Sub
Dim i As Long, j As Long For i = 1 To 10 For j = 2 To 5 Cells(i, j) = "tanaka" Next j Next i
Dim i As Long, cnt As Long For i = 1 To 100 If Cells(i, 1) = "田中" Then cnt = cnt + 1 End If Next i MsgBox "田中は、" & cnt & "件です"
Dim msg As String, buf As String msg = "住所を入力してください。" & vbCrLf & _ "東京都の方は区からでけっこうです。、" & vbCrLf & _ "その他の方は道府県名を省略しないでください。" buf = InputBox(msg) If buf = "" Then Exit Sub msg = "住所は" & vbCrLf & buf & "ですね。" & vbCrLf & _ "この住所は、後で変更できます。" MsgBox msg, vbInformation
Dim flag As Boolean, i As Long For i = 1 To Sheets.Count If Sheets(i).Name = "合計" Then flag = True Exit For End If Next i If flag = True Then MsgBox "[合計]シートは存在します" End If
Dim n As Long, i As Long n = Cells(Rows.Count, 1).End(xlUp).Row If n > 1 Then For i = 2 To n Cells(i, 1).Font.ColorIndex = 3 Next i End If
変数の名前に関するルールのひとつに「ハンガリアン記法」と呼ばれるものがあります。ハンガリアン記法の詳しい解説は割愛しますが、簡単に言うと「変数名の先頭に、その変数の型を表す文字を付ける」というルールです。たとえば、文字列型(String)であれば「str○○」、長整数型(Long)の変数であれば「lng××」などのように。こうしたハンガリアン記法に関しては賛否両論で、最近では否定派が多いように感じます。
私も、どちらかと言えば、ハンガリアン記法に関して否定派です。特に、Excel VBAにおいては不要だと感じます。
そもそも、ハンガリアン記法が推奨された理由のひとつは「誤りが誤って見えるように書く」ということです。たとえば、C#で、次のコードはエラーになります。
private void sample() { string strBuf = "100"; int intBuf = 0; strBuf = strBuf * 2; intBuf = strBuf; MessageBox.Show(intBuf); }
文字列型の変数を計算したり、整数型の変数をMessageBoxで表示しようとしているからです。確かにC#では、文字列型の変数を計算したり、整数型の変数をMessageBoxの引数に指定することはできません。型が違うからです。
では、VBAではどうでしょう。
Sub Sample28() Dim strBuf As String, lngBuf As Long strBuf = 100 strBuf = strBuf * 2 lngBuf = strBuf MsgBox lngBuf End Sub
文字列型変数(strBuf)に数値を代入したり、その文字列型変数(strBuf)を計算してもエラーになりません。また、本来MsgBoxの引数には文字列を指定しなければなりませんが、長整数型(lngBuf)を指定してもエラーになりません。VBAでは、データの型が自動的に変換(キャスト)されます。良くも悪くも、これがVBAの特徴なのです。であるなら、変数が文字列型か長整数型かを明記することは、あまり意味がないように感じます。何しろ「strBuf = strBuf * 2」は間違っていないのですから。また、VBAにはすべての型を格納できるバリアント型(Variant)という型があります。バリアント型には文字列でも、数値でも、オブジェクトでも格納できます。そのバリアント型変数が「varBuf = varBuf * 2」のように使われていたとき、これが誤っているかどうかは、コードを見ただけで判別できません。
変数名に、変数の型を示す文字を付けるより、その変数が何に使われるかを明確にすべきです。「strBuf = strBuf * 2」は正しいコードかもしれません。しかし「UserName = UserName * 2」は、どう考えても間違っていると思います。
いわゆる、システムハンガリアンではなく、アプリケーションハンガリアンの考え方なら、私も賛成です。システムハンガリアンとアプリケーションハンガリアンについては・・・各自ネットなどで検索してくださいな。