前回に引き続き、作成したメニューフォームの構造を調べていきます。
Form_currentを読み込んだ時に呼び出されるFillOptionsプロシージャを見てみましょう。ここでは何をしているのでしょうか?
FillOptionsプロシージャ
中身を確認してみると、今までのものとは比べ物にならない長いコードが記述されていますがめげずに読み進めていきましょう。
変数及び定数の宣言
それではまず変数や定数の宣言セクションを。
' Fill in the options for this switchboard page.
' The number of buttons on the form.
Const conNumButtons = 8
Dim con As Object
Dim rs As Object
Dim stSql As String
Dim intOption As Integer
宣言している定数と変数は
- conNumButtonsを定数として宣言、その値は「8」
- conをオブジェクト型の変数として宣言
- rsをオブジェクト型の変数として宣言
- stSqlを文字列型の変数として宣言
- intOptionを整数型の変数として宣言
となります。
全ボタンを一旦非表示にする
続いて各ボタンに対する最初の処理が行われています。
' Set the focus to the first button on the form,
' and then hide all of the buttons on the form
' but the first. You can't hide the field with the focus.
Me![Option1].SetFocus
For intOption = 2 To conNumButtons
Me("Option" & intOption).Visible = False
Me("OptionLabel" & intOption).Visible = False
Next intOption
まずは「Option1」ボタンにカーソルを合わせた(setfocus)あと、変数「intOption」に2から8の数値を代入して処理を繰り返します。(For ~以下)
※ちなみにconNumButtonsを8として宣言したため2~8になっているだけなので、ボタンを増やしたときは上の宣言セクションで8ではなくボタンの数を指定してやればうまく動作してくれます。
繰り返し処理の内容は
Option2ボタンからOption8ボタンとOptionLabel2~OptionLabel8をそれぞれ非表示にする(Visible = False)というもの。
"Option"またh"OptionLabel"という文字列と変数IntOptionの数字を & でつなげてボタンやラベルの名称を指すようにしているんですね。※少なくとも1つのボタンだけは表示するため「2」からスタートしているんですがその理由はあとでわかります。
Switchboard Itemから必要なデータを抽出
つぎはADOを使用したセクションへと続いています。
' Open the table of Switchboard Items, and find
' the first item for this Switchboard Page.
Set con = Application.CurrentProject.Connection
stSql = "SELECT * FROM [Switchboard Items]"
stSql = stSql & " WHERE [ItemNumber] > 0 AND [SwitchboardID]=" & Me![SwitchboardID]
stSql = stSql & " ORDER BY [ItemNumber];"
Set rs = CreateObject("ADODB.Recordset")
rs.Open stSql, con, 1 ' 1 = adOpenKeyset
正直、普段はDAOを使用していてADOは使ったことがないので解読に苦労しましたが順を追って纏めると
- 変数:conをカレントデータベースに対するコネクションオブジェクトとして定義
- 変数:stSqlにSQL文を格納(詳細は後ほど)
- 変数:rsにSQLで抽出したデータをADOレコードセットとして格納
- レコードセット:rsを開く
というところでしょうか。ちなみにSQLの内容は「Switchboard ItemテーブルからItemNumber>0かつSwitchboardIDがフォームで保持しているSwitchboardIDと一致するものレコード(今のフォームを開く段階ではArgumentがDefaultであるSwitchboardID=1)を抽出してItemNumber順に並び替える、という内容です。
この結果をrsオブジェクトに格納して、残りの処理に引き継いでいます。
ボタンとラベルの表示設定を更新
最後に、前項で抽出したデータを基にボタンの表示を変更していきます。
If (rs.EOF) Then
Me![OptionLabel1].Caption = "There are no items for this switchboard page"
Else
While (Not (rs.EOF))
Me("Option" & rs![ItemNumber]).Visible = True
Me("OptionLabel" & rs![ItemNumber]).Visible = True
Me("OptionLabel" & rs![ItemNumber]).Caption = rs![ItemText]
rs.MoveNext
Wend
End If
rsのレコードがEOF、つまり1件もなければOptionLabel1の値を"There is no ~(該当するメニューページがないよ)"と表示します。
データがある場合はレコードを1件ずつ処理してデータが空になるまで処理を続けます。その内容は
- "Option"文字列とItemNumber(最初は1)を繋げて指定したボタンを表示(Visible = True)
- "OptionLabel"文字列とItemNumberを繋げて指定したラベルを表示(Visible = True)
- "OptionLabel"文字列とItemNumberで指定したラベルの文字をレコードセットのItemTextへ変更(Caption=~)
- レコードセットを次に移動して処理を繰り返し
という内容です。
あと片付け
' Close the recordset and the database.
rs.Close
Set rs = Nothing
Set con = Nothing
作成したレコードセットやデータベースとの接続をそのままほっとくとメモリに常駐してしまいますので、明示的に宣言してあと片付けをしています。
ここまでやって、初めてメニュー画面が開かれるわけですね。
フォームの起動完了と残りのモジュール
こうして、最初にメニューを開くときの挙動がなんとなくわかりました。
残る処理はボタンをクリックしたときの動作なんですが、これもテーブルとモジュールで制御されています。が、こちらは更に長い処理になってしまうのでまた次回にしたいと思います。