36 コントロール系 - コントロールソースに特定の文字列を含むコントロールを収集する

カレントデータベース内にあるすべてのフォームとその中のすべてのコントロールを探索し、コントロールソースプロパティに特定の文字列を含むコントロールの一覧を収集します。 これを応用することで、あるフィールドと関係のあるコントロールを探すことができます。
  1. 「Database」オブジェクト「Container」オブジェクトを設定し、「Documents」コレクションの中から、For Each〜Nextステートメントでひとつずつフォーム情報を取り出し、「Document」オブジェクトの変数「doc」にセットしていきます。

  2. 取り出されたひとつのフォーム情報のうち、フォーム名である「Name」プロパティの値を、ここではそれを何度か使用するため、いったん変数「strFormName」にセットします。

  3. フォーム内のオブジェクトを参照するので、そのフォームを”デザインビュー”(引数に「acDesign」を指定)で開きます。

  4. そのフォーム内に配置されているすべてのコントロールのコレクションである「Controls」の中から、For Each〜Nextステートメントでひとつずつコントロール情報を取り出し、「Control」オブジェクトの変数「ctl」にセットしていきます。

  5. 取り出されたひとつのコントロールについて、そのコントロールソースである「ControlSource」プロパティの値を取得し、そこに特定の文字列(ここでは”商品”)が含まれているかどうかを検査します。

    ※ここでは「InStr」関数を使っています。この関数は指定文字列が見つかった場合はその位置を返し、見つからなければ”0”を返しますので、”0より大きければその文字列が含まれている”と判定することができます。

  6. 指定文字列を含んでいたら、そのフォーム名とコントロール名、およびその「コントロールソース」をイミディエイトウィンドウに出力します。

    このプロパティ値を出力する前後ではエラー処理を行っています。コントロールソースプロパティはテーブルのフィールドと連結可能、あるいは演算式を設定可能なコントロールしか持っていないため、それ以外のコントロールで参照しようとするとエラーとなるからです。
    • まず「On Error Resume Next」ステートメントで以降に発生するエラーを無視するようにします。
    • 次の行で変数strCtlSourceにControlSourceプロパティの値をセットしようとします。
    • もしそのプロパティがあれば正しく変数にセットされますが、なければ実際にはエラーが発生します(無視するようになっているのでプログラムは止まりません)。
    • 次の行で、「Err.Number」をチェックします。前行でエラーが発生していなければその値は「0」ですので、指定文字列有無の検査へ進みます。エラーが発生してれば「0以外」の値になっていますので、検査や出力は行わずに次へ進みます。
    • 「On Error GoTo 0」ステートメントによっていったんエラー無視を念のため解除しておきます。

  7. そのフォームを閉じます。
    ここではデータ収集のみでデザイン変更はありませんので、引数に「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

実行例:


| Index | Prev | Next |



Copyright © T'sWare All rights reserved