Formular- und Datenbankeinstellungen speichern und wiederherstellen

15.02.2007
Jeder Benutzer hat eine andere Art zu arbeiten. Daher ist es sehr lästig, wenn Access dem Benutzer per Standardeinstellungen für Formulargrößen und -anordnung vorschreibt, wie sein Bildschirm auszusehen hat. Ich zeige Ihnen, wie Sie Ihre Formulare, Berichte und die Datenbankanwendung mit Code ausstatten, der die persönlichen Einstellungen des Anwenders beim nächsten Starten der Anwendung wiederherstellt.

Viele Benutzer ärgern sich darüber, wenn sie immer wieder die Fenster neu positionieren müssen, weil sie sich mittig öffnen und dann stören. Gleiches gilt für Symbolleisten, die immer wieder manuell eingeblendet werden müssen, weil Access sie ausblendet oder nur die Standardsymbolleisten sichtbar macht. Alle diese Einstellungen können Sie jedoch mit verhältnismäßig wenig Aufwand speichern und so beim nächsten Öffnen eines Formulars oder der Datenbank wiederherstellen.

Daten speichern, aber wo?

Generell könnte man natürlich solche Daten in der Datenbank selbst ablegen. In vielen Fällen ist das einer der großen Vorteile von Access gegenüber anderen VBA-Hostanwendungen. Arbeiten aber mehrere Personen mit der gleichen Datenbank, beispielsweise zwei Halbtagskräfte an einem Rechner, müssten sich beide die Einstellungen teilen.

Besser ist in diesem Fall die Speicherung in der Registry, da VBA die Einstellungen im Zweig HKEY_CURRENT_USER für jeden Benutzer separat speichert. Jeder kann daher seine eigenen Einstellungen verwenden. Sie können die Einstellungen ganz bequem mit SaveSetting schreiben und mit GetSetting aus der Registry lesen.

Einstellungen von Access

Wichtig an den Access-Einstellungen sind beispielsweise die sichtbaren und unsichtbaren Befehlsleisten. Möchten Sie diese speichern, um sie bei Bedarf wieder einzublenden, ist das im Prinzip ganz schnell erledigt. Sie durchlaufen einfach alle Befehlsleisten und prüfen deren Visible-Eigenschaft. Die Namen aller Befehlsleisten, bei denen diese den Wert True hat, fügen Sie dann an eine semikolonseparierte Liste in der Variablen strNamen an. Diese Liste speichern Sie in der Registry (Listing 1).

Const appName = "MeineAnwendung" 'Hier eindeutigen Namen festlegen
Sub AnwEinstellungenSpeichern()
Dim objCBar As CommandBar
Dim strTemp As String
'Alte Einstellungen löschen
On Error Resume Next
DeleteSetting appName, "Anwendung", _
"Symbolleisten"
'Sichtbare Befehlsleisten ermitteln
On Error GoTo 0
For Each objCBar In Application.CommandBars
If objCBar.Visible = True Then
strTemp = strTemp & ";" & objCBar.Name
End If
Next objCBar
strTemp = Mid(strTemp, 2)
SaveSetting appName, "Anwendung", _
"Symbolleisten", strTemp
End Sub

Wichtig ist allerdings, dass Sie das Semikolon als Trennzeichen, das entweder hinter dem letzten Eintrag oder wie im Beispiel vor dem ersten Eintrag steht, abschneiden, bevor Sie den Wert speichern. Dazu wird hier noch die mid-Funktion aufgerufen und das erste Zeichen abgeschnitten. Im Anschluss wird die SaveSetting-Anweisung aufgerufen, um die Zeichenfolge zu speichern. Die Konstante appName ist dazu auf Modulebene definiert.

Das Lesen und Wiederherstellen der Einstellungen ist im Prinzip auch sehr einfach. Hier gilt jedoch zu beachten, dass Sie nicht zuerst alle Befehlsleisten ausblenden können, um dann die benötigten wieder einzublenden. Das geht deshalb nicht, weil zum einen mindestens eine Menüleiste sichtbar sein muss, zudem gibt es eingebaute Symbolleisten, die Sie nicht explizit ausblenden können. Aus diesem Grund müssen Sie in einem Rutsch alle unerwünschten Befehlsleisten einblenden und die nicht erwünschten ausblenden und dabei außerdem Fehlermeldungen unterdrücken (Listing 2).

Sub AnwEinstellungenLaden()
Dim objCBar As CommandBar
Dim strTemp As String
Dim arrString As Variant
strTemp = GetSetting(appName, "Anwendung", _
"Symbolleisten", "")
If strTemp > "" Then
arrString = Split(strTemp, ";")
Else
Exit Sub
End If
'Alle nicht gespeicherten Symbolleisten ausblenden
For Each objCBar In Application.CommandBars
On Error Resume Next
objCBar.Visible = inArray(objCBar.Name, arrString)
Next objCBar
On Error GoTo 0
End Sub
Function inArray(strWert As String, varArr As Variant) As Boolean
Dim strName As Variant
inArray = False
For Each strName In varArr
If strName = strWert Then
inArray = True
Exit For
End If
Next strName
End Function

Zuerst lesen Sie also die gespeicherte Zeichenkette aus der Registry aus und spalten sie dann mit der Split-Funktion in ein Array auf.

Anschließend durchlaufen Sie alle Befehlsleisten und prüfen für jede, ob deren Name im Array enthalten ist. Dazu benötigen Sie eine zusätzliche Funktion inArray. Ihr übergeben Sie das Array und den Namen der Befehlsleiste. Sie gibt einen booleschen Wert zurück, der bestimmt, ob der Wert im Array vorhanden ist. Sie müssen daher also nur der Visible-Eigenschaft den Rückgabewert der Funktion zuweisen.

