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

汎用的な機能をコンポーネント化する
長谷川裕行
2000/09/12

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

業務処理では、あちこちの異なるアプリケーションで、似たような処理を利用することが多くなります。開発効率を向上させるには、こういった“似たような処理”を1つにまとめて共通化させることが大切です。
最も効率的な処理の共通化は、コンポーネントを作ってしまうことでしょう。汎用的な機能をコントロールとして保存すれば、あらゆるプロジェクトで再利用できます。電卓コントロールで、コンポーネント化を試してみましょう。


共通処理をコンポーネント化する

共通する処理、似たような処理を1つにまとめることが、プログラミングの基本です。最も有効なまとめ方は、コンポーネント化することです。


- 再利用可能な共通処理 -

効率的なアプリケーション開発を行うには、
共通する処理を1つにまとめて再利用する ことが重要です。そのためには、「汎用性の高い共通処理」を作る必要があります。

VBで再利用可能な処理を作るには

 ソースコードとして保存する
 クラスを作る
 ユーザーコントロールを作る
 ActiveXコントロールを作る

という4通りの方法があります。


- フォームを使うならコントロールにする -

ソースコードとして保存する方法とクラスを作る方法は、共に「処理がコードとして記述できる」ものである場合に有効です。視覚的要素であるフォームを必要とする処理では、これらは利用できません。
前回紹介した印刷処理も、フォームにプリンタ名を表示する機能を削除すれば、コードだけでまとめることができます。
ユーザーコントロールとする方法とActiveX化する方法は、共にフォームを必要とする場合に有効です。
実際には視覚的要素をまったく持たない処理でも、ユーザーコントロールやActiveXコントロールとすることは可能です。VBに標準で備わっているタイマーコントロール(Timer)は、単にアイコンが表示されるだけで、処理自体に視覚的な要素は存在しません。


- ActiveXコントロールが便利 -

再利用性の高さから考えれば、コードを保存するよりクラス化するユーザーコントロールを作るよりActiveX化する ということになります。
ここでは、フォームを持つコントロールの例として「電卓コントロール」を作る手順と、それを利用したアプリケーションを作る手順を紹介します。
電卓機能は、様々な業務アプリケーションで頻繁に利用されます。これをActiveXコントロールとしてコンポーネント化しておけば、あらゆるプロジェクトで簡単に再利用できます。
アプリケーションを開発するたびに、同じようなフォームをデザインし、同じようなコードを記述する必要はなくなり、同時にバグの入り込む可能性も減ります。


電卓コントロールを作る(1)
準備とフォームデザイン

ActiveXコントロールもプロジェクトとして管理され、通常のEXEファイルを作る場合と同じ要領で作成できます。まず外観をデザインしましょう。


- プロジェクトの新規作成 -

プロジェクトの新規作成時に「ActiveXコントロール」を選択すれば、ActiveXコントロール作成のための統合環境がオープンします。

ウィンドウの構成は、一般のEXEファイルを作る場合と変わりません。フォームをデザインするウィンドウのオブジェクト種別が“Form”ではなく、“UserContorol”となっています。
つまり一般のEXEファイル用プロジェクトから、ユーザーコントロールの作成部分だけを抜き出してきたような形です。ActiveXコントロールは、ユーザーコントロールをOCX化したものと捉えられるので、作成の要領もユーザーコントロールとまったく変わりません。

画面1:「ActiveXコントロール」を選択する


- 明確な名前を付ける -

ActiveXコントロールのプロジェクトでは、プロジェクト名がコントロールの名前(一覧に表示される際の説明)、コントロール名(コントロールのオブジェクト名)が生成されるocxファイルの名前になります。
ここでは、プロジェクト名:SimpleCalculator、コントロール名:MiniCalc としておきます。
業務アプリケーションでは、生成されるEXEファイルでの名前だけが重要なので、プロジェクト名やプロジェクトファイル名、その中で使うコントロールの名前などは適当に(標準状態のまま)付けてしまいがちですが、ActiveXコントロールを作る場合はこれらが重要になります。

画面2:プロジェクト名とコントロール名を設定する


- 外観のデザイン -

電卓の外観をデザインしましょう。コントロールがフォームに貼り付けられた際の外観です。画面3のようにテキストボックスをコマンドボタンを使って、「電卓そのまんま」のデザインとしました。

画面3:コントロールの外観をデザインする


