Visual Basic 業務アプリ構築法 第24回

分かりやすいコーディングの工夫(1) ~
変数の適切なデータ型と分かりやすい名前

長谷川裕行
2000/04/11

長谷川 裕行 (はせがわ ひろゆき)
有限会社 手國堂 代表取締役
http://www.hirop.com/
テクニカルライターとして活躍。プログラミングに関する著書多数、DB Magazineなどにも多くの記事を提供している。

気軽にプログラミングできるのがVBの大きな特徴ですが、業務で使用するアプリケーションとなると、行き当りばったりに組み上げる訳にはいきません。特に、後々の保守を考えて、分かりやすいコードを書くことが非常に重要です。今回から数回に分けて、分かりやすいコードの書き方を考えていきます。


VBだからお気楽…という訳ではない

思い立ってすぐに統合環境を動かし、フォームをデザインする…といった使い方も可能なVBですが、事前設計は重要です。名前の設定や処理の設計を適当に済ませてしまうと、必ず後悔することになります。


- VBでもコードの記述は重要 -


VBでは、まずフォームにコントロールを貼り付けるところからプログラミングが始まるため、「ソースコードを記述する」という従来の(他のプログラミング言語の)スタイルとは異なるような印象があります。
しかし、フォームをデザインしただけではアプリケーションが作れない…ということは、ご存じのとおりです。デザインしたフォーム上のコントロールがユーザーの操作に反応し、内部で処理を行うようにするには、やはりソースコードを記述しなければなりません。
VBだけではなく、そもそもWindowsプログラミングでは、
  外観(ウィンドウ)のデザイン
  内部処理のコーディング
という2つの工程が必須となります。VBが簡単にしてくれているのは、
  外観のデザイン工程

  デザインした外観(フォーム)と内部処理を
  結び付ける作業
です。ソースコードの記述作業まで、他の言語に比べて簡単…という訳ではありません。他の言語同様の注意が必要です。

- 適切な名前と読みやすいコード -

VBでは「フォームにコントロールを貼り付けて、ソースコードを書くだけ」というイメージが強いので、内部処理の設計もそこそこに、統合環境を動かして即座に開発作業に入ってしまう人もいます。
慣れてしまえば、事前設計を省略して「統合環境内で考える」「作りながら考える」というスタイルを採ることも、不可能ではありません。が、行き当りばったりのプログラミングは、後々の手直しや改良で混乱を生じる原因ともなります。
 特に重要なのは
  適当に設定したデータ型
  適当に付けた変数名
  適当に付けたオブジェクト名
など命名に関する部分です。
 また、
  構造化されていないプロシージャ
  読みにくいソースコード
も問題となります。
これらについて、「どこがどう問題となるのか?」「どのように対処すればよいか?」を考えていきましょう。最初は「変数名とデータ型の問題」からです。


データ型を適当に割り当てるとどうなるか?

変数の宣言では、データ型を正しく指定することが重要になります。適当なデータ型を割り当てるとどうなるかを、考えてみましょう。


- VBで利用できるデータ型 -

数値を保存する変数はすべてInteger型…などとする人はいないと思いますが、変数の保持できる値の範囲を意識しない人はいます。
特に、汎用機やオフコンでCOBOLを扱っていた人には、「適切なデータ型」の概念に弱い人が目立ちます。ここで、もう一度VBで利用できるデータ型の一覧を掲げておきましょう。

表1:変数のデータ型


- オーバーフローに注意 -

例えば、1回の処理件数を保存する変数をInteger型で宣言したとします。Integer型は32,767までの整数しか保存できません。あるとき、処理件数が32767に達したとします。あと1件処理をすると、画面1のようなメッセージが表示され、プログラムは実行時エラーで停止してしまいます。
オーバーフロー(overflow)とは桁溢れのことです。コンピュータはメモリ上の特定の領域にデータを格納するため、その領域をはみ出して値を保存することはできません。
C言語などデータのチェックが緩やかな言語では、このようなとき
  32767に1を加えたら-32768になる
といった、人間にとっては不思議な現象が生じます。しかしVBでは、変数の値が保存できる範囲を超えると、上記のようなメッセージを出して処理が止まります。
リスト1のコードを試してみてください(サンプルの[桁溢れ]ボタンに登録してあります)。

画面1:変数の保持できる範囲を超えると処理が停止する
リスト1:桁溢れのテスト

この処理を実行すると、イミディエイトウィンドウに
1 : 32766
2 : 32767
まで表示され、先の画面1のメッセージが表示されます。


小数部の切り捨てに注意

答が小数となるような割り算の結果をIntegerに保存した場合、変数には小数部が切り捨てられた整数のみが格納されます。この変数の値をさらに別の計算に用いる場合、結果が予測と大きく異なる場合もあり得ます。
リスト2のコードを試してみてください(サンプルの[切り捨て]ボタンに登録してあります)。

