和風スパゲティのレシピ

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

アプリケーションハンガリアン+日本語は最強の変数名だ

アプリケーションハンガリアンと日本語変数はとっても相性が良くて、
キーボードの日本語入力をOFFのままで日本語変数を使えるよ。

というお話です。

お忙しい方のために、最終目的のgifアニメを張ります。

アプリケーションハンガリアン日本語変数の入力アニメ

便利そうですよね?
キーボードは一度も日本語入力ONになっていません。

やり方はものすごく簡単です。

「何の変数?」を表す英語を接頭するルールで命名し、
その英語を打ったら、「Ctrl + Space」で候補を呼び出しているだけです。

便利!と思っていただけたなら使ってみてください。

では解説に入ります。

ハンガリアン記法とは

ハンガリアン記法とは「変数の名付けルール」のひとつです。
Long売上やString商品名など、変数の型を接頭(先頭に付ける)するルールです。

Long売上 + String商品名 のように、「間違ったコードが間違って見えること」が売りらしいです。


しかし、残念ながらこの記法はものすごく嫌われています。
面倒だし、見づらいし、ちゃんとした変数名を付ければいらんやろっていう。


たしかに言われてみれば、売上 + 商品名 でも十分すぎるほど間違って見えます。

たいしたメリットがあるわけでなく、争いの火種になるだけなので、
ハンガリアン記法での変数名づけはやらない方がいいです。

アプリケーションハンガリアン記法とは

ハンガリアン記法を編み出したハンガリー人のシモニーさんは、
何も「変数の型をつけろ」と言っていたわけではないのです。

シモニーさんは「名前で表現しきれない意味を付けろ」と言っていました。

例えば、

dolニューヨーク支店の売上 + yen東京支店の売上

こういうことです。

たしかにLongと違ってこっちは便利ですね。
データの型だけでは気づきにくいバグを見つけることができます。


こっちの「意味をつけようね」タイプの接頭詞を、さっきのハンガリアンと区別して「アプリケーションハンガリアン」と呼びます。
こちらは嫌われていないというか、むしろ推奨されている環境も多いみたいですね。

ちなみにさっきの「変数の型をつけようね」タイプを区別して呼ぶ場合は「システムハンガリアン」と呼びます。

  • システムハンガリアン … 変数の型をつける ⇐NG
  • アプリケーションハンガリアン … 変数の用途や意味をつける ⇐OK

が、今のプログラミング世界の主流の考えのようです。


なお、単に「ハンガリアン」といった場合は、
(考案者の意図に反して)先に広まったシステムハンガリアンを指します。

「ハンガリアン使うよ!」っていうと猛反対されるので、
しっかりと「アプリケーションハンガリアン使うよ!」と言うようにしましょう。


