Mehrere Instanzen eines Formulars öffnen

Diskussionen über den Quellcode (Module, Klassenstruktur, Schnittstellen u.s.w.) der Access Code Library

Mehrere Instanzen eines Formulars öffnen

Beitragvon Josef Pötzl » Fr 13. Okt 2017, 08:50

Hallo!

Wenn man von einem Formulare mehrere Instanzen öffnen möchte (z. B. falls der User Daten vergleichen will), muss man diese Instanzen über New erzeugen, da Docmd.OpenForm nicht verwendet werden kann.
Will man dann das Formular offen halten, muss eine Referenz irgendwo gespeichert blieben. Das kann eine Collection, eine Variable im Formular o. ä. sein.

Was haltet ihr von folgendem Konstrukt:

Aufrufbeispiele
Code: Alles auswählen
'Standard:
DoCmd.OpenForm "Formular1"

'Neue Instanz (über select-case-Kosntrukt) + Instanz offen lassen
DoCmd.OpenForm "Formular1", , , , , , , True, True

'Neue Instanz mit New, OpenForm für das Offenlassen der Instanz verwenden
DoCmd.OpenForm New Form_Formular1, , , , , , , True

'Verwendung in With, da Form-Ref der Rückgabewert der OpenForm-Funktion ist
With DoCmd.OpenForm("Formular1", , , , , , , True, True)
   .Section(acDetail).BackColor = vbYellow
End With





Der Code-Hintergrund
Im Formular, das geöffnet werden soll, ist keine Codeanpassung notwendig.

Angepasste OpenForm-Prozedur:
Code: Alles auswählen
Public Function OpenForm(ByVal FormNameOrInstance As Variant, Optional ByVal View As AcFormView = acNormal, _
           Optional ByVal FilterName As Variant, Optional ByVal WhereCondition As Variant, _
           Optional ByVal DataMode As AcFormOpenDataMode = acFormPropertySettings, Optional ByVal WindowMode As AcWindowMode = acWindowNormal, _
           Optional ByVal OpenArgs As Variant, _
           Optional ByVal UseComSelfRef As Boolean = False, Optional ByVal NewInstance As Boolean = False) As Form

   Dim FormRef As Form
   
   If Not (IsObject(FormNameOrInstance) Or NewInstance) Then
      Set OpenForm = OpenFormByName(FormNameOrInstance, View, FilterName, WhereCondition, DataMode, WindowMode, OpenArgs)
   Else
   
      If Not IsObject(FormNameOrInstance) Then
         Set FormRef = GetFormInstanceByName(FormNameOrInstance)
      ElseIf TypeOf FormNameOrInstance Is Access.Form Then
         Set FormRef = FormNameOrInstance
      Else
         Err.Raise vbObjectError, "DoCmdX.OpenForm", "Übergebene Objektreferenz ist kein Formular"
      End If
   
      Set OpenForm = OpenFormInstance(FormRef, View, FilterName, WhereCondition, DataMode, WindowMode, OpenArgs, UseComSelfRef)
   
   End If
   
End Function

Private Function OpenFormByName(ByVal FormName As Variant, Optional ByVal View As AcFormView = acNormal, _
           Optional ByVal FilterName As Variant, Optional ByVal WhereCondition As Variant, _
           Optional ByVal DataMode As AcFormOpenDataMode = acFormPropertySettings, Optional ByVal WindowMode As AcWindowMode = acWindowNormal, _
           Optional ByVal OpenArgs As Variant) As Form
   
      Application.DoCmd.OpenForm FormName, View, FilterName, WhereCondition, DataMode, WindowMode, OpenArgs
      If WindowMode <> acDialog Then
      If CurrentProject.AllForms(FormName).IsLoaded Then
         Set OpenFormByName = Forms(FormName)
      End If
      End If
   
End Function

Public Function OpenFormInstance(ByVal FormRef As Form, Optional ByVal View As AcFormView = acNormal, _
           Optional ByVal FilterName As Variant, Optional ByVal WhereCondition As Variant, _
           Optional ByVal DataMode As AcFormOpenDataMode = acFormPropertySettings, Optional ByVal WindowMode As AcWindowMode = acWindowNormal, _
           Optional ByVal OpenArgs As Variant, _
           Optional ByVal UseComSelfRef As Boolean = False) As Form

   If Not IsMissing(OpenArgs) Then
      FormRef.OpenArgs = OpenArgs
   End If
   
   If WindowMode <> acHidden Then
      FormRef.Visible = True
   End If
   
   If UseComSelfRef Then
      With New FormRefSaver
         Set .Form = FormRef
      End With
   End If
     
   Set OpenFormInstance = FormRef

End Function
 


Falls man Docmd.OpenForm statt EigeneInstanz.OpenForm verwenden will, muss noch zusätzlich DoCmd überschrieben werden (dann müssen aber auch alle Methoden von Application.DoCmd eingebaut werden).
Weiteres ist es für die Instanzieren über den Formularnamen notwendig, eine Prozedur zu erstellen, die über den Namen einen Instanz erzeugt. (Select-Case-Konstrukt) - Das würde ich in einem Add-In umsetzen.

Ein Konzept-Beispiel ist im Anhang.

mfg
Josef
Dateianhänge
OpenFormEreiterung.zip
Konzept-Beispiel
(26.92 KiB) 991-mal heruntergeladen
Josef Pötzl
Moderator
 
Beiträge: 805
Registriert: Mo 30. Nov 2009, 10:08
Wohnort: Klagenfurt
Accessversion: 2016

Zurück zu Quellcode

cron