Kalender mit Termineingabe

Sicherlich kennen Sie das Kalender-Steuerelement, das mit Access ausgeliefert wird. Klassischerweise setzen Sie es in Formularen ein, um die Datumsauswahl für Eingabefelder zu vereinfachen. Besonders komfortabel ist aber auch der Einsatz in Terminlisten, Projektplänen und ähnlichen Anwendungen. Zum Beispiel: In einem Formular soll links das Kalender-Steuerelement angezeigt werden. Nach einem Klick auf ein Datum werden dann rechts davon die passenden Termine angezeigt. Am einfachsten lässt sich das realisieren, wenn Sie eine Kombination aus Kalender- Steuerelement und Unterformular verwenden. Dabei wird das Datum direkt mit dem Kalender-Steuerelement verknüpft.

Sie finden hier einen Monatskalender, in dem Sie über zwei Kombinationsfelder komfortabel blättern können. Wenn Sie einen beliebigen Tag anklicken, erscheint direkt daneben automatisch eine Liste der bereits vorgemerkten Termine. Außerdem können Sie an dieser Stelle neue Einträge für den ausgewählten Tag vornehmen. Einfacher geht es nicht.

 

Sehen wir uns die Funktionsweise dieser Lösung einmal etwas genauer an. Die Grundlage bildet eine Tabelle „Termine“ mit den Feldern „tDatum“ (Datum des Termins), „tZeit“ (Uhrzeit für den Termin) und „tText“ (Beschreibung des Termins). Basierend auf dieser Tabelle, haben wir eine Abfrage „AFfrm Termine“ und ein Unterformular „UF Übersicht“ erstellt.

Zusammengesetzt wird das Ganze im Formular „Übersicht“. Hier haben wir zunächst links das Kalender-Steuerelement über den Befehl EINFÜGEN-ACTIVEXSTEUERELEMENT platziert. Rechts davon befindet sich ein Unterformular-Steuerelement, dem wir als Herkunftsobjekt „UF Übersicht“ zugeordnet haben.

Damit das Kalender-Steuerelement nicht zu viel Platz wegnimmt, haben wir die Anzeige von Monat und Jahr ausgeschaltet. Im Eigenschaftenfenster können Sie dazu auf der Registerkarte „Allgemein“ im Bereich „Anzeigen“ die Option „Monat/Jahr- Titel“ deaktivieren und die Änderung mit einem Klick auf OK übernehmen.

 

Steuerelement und Unterformular verknüpfen

Die Verknüpfung vom Kalender-Steuerelement zum Unterformular „UF Übersicht“ erfolgt über die Eigenschaften „Verknüpfen von“ und „Verknüpfen nach“ des Unterformular-Steuerelementes. Bei „Verknüpfen von“ geben Sie den Namen des Feldes im Unterformular an, das das Datum des Termins beinhaltet – in unserem Beispiel ist das „tDatum“. Bei „Verknüpfen nach“ geben Sie normalerweise den Namen eines Feldes des Hauptformulars an. Da in unserem Fall kein Feld, sondern ein Steuerelement verwendet wird, müssen Sie hier den Namen des Steuerelementes und die entsprechende Eigenschaft des Steuerelementes angeben, zu der verknüpft werden soll. Das Steuerelement heißt in unserem Beispiel „MsCal1“, die Eigenschaft, die das jeweils eingestellte Datum beinhaltet, hat den Namen „Wert“ (Value). Die Verknüpfung geht also von „MsaCal1.Wert“ zu „tDatum“.

Leider ist das erst die halbe Miete: Während Access bei Verknüpfungen zu Unterformularen, die auf Feldern basieren, das Unterformular automatisch nach einer Änderung aktualisiert, müssen Sie das bei einem ungebundenen Steuerelement manuell erledigen. Dazu müssen Sie in der Ereignisprozedur „Click“ die folgende Anweisung eingeben:

Me.UF_Übersicht.Requery

Klicken Sie dazu mit der rechten Maustaste auf das Kalender-Steuerelement, wählen Sie den Eintrag EREIGNIS aus dem Kontextmenü und wählen „Click“ in der Liste oben rechts im VBA-Editor. Nach Eingabe der oben gezeigter Anweisung schließen Sie den VBA-Editor wieder. Durch diese Anweisung wird nun nach jeder neuen Auswahl eines Datums das Unterformular entsprechend aktualisiert.