シモニーさんは自分の説が勘違いされて広まった挙句、
ハンガリー = 悪 みたいに祖国が貶められていて不憫でならないですね(´・ω・`)

日本語とハンガリアンの相性の良さ

上の例ですでに感じた方もいるかもしれません。
英語のハンガリアン + 日本語の変数名は、区切りがはっきりしていてとても見やすいです。

Wikipediaのハンガリアン記法のページで使われているサンプルコードを日本語化して比べてみると一目瞭然です。

dolIncome + yenDeposit
dol収入 + yen預金

日本語部分だけで意味が通じるため、ハンガリアンの弱点である冗長さが、かなり軽減されるのがわかります。

さらに、コードを読み解く際には、

  • 英語:「何のオブジェクト?プロパティ?」っていうシステム的な意味づけ
  • 日本語:「何の業務?帳票?」っていうビジネス的な意味づけ

と、文字の種類で役割が分かれるため、プログラムの構文をチェックしたいときは英語を、処理の流れを追いたいときは日本語を読むといった、読み方の違いを活用することができます。

自動メンバー候補(単語の予測入力)機能

さて話は変わりますが、VBAには途中まで書いたコードの残りを埋めてくれる素晴らしい機能があります。
そんなのどの言語にもあるとか言わない。

単語を途中まで書いて「Ctrl + Space」を押します。
すると、右のように候補が表示され、↑↓で選んでTabを押すと、残りの部分が入力されるのです。
(候補が一つしかなければCtrl + Spaceを押した瞬間残りが入力されます)

これを「自動メンバー表示」と呼びます。

長い単語を正確に書くのは面倒なので、
最初の3文字ほど書いたら、残りはこの機能で補完する癖をつけましょう。タイプミスも減ります。

日本語入力をONにしないで日本語変数を入力する

ようやく冒頭の話に戻りましたが、
アプリケーションハンガリアンと入力補完機能を組み合わせることで、
日本語入力をOFFのままで日本語変数を使うことができます。

例えばマクロ内で使用されるワークシートを、「必ずwsで始める」ルールで命名します。

Dim ws領収書 As Worksheet
Dim ws購入歴データ As Worksheet
Dim ws集計表シート As Worksheet

この時、「ws」だけ入力して自動メンバーを起動すると、↓のリストが表示されます。

アプリケーションハンガリアンからの予測入力

ワークシートを呼び出したいとき、「ws」でこの選択肢を出せるようになるのです。
すごく便利ですね。

他にも、「行番号(RNo)」「列番号(CNo)」「セルアドレス(Adrs)」などのようにルールを自分で決め、
エクセル固有の変数にアプリケーションハンガリアンを割り当てれば、冒頭のgifのように入力することができます。

アプリケーションハンガリアン日本語変数の入力アニメ

日本語変数の弱点である「入力の面倒さ」がかなり軽減されますし、
変数の呼び間違いによるバグもだいぶ減らせます。

このようにアプリケーションハンガリアンと日本語変数は相性が良く、
便利だし見やすいし言うことないので、積極的に使っていきましょう。

おまけ:私が使っている接頭詞の例

私がアプリケーションハンガリアンの接頭詞にどんなものを使っているかを紹介します。

※ 変数名に大事なのは日本語部分で、接頭するハンガリアンはぶっちゃけなんでもいいので、ここから先は読む必要はありません。あくまで参考に。

行番号・列番号

RNo ' 行番号(Noはナンバーの意)
R1st ' 第1行
RLast ' 最終行
CNo ' 列番号
C1st ' 第1列
CLast ' 最終列

いきなりですが、Row、Columnではないです。

  • Rowだと、行全体「Rows」を格納したRange変数と混同しやすい。
  • Columnは、Color,Collectionなどの頭文字被りが多く、Colの時点でまだ列関係の変数が出てきてくれない。
  • 逆に子音2文字で始める接頭詞は、他の単語と被らず予測能力が高い。
  • 子音2文字なら、日本語入力ONでも打てる(ろw、こlだと予測が出ない)

が主な理由です。

ただし、着目しているワークシートが明確な場合は、「R」「C」の1文字変数を積極的に使います。
変数名を完璧に書きすぎると、しつこくなって逆に読みづらくなるので、適度に情報を断捨離しましょう。

使用例
Dim R as Long
For R = R1st売上シート To RLast売上シート

    Call 商品マスタから値段を取得する(ws売上シート.Cells(R, CNo売上シート.商品コード))

Next

ちょっと雑談

余談ですが、このブログを公開する際、このRNo,CNoという我流をどうするか悩みました。
普段書いているコードはすべてRNo、CNoで書かれているのですが、説明なく書くのはわかりづらい気がして。

なので、Row, LastRow, FirstRowに置換してから公開しようとも思ったのですが、

  • コードを下手に変えることで、コピペで動かないマクロを世に出してしまうのが怖い
  • Cells(R○○, C△△)という配置がとても見やすい ⇒ 頭文字がRじゃないLastRowは嫌い

という理由で、我流のまま公開することにしました。

特に「CNoくだもの売上表.品物」みたいな列挙型の列番号がこのブログには断りなく登場します。
そのせいで、読みづらかったら、ごめんなさい。

行数・列数

RCount ' 行数
CCount ' 列数

行数は「RLast - R1st +1」で計算できますが、
よくあるこの「+1」が入る計算は、使えば使うほど読みづらくなるので、しっかり変数にいれて処理しましょう。

ブック・シート

wb ' ブック
ws ' 変数で扱うシート
WS ' オブジェクトを直接命名した固定シート

ブックとシートはそのままですね。
「定数は頭文字を大文字」という英語の慣習に倣い、固定シートは大文字で表現しています。


ちなみに、このブック・シートの名付けに多いのですが、
ハンガリアン部分と日本語部分で意味が被っても問題ないです。

  • wb処理ブック > wb処理
  • wsデータシート > wsデータ

どちらも前者の方がわかりやすいですよね。
頭痛が痛いのは気にしなくてOKです。

セル(Rangeオブジェクト)

cell ' 単独のセル
area ' セル範囲
row ' 行
column ' 列

アプリケーションハンガリアンの真骨頂ですね。
Rangeオブジェクトだからと、全部Rangeを接頭するシステムハンガリアンではダメ。

Rangeを扱う変数は、使う場面によって、

  • 単独のセルを処理する
  • 指定の範囲を処理する
  • 1行×n列の「行データ」を処理する
  • n行×1列の「列データ」を処理する

が、明確に分かれるオブジェクトです。
きっちり分けて、コードを書きましょう。

セルアドレス

' 定数の宣言
Const Adrs領収書_日付 = "D2"

' 処理内の記述
ws領収書.Range(Adrs領収書_日付)

↑のように、Range("A1")の"A1"部分を文字列の定数/変数で扱うことができます。

ただし、ブック・シートが固定のセルアドレスについては、

Function Cell領収書_日付() As Range
    Set Cell領収書_日付 = WS領収書.Range("D2")
End Function

このように「Functionで定義するけど、定数だと思って使う」なんちゃって定数を使うことの方が多いです。

真偽値Boolean

is変数名 ' Boolean変数
Is関数名 ' Booleanを返す関数

英語的な文法が間違ってようが全部「Is」にしました。
「Exist」とか「Has」とか使ってたこともあったけど、あんまりメリットがないです。

こんなブログを好んで読んでいる皆さまは、英語の文法なんて気にせずぜんぶisに統一したほうがいいでしょう。
「Isシートが存在する」でOKだと思います。

Booleanの変数名はなるべく長く正確に

Booleanを扱う上で重要なのが、日本語の部分はとにかく長くした方が分かりやすいという点です。
計算するような値ではないので、超長い変数名でも特に問題ありません、

BooleanのTrue/Falseは、あいまいになりやすいことが多く、複雑な条件の判定にも使います。

「isエラーチェック」とかは最悪で、何のエラーかわからない以前に、
そもそもエラーがあるのがTrueなのかFalseなのかすらわかりません。
「isユーザーのセル入力値に不備がある」などのように、しっかり命名しましょう。


ちなみに最近書いたものの中で一番長かったのが↓

If Is10月1日を過ぎても契約都合で消費税8で計算するデータ(取引ID) Then

Is消費税8データ なんて略していると、来年見たときさっぱりわからなくなります。
こんなに長くても「i s 1 0 Ctrl Space Tab」の7キーで入力は完了しますので。

まとめ

いろいろ脱線してしまったのでもう一度本題に。

  • アプリケーションハンガリアンで書いた日本語変数は、区切りと役割がはっきり分かれて読みやすい
  • 日本語入力をOFFのままで日本語変数を入力できる

というお話でした。

アプリケーションハンガリアン日本語変数の入力アニメ

どんな接頭詞が良いかは、よく作るマクロによっても変わるので、自分なりに読みやすいものを研究してみてください。