リスト2:小数部切り捨てのテスト

この処理を実行すると、イミディエイトウィンドウに

Single型 33.33333
Integer型 33

と表示されます。同じ計算の結果も、受け取る変数のデータ型によって変わってしまいます。
また変数がSingleやDouble型であっても、結果が割り切れない場合は、変数の保持できる範囲内で切り捨てられてしまいます。これを(小数部の)「丸め」と言い、その結果発生する数値の差を「丸め誤差」と言います。


- 事前設計と予測が大切 -

データ型の制約が面倒だからと、どのようなデータ型でも保存できるVariant型を多用する人がいます。しかしVariant型はメモリを余分に消費する上、変数がどのような種類のデータを保持するのか把握できなくなるため、あまりお勧めできる方法ではありません。
また、String型なら変数名の後ろに$記号を付ける…など、型指定文字を使って変数名でデータ型を明示する方法もあります。が、これも変数を宣言しないで自由に使用できるという、BASICの悪い仕様を受け継いだものなので、お勧めはできません。
日付ならDate型、金額ならCurrency型、小数を扱うならSingleまたはDouble型…と、扱うデータに合わせて適切なデータ型を用いましょう。
また、先述したようなオーバーフローや丸め誤差を防ぐためにも、変数に保持される値の上限と下限を見極め、余裕を持たせるようにしておきましょう。特に小数を扱う場合は、変数が保持できる桁数の範囲内で、明示的に切り上げ、切り捨て、四捨五入を行うようにしましょう。
そのためには、事前に
どの変数がどのようなデータを扱うのか
を明確に把握し、
最大値/最小値がどの範囲に収まるか
を予測する必要があります。


適当な名前を付けるとどうなるか?

変数やコントロールに適当な名前を付けると、どのような事態を招くかを考えてみましょう。仮にプログラムはうまく動いても、混乱は必至です。


- すべて名前で特定する -

フォームもその上のコントロールもオブジェクトであり、それぞれ名前で特定します。プロパティウィンドウに表示されるプロパティシートでは、プロパティは「オブジェクト名」となっていますが、コードではNameプロパティとして扱われます。
もっとも、コントロールの名前はフォームに貼り付けたときに設定するため、コード内で名前を設定する機会はありません。従ってNameプロパティは、実行時には参照のみ可能となっています。
コード内で特定のコントロールのプロパティを操作したり、メソッドを実行したりする場合には、当然そのコントロールの名前(Nameプロパティの値)を指定します。そうしなければ、コントロールを特定できません。よって、コード内で明示的に"Name"というキーワードを用いる機会も、基本的にありません。

If txtUserCount.Name = "txtUser.Count" Then...

というコードは、
山田美代子さんの名前は山田美代子さんですよね?
と言っているようなもので、まったく無意味です。
 
- 最初の名前が最後まで尾を引く -

つまり、コントロールは
フォームに貼り付けたときに決めた名前が
最後まで使用され続ける
ということです。
例えば、ある商品の「販売数」を入力するテキストボックスの名前を、「数量」という意味から
"Amount"と付けたとしましょう。
その後、同じフォームに別の商品の「在庫数」を表示する必要が生じたとします。これも"Amount"としたいけれど、同じフォーム上に同じ名前のコントロールを複数配置することはできません。仕方なく
"Zaiko"とローマ字で付けてしまいました。



- 適当に付けると混乱する -

コード上で、これらのコントロールに値を設定したり、値を読み取ったりする処理を記述することになりました。テキストボックス"Amount"に入力されたString型の値を数値型に変換し、変数に受け取ります。
さて、変数名はどうしましょう?
やはり"Amount"
は使えません。フォームとコードは、同じモジュール内のオブジェクトだからです。そこで仕方なく、
"Amount2"と付けてしまいました。
テキストボックス"Zaiko"に表示する在庫数は、別の数値型の変数に保存したものを代入します。この変数名はどうしましょう?
"Zaiko2"とでもしなければ、先に進めなくなってしまいました。
コードウィンドウ内には

Amount2 = Val(Amount.Text)


とか

Zaiko.Text = CStr(Zaiko2)


といった訳のわからないコードが、あちこちに記述されることになります。


- 自分にさえ理解できない?! -

あとからこのコードを読んだとき、果たして

Amount:販売数を入力するテキストボックス
Amount2:テキストボックスAmountに入力された販売数

…といったことが理解できるでしょうか?
無論、フォームウィンドウのデザイン画面とコードウィンドウとを行ったり来たりし、プロパティシートを何度も眺めれば理解はできるでしょう。コメントを使うという手もあります。しかし、いたずらに労力を消費するのは間違いありません。
「自分で作ったプログラムなんだから、そんなに迷うわけはないよ」と思う人もいるかもしれません。しかし、プログラマーたちの間にはこんな格言(?)があります。

