In diesem Beispiel werden zwei Varianten gezeigt, um zwei Unterformulare ("Endlosformular" und "Einzelnes Formular") synchron zu halten. Eine Variante nutzt Ereignisse und Eigenschaften, um bei einem Datensatzwechsel die Datensätze zu synchronisieren. Die andere Variante verwendet eine gemeinsame Recordset-Instanz.
Ausgangslage
Es sollen in einem Hauptformular zwei Unterformulare miteinander verbunden werden, damit Datensatzwechsel in beiden Formularen synchron ablaufen.
Ein Unterformular ist ein Endlosformular, im anderen Unterformular (Detailansicht) wird nur ein Datensatz angezeigt.
Synchronisation über ein Ereignis
Diese Variante erlaubt einen sehr flexiblen Einsatz. Diese Flexibilität erfordert allerdings etwas mehr Code als anderer Synchronistationsmöglichkeiten.
Konzept
Das Endlosformular löst ein Ereignis aus, auf welches im Formular für die Detailansicht reagiert wird.
Wenn im Detailformular der Datensatz gewechselt wird, gibt das Formular diese Information an eine Methode des Endlosformulars weiter.
Man könnte auch im Detailformular ein Ereignis auslösen und im Endlosformular darauf reagieren. Das hat allerdings den Nachteil, dass ein Zirkelbezug zwischen den Formularinstanzen entsteht, der zusätzlich behandelt werden müsste.
Codeauszüge
Endlosformular
Ereignisdeklaration
Public Event RecordsetSelected(ByVal DS_ID As Variant)
Ereignis bei Datensatzwechsel auslösen
Private Sub Form_Current() RaiseEvent RecordsetSelected(Me!id) 'Ereignis auslösen End Sub
Methode zum Wechseln des Datensatzes
Public Sub SetCurrentID(newID As Variant, bRequery As Boolean) 'zu DS mit ID wechseln If Me!id = newID Then If bRequery Then Me.Refresh Else If bRequery Then Me.Requery 'z. B. falls neuer DS erstellt wurde If IsNull(newID) Then Exit Sub 'nach NULL suchen bringt nichts, höchsten zu neuem DS wechseln? Me.Recordset.FindFirst "id=" & Nz(newID, 0) End If End Sub
Detailformular
Deklaration mit Withevents
Dim WithEvents m_EndlosForm As Form_frmEndlos
Reaktion auf RecordsetSelecte
Private Sub m_EndlosForm_RecordsetSelected(ByVal DS_ID As Variant) If Not blockRecordsetSelectedEvent Then blockRecordsetSelectedEvent = True findDsID DS_ID blockRecordsetSelectedEvent = False End If End Sub
Datensatzwechsel ans Endlosformular übergeben
Private Sub Form_Current() If Not blockRecordsetSelectedEvent Then blockRecordsetSelectedEvent = True setListFormDsID Me!id blockRecordsetSelectedEvent = False End If End Sub Private Sub setListFormDsID(ByVal DS_ID As Variant) If Not m_EndlosForm Is Nothing Then m_EndlosForm.SetCurrentID DS_ID, True End If End Sub
Mit blockRecordsetSelectedEvent
wird verhindert, dass zu einer nicht erforderlichen Reaktion auf das Ereignis RecordsetSelected
kommt
Übergabe der Endlosformular-Instanz
Public Property Set ListForm(ByRef frm As Form_frmEndlos) Set m_EndlosForm = Nothing If Not (frm Is Nothing) Then blockRecordsetSelectedEvent = True findDsID frm.CurrentID blockRecordsetSelectedEvent = False Set m_EndlosForm = frm End If End Property
Hauptformular
Im Hauptformular muss nun noch dafür gesorgt werden, dass die beiden Formularen zusammenarbeiten können.
Private Sub Form_Load() 'Unterformulare gesteuert laden Me.sfrEndlos.SourceObject = "frmEndlos" Me.sfrDetail.SourceObject = "frmDetail" 'dem Formular frmDetail die Form-Referenz von frmEndlos in sfrEndlos übergeben, 'damit auf Events reagiert werden kann: Set Me.sfrDetail.Form.ListForm = Me.sfrEndlos.Form End Sub
Synchronisation über ein gemeinsames Recordset
Wenn beide Formulare eine identische Datenbasis haben, kann man eine Varainte verwenden, die nur aus wenigen Code-Zeilen besteht.
Man muss nur dafür sorgen, dass beide Formulare ein gemeinsames Recordset verwenden.
Code im Hauptformular
Private Sub Form_Load() 'Unterformulare gesteuert laden Me.sfrEndlos.SourceObject = "frmEndlos" Me.sfrDetail.SourceObject = "frmDetail" 'im Form frmDetail das Recordset von Form frmEndlose verwenden: Set Me.sfrDetail.Form.Recordset = Me.sfrEndlos.Form.Recordset End Sub
Weiterer Code ist nicht erforderlich.