Es gibt allerdings ein Problem, das Sie kennen sollten: Die Auswahl eines neuen Monats/Jahres aus den Listen im Kalender- Steuerelement lässt sich auf diesem Weg nicht abfangen! Wenn nun beispielsweise im Unterformular die Termine für den 15. 3. 2004 angezeigt werden und der Anwender den Monat „Februar“ wählt, bleiben die Termine vom 15. 3. sichtbar. Erst wenn der Anwender auf einen Tag im Februar klickt, wird die Anzeige aktualisiert. Das lässt sich leider nicht ändern, da das Kalender-Steuerelement keine Ereignisprozeduren zur Verfügung stellt, um auf Monats- oder Jahreswechsel zu reagieren.

Und noch ein nützlicher Tipp: Wenn Sie ein Formular mit einem darin enthaltenen Kalender-Steuerelement öffnen, zeigt das Kalender-Steuerelement normalerweise immer das aktuelle Systemdatum an. Um das Kalender-Steuerelement auf ein anderes Datum zu setzen, verwenden Sie die Ereignisprozedur „Beim Laden“ des Formulars:

Private Sub Form_Load()
Me.MsCal1.Value = „12.3.2004“
Me.UF_Übersicht.Requery
End Sub

Durch diese Zuweisung ändern Sie Tag, Monat und Jahr für die Anzeige im Kalender- Steuerelement auf den 12. März 2004. Anschließend wird dann eine Aktualisierung des Unterformulars durchgeführt.

Inputbox für Anwendungen

Datenbank

Die Funktion „InputBox$()“ eignet sich hervorragend dazu, um in VBA-Routinen ohne viel Aufwand Informationen vom Anwender zu erfragen. Allerdings sieht die Eingabebox etwas schmucklos aus und bietet keinen Platz für Zusatzinformationen. Unsere Alternative besteht aus einer individuellen Funktion „InpBox()“, die Sie in Zukunft anstelle von „InputBox$()“ einsetzen können.

„InpBox()“ erwartet zunächst einmal die auch von „InputBox$()“ verwendeten Parameter:

Prompt: Hinweis an den Anwender über die erwartete Eingabe

Title: Text für die Titelleiste

Default: Vorgabe im Textfeld

Die optionalen „InputBox$“-Parameter „XPos“, „YPos“, „HelpFile“ und „Context“ unterstützt „InpBox()“ nicht, da sie erfahrungsgemäß kaum genutzt werden. Dafür kennt „InpBox()“ den Parameter „Help“, über den Sie einen Hilfetext übergeben können, der nach einem Klick auf eine Schaltfläche HILFE per „MsgBox“ angezeigt wird.

Die Aufrufsyntax sieht also folgendermaßen aus:

strX = InpBox(Prompt, [Title],[Default], [Help])

Die Parameter „Title“, „Default“ und „Help“ sind optional, „Prompt“ hingegen muss immer angegeben werden. Neben der bereits erwähnten HILFE-Schaltfläche verfügt „InpBox()“ über eine UNDOSchaltfläche, über die der Anwender bei Bedarf die Vorgabe wiederherstellen kann.

Das Ergebnis von „InpBox()“ ist analog zu „InputBox$()“ eine Zeichenkette (String) mit der Eingabe des Anwenders. Hat dieser auf ABBRECHEN geklickt, ist das Funktionsergebnis eine leere Zeichenkette („“).

Sie können also wie gewohnt den Erfolg einer Eingabe durch eine Ab frage auf den Leerstring feststellen:

…..
strX = InpBox(„Bitte den gesuchten Ort eingeben:“, _
„Ort eingeben:“, _
„Hamburg“)
If strX = „“ Then Exit Sub
…..

Um die neue Funktion „InpBox()“ in eigenen Projekten zu nutzen, übertragen Sie zunächst das Formular „frmInpBox“ und das Modul „modInpBox“ aus der Beispieldatenbank in Ihre Datenbank.

Um den Import direkt zu testen, öffnen Sie über Strg+G das Testfenster bzw. den Direktbereich und geben die folgen de Anweisung ein:

? InpBox(„Bitte etwas eingeben“,“Test“,“Vorgabe“)

Der neue Eingabedialog wird nun an gezeigt, nimmt die Eingabe entgegen und gibt das Ergebnis im Testfenster/Direktbereich aus. Die Schaltflächen OK und ABBRECHEN sind übrigens, wie bei „Input Box$()“, als Standard für die Return-Taste bzw. für die Esc-Taste gesetzt, sodass die Eingabe sofort mit dem Drücken der Return-Taste übernommen oder mit der Esc-Taste abgebrochen werden kann.


Modul: modInpBox

 