三日も経てば自分も他人

作っているときは設定を頭に入れていても、数日経ってからそれを見直したときには頭の中がきれいにリセットされ、いかに作者といえども「作ったときの設定」を思い出すことが難しい…ということです。
まして、複数のメンバーが共同で1つのアプリケーションを開発するような場合、(本物の)他人が書いたコードを読み取らなければならなくなります。そんな状況だと、上記のような行き当りばったりの命名は、大混乱を引き起こす原因となります。



適切な変数名の指針

変数やオブジェクトの名前をシンボル名(symbol name)と呼びます。命名の基本は、データ型と役割が分かることです。


- シンボルの命名規則 -

VBでは、変数名は255バイトまで指定でき、英数字および日本語と一部の記号が使用できます。但し、先頭には記号と数字は使えません。
規則をまとめると、以下のようになります。
1. 先頭は文字(英字または日本語)でなければなりません
2. スペース、.、!、および @、&、$、# などの記号は使えません
3. 255バイト以内でなければなりません
4. VBのキーワード(ステートメント、関数、プロパティ名、メソッド名)と同じ名前は使えません
5. 但し、名前の一部にキーワードが含まれることは問題ありません

4.と5.の規則は、例えば
  Len、Name、Stringというシンボル名
   → ×不可
  NameLen、BufferStringというシンボル名
   → ○可
ということです。


- 名前でデータ型を示す -

変数名は、必ずその変数の用途が分かるような名前とします。また、名前からデータ型も分かった方がよいので、以下に示す表のような接頭記号(プリフィックス)を変数名の前に付けると便利です。
この方法はハンガリアン記法と呼ばれ、Windowsをはじめとする各種プログラミングで利用されています。

表2:データ型を示す接頭記号


- 英単語を基本にする -

VBでは日本語(2バイト文字)の変数名も使えます。

金額 = 単価 * (消費税率 / 100)

といった式は、表計算っぽくて分かりやすいように思えます。

しかし、日本語はコメントと間違えやすい上、入力時にかな漢字変換を使う手間が増えるため、あまりお勧めできません。できれば英字を使った方がよいでしょう。
だからといって、日本語のローマ字表記を使うのも問題です。特にCOBOL出身のプログラマーには、この傾向が目立ちます。それも、文部省式表記ですべて大文字だったりするので、読んで意味を理解するのに苦労します。

SYOHINMEI、YUZAMEI、TANKA

といった感じです。こんな調子で

KAIINBANGOU、ZEIKOMIKAKAKU

などとやられてはたまりません。日本語で

会員番号、税込価格

とする方がまだましです。

また、メモリが高価だった時代の名残からか、名前をやたらと省略してしまう人もいます。

If SMEI = INPUTDATA & YZMEI Then ...


とか

SHINTAN = KAKAKU * SZEI

などとされると、ローマ字の省略表記がVBのコードの中に紛れ、訳がわからなくなります。ちなみに

SMEI→氏名、YZMEI→ユーザー名
SHINTAN→商品単価、SZEI→消費税

だそうです。


- 自分なりのパターンを作る -

英単語と言っても、特別難しい名前を使う必要はありませんし、文法を意識することもありません。英字では、大文字と小文字を使い分けできるので、単語の先頭を大文字、残りを小文字にするなどして、分かりやすい名前を付けましょう。
例えば、会員名を保存する文字列なら

strMembersName

のようにします。
また、間に_(アンダースコア)記号を挿入し

strMembers_Name

などとしても構いません。

変数名に使用できる記号には制約が多いため、できれば"_"記号だけを使った方が安全でしょう。あまり多くの記号を用いると、綴り間違いの可能性も高くなります。
参考までに、プログラミングでよく用いられる英単語の表記を掲げておきます。あくまで一例なのでこれにこだわる必要はありませんが、表記を統一して自分なりのパターンを作れば、分かりやすくなるでしょう。
以下の表に示した英単語には、VBのステートメントや関数に使われているキーワードも存在します。これらは単語単独では使用できませんが、先述したように、他の語と組み合わせて使用することは可能です。

表3:プログラミングでよく用いられる英単語の表記



サンプルプログラムについて
今回のサンプルは、変数の桁溢れと丸め誤差の参考例です。いずれもイミディエイトウィンドウに計算結果を表示するため、必ず統合環境内で実行してください。コンパイルしてexeファイルを作っても、結果は表示されません。

DownloadVBプロジェクトファイルのダウンロード
(LZH形式 1.49KB)
Copyright © MESCIUS inc. All rights reserved.