Microsoft Access 掲示板

メインフォーム上に置いたサブフォームコントロールのレコード移動時 / 9

16 コメント
views
9
hatena 2025/04/17 (木) 12:26:04 修正

サブフォームコントロールにクエリ(データシート)を設定した場合、
代替案はないでしょうか?というのが冒頭での質問の本意です。

そういうことでしたか。
ソースオブジェクトにテーブルやクエリを設定した場合、メインフォームを開いたときに自動でサブフォームオブジェクトが生成されますので、それにイベントを設定することができます。
Accessのフォームの場合、イベントプロパティにFunctionを設定できますので、それを利用すればご希望のことは実現可能です。

まず、標準モジュールに下記のFunctionを記述してください。

Function CurentEvent()
    With CodeContextObject
        Debug.Print "レコード移動しました!IDは" & !ID
        .Parent!テキスト1.Value = !ID
   End With
End Function

CodeContextObject はFunctionが呼び出されたオブジェクトを返します。

メインフォームの読み込み時イベントに下記のコードを設定してください。

Private Sub Form_Load()
    Me.サブフォームコントロール名.Form.OnCurrent = "=CurentEvent()"
End Sub

クエリにはIDフィールドがあり、メインフォームには「テキスト1」というテキストボックスがあるという前提です。

メインフォームを開いてサブフォームでレコード移動してみてください。
イベントが発生しているのが確認できるでしょう。

通報 ...
  • 10
    hiroton 2025/04/17 (木) 13:20:42 da23d@f966d >> 9

    あー、なるほど、そういう仕組みありましたねぇ。使わないとパッと出てこないです
    サブフォームを作る労力とどのくらい差があるかなぁとも思っていしまいますし

    11

    サブフォームを作る労力とどのくらい差があるかなぁとも思っていしまいますし

    ですよね。
    フォームウィザードでデータシートビューで作成すれば1分もかからずに作成できますからね。
    現状のロジックも参照先を変更するだけでそのまま使えるはずですし。

  • 12
    はづき 2025/04/17 (木) 13:44:01 69f3e@da8eb >> 9

    なな、なんと。そんなやり方ありましたか。
    確認させていただきます。

    13
    はづき 2025/04/17 (木) 14:45:48 69f3e@da8eb >> 12

    できないと思って原因を探ったところ、
    メインフォームの読み込み時に、UserNameによって、見える範囲(列)を動的に設定しています。
    あくまで簡易的なアクセス制限ですので、非表示で隠してあるテーブルとかクエリを直接見ることはできるのですが。

    具体的には、これが影響していると思われます。
    サブフォームコントロールのレコードソース:Qry_名簿です。
    UserNameに応じて、見せる属性をstrFileldsで生成して、クエリを置き換えています。

    currentdb.QueryDefs("Qry_名簿").SQL="select " & strFilelds & " from Mtbl_名簿"
    Me.サブフォームコントロール名.form.recordSource = "select * from Qry_名簿"

    Me.サブフォームコントロール名.Form.OnCurrent = "=CurentEvent()" ←------この場所で入れてもダメですか?

    上記の動的に変えているところを削除すると、イベントが発生することは画にしました。
    人により、列の属性数がかなり変わるので、見せない人には見せない属性の存在も知らせたくない、
    といったこともあり、パターンを網羅した固定サブフォームは作り難いという背景もありました。

    14
    hatena 2025/04/17 (木) 18:16:30 修正 >> 12

    簡単なサンプルを作成して動作確認してみました。

    テーブル
     Mtbl_名簿 (ID, F1, F2, F3, F4)

    クエリ Qry_名簿
     SELECT ID, F1 FROM Mtbl_名簿;

    メインフォーム
     テキストボックス テキスト1

    コンボボックス cbFilelds
     値集合タイプ 値リスト
     値集合ソース F2;F3;F4
     規定値 "F2"

    サブフォームコントロール SF1
     ソースオブジェクト 空欄

    メインフォームのフォームモジュール

    Option Compare Database
    Option Explicit
    
    Private Sub Form_Load()
        SetSFList
    End Sub
    
    Private Sub cbFilelds_AfterUpdate()
        SetSFList
    End Sub
    
    Public Sub SetSFList()
        Dim strFilelds As String
        strFilelds = "ID, F1, " & Me.cbFilelds
    
        CurrentDb.QueryDefs("Qry_名簿").SQL = "select " & strFilelds & " from Mtbl_名簿"
        Me.SF1.SourceObject = "クエリ.Qry_名簿"
        Me.SF1.Form.OnCurrent = "=CurentEvent()"
    End Sub
    

    標準モジュール

    Function CurentEvent()
        With CodeContextObject
            Debug.Print "レコード移動しました!IDは" & !ID
            .Parent!テキスト1.Value = !ID
       End With
    End Function
    

    仕様
    サブフォームのリストには ID, F1 フィールドは常に表示
    コンボボックスで選択されたフィールドが表示

    上記でメインフォームを開くと、ID, F1, F2列が表示されている
    レコード移動するとイベントが発生してテキスト1にカレントのIDが表示される

    コンボボックスでフィールド名を変更するとサブフォームの表示も変更される
    レコード移動イベントも発生する。

    というように動作確認できました。

    15

    ポイントは、下記ですね。

    Me.SF1.Form.RecordSource = "SELECT ・・・・"
    というようにサブフォームの RecordSource を書き換えてもサブフォームオブジェクトは再生成されない。
    Me.SF1.SourceObject = "クエリ.Qry_名簿"
    というようにソースオブジェクトを設定すると再生成される。
    再生成される前にサブフォームのレコードソースのクエリのSQLを書き換えておく。
    その後、
    Me.SF1.Form.OnCurrent = "=CurentEvent()"
    というようにイベントを設定する。

    16
    はづき 2025/04/18 (金) 06:56:14 3a7d2@da8eb >> 12

    ポイントの通りの順番でやったらできました。
    完璧です!
    勉強になりました、どうもありがとうごいざいました。