カレントデータベース内にあるすべてのフォームとその中のすべてのコントロールを探索し、コントロールソースプロパティに特定の文字列を含むコントロールの一覧を収集します。
これを応用することで、あるフィールドと関係のあるコントロールを探すことができます。
- 「Database」オブジェクトや「Container」オブジェクトを設定し、「Documents」コレクションの中から、For Each~Nextステートメントでひとつずつフォーム情報を取り出し、「Document」オブジェクトの変数「doc」にセットしていきます。
- 取り出されたひとつのフォーム情報のうち、フォーム名である「Name」プロパティの値を、ここではそれを何度か使用するため、いったん変数「strFormName」にセットします。
- フォーム内のオブジェクトを参照するので、そのフォームを”デザインビュー”(引数に「acDesign」を指定)で開きます。
- そのフォーム内に配置されているすべてのコントロールのコレクションである「Controls」の中から、For Each~Nextステートメントでひとつずつコントロール情報を取り出し、「Control」オブジェクトの変数「ctl」にセットしていきます。
- 取り出されたひとつのコントロールについて、そのコントロールソースである「ControlSource」プロパティの値を取得し、そこに特定の文字列(ここでは”商品”)が含まれているかどうかを検査します。
- 指定文字列を含んでいたら、そのフォーム名とコントロール名、およびその「コントロールソース」をイミディエイトウィンドウに出力します。
このプロパティ値を出力する前後ではエラー処理を行っています。コントロールソースプロパティはテーブルのフィールドと連結可能、あるいは演算式を設定可能なコントロールしか持っていないため、それ以外のコントロールで参照しようとするとエラーとなるからです。
- まず「On Error Resume Next」ステートメントで以降に発生するエラーを無視するようにします。
- 次の行で変数strCtlSourceにControlSourceプロパティの値をセットしようとします。
- もしそのプロパティがあれば正しく変数にセットされますが、なければ実際にはエラーが発生します(無視するようになっているのでプログラムは止まりません)。
- 次の行で、「Err.Number」をチェックします。前行でエラーが発生していなければその値は「0」ですので、指定文字列有無の検査へ進みます。エラーが発生してれば「0以外」の値になっていますので、検査や出力は行わずに次へ進みます。
- 「On Error GoTo 0」ステートメントによっていったんエラー無視を念のため解除しておきます。
- そのフォームを閉じます。
ここではデータ収集のみでデザイン変更はありませんので、引数に「acSaveNo」を指定することで意図的に変更を保存せずに閉じます。
Sub Sample_4_11()
'コントロールソースに特定の文字列を含むコントロールを収集する
Dim dbs As Database
Dim ctn As Container
Dim doc As Document
Dim ctl As Control
Dim strFormName As String
Dim strCtlSource As String
Dim strFind As String
strFind = "商品"
Set dbs = CurrentDb
Set ctn = dbs.Containers!Forms
For Each doc In ctn.Documents
strFormName = doc.Name
DoCmd.OpenForm strFormName, acDesign
For Each ctl In Forms(strFormName).Controls
With ctl
On Error Resume Next
strCtlSource = .ControlSource
If Err.Number = 0 Then
If InStr(strCtlSource, strFind) > 0 Then
Debug.Print strFormName,
Debug.Print .Name,
Debug.Print strCtlSource
End If
End If
On Error GoTo 0
End With
Next ctl
DoCmd.Close acForm, strFormName, acSaveNo
Next doc
End Sub
実行例:
|