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