Haupt- und Detaildatensätze löschen

Frage: Ich habe eine Adressverwaltung aufgebaut, die aus zwei Tabellen „Adressen“ und „Ansprechpartner“ besteht. Die Tabellen sind über ein Feld „AdressNr“ verbunden; die Ansprechpartner werden als Unterformular im Hauptformular für die Adressen angezeigt. Die zweite Tabelle ist notwendig, weil pro Kunde durchaus 20 oder mehr Ansprechpartner vorhanden sein können und ich das gern flexibel handhaben möchte. Nun habe ich folgendes Problem: Wenn ich einen Kunden lösche, verbleiben die damit verbundenen Datensätze eventueller Ansprechpartner in der Tabelle „Ansprechpartner“ und müssen dort manuell gelöscht werden.

Wie lässt sich das automatisieren?

Antwort: Sie müssen dazu die beiden Tabellen in Beziehung bringen und referenzielle Integrität einschalten.

Dann kümmert sich Access darum, dass beim Löschen eines Hauptdatensatzes auch alle Detaildatensätze gelöscht werden. So geht’s:

  1. Wählen Sie das Menü EXTRAS-BEZIE – HUNGEN an (Access 2003, 2002/XP und 2000) bzw. klicken Sie im Register „Entwicklertools“ in der Gruppe „Einblenden/Ausblenden“ auf BEZIE – HUNGEN (Access 2010/2007).
  2. Fügen Sie die beiden Tabellen hinzu.
  3. Ziehen Sie das Feld „AdressNr“ aus der Tabelle „Adressen“ auf das Feld „AdressNr“ der Tabelle „Ansprechpartner“, um eine Beziehung herzu – stellen.
  4. Doppelklicken Sie auf die Verbindungslinie.
  5. m nachfolgenden Dialog aktivieren Sie die Option MIT REFERENTIELLER INTEGRITÄT und dann die Option LÖSCHWEITERGABE AN VERWANDTE DATENSÄTZE.
  6. Klicken Sie auf OK und blenden Sie das Fenster „Beziehungen“ wieder aus. In Zukunft sorgt Access automatisch dafür, dass beim Löschen von Hauptdatensätzen auch die dazugehörenden Detaildatensätze gelöscht werden.

In Zukunft sorgt Access automatisch dafür, dass beim Löschen von Hauptdatensätzen auch die dazugehörenden Detaildatensätze gelöscht werden.

Formular / Bericht unterbrechen

Datenbank

Bei der Entwicklung Ihrer Access-Lösungen stehen Sie immer wieder vor dem Problem, dass eine VBA-Routine genau so lange unterbrochen werden muss, bis ein zuvor geöffnetes Formular oder ein in der Seitenansicht angezeigter Bericht wieder geschlossen ist.

Mit der Anweisung

DoCmd.OpenForm „Neuer Datensatz“, , , , ,acDialog

lässt sich hier nur bedingt arbeiten, da sie

1. nicht mit Berichten angewendet werden kann (denn hier gibt es keinen „acDialog“-Modus) und

2. nicht immer alle Formulare als Dialoge angezeigt werden können, weil beispielsweise auch der Einsatz von Formularen denkbar ist, die nebeneinander angezeigt werden.

Sie können aber zur Lösung des Problems auf ein wenig beachtetes Feature der „Sys- Cmd()“-Funktion zurückgreifen: Über die Sub-Funktion „GetObjectState()“ von SysCmd() lässt sich recht einfach feststellen, ob ein Formular oder ein Bericht geöffnet ist. Solange das der Fall ist, können Sie in einer entsprechenden Schleife warten.

In der Beispieldatenbank VBA_WARTEN. MDB finden Sie ein Modul „basWaitObjects“, das wir für Sie vorbereitet haben und das Sie direkt in eigene Projekte übernehmen können. In diesem Modul sind die beiden Prozeduren „WaitForm“ und „WaitReport“ abgelegt:

Sub WaitForm(strForm As String)
While SysCmd(acSysCmdGetObjectState, acForm, strForm)
DoEvents
Wend
End Sub


Sub WaitReport(strReport As String)
While SysCmd(acSysCmdGetObjectState, acReport, strReport)
DoEvents
Wend
End Sub

Die Funktion SysCmd() prüft hier jeweils über die Sub-Funktion „acSysCmdGet- ObjectState“, ob das Objekt, dessen Name als Parameter übergeben wurde, geladen ist. Sollte das der Fall sein, ist das Funktionsergebnis „True“ und die Schleife wird weiter ausgeführt. Andernfalls ist das Objekt geschlossen worden und die Schleife ist beendet.

