和風スパゲティのレシピ

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

英訳してはいけない変数名第2位「列見出し名」

今回は日本語変数に関するお話です。


さて、英訳してはいけない変数名第1位は「ワークシート」でした。

www.limecode.jp


続きの話なので、先にこちらから読んでいただけると嬉しいですが、
本記事だけ読みたい方向けにざっくり流れだけ書くと、

  1. ExcelVBAの主役となる「ワークシート」は、「ソースコードとワークシートを交互に見ながらマクロを実行」するくらい密接な関係。
  2. つまり、「ワークシート名もソースコードの一部
  3. プログラミング全般に言えることだが、同じ処理、同じオブジェクトは、同じ単語に統一して命名しなければいけない


よって、同じオブジェクトを表すソースコード同士と言える、

ワークシート名

シートオブジェクト名

この二つの名称を不一致させてはいけません。


という論旨でした。



今回主張したいことも、全く同じ話です。



ソースコードとにらめっこしながらマクロを作るであろう、

列見出し名

こいつもソースコードみたいなものですので、
 

Enum CNoデータ
    品物 = 2
    価格
    個数
    売上
End Enum

ここと名前を一致させてください。


というお話です。



細かい理由はワークシートと全く同じなので、先ほどの記事を読んでみてください。

本記事では実務上の注意点だけを書いていきますね。

列番号を定数化する場合

先ほどあげた、

Enum CNoデータ
    品物 = 2
    価格
    個数
    売上
End Enum

これは、列番号を定数にしたもので、
 

Const データの列_品物 = 2
Const データの列_価格 = 3
Const データの列_個数 = 4
Const データの列_売上 = 5

これと同じものだと思ってください。


実際にコードを書く時も、

見出し名メンバー候補

と、「.」から選べるメリットが追加されているだけで、
他は普通の定数と変わりません。


Enum(列挙型定数)は列番号の定数定義に非常に便利なので、
もし知らなかった方は、この機会に覚えてしまってください。


何が非常に便利かっていうとですね。

「品物=2」以降は、3,4,…と連番が自動で振られるおかけで、

  1. 見出しをコピー&適当なセルに行列を入れ替えてペースト
  2. 縦になった見出しをコピーしてVBEに張り付け
  3. 上にEnum CNoシート名、下にEnd Enumを書く

これでEnumの定義が終わっちゃうんですよ。


頑張ってノーミスで撮影できるまでトライしたgifを見てください。

TAKE24

Enum定義の作成アニメ

 

  • 空のセルが1Tab分のインデントになる
  • えcという読みでEnum CNoを変換するズルをしている
  • 本当は品物に「 = 2」を入れなければいけないが、撮りなおすのが面倒

がどうでもいいポイントです。


それで、実際のコードも、

見出し名メンバー候補

ここから選択できるので、日本語入力もONにしなくていいですし、


この入力選択肢も、

列見出し名

これと一致してるわけだから、素早く正確に入力ができるわけです。


最強でしょ?



日本語変数の最大の弱点は、「入力が面倒なこと」です。


日本語変数信者の私でも面倒だなと思ってるくらいなので、
使い捨てマクロだと、半角で書くことは普通にあります。


しかし、このEnumが半角英字になることは絶対ありません。


アニメ用にCtrl+CとVすら縛っても20秒足らずで作れて、
実際のコード入力もすべて選択肢(半角入力のまま)なんですから。


流石に「日本語の方が入力も楽」という場面では、日本語を使っていきましょう。

データを変数に記憶させて処理する場合

例えばループ処理で、

For R = 2 To 10
    売上 = Cells(R, 5)

    If 売上 > 1000 Then
        ~~売上がそこそこの時の処理

    ElseIf 売上 > 10000 Then
        ~~売上がなかなかの時の処理

    ~~以降ループ処理

Next

こんな風に書くことがあると思います。


この「売上」も、列見出し名と一致させておくべき変数名です。


どの列を指しているのかが明確でいいのはもちろんなのですが、

一致しない名前の変数を使用した場合は、

Sales = Cells(R, 5)

このコードが、ループの下部からは視認できないため、

ElseIf Sales > 10000 Then

と書いてあった時に、これがどの列を対象としているのかを調べるのが少々面倒というデメリットもあります。


定数なら「Shift + F2」で定義位置まで飛べるのですが、

Sales = Cells(R, 5)

これはシステム的にはただのコードと変わらないため、
完全に目視で探しに行かなければいけません。


間違いの元ですし、代入コードを探すのも面倒なので、
こういった現データを記憶する変数も、列見出し名と一致させておきましょう。



ただ、列名と完全に一致させた「売上」という名前だと、

Enum CNoデータ
    品物 = 2
    価格
    個数
    売上   ' ←こいつと被る
End Enum

このEnum要素と命名が被るのが、ちょっとした罠を生みます。