- コントロールの設定 -

貼り付けたコントロールのオブジェクト名は以下の通りです。

表1:コントロールのオブジェクト名

0~9のテンキーと[+][-][×][÷]の四則演算キーは、コントロール配列とします。これも、「基本的に同じ働きのコントロールは、同じ名前とする」という原則に従ったものです。
コントロール配列とすることによって、[0]キーは"cmdTenkey(0)"、[3]キーは"cmdTenkey(3)"、[+]キーなら"cmdOperator(0)"…と、1つのイベントプロシージャ内で要素番号(引数“Index”の値)によってキーを識別できます。


電卓コントロールを作る(2)
コードを入力する

コードは、リスト1~リスト7のようになります。順に説明していきましょう。


- グローバル変数の宣言 -

コードモジュールの宣言セクションで、グローバル変数を宣言します。電卓機能は非常に単純なものとするので、グローバル変数もわずかです。
電卓のインターフェイスは、テンキー、演算子キー、[=]キーなど多数のコマンドボタンで構成され、それぞれのイベントプロシージャ内で互いにデータを参照し合います。そのため、置数(入力された数値)や押された演算子などは、すべてグローバル変数として他のプロシージャからも参照できるようにします。
計算結果を保存するSingle(単精度浮動小数点)型の変数“sglResult”だけは、Publicキーワードを付けて宣言します。こうすることで、コントロール内で用いている変数が、それを貼り付けたアプリケーションから参照できるようになります。
コントロールを貼り付けたアプリケーションから参照できるデータとは、つまりプロパティです。コントロールでPublicキーワードを付けて宣言したグローバル変数は、プロパティとなります。

リスト1:グローバル変数の宣言


- 初期化処理 -

プロシージャInitializeは、数値を表示するテキストボックスに文字列“0”を表示し、グローバル変数を0でリセットします。
これは下請けプロシージャで、リスト3のUserControl_Initializeとリスト4のcmdClearAll_Clickから呼び出されます。
UserControl_Initializeは、コントロールが機能するときに、必ず実行される初期化処理、cmdClearAll_Clickは[C]キー(ご破算キー)をクリックしたときに実行される処理です。
要するに、初期化とご破算の処理はまったく同じということです。

リスト2:初期化処理
リスト3:コントロールの初期化処理
リスト4:[C]ボタンをクリックしたときの処理(ご破算)


- テンキー(0~9)が -
- クリックされたときの処理 -

テンキーがクリックされるとcmdTenkey_Clickが実行されます。テンキーはコントロール配列としたので、どのキーがクリックされたかは引数“Index”で判別できます。
この処理では、まずテキストボックスtxtNumberが初期状態(0)かどうかを調べ、0なら“データ未入力状態”として、一旦中を空白にします。

If txtNumber.Text = 0 Then_
               txtNumber.Text = ""
 
その上で、押されたキーに対応する数値をテキストボックスに表示します。

txtNumber.Text = txtNumber.Text & CStr(Index)

0~9のキーにそのままIndexの0~9が対応するので、Indexの値を単純にCStr関数で文字列に変換しています。
電卓では、最終的に演算子キー(+, -, *, /)が押されるまで、入力される数値は決定できません。そのため、ここでは入力された数値をどんどん連結してテキストボックスに表示していきます。

リスト5:テンキー(0~9)がクリックされたときの処理


- 小数点キー([.])が -
- クリック されたときの処理 -

小数点キーがクリックされるとcmdDotkey_Clickが実行されます。単に、テキストボックスに表示する文字列に小数点(.)を挿入するだけです。

txtNumber.Text = txtNumber.Text & "."

1つの数値に小数点は2つ以上存在しないので、既に小数点が入力されているかどうかを調べるために、Boolean型の変数IsCammaを利用します。一度このプロシージャが実行されたらIsCammaをTrueにし、次回以降このプロシージャが実行されたときにIsCammaがTrueなら何もしないで処理を抜けます。

If IsCamma = True Then Exit Sub

リスト6:小数点キー([.])がクリックされたときの処理
 
- 演算子キー(+, -, *, /)が -
- クリックされたときの処理 -

+, -, *, /の演算子キーがクリックされると、cmdOparator_Clickが実行されます。演算子キーもコントロール配列です。処理としては、グローバル変数intOperatorに演算子を示す値(“Index”の値)を保存するだけです。
同時に、演算子キーが押されたということは、それまでに入力された数値が確定されたということなので、テキストボックスに表示されている数値を、置数としてグローバル変数“sglNumber1”に保存します。