Es geht dann in der VBA-Routine weiter, von der aus Sie die Prozedur aufgerufen haben. Die Anweisung „DoEvents“ sorgt jeweils dafür, dass Access innerhalb der Schleife Prozessorzeit an das System zurückgibt und so die Performance nicht bremst.

Diese beiden Prozeduren können Sie in Zukunft in VBA-Routinen einsetzen, um mit der Ausführung zu warten, bis ein Formular oder Bericht wieder geschlossen ist. In der Beispielsdatenbank finden Sie das Formular „Test für WaitForm/Wait- Report“, in dem die Prozeduren über zwei Schaltflächen getestet werden können:

Private Sub btnTestForm_Click()
DoCmd.OpenForm „Test-Formular“
WaitForm „Test-Formular“
MsgBox „Formular wurde geschlossen!“
End Sub

Hier wird zunächst ein Formular geöffnet und anschließend die Prozedur „WaitForm“ mit dem Namen des betreffenden Formulars als Parameter aufgerufen. „WaitForm“ wartet nun so lange, bis das Formular geschlossen ist, anschließend geht es in der VBA-Routine weiter. Sie zeigt hier zu Testzwecken eine kleine Meldung an. Genauso einfach warten Sie auch darauf, dass ein Bericht wieder geschlossen wird:

Private Sub btnTestReport_Click()
DoCmd.OpenReport „Test-Bericht“, acViewPreview
WaitReport „Test-Bericht“
MsgBox „Bericht wurde geschlossen!“
End Sub


Modul: basWaitObjects


Formulare und Datenbanken automatisch schließen

Datenbank

Solange in Access ein Formular geöffnet ist, wird der aktuell bearbeitete Datensatz für jeden weiteren Zugriff gesperrt. Außerdem sind Änderungen an Tabellen nicht möglich. Der Datensatz erst wieder freigegeben, wenn der Anwender den Datensatz wechselt oder das Formular bzw. die Datenbank schließt. Auf diese Weise stellt Access sicher, dass in Mehrbenutzerumgebungen ein Datensatz nicht von mehreren Anwendern gleichzeitig bearbeitet wird und sich die Änderungen womöglich gegenseitig überschreiben. Gleichzeitig unterbindet Access Änderungen am Entwurf von Tabellen, während sich noch Datensätze in Bearbeitung befinden, und verhindert so, dass sie aufgrund von Strukturoder Feldänderungen nicht mehr gespeichert werden können und verloren gehen.

Diese eigentlich sehr sinnvolle Einrichtung hat auch einen Nachteil: Verlässt z. B. ein Mitarbeiter den Arbeitsplatz, um in die Mittagspause zu gehen oder sogar Feierabend zu machen, ohne die Datenbank mit ein oder mehreren geöffneten Formularen wieder zu schließen, bleibt nicht nur der aktuelle Datensatz gesperrt. An den entsprechenden Tabellen können auch keine Änderungen vorgenommen werden und die Mehrbenutzerdatenbank lässt sich nicht komprimieren oder reparieren.

Wir bieten Ihnen in diesem Beitrag eine effektive Lösung für dieses Problem. Dabei überwachen Sie die Aktivität in einem Formular und schließen es dann – optional zusammen mit der kompletten Datenbank –, wenn eine gewisse Zeit keine Tastatureingaben oder Mausbewegungen zu verzeichnen sind.

Inaktivität des Anwenders prüfen
Im ersten Schritt ist dafür zu sorgen, dass jeder Tastendruck und jede Mausbewegung das Setzen eines Aktivitätskennzeichens auslöst. Dieses Kennzeichen wird in bestimmten Abständen geprüft. Wurde es einige Zeit nicht verändert, hat der Anwender keine Eingaben vorgenommen oder die Maus nicht bewegt. Dann wird das Formular geschlossen bzw. die Datenbank beendet. Access stellt zur Erledigung solcher Aufgaben für Formulare einen Zeitgeber (Timer) zur Verfügung, der in bestimmten Abständen ein Ereignis auslöst. Dieser Zeitraum ist über die Eigenschaft „Zeitgeberintervall“ des Formulars in Tausendstelsekunden (Millisekunden) einstellbar. In der dazugehörigen Ereignisprozedur des Timers können Sie das erwähnte Aktivitätskennzeichen abfragen und bei Bedarf entsprechende Maß nahmen ergreifen.