Formulareigenschaften speichern und wiederherstellen

Auch die Eigenschaften von Formularen, wie Größe und Position der Formulare, können Sie in der Registry speichern. Der Einfachheit halber dient der Name des Formulars als Name des Schlüssels.

Die Position und Größe des Fensters ermitteln Sie über die Eigenschaft WindowWidth, Window Height, WindowTop und WindowLeft (Listing 3).

Sub FormularSpeichern(objForm As Form)
SaveSetting appName, objForm.Name, "Hoehe", objForm.WindowHeight
SaveSetting appName, objForm.Name, "Breite", objForm.WindowWidth
SaveSetting appName, objForm.Name, "Oben", objForm.WindowTop
SaveSetting appName, objForm.Name, "Links", objForm.WindowLeft
End Sub

Wenn Sie die gespeicherten Eigenschaften aus der Registry auslesen, können Sie diese aber nicht direkt den Eigenschaften zuweisen, weil sie schreibgeschützt sind. Stattdessen müssen Sie die gespeicherten Werte in Variablen speichern, die Sie dann an die Move-Methode des Formulars übergeben (Listing 4).

Sub FormularLaden(objForm As Form)
Dim lngBreite As Long
Dim lngHoehe As Long
Dim lngOben As Long
Dim lngLinks As Long
lngHoehe = GetSetting(appName, objForm.Name, _
"Hoehe", objForm.WindowHeight)
lngBreite = GetSetting(appName, objForm.Name, _
"Breite", objForm.WindowWidth)
lngOben = GetSetting(appName, objForm.Name, _
"Oben", objForm.WindowTop)
lngLinks = GetSetting(appName, objForm.Name, _
"Links", objForm.WindowLeft)
objForm.Move lngLinks, lngOben, lngBreite, lngHoehe
End Sub

Damit Formularposition und -größe auch für jedes einzelne Formular gespeichert werden, müssen Sie die Prozeduren natürlich noch aufrufen. Dazu müssen Sie in jedem Formular je eine Ereignisprozedur für das Load-Ereignis und das Unload-Ereignis erstellen (Listing 5).

Private Sub Form_Load()
FormularLaden Me
End Sub
Private Sub Form_Unload(Cancel As Integer)
FormularSpeichern Me
End Sub

Berichte

Für Berichte gilt prinzipiell das Gleiche, nur dass Sie hier den Bericht als Report-Objekt an die Prozeduren übergeben (Listing 6). Allerdings scheint Access hier die Breite und Höhe des Fensters nicht zu setzen, wenn Sie sie an die Move-Methode übergeben. Das sieht nach einem Bug von Access aus, da die Move-Methode für Berichte keinen Einschränkungen unterliegt.

Sub BerichtSpeichern(objRep As Report)
SaveSetting appName, objRep.Name, "Hoehe", objRep.WindowHeight
SaveSetting appName, objRep.Name, "Breite", objRep.WindowWidth
SaveSetting appName, objRep.Name, "Oben", objRep.WindowTop
SaveSetting appName, objRep.Name, "Links", objRep.WindowLeft
End Sub
Sub BerichtLaden(objRep As Report)
Dim lngBreite As Long
Dim lngHoehe As Long
Dim lngOben As Long
Dim lngLinks As Long
lngHoehe = GetSetting(appName, objRep.Name, _
"Hoehe", objRep.WindowHeight)
lngBreite = GetSetting(appName, objRep.Name, _
"Breite", objRep.WindowWidth)
lngOben = GetSetting(appName, objRep.Name, _
"Oben", objRep.WindowTop)
lngLinks = GetSetting(appName, objRep.Name, _
"Links", objRep.WindowLeft)
objRep.Move lngLinks, lngOben, lngBreite, lngHoehe
End Sub

Auch in Berichten müssen Sie die Prozeduren natürlich noch aufrufen, indem Sie in jedem Bericht die Ereignisprozeduren aus Listing 7 erstellen.

Private Sub Report_Close()
BerichtSpeichern Me
End Sub
Private Sub Report_Open(Cancel As Integer)
BerichtLaden Me
End Sub

Den Code beim Öffnen und Schließen der Datenbank ausführen

Die Einstellungen von Formularen und Berichten werden nun beim Öffnen und Schließen der Formulare und Berichte geladen und gespeichert. Für die Einstellungen der Datenbank müssen Sie sich aber noch etwas einfallen lassen. Optimal funktioniert das, wenn Sie ein Startformular haben, das beim Öffnen der Datenbank angezeigt wird und nur geschlossen werden kann, wenn auch die Datenbank geschlossen wird.

Wenn Sie ein solches Startformular verwenden und über Extras/Start festgelegt haben (Bild 1), müssen Sie dafür die Ereignisprozeduren aus Listing 8 erstellen. Beim Laden des Formulars rufen Sie die Prozedur AnwEinstellungenLaden auf und minimieren dann das Formular. Beim Schließen speichern Sie die Einstellungen mit der Prozedur AnwEinstellungenSpeichern und schließen dann die Datenbank mit der CloseCurrentDataBase-Methode.

Bild 1: Startformular festlegen.

Private Sub Form_Load()
AnwEinstellungenLaden
DoCmd.Minimize
End Sub
Private Sub Form_Unload(Cancel As Integer)
AnwEinstellungenSpeichern
Application.CloseCurrentDatabase
End Sub