リスト7:演算子キー(+, -, *, /)がクリックされたときの処理


- [=]キーがクリックされたときの処理 -

=キーが押されたらcmdEqual_Clickが実行されます。このときには、既に演算子キーとそれに続く2番目の置数が入力されているので、テキストボックスに表示されている値を変数“sglNumber2”に保存し、演算子を示すintOperatorに従ってSelect Caseで計算します。

Select Case intOperator
Case 0: sglAnswer = sglNumber1 + sglNumber2
     :
End Select

結果はsglAnswerに保存し、最終的にsglResultに代入して外からも参照できるようにします。

リスト8:[=]キーがクリックされたときの処理



電卓コントロールを作る(3)
保存とファイルの生成

EXEファイルの場合は、「実行」メニューから統合環境内でのテスト実行ができました。ActiveXコントロールでも、同じ方法でテスト実行できます。但しコントロールは、EXEファイルのように単体で動作するものではないため、InternetExplorerが起動してその中で動作することになります。
デバッグのためのブレークポイントの設定や変数のウォッチも可能です。
ソースを作成し保存したら、最後にocxファイルを生成します。これが、他のプロジェクトで利用できるコンポーネントとなります。
生成方法はEXEファイルの場合とまったく同じで、メニューから「ファイル(F)」→「xxx.ocxの作成(K)」を選択するだけです。このとき、コントロールに任意の名前を付けることも可能です。


電卓コントロールの制限事項

これで電卓のコントロールが完成しました。なお、この電卓は、一般的な電卓に比べてかなり機能を削ぎ落としています。
まず、[CE]キーを押したときの処理を記述していません。
本来このキーはそのときの処理状況によって最初の置数または次の置数のいずれかを消去するという働きをします。
これに対応させると内部処理が複雑になり、コントロールを作るという目的から離れてしまうため、省略しました。
その他、数値表示の桁数制限にも対処していません。数値データはSingle型としているので、除算結果の丸め誤差にも対処していません。除算結果の最終桁は、Single型の規則に従って丸められます。
従ってこの電卓は、事務処理用電卓としてはまだまだ未完成です。メモリ機能を付ける、%計算、べき乗や平方根の計算機能などを付加するなど、気が向いたら各自改造して、立派な電卓に仕上げてみてください。


電卓コントロールを利用する

次に、この電卓を利用したプログラムを作ってみましょう。単純な電卓ですが、[コピー]キーを押すことで計算結果をクリップボードにコピーするようにします。


- コンポーネントを追加する -

新規プロジェクトで「標準EXE」を選択して統合環境を準備したら、生成した電卓コンポーネントをプロジェクトに追加します。
生成したコンポーネント(ocxファイル)は他のActiveXコントロールとまったく同じに扱えます。
メニューから「プロジェクト(P)」→「コンポーネント(O)」を選んで「コンポーネント」ダイアログボックスを表示させ、「コントロール」パネルのリストからコンポーネントを選択します。


- 保存場所を指定して組み込む -

自作コントロールは、このとき[参照]ボタンをクリックして、ファイルの保存場所を指定しなければなりません。
場所を指定すれば、コントロールの作成時に設定したプロジェクト名――“SimpleCaluculator”がリストに表示され、チェックマークが付けられます。

画面4:自作コンポーネントをプロジェクトに組み込む

サンプルのプロジェクトでは、ocxコントロール“MiniCalc.ocx”を“C:\My Documents”フォルダに保存し、それを組み込んでいます。サンプルのプロジェクトを試す場合は、先に“mcalc.ocx”を“C:\My Documents”フォルダにコピーしておいてください。
ocxファイルが見つからない場合は、プロジェクトを開くときにエラーメッセージが表示され、フォームに貼り付けた電卓コントロールが表示されなくなります。
独自に新規プロジェクトを生成する場合は、先述した要領でコンポーネントを組み込めば、使用できるようになります。


- コントロールを貼り付ける -

プロジェクトにコントロールを組み込むと、ツールボックスにコントロールのアイコンが表示されます。電卓コントロールにはアイコンを設定していなかったので、ここではユーザーコントロールのアイコンとなっています。



