和風スパゲティのレシピ

日本語でコーディングするExcelVBA

VBAではカウンタ変数に「i」を使うな

読みやすいコードの書き方に関する小ネタです。


単刀直入に、何が言いたいかというとですね、

Dim i As Long
For i = 2 To 100
    Cells(i, 1) = Cells(i, 2) + Cells(i, 3)
Next

↑これをもうやめて、

Dim R As Long
For R = 2 To 100
    Cells(R, 1) = Cells(R, 2) + Cells(R, 3)
Next

↑こうしませんか?という話です。

たまには挑戦的なタイトルにしてみましたが、別にi全否定ではないです。
配列の添字とか、純粋なカウンタは、もちろんiでいいと思います。


でもですね。
行番号をわざわざiにする必要はないと思うんですよね。


こっちのがわかりやすい!

って賛同してくれた方は、今日からこっちを使ってみてください。

列番号にjを使うと死にます。

行番号だけならまだしも

Cells(i, j)

↑これは絶対やめましょう。

Cells(R, C)

↑絶対にこっちがいいですよ。

特に日本人は。


行と列をどっちも変数にしなければいけないような込み入った状況で、
iとjという、似ているアルファベット選手権の優勝コンビをわざわざ使うとか、
自らバグを呼び込むようなもんです。

Cells(,)

っていうコードを外人に書かせたら、絶対災害が起きますよ。

iが使われたコードはコピペ合体できない

' すべてのシートに○○する
Dim i As Long
For i = 1 To Worksheets.Count
    Worksheets(i). ~~

というコードと、

' A列の全データを○○する
Dim i As Long 
For i = 2 To 10
    Cells(i, 1) =

というコードがあったとき。


これ、コピペしてくっつかないんですよね。


本質的にはプロシージャを分けるべきなんですが、
非プログラマが多いVBAユーザーにいきなりプロシージャ分割は敷居が高いでしょうし。


それでその結果、初心者は行番号がjになるんですよ。
かわいそうに。

カウンタ変数は、何のカウンタかわかるように命名する

冗談はこれくらいにして、ちょっと真面目な考察を。

Excelの各機能、特にワークシート・セルと密接にかかわるVBAは、
カウンタを必要とするオブジェクトを「複数」扱う場面に出くわしやすいです。

「ワークシートからワークシートへのデータの集計」だったり、
「ブック内すべてのシートの中のすべての○○」だったり。


なので、カウンタも最初から分けておいた方がいいと思うんですよね。

ネットのサンプルコードが

Dim シート番号 As Long
For シート番号 = 1 To Worksheets.Count
    Worksheets(シート番号). ~~

Dim R As Long 
For R = 2 To 10
    Cells(R, 1) =

って書かれていたら、コピペし放題で、何個使っても可読性も損なわれないので、
幸せになる人が多いと思うんですよ。


特に、シート番号をiでループするのは、
変数名を極端に省略してはいけない
省略していいのはスコープが短いものだけ
という現代のコーディング規約に抵触している気がします。


ワークシートは、セルなどの子オブジェクトを無数に持つ巨大な親オブジェクトです。
つまり、WithとかForとかが入れ子になる可能性が極めて高いオブジェクトなわけです。
結果的にシートのカウンタは、長大なスコープを持つ可能性があるわけです。

それをiにするのは、割とタブーなのでは…?


ということでまとめると、

複数のオブジェクトを平行して処理する場面が多いExcelVBAにおいて、
カウンタ変数は、何のカウンタかわかるように命名する
ことは、とても重要な命名規則なんじゃないかと思っています。


入門者向けのサンプルコードなんかでは、
シート番号、行番号(R)、列番号(C)、図形番号、グラフ番号…
という命名を暗黙のルールにして、iを教えるのは「配列」あたりでよいのでは?

超絶便利な2次元配列「ワークシート」があれば配列なんて使わないから、iは一生教えなくてよいのでは?

まあ既存のコードを読むときに必要だから、実際はすぐに教えますけどね。

おまけ:変数名のつけ方

例えばグラフ番号をGraphNoとかにするのは、iとは別の理由でダメです。

そのグラフをよーく見てください。
グラフの中身は日本語だらけじゃないですか?

Excelと密接にかかわるVBAにおいて、「ワークシートが日本語だらけ」の時点で、
変数名だけ英語にしたって、どうぜ外人には読めません。

ましてあなたがプログラマでもなく、チームで開発なんかしない模範的VBAユーザーであるならば、変数を英語にする意味はまったくありません。
堂々と Dim グラフ番号 As Long と命名してください。

本編とまったく違う話ですが、
このブログのメインテーマなので隙あらば取り上げます。

おまけ:ワークシートは配列じゃなくて座標だと思う

はじめてこの話をしたとき、つべこべ言ってないでiとかjに慣れろと言われました。

私は理学部数学科の出身なので、割と死ぬほどiやjを使って来たと思っていますが、
まだまだ足りないのかもしれません。

さて、数学的に見ても、セルアドレスにiとjは、やっぱり違和感があります。

セルは添字で表現するような数列的なものでなくて、
x軸、y軸みたいな、座標的なものだと思うので、
Row軸とColumn軸の変数は、やっぱりRとCだと思います。

おまけ:rとRはどっちがいいの?

どっちでもいいと思います。

変数は小文字の方がしっくりくる方は、rでいいと思います。

私がRにしているのは、R1C1形式とか、.Rowとか、
既存の行関係の用語がほとんど大文字Rから始まるので、
合わせたほうが見やすいと思ってそうしています。

お好きな方でどうぞ。