ということで、私は「現ループ:Current」を意味するCurを接頭し、
「Cur売上」のような変数名にしています。

For R = 2 To 10
    Cur売上 = Cells(R, 5)
    Cur品物 = Cells(R, 2)

    If Cur売上 > 1000 Then
        ~~売上がそこそこの時の処理
    End If

    If Cur品物 = Prev品物 Then
        ~~同じ品物が連続したときの処理
    End If

    Prev品物 = Cur品物
Next

こんな感じで、「Prev」「Cur」「Next」を接頭して、
ループの前後条件を表現すると見やすいかなと。


まあこのくらいだと

If Cells(R, 2) = Cells(R - 1, 2) Then

で十分ですけどね。

「前,現,次」の遷移が複雑なループでは、この手法を取ります。


ちなみにこれをやると、Cur + Ctrl + Space で候補から入力できるので、
例によって、日本語入力をOFFのままキー変数を扱えます。


別に接頭する英字は今を表す「Now」とかでもいいと思います。
(ちょっと違和感あるけど)

お好きなものを使ってください。

列見出しは本当にソースコードになることもある

頻出の基本コードの話は↑で以上です。


ここまでは、

列見出し名

これもソースコードみたいなものなんだから一致させましょ?

という話でしたが、これが本当にソースコードになることもあります。


先ほどの表に、このように↓

テーブルを設定

「テーブル」機能を設定します。


このテーブル上では、

Dim テーブル As ListObject
Set テーブル = ActiveSheet.ListObjects(1)

Dim 売上列 As Range
Set 売上列 = テーブル.ListColumns("売上").DataBodyRange

このように、列見出し名でRangeオブジェクトを取得することができます。

この指定ができるという機能を保持するため、
「テーブル」は同じ名前の列見出しを許しません。


「ピボットテーブル」もそうですよね。
列見出し名を使って集約を行う機能ですし、同じ見出し名を許しません。


要はMicrosoftさんも、見出し名で列を指定する想定で、
表形式データの機能を作っているわけですよ。


この辺の機能を使うときにも、変数と見出し名の一致は重要になりますから、
列見出し名はそのままの名前で、大事に扱ってください。

まとめ

今回は、英訳してはいけない変数名第2位「列見出し名」ということで、

  • Enum定数をはじめとした、列番号の定義
  • 表中のデータを格納する変数名
  • テーブルなど直接見出し名を指定する機能

を、見出し名とキッチリ一致させましょうというお話でした。


ちなみにこの「列見出し名をそのまま使ったEnum定数」の作成は、
機械的な作業であるため、マクロにやらせることもできます。


興味がある方はこちらの記事を是非。

www.limecode.jp

おまけ:日本語はシステム用語と絶対にかぶらない

例えば今回の表を、

Enum eFruitsCol
    Product = 1
    Value
    Count
    Sales
End Enum

こうされていると、英訳とは別の困ったことが生じますよね?


「ValueとCountが既存の用語とかぶる」ため、例えば

Set CurValue = Cells(R, eFruitsCol.Value)

このコードを見て、ぱっと見CurValueがRange変数に見えません。


こういった問題を避けるためにも、
英訳は「Price」や「Quantity」をあてるべきです。


この点、日本語の変数は絶対にプロパティ名と被りませんので、
何でもやりたい放題というメリットがあります。


これに関連した日本語変数の重要なメリットとして、

英語 オブジェクトやプロパティを表すシステム名
日本語 業務やデータを表すビジネス名

と、はっきり分かれてくれる利点が挙げられます。


しかも「変数名」と「プロパティ名」が分かれてくれるだけでなく、
先ほどの「Cur売上」や、「GetRange対象商品」のように、

変数名の中でシステム/ビジネスを分割命名することもできます。

  • プログラムの構文をチェックしたいときは英語部分を読む。
  • 全体的な処理の流れを追いたいときは日本語部分を読む。

というコードの読み分けができるのも、使ってみるとわかる日本語変数の良さです。

是非お試しを。



最後にどうでもいい余談になりますが、私はこのメリットを、

母国語でなくてもスラスラコードを読めるようになった上級者にも利点がある、
日本語変数(母国語がアルファベットでない言語)の重要なアドバンテージ

だと思っています。

構文 世界共通言語
識別子 母国語

こそが、全人類が目指すべき理想郷だと思っています。



とういことで私は、

If → もし、Then → なら 、と書くような、
日本語プログラミング言語については割と否定派です。


めんどくさいやつめ。



たまに日本語プログラミング言語への批判を私に寄越す方がいらっしゃいますが、

「だよね~わかるわかる(´∀`)」

としか返せませんのであしからず。



私が美しいと思っているのは、

If is日本語変数を使う Then みんな.Get(幸せ)

この和洋織り交ぜたコードです。


かなりどうでもいい身の上話でしたが、一応、お含みおきください。