電卓コントロールのアイコンをクリックし、フォーム上でドラッグして貼り付ければ、電卓のフォームが出来上がります。コマンドボタンを2個貼り付け、以下のようにプロパティを設定します。
・終了ボタン オブジェクト名:cmdClose
  Caption:閉じる
・コピーボタン オブジェクト名:cmdCopy
  Caption:コピー

画面5:ツールボックスにコントロールのアイコンが表示される
画面6:フォームに電卓コントロールを貼り付ける


- コードを記述する -

コードは、以下のように非常に単純です。
[終了]ボタンがクリックされたら、無条件にこのフォームを閉じてアプリケーションを終了させます(リスト9)。
[コピー]ボタンがクリックされたら、ClipboardオブジェクトのSetTextメソッドで、電卓コントロールのstrResultプロパティの値をクリップボードにコピーします。
ClipboardオブジェクトはVB組み込みのシステムオブジェクトなので、変数を宣言する必要はありません。直接オブジェクト名を参照します。

リスト9:終了処理
リスト10:計算結果のコピー


- あらゆるプロジェクトに組み込める -

電卓の機能自体はすべてコントロールが受け持っているため、それを利用するアプリケーションでは、計算結果を受け取るだけで済んでしまいます。
コンポーネントはあらゆるプロジェクトに組み込んで利用できるので、電卓コントロールをうまく使えば、業務処理の伝票入力などでちょっとした計算を行いたい場合などに、ダイアログボックスで電卓を表示させることができます。
このように、様々な局面で使う小さな処理はActiveXコントロールとしてコンポーネント化しておけば、アプリケーションの開発が効率化できます。

画面7:出来上がった電卓アプリケーション


コンポーネントを活用する

「共通する機能は1つにまとめる」これはプログラミングの大原則です。サブルーチン、関数、プロシージャ…と呼び方は異なりますが、どれも基本はこの原則なのです。オブジェクト指向言語のクラスも、この原則の発展形と言えるでしょう。


- コンポーネントを蓄積する -

VBの長所は、WindowsAPIや複雑なクラスライブラリの知識を持っていなくても、簡単に「処理の共通化」を実現できるところです。VBでは「クラスモジュール」「ActiveXコントロール」「ユーザーコントロール」という、共通化の手段が提供されています。
ユーザーコントロールとするかActiveX化するかは、「そのコントロールを他のプロジェクトでも頻繁に用いるかどうか」で判断が分かれます。ユーザーコントロールとAvtiveXコントロールは基本構造が同じなので、一旦ユーザーコントロールとして特定のプロジェクト内で作成したコントロールを、別途ActiveX化することも可能です。
ユーザーコントロールのフォームとコードをコピーし、ActiveXコントロールの統合環境に貼り付けるだけです。
こうして他のフォームや他のプロジェクトで利用できる機能をコンポーネント化し、どんどん蓄積していけば、プログラミングの効率は大きく向上するでしょう。


- 市販コンポーネントなら安心 -

しかし、ユーザー自身の手でコントロールを蓄積する方法が、必ずしも効率化に寄与するとは限りません。一度作ったオブジェクトを再利用して開発効率を上げるには、
あらゆる局面で一定の機能が安定して提供される ように設計されていなければなりません。これは、結構難しい作業です。ときには、思い通りの結果を得られず、コンポーネントを改良する必要も生じるでしょう。
また、処理系(この場合はVB)のバージョンが変われば、旧バージョンのコンポーネントがそのまま動作するかテストし、必要なら再設計、再作成、再コンパイルする必要があります。
そういう意味で、コンポーネントの作成にはしっかりした設計と管理が必要です。最も安心できる方法は、市販のコンポーネントを利用することでしょう。汎用性、動作テスト、サポート体制、新バージョンへの対応など、あらゆる面で安心できます。

- 注意 -

今回のサンプルプロジェクトは2つあります。
  minicalc.lzh:電卓コントロール
dentaku.lzh:電卓アプリケーション
電卓アプリケーションのプロジェクトを試す場合は、予めMinicalcに入っているMiniCalc.ocxを、“C:\My Documents”フォルダにコピーしておいてください。




DownloadVBプロジェクトファイル
のダウンロード(mimical.lzh)

(LZH形式 13.5KB)

DownloadVBプロジェクトファイル
のダウンロード(dentaku.lzh)

(LZH形式 4.74KB)
Copyright © MESCIUS inc. All rights reserved.