フォームを作ってみましょう。フォームとは、データの入力や表示に利用するためにユーザが定義できる画面(ウィンドウやダイアログボックス)のことです。
データの入力には、InputBoxという関数がありました。3.2 Function プロシージャで以下のようなプログラムを紹介しました。
Sub main() Dim temp As Long temp = Application.InputBox(Prompt:="華氏で温度を入力してください。", Type:=1) MsgBox "温度は摂氏 " & Celsius(temp) & " 度です。" End Sub Function Celsius(fDegrees As Long) As Long Celsius = (fDegrees - 32) * 5 / 9 End Functionちょっとした入力には便利ですが、反面、プログラムのあちこちに入力処理が分散してしまいがちです。また、一般の人に使ってもらうような場合は、その都度、入力データをチェックする処理を書かなければなりません。データ処理の中に入力処理が紛れ込んでしまってプログラムが分かりにくくなる傾向があります。
しかし、フォームを使うとたくさんのデータをまとめて入力できます。値のチェックなどもまとめて記述できるので、プログラムが分かりやすくなり、保守も容易になります。
フォームを準備して、おおよその形を作りましょう。目的によってデザインは異なりますが、ここでは練習として、以下のようにラベル、テキストボックスを1個ずつ、そして、コマンドボタンを2個配置しましょう。
プロジェクトにフォームウィンドウを追加するには、VBA エディタの[挿入]メニューから[ユーザフォーム]を選びます。
図1.5.1-1
UserForm1 という名前のついたフォームウィンドウができます。フォームウィンドウには [閉じる] ボタンが配置されています。フォームにはグリッドが表示されています。フォームウィンドウの周りに表示されている8つの正方形(ハンドル)をドラッグすると大きさを変更できます。
図1.5.1-2
フォームウィンドウの左横に[ツールボックス]も表れます。見あたらないときは、VBA エディタの[表示]メニューから[ツールボックス]をクリックすると表示されます。もう一度クリックすると消えます。[ツールボックス]ウィンドウの[閉じる]ボタン(×)をクリックしても消えます。
図1.5.1-2a
図1.5.1-1では[ツールボックス]に隠れて見えませんが、プロジェクトエクスプローラの中には[フォーム]フォルダができています。
図1.5.1-2b
フォームウィンドウにコントロールを描画し表示してみましょう。 フォームフォームウィンドウにコントロールを描画するには、ツールボックスのボタンを使用します。
ツールボックスからフォームにコントロールを追加するには、以下のような方法があります。
追加されたテキストボックスの周りには小さな8個の正方形(ハンドル)が表示されます。ハンドルをドラッグして大きさを調節できます。追加したテキストボックスを囲む枠線をドラッグすると移動できます。適当な場所に適当な大きさで配置してください。
図1.5.1-4
コントロールの上にマウスを乗せると、コントロールの名前が表示されます。テキストボックスの他にラベルを1つ、コマンドボタンを2つ追加して目標のフォーム図1.5.1-6を完成させてください。
図1.5.1-5
図1.5.1-6
フォームにはプログラムみたいなものは何も書いていませんが、VBA エディタの[実行]メニューから[Sub/フォームの実行]をクリックすると動作を確認できます。[F5]キーでも実行できます。
[閉じる]ボタン(×)で閉じられます。
図1.5.1-6
フォームと追加したコントロールを図1.5.2-1のようにカスタマイズしましょう。
図1.5.2-1
カスタマイズするには、[プロパティウィンドウ]を使います。ふつうは、左側の[プロジェクトエクスプローラ]の下に表示されていますが、見あたらないときは、VBA エディタの[表示]メニューから[プロパティウィンドウ]をクリックすると表示できます。
カスタマイズしたいコントロールをクリックすると、[プロパティウィンドウ]に選択したコントロールのプロパティが表示されます。プロパティの値を書き換えてカスタマイズしてゆきます。
フォームをクリックして表示されるプロパティのひとつに[Caption]があります。フォームの[Caption]の既定値は"UserForm1"ですが、これを変更するとフォームのタイトルが変わります。
図1.5.2-2b
フォーム、ラベル、テキストボックス、コマンドボタンのキャプションをそれぞれ変えてみてください。
図1.5.2-3
テキストボックスには[Text]というプロパティがあります。これは、利用者が入力する初期値の設定に利用できます。[Value]プロパティと連動しています。[Value]プロパティには、利用者が入力した値が保存されます。
図1.5.2-4
ここでは、利用者に入力を促すメッセージを表示してみましょう。
実行すると、入力欄に初期値として[Text]プロパティの値が表示されます。
図1.5.2-5
利用者に対するメッセージを[Text]プロパティに表示すると、利用者は文字列を入力するときに表示されているメッセージを削除してから入力しなければなりません。
操作に慣れている人が利用するような場合は、[ControlTip Text]プロパティを使うのが良いでしょう。マウスポインタをテキストボックスに重ねた時にメッセージを表示する機能です。
図1.5.2-6
しかし、このような機能があることを知らない利用者にはせっかくのメッセージを伝えることができないかもしれません。そのような場合には、操作が面倒でも[Text]プロパティを使った方が良いかもしれません。
フォームを実行して、マウスポインタをテキストボックスの上に重ねると図1.5.2-7のようにメッセージが表示されます。
図1.5.2-7
フォームが完成したら、コマンドボタンにプロシージャを登録してみましょう。ボタンをクリックしても何も起きませんでしたが、プロシージャを登録するとさまざまな動作をさせることができます。
フォームウィンドウ上の[入力]ボタン(CommandButton1)をダブルクリックすると、実行時に[入力]ボタンをクリックしたときに実行されるプロシージャ(イベントプロシージャ)が自動的に作られます。自動的に作られるといっても図1.5.3-1のようにプロシージャの雛形ができるだけです。これだけでは何も変化しません。
図1.5.3-1
このとき、フォームウィンドウが消えてしまいますが、フォームウィンドウを表示するには、プロジェクトエクスプローラの上にあるボタンを使います。[表示]メニューから[オブジェクト]を選んでも切り替わります。[Shift]+[F7]でも同じです。ちなみに、[F7]でコード表示の画面に移れます。
図1.5.3-2
[入力]ボタン(CommandButton1)と[取消]ボタン(CommandButton2)のイベントプロシージャをつくり、次のように編集してみましょう。
Option Explicit Private Sub CommandButton1_Click() MsgBox TextBox1.Value hide End Sub Private Sub CommandButton2_Click() TextBox1.Value = "" End Sub
CommandButton1_Click()というプロシージャは、[入力]ボタン(CommandButton1)をクリックしたときに実行するプロシージャです(イベントプロシージャ)。
MsgBox関数で[TextBox1]コントロールの[Value]プロパティの値、すなわち利用者がテキストボックスに入力した値を表示しています。
hide という文は、[文字列入力」フォームを画面から消すという命令です。
CommandButton2_Click()というプロシージャは、[取消]ボタン(CommandButton2)のイベントプロシージャです。
MsgBox関数で[TextBox1]コントロールの[Value]プロパティの値に空文字列を代入しています。すなわち利用者がテキストボックスに入力した値をクリアしています。
このプロシージャを見ると、フォーム上のコントロールもオブジェクトの一種であることが分かります。プログラムでプロパティの値を参照したり変更したりするときの記述方法が同じです。
[実行]メニューから[Sub/フォームの実行]をクリックして動作を試してみてください。
フォームができあがったので、実際に他のプロシージャから画面を表示して、利用者の入力を受取ってみましょう。標準モジュールの中に、以下のようなプロシージャを編集してください。
Sub FormTest() UserForm1.Show MsgBox "フォームに入力された文字列は、「" & UserForm1.TextBox1.Value & "」です。" End Sub
UserForm1.Show という文は、フォームを画面に表示するメソッドを呼び出しています。これでUserForm1、すなわち「文字列入力」画面に制御が移ります。「文字列入力」画面が、Hide関数が呼び出されて非表示になるまで、処理は呼び出し元のプロシージャFormTest()には戻ってきません。
「文字列入力」画面で「入力」ボタンがクリックされると、CommandButton1_Click()プロシージャが呼び出されるようになっていました。CommandButton1_Click()プロシージャでは、テキストボックスに入力された値(TextBox1.Value)をMsgBox関数でダイアログボックスに表示した後、Hide関数を呼び出し「文字列入力」画面を非表示にしていましたので、FormTest()プロシージャに制御が戻ってきます。
そこで、FormTest()プロシージャは、再び「文字列入力」フォームのテキストボックスに入力された値をUserForm1.TextBox1.Valueというふうに参照して、MsgBox関数でダイアログボックスに表示しています。
ここで使っている「&」は文字列を連結する演算子です。3つの文字列を1つに結合しています。
- "フォームに入力された文字列は、「"
- UserForm1.TextBox1.Value
- "」です。"
では、実際にFormTest()プロシージャを実行して、動作を確認してみましょう。
入力文字列を変更して何度か実行していると、プロシージャの実行が終了しても、再実行すると前に入力した値がテキストボックスに残っていることに気がつかれるでしょう。
これは、フォームを非表示にしただけでは、プログラムが終了しても、フォームオブジェクトはメモリ上に残ったままだからです。
プログラムの終了とともにフォームオブジェクトも消滅すには、以下のように Unload 関数を使います。
Sub FormTest() UserForm1.Show MsgBox "フォームに入力された文字列は、「" & UserForm1.TextBox1.Value & "」です。" Unload UserForm1 End Sub
以上で、フォームの紹介を終わりますが、コントロールのプロパティには有用なものがいろいろあります。例えば、