Tastatur- und Mausaktionen festhalten
Wie aber können Sie nun feststellen, ob der Anwender mit einem Formular tatsächlich arbeitet? Zu diesem Zweck lassen sich die Ereignisse „Bei Taste“ und „Bei Mausbewegung“ aller Steuerelemente und des Formulars nutzen. Wann immer der Anwender eine Taste drückt oder die Maus bewegt, kann über diese Ereignisprozeduren festgehalten werden, dass eine Aktion stattgefunden hat. Wir verwenden dazu eine Funktion „TimeOut()“, die eine globale Variable „TimeoutFlag“ auf „1“ setzt und so signalisiert, dass eine Aktion stattgefunden hat. Diese Variable kann der Timer des Formulars regelmäßig prüfen und auf „0“ zurücksetzen. Steht die Variable beim nächsten Auslösen des Timer-Ereignisses immer noch auf „0“, hat der Anwender weder eine Taste gedrückt noch die Maus bewegt; das Formular wird geschlossen und die Datenbank ggf. verlassen. Wichtig: Der Timer eines Formulars ist Dreh- und Angelpunkt der Lösung. Dem entsprechend muss es in der betreffenden Datenbank ein Formular geben, das über seine Ereignisprozeduren die Aktivitäten des Anwenders registrieren kann. Für die Nutzung dieser Technik in Ihren Mehrbenutzerdatenbanken können wir nur bedingt eine vorbereitete Lösung liefern. Vielmehr müssen Sie die Steuerelemente in jedem Formular, das Datensätze oder Tabellen blockieren könnte, entsprechend anpassen. Das hört sich zunächst nach viel Aufwand an, aber glücklicherweise können Sie die meisten Einstellungen für mehrere markierte Steuerelemente ein einem Durchgang vornehmen:

  1. Öffnen Sie das gewünschte Formular im Entwurfsmodus, wechseln Sie mit Alt + F11 in die VBA-Entwicklungsumgebung und deklarieren Sie hier zunächst im allgemeinen Teil die globale Variable „TimeoutFlag“
    Dim TimeoutFlag As Integer

  2. Geben Sie anschließend die folgende Funktion ein:
    Function TimeOut()
    TimeoutFlag = 1
    End Function

  3. Diese Funktion ordnen Sie nun allen Steuerelementen in den Eigenschaften „Bei Taste“ und „Bei Mausbewegung“ zu. Markieren Sie dazu alle Steuerelemente gemeinsam mit gedrückter Umschalt-Taste und wählen Sie dann das Menü ANSICHT-EIGENSCHAFTEN an bzw. klicken Sie auf EIGENSCHAFTENBLATT. Im Eigenschaftenfenster können Sie die Ereignisprozeduren für alle Steuerelemente gemeinsam setzen, indem Sie hier jeweils „=TimeOut()“ eingeben.

  4. Öffnen Sie dann das Eigenschaftenfenster für das Formular, in dem Sie einen Doppelklick in den grauen Bereich unter dem Detailbereich ausführen. Die Eigenschaft „Tastenvorschau“ setzen Sie zunächst auf „Ja“. Tragen Sie dann in den Eigen schaften „Bei Taste“ und „Bei Mausbewegung“ ebenfalls „=TimeOut()“ ein.

  5.  Danach markieren Sie der Reihe nach Seiten-/Formularkopf und -fuß sowie Detailbereich und stellen hier die Eigenschaft „Bei Mausbewegung“ auf „=TimeOut()“.

Formulare automatisch schließen
Mit diesen Anpassungen haben Sie nun sichergestellt, dass alle Anwenderaktionen entdeckt und über die Funktion „TimeOut() in der globalen Variablen „TimeoutFlag“ festgehalten werden. Wenn der Anwender nun in ein Feld klickt und eine Eingabe vornimmt oder die Maus über Felder und Formular bewegt, wird diese Aktion protokolliert. Beim Aufruf der Timer-Routine steht also jeweils eine „1“ in der globalen Variablen „Timeout- Flag“. Dazu gleich noch etwas mehr. Im nächsten Schritt muss zunächst noch die Timer-Routine eingerichtet werden:

  1. Stellen Sie die Eigenschaft „Zeitgeberintervall“ des Formulars auf „180000“ ein. Diese Angabe erfolgt in Millisekunden und bedeutet somit, dass die Ereignisprozedur des Timers alle drei Minuten aufgerufen wird.
  2. Stellen Sie die Eigenschaft „Bei Zeitgeber“ auf „Ereignisprozedur“ ein und klicken Sie auf die Schaltfläche mit den drei Punkten, um den VBA-Editor zu starten. Hier geben Sie nun die folgenden Anweisungen ein: Private Sub Form_Timer()
    If TimeoutFlag = 0 Then
    DoCmd.Close acForm,
    Me.Name, acSaveNo
    End If
    TimeoutFlag = 0
    DoEvents
    End Sub

    Die Ereignisprozedur des Timers prüft hier zunächst, ob die Variable „TimeoutFlag“ auf „0“ steht. Ist das der Fall, hat der Anwender drei Minuten nichts getan und das Formular wird geschlossen. Ansonsten wird „TimeoutFlag“ zurück auf „0“ gesetzt. Bis zum nächsten Aufruf der Ereignisprozedur des Timers vergehen nun drei Minuten, in denen eventuell eine Aktion erfolgt und „TimeoutFlag“ wieder auf „1“ gesetzt wird.

Datenbank automatisch beenden
Möchten Sie nicht nur Formulare automatisch schließen, sondern auch die komplette Datenbank bei Inaktivität beenden, nutzen Sie ein Menüformular, das automatisch beim Start der Datenbank geöffnet wird und die Datenbank bei Inaktivität beendet:

 

  1. Setzen Sie zunächst die Eigenschaft „Zeitgeberintervall“ des Menüformulars auf „1800000“. Dieser Wert entspricht 30 Minuten. Bleibt das Menü also 30 Minuten ohne Aktivität des Anwenders an gezeigt, wird die Datenbank verlassen beziehungsweise Access beendet.
  2. Stellen Sie anschließend die Eigenschaft „Bei Deaktivierung“ des Formulars auf „[Ereignisprozedur]“ ein und geben dort folgende Anweisung ein: Diese Anweisung sorgt dafür, dass beim Aufruf eines anderen Formulars der Timer des Menüformulars aus geschaltet wird. Andernfalls würde das Menü irgendwann wegen vermeintlicher Inaktivität des Anwenders die Datenbank schließen und so die Arbeit im anderen Formular sabotieren.
  3. Stellen Sie die Eigenschaft „Bei Aktivierung“ des Formulars auf „[Ereignisprozedur]“ ein und geben Sie die folgende Anweisung ein: Diese Prozedur sorgt nun dafür, dass nach dem Schließen des anderen Formulars und damit bei der Aktivierung des Menüformulars der Timer wieder eingeschaltet wird und wieder alle 30 Minuten auf Inaktivität prüfen kann.
  4. Die Timer-Prozedur sieht in einem Menüformular folgendermaßen aus: Anstelle von „DoCmd.Close“ zum Schließen eines Formulars wird hier ein „DoCmd.Quit“ zum Beenden von Access und somit zum Schließen der Datenbank ausgeführt.

In der Beispieldatenbank wird diese Technik im Formular „Hauptmenü“ demonstriert. Zum Testen werden einfach mehrere Ins tanzen des Formulars „Kunden“ geöffnet. Der Timer-Intervall für das Menüformular ist auf 60 Sekunden eingestellt.

Formular automatisch schließen

Wenn Sie in Access ein Formular benutzen, ist der aktuell bearbeitete Datensatz für jeden anderen Zugriff gesperrt, bis der Datensatz gewechselt oder das Formular geschlossen wird. Dadurch stellt Access sicher, dass in Mehrbenutzerumgebungen nicht verschiedene Anwender den gleichen Datensatz bearbeiten und sich so die Änderungen gegenseitig überschreiben. Diese sinnvolle Einrichtung hat allerdings auch einen großen Nachteil: Geht der betreffende Mitarbeiter in ein Meeting oder in die Mittagspause, ohne das Formular zu schließen, so bleibt der aktuelle Datensatz gesperrt, bis er zurückkehrt und das Formular irgendwann schließt. Der Datensatz kann also so lange nicht von anderen Mitarbeitern bearbeitet werden. Im Folgenden zeigen wir Ihnen nun einen Mechanismus, der ein Formular automatisch schließt, wenn der Anwender eine gewisse Zeit keine Eingaben vornimmt oder die Maus nicht bewegt.

Nutzen Sie den Formular-Timer

Eine Lösung, die ein Formular automatisch bei Nichtbenutzung schließt, lässt sich relativ einfach realisieren, da Access für Formulare einen Zeitgeber (Timer) zur Verfügung stellt, der in bestimmten Abständen ein Ereignis auslöst. Dieser Zeitraum ist über die Eigenschaft „Zeitgeberintervall“ des Formulars in Tausendstel Sekunden einstellbar. In der dazugehörigen Ereignisprozedur des Timers können wir dann entsprechende Abfragen vornehmen und zum Beispiel das Formular schließen, sodass der aktuell gesperrte Datensatz wieder freigegeben wird. Dabei ist allerdings zu prüfen, ob der Anwender zwischendurch Eingaben vornimmt oder die Maus bewegt – es kann ja durchaus möglich sein, dass Änderungen an einem Datensatz länger als das eingestellte Zeitintervall dauern.

Wie kann man nun feststellen, ob der Anwender irgendetwas getan hat? Dazu werden die Ereignisse „Bei Taste“ und „Bei Mausbewegung“ aller Steuerelemente und des Formulars eingesetzt. Wann immer der Anwender eine Taste drückt oder die Maus bewegt, kann über diese Ereignisprozeduren festgehalten werden, dass eine Aktion stattgefunden hat. Das erfolgt am einfachsten über eine Funktion „TimeOut()“, die eine globale Variable „TimeoutFlag“ auf „1“ setzt und somit signalisiert, dass eine Aktion stattgefunden hat.

Diese Variable kann der Timer des Formulars regelmäßig prüfen und zurücksetzen. Steht die Variable dann irgendwann einmal auf „0“, so hat der Anwender weder eine Taste gedrückt noch die Maus bewegt, das Formular wird geschlossen. Wechseln Sie also in den VBA-Editor und legen Sie zunächst im allgemeinen Teil des Formulars die globale Variable „TimeoutFlag“ sowie die folgende Funktion an:

Dim TimeoutFlag As Integer
Function TimeOut ()
TimeoutFlag = 1
End Function

Den Aufruf dieser Funktion ordnen Sie nun allen Steuerelementen in den Eigenschaften „Bei Taste“ und „Bei Mausbewegung“ zu. Markieren Sie dazu alle Steuerelemente gemeinsam und wählen Sie dann das Menü ANSICHT-EIGENSCHAFTEN an. Im Eigenschaftenfenster können Sie dann die Ereignisprozeduren für alle Steuerelemente gemeinsam setzen. Geben Sie hier jeweils Folgendes ein:

=TimeOut()

Öffnen Sie anschließend das Eigenschaftenfenster für das Formular, indem Sie einen Doppelklick in den grauen Bereich unter dem Detailbereich ausführen, und tragen Sie hier bei den Ereignissen „Bei Taste“ und „Bei Mausbewegung“ Folgendes ein:

=TimeOut()

Abschließend markieren Sie der Reihe nach Seiten-/Formular-Kopf und -Fuß sowie den Detailbereich und stellen hierfür die Ereignisse „Beim Klicken“ und „Bei Mausbewegung“ ebenfalls auf „Time- Out“. Auf diese Weise ist nun sichergestellt, dass alle Anwenderaktionen entdeckt und über die Funktion „TimeOut()“ in der globalen Variablen „TimeoutFlag“ festgehalten werden. Klickt der Anwender in ein Feld oder nimmt dort eine Eingabe/Änderung vor oder bewegt er die Maus über Felder und Formular, wird diese Aktion protokolliert. Beim Aufruf der prüfenden Timer-Routine steht also jeweils eine „1“ in der globalen Variablen „TimeoutFlag“. Erst wenn der Anwender mehr als 3 Minuten keine Aktion tätigt, wird das Formular automatisch geschlossen, weil „TimeoutFlag“ in diesem Fall auf „0“ steht.

Timer-Routine aktivieren

Dazu muss nun noch die Timer-Routine aktiviert werden. Stellen Sie die Eigenschaft „Zeitgeberintervall“ des betreffenden Formulars auf „30000“ (entspricht 3 Minuten). Das bedeutet, dass die Ereignisprozedur des Timers nun alle drei Minuten aufgerufen wird. Setzen Sie dann die Eigenschaft „Bei Zeitgeber“ auf „Ereignisprozedur“ und klicken Sie auf die Schaltfläche mit den drei Punkten, um den VBA-Editor zu starten. Hier geben Sie folgende Anweisungen ein:

Sub Form_Timer ()
If TimeoutFlag = 0 Then
DoCmd.Close , , acSaveYes
TimeoutFlag = 0
End Sub

Die Ereignisprozedur des Timers prüft zuerst, ob die Variable „TimeoutFlag“ auf „0“ steht – wenn ja, hat der Anwender 3 Minuten nichts getan, das Formular wird geschlossen. Ansonsten setzen wir „TimeoutFlag“ zurück auf „0“. Bis zum nächsten Aufruf der Ereignisprozedur des Timers vergehen nun 3 Minuten, in denen eventuell eine Aktion erfolgt und dadurch „TimeoutFlag“ auf „1“ zurückgesetzt wird. Die Angabe des Parameters „acSaveYes“ sorgt dafür, dass Access ein eventuell geändertes Formular automatisch speichert. Andernfalls würde eine Abfrage, ob die Änderungen am Entwurf gespeichert werden sollen, das Schließen des Formulars und damit die Freigabe des gesperrten Datensatzes blockieren.

Wenn Sie Ihre Formulare mit diesem Mechanismus ausrüsten, werden Sie in Zukunft keine Probleme mehr mit Datensätzen haben, die aus Unachtsamkeit mehrere Stunden lang gesperrt sind und sich nicht mehr bearbeiten lassen.

Und noch ein Tipp: Informieren Sie die Anwender Ihrer Datenbank bitte darüber, dass Sie einen Mechanismus zum automatischen Schließen bei Inaktivität eingebaut haben. Das erspart Ihnen erfahrungsgemäß viele unnötige Support- Anfragen!

Geben Sie dem Anwender einen Hinweis

Sie können einen solchen Hinweis aber auch direkt in die Lösung integrieren. Dazu ist lediglich ein weiteres Formular „Hinweis“ notwendig. Dieses Formular enthält ein Bezeichnungsfeld mit dem Text „Ihr Formular wurde wegen Inaktivität automatisch geschlossen!“. Der Hinweis wird auffällig, beispielsweise in Fett, Rot und 14 Punkt großer Schrift, formatiert. Eine Schaltfläche OK erlaubt das Schließen dieses Hinweisfensters über die Ereignisprozedur „Beim Klicken“:

Private Sub btnClose_Click()
DoCmd.Close
End Sub

Damit dieser Hinweis nun nach dem automatischen Schließen eines Formulars bei einem Timeout angezeigt wird, muss die Timer-Routine wie folgt angepasst werden:

Private Sub Form_Timer()
If TimeoutFlag = 0 Then
DoCmd.Close , , acSaveYes
DoCmd.OpenForm „Hinweis“
End If TimeoutFlag = 0
End Sub

Formular als Startfenster

Datenbank

Um beim Öffnen Ihrer Datenbanken ein eigenes Logo anzeigen zu lassen, können Sie ein normales Formular nutzen. Bauen Sie dieses Formular zunächst wie gewünscht auf. Platzieren Sie also eine Grafik und die notwendigen Texte darin.

Dann stellen Sie die folgenden Eigenschaften für das Formular ein:

  • Rahmenart: Dünn
  • Popup: Ja
  • Gebunden: Ja
  • Automatisch zentrieren: Ja
  • Mit Systemmenüfeld: Nein
  • MinMax-Schaltflächen: Keine
  • Schließen-Schaltfläche: Nein
  • Größe anpassen: Ja
  • Zeitgeberintervall: 3000

In der Ereignisprozedur „Beim Öffnen“ geben Sie folgende Anweisung ein:

Me.Caption = “ „

Diese Anweisung sorgt für eine leere Ti telleiste. Alternativ können Sie hier auch den Anwendungsnamen anzeigen lassen, indem Sie ihn über die Eigenschaft „Beschriftung“ festlegen und die Ereignisprozedur „Beim Öffnen“ nicht benutzen.

In der Ereignisprozedur „Bei Zeitgeber“ geben Sie anschließend die folgende Anweisung ein:

DoCmd.Close acForm, Me.Name, acSavePrompt

Diese Anweisung schließt das Formular nach Ablauf der über „Timerintervall“ eingestellten Zeit in Millisekunden – hier also nach drei Sekunden. Speichern Sie das Formular zum Beispiel unter dem Na men „frmStartup“ ab.

Damit das Formular beim Öffnen der Datenbank automatisch angezeigt wird, legen Sie es entweder über EXTRAS-START (bis Access 2003) bzw. im Dialog ACCESSOPTIONEN- AKTUELLE DATENBANK als Startformular fest oder erstellen ein „AutoExec“-Makro, das als Erstes eine „ÖffnenFormular“-Aktion mit „frm- Startup“ ausführt.

Forms!-Befehl

Tagesbedarf![Gericht] = Das Feld „Gericht“ in dem Formular „Tagesbedarf

[Montag] = Feld im aktuellen Formular

Forms!Tagesbedarf![Gericht] = [Montag]