Chapter 5 | モジュールを作る(2) | ||
5-1.標準モジュールを作る ・Declarationsセクション ・smp_Mainプロシージャ ・smp_GetFormListプロシージャ ・smp_GetPropListプロシージャ 5-1.標準モジュールを作る やっとこのサンプルアドインの中心である標準モジュールの説明に入れるようになりました。個々のコードを説明する前に、標準モジュールの全体構造を簡単に説明します。 アドインが起動されると、まずsmp_Mainプロシージャが呼び出されます。これがこのアドインの処理フローのメインとなるもので、この中からさらに同じ標準モジュール内のsmp_GetFormListとsmp_GetPropListの2つのFunctionプロシージャを呼び出します。そして最後にこのsmp_Mainプロシージャを抜けたらアドイン全体の処理が完了します。 それでは、標準モジュールにあるDeclarationsセクションと3つのプロシージャ、それぞれについて説明していきたいと思います。 ■Declarationsセクション ここではエラー処理におけるエラー番号を定数として宣言しています。それぞれのエラーがどんなときに発生するかは以降のプロシージャのコードを参照してください。("Option Explicit"も忘れずに!) Option Compare Database
Option Explicit '削除テーブルが存在しないときのエラー Const ERR_TABLENOTEXIST = 7874 'フォームが見つからないときのエラー Const ERR_NOTFINDFORM = 2450 'デザインビューでプロパティを参照できないエラー Const ERR_CANTPROPREF = 2186 ■smp_Mainプロシージャ サンプルアドインの「スタートアッププロシージャ」です。 Public Function smp_Main()
On Error GoTo Err_smp_Main 'フォームの一覧を取得する If smp_GetFormList() Then 'フォーム選択ダイアログを開く DoCmd.OpenForm "smp_frmSelectForm", , , , , acDialog With Forms!smp_frmSelectForm If .OKCancelFlg Then 'OKボタンがクリックされたときすべてのプロパティを取得 If smp_GetPropList(.SelectFormName) Then 'プロパティ一覧のフォームをデータシートで表示 DoCmd.OpenForm "smp_frmPropList", acFormDS End If End If End With 'フォーム選択ダイアログを閉じる DoCmd.Close acForm, "smp_frmSelectForm" End If Exit_smp_Main: Exit Function Err_smp_Main: If Err.Number = ERR_NOTFINDFORM Then 'フォーム選択ダイアログがフォームの[閉じる]ボタンで '閉じられたときはエラーを無視してそのまま終了 Else Beep MsgBox Err.Description, vbOKOnly + vbCritical End If Resume Exit_smp_Main: End Function このアドインでは、フォームを選択する"smp_frmSelectForm"で[OK]ボタンがクリックされたときの処理を、そのフォームのクラスモジュールではなくこのsmp_Mainプロシージャで行うようにしています。このプロシージャでは、フォームを開く操作からプロパティ一覧の取得処理まで、サンプルアドインのすべての処理を集中的にコントロールしています。 このプロシージャでは、アドインの起動とともにsmp_GetFormList()プロシージャを呼び出し、カレントデータベース上のすべてのフォームをリストアップします。その処理が正常に返ってきたら、そこで取得されたデータ、つまりフォーム一覧を表示するフォーム"smp_frmSelectForm"を開きます。ここでは"DoCmd.OpenForm"の6ケ目のパラメータに組み込み定数"acDialog"を指定することによって、フォームを「ダイアログ」として開きます。そしてそのダイアログが非表示になるまで待機します。 "smp_frmSelectForm"フォームでOKが押されたかキャンセルが押されたかの判断については、すでに概略説明していますので、ここでは特に説明は要らないでしょう。"smp_frmSelectForm"フォームで[OK]ボタンがクリックされた場合には、そのリストボックスで選択されたフォームのプロパティ一覧を取得します。リストボックスで選択されたフォームは、リストボックスコントロールを直接参照するのではなく、"smp_frmSelectForm"フォームのPublic変数"SelectFormName"から得ます。そしてそのフォーム名を引数として、フォームのプロパティを調べるプロシージャ"smp_GetPropList"を呼び出します。 エラー処理を行うルーチン "Err_smp_Main:" の部分では、もしもダイアログが[OK]または[キャンセル]ボタンではなく、ウィンドウの[閉じる]ボタン(右上の×)で閉じられた場合、"With Forms!smp_frmSelectForm"の部分でエラーとなるので、そのトラップを行います。ここでのエラーはすでに閉じられたフォームを参照しようとするために起こるもので、[OK]または[キャンセル]ボタンがクリックされた場合にはフォームが非表示になるだけで閉じるわけではないので、このエラーは発生しません。 ■smp_GetFormListプロシージャ このプロシージャは、カレントデータベースのフォームの一覧を取得し、テーブル"smp_tblObjList"にその結果を出力します。出力前にはテーブルの既存レコードの削除(実際にはテーブルの再生成)も行います。 Private Function smp_GetFormList() As Boolean
'フォームの一覧を取得する Dim dbsCd As Database Dim dbs As Object Dim aObj As AccessObject Dim rst As Recordset On Error GoTo Err_smp_GetFormList DoCmd.Hourglass True DoCmd.SetWarnings False '既存テーブルを削除 DoCmd.DeleteObject acTable, "smp_tblObjList" 'テーブルを作成する定義クエリーを実行 DoCmd.OpenQuery "smp_qdefObjList" DoCmd.SetWarnings True 'フォーム一覧をコードDBのテーブルに書き出し Set dbsCd = CodeDb Set rst = dbsCd.OpenRecordset("smp_tblObjList") Set dbs = Application.CurrentProject For Each aObj In dbs.AllForms With rst .AddNew !ObjectName = aObj.Name .Update End With Next aObj smp_GetFormList = True Exit_smp_GetFormList: rst.Close: Set rst = Nothing dbsCd.Close: Set dbsCd = Nothing Set dbs = Nothing DoCmd.Hourglass False Exit Function Err_smp_GetFormList: If Err.Number = ERR_TABLENOTEXIST Then '削除テーブルが存在しない時のエラー Resume Next Else smp_GetFormList = False Beep MsgBox Err.Description, vbOKOnly + vbCritical Resume Exit_smp_GetFormList: End If End Function ここでの大きなポイントは、太字で示した "Application.CurrentProject"オブジェクトと"For Each...Next"ステートメントです。CurrentProjectオブジェクトはAccess2000から追加されたオブジェクトで、カレントデータベース内のAccessオブジェクト(フォームやレポート、マクロなど)のコレクションを持っています。つまり、このオブジェクトを使うことによって、データベース内にどんなフォームがあるか、あるいはどんなレポートがあるかなどを調べることができるのです。それを具体的に実行しているのが、"For Each...Next" で囲まれた部分です。ここでは、CurrentProjectオブジェクトの持つ"AllFormsコレクション" から、1つずつフォームを"aObj"というオブジェクト変数に取り出し、さらにそこからNameプロパティつまりフォーム名を取得しテーブルに書き出しています。 なおこの操作を行うために、次のような変数、特に"As"の右にある型を宣言していることに注意してください。 Dim dbs As Object Dim aObj As AccessObject ■smp_GetPropListプロシージャ 引数に指定されたフォームのプロパティ一覧を取得するFunctionプロシージャです。その結果は"smp_tblObjPropList"テーブルに出力されます。 Private Function smp_GetPropList(strFormName As String) As Boolean
Dim dbsCd As Database Dim dbs As Database Dim rst As Recordset Dim frm As Form Dim prp As Property On Error GoTo Err_smp_GetPropList DoCmd.Hourglass True DoCmd.SetWarnings False '既存テーブルを削除 DoCmd.DeleteObject acTable, "smp_tblObjPropList" 'テーブルを作成する定義クエリーを実行 DoCmd.OpenQuery "smp_qdefObjPropList" DoCmd.SetWarnings True '指定フォームをデザインビューで開く DoCmd.OpenForm strFormName, acDesign Set frm = Forms(strFormName) 'フォームのコントロール一覧をコードDBのテーブルに書き出し Set dbsCd = CodeDb Set dbs = CurrentDb Set rst = dbsCd.OpenRecordset("smp_tblObjPropList") '指定フォームのすべてのプロパティを列挙するループ For Each prp In frm.Properties With rst .AddNew !PropertyName = prp.Name !PropertyValue = CStr(Nz(prp.Value)) .Update End With Next prp smp_GetPropList = True Exit_smp_GetpropList: '指定フォームを閉じる DoCmd.Close acForm, strFormName, acSavePrompt rst.Close: Set rst = Nothing dbsCd.Close: Set dbsCd = CodeDb dbs.Close: Set dbs = CurrentDb DoCmd.Hourglass False Exit Function Err_smp_GetPropList: If Err.Number = ERR_TABLENOTEXIST Then '削除テーブルが存在しない時のエラー Resume Next ElseIf Err.Number = ERR_CANTPROPREF Then 'デザインビューでプロパティを参照できないエラー rst!PropertyValue = "<参照不可>" Resume Next Else smp_GetPropList = False Beep MsgBox Err.Description, vbOKOnly + vbCritical Resume Exit_smp_GetpropList: End If End Function フォームのプロパティはフォームが開かれていないと調べることができません。そこでまず、プロパティ値を調べる前に対象フォームを開きます。フォームを開くのは、デザインビューでもフォームビューでも、あるいは非表示でもかまいません。ただ、フォームビューで開くとそのフォームのモジュールに含まれるプログラムも実行されることになりますので、ユーザーの作ったモジュールによってはどんな動作が始まってしまうか分かりません。そこでここではモジュールが実行されることのない「デザインビュー」としてフォームを開くようにします。そして開いたフォームを、フォームのオブジェクト変数である"frm"変数にセットします。 さて、このプロシージャの最も重要なところは、For Each prp In frm.Properties〜Next prp の、フォームのすべてのプロパティを取得するループの部分です。"For Each prp In frm.Properties"の記述は、frmオブジェクトのPropertiesコレクションに含まれるすべてのプロパティを、1つずつプロパティを表す変数"prp"に代入することを意味します。つまり、特定のプロパティ名を指定するのではなく、とにかくフォームが持つプロパティを全部列挙するというものです。このループの中の"prp.Name"の部分では、ループ内の現在のプロパティの名前を取得します。例えば、"Visible"や"Caption"や"Name"などの文字列が得られます。一方、"prp.Value"はそのプロパティの値です。プロパティによってはこの値がNullの場合もありますので、エラーにならないようにNZ関数で置き換えを行います。また、プロパティの値は文字列データの場合も数値データの場合もありますが、ここではすべてCStr関数で文字列に置き換えた上でテーブルに書き込むようにしました。 ところで、プロパティの中にはデザインビューでは取得できないものもあります。例えば、"SelTop"プロパティはレコードセレクタで複数選択されているレコードの先頭のレコード番号を返すプロパティで、フォームの実行時にしか取得できません。このようなプロパティ値を参照しようとするとエラーが発生しますので、ここではその種のエラーをトラップし、"<参照不可>"という文字列をテーブルに書き出すようにしています。 最後に、プロパティを取得し終わったらそのフォームを閉じます。しかし、これは必ずしも必要なわけではありません。もし、フォームのデザインを変更するようなアドインを作る場合には、変更のあったフォームはデザインビューのままにしておいた方がいいかもしれません。また、すべての変更を強制的に保存した方がよいアドインもあるかもしれません。これは作るアドインによって判断すればよいでしょう。 以上で今回のサンプルアドインのフォームやモジュールなど、必要なオブジェクトの作成作業は完了しました。次回では、サンプルアドインのテスト、そして最終形であるMDAへの移行作業を行います。 |
|||
|
Copyright © T'sWare All rights reserved |