Home > Artikel > Ausgabe 1/2013 > Feiertage verwalten, Teil 1

Feiertage verwalten, Teil 1

Achtung: Sie sind nicht angemeldet. Wenn Sie Abonnent sind und sich anmelden, lesen Sie den kompletten Artikel, laden das PDF herunter oder probieren die Beispieldatenbank aus (sofern vorhanden).

Wenn Sie in einer Datenbank jegliche Datumsangaben oder Zeiträume verwalten, die irgendwie durch die Anwesenheit von Feiertagen beeinflusst werden, sollten Sie diese Feiertage in einer Tabelle bereithalten oder diese schnell per VBA berechnen können. Dabei kann es sich etwa um die Berechnung von Fristen handel (Rückgabe innerhalb von 7 Werktagen) oder auch um die Ermittlung der Urlaubstage für den durch zwei Datumsangaben festgelegten Zeitraum. Diese Artikelreihe zeigt, wie Sie die Basisdaten verwalten und daraus die tatsächlichen Feiertage in einem vorgegebenen Zeitraum ermitteln.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1301_FeiertageErmitteln.mdb.

Feiertage

Es gibt verschiedene Arten von Feiertagen:

  • solche, die immer auf das gleiche Datum fallen (Weihnachten, Silvester, Tag der Arbeit, Tag der deutschen Einheit) und
  • solche, die immer auf einen bestimmten Wochentag fallen, aber kein festes Datum haben. Diese teilen sich wiederum in zwei Gruppen auf: Die ersten haben einen bestimmten Abstand zum Ostersonntag (Osterfeiertage, Christi Himmelfahrt, Fronleichnam), die zweiten zum vierten Advent (Weihnachten, Buß- und Bettag).

Außerdem werden einige Feiertage nicht in allen, sondern nur in bestimmten Bundesländern gefeiert.

Tabelle oder dynamisch?

Die Ermittlung von Feiertagen kann auf zwei Arten erfolgen – dynamisch zur Laufzeit, also mit einer geeigneten VBA-Prozedur, oder durch das Speichern der Feiertage in einer Tabelle und anschließendes Ermitteln der Feiertage. Wenn wir schon mit Access arbeiten, nutzen wir natürlich die Variante mit der Tabelle. Mit dieser Tabelle lässt sich anschließend leicht ermitteln, ob und wieviele Feiertage sich in einem bestimmten Zeitraum befinden.

Basistabellen

Wir wissen nun, dass Feiertage bestimmte Eigenschaften haben. Um die Feiertagsdaten für einen Zeitraum zu ermitteln, benötigen wir einen Satz grundlegender Informationen, die wir – der Natur von Access entsprechend – in Tabellen speichern. Wir wissen, dass Feiertage teils ein festes Datum haben und teils von anderen Feiertagen abhängen. Deshalb speichern wir die grundlegenden Informationen in einem Satz von Tabellen. Die erste legt fest, welche Arten von Feiertagen es gibt – mit fixem Datum, von Ostern abhängige oder vom vierten Advent abhängige. Diese drei Varianten speichern wir in einer Tabelle namens tblFeiertagsarten, die im Entwurf wie in Bild 1 aussieht.

Tabelle der Feiertagsarten in der Entwurfsansicht

Bild 1: Tabelle der Feiertagsarten in der Entwurfsansicht

Gefüllt sieht die Tabelle wie in Bild 2 aus. Was machen wir mit dieser Tabelle? Wir verwenden sie als Lookup-Tabelle für eine weitere Tabelle mit den eigentlichen Basisdaten der einzelnen Feiertage. Diese heißt tblFeiertageBasis und sieht im Entwurf wie in Bild 3 aus.

Tabelle der Feiertag-Basisdaten in der Entwurfsansicht

Bild 2: Tabelle der Feiertag-Basisdaten in der Entwurfsansicht

Tabelle der Feiertagsarten mit allen Werten

Bild 3: Tabelle der Feiertagsarten mit allen Werten

In dieser Tabelle finden Sie Daten wie in Bild 4. Zu jedem Feiertag speichert die Tabelle

Tabelle der Feiertag-Basisdaten in der Datenblattansicht

Bild 4: Tabelle der Feiertag-Basisdaten in der Datenblattansicht

  • die Bezeichnung,
  • den Tag und den Monat (für fixe Feiertage, sonst den Wert 0),
  • die Anzahl der Tage bis zum Stichtag, sollte es sich nicht um einen fixen Feiertag handeln und
  • die Art des Feiertags.

Was fehlt? Die Zuordnung der Feiertage zu den Bundesländern. Wie speichern wir diese Information in Tabellen? Es gibt n Feiertage und m Bundesländer, von denen jeder Feiertag einem oder mehreren Bundesländern zugeordnet werden soll. Das hört sich nach einer klassischen m:n-Beziehung an – und so ist es auch. Die eine Tabelle der m:n-Beziehung haben wir schon – die Tabelle tblFeiertageBasis. Fehlt noch die Tabelle mit den Bundesländern und die Tabelle für die Verknüpfung der Bundesländer mit den Feiertagen.

Die Tabelle zum Speichern der Bundesländer besteht lediglich aus den beiden Feldern BundeslandID und Bundesland. Interessanter ist die Tabelle zum Herstellen der Verknüpfung zwischen Feiertagen und Bundesländern. Sie heißt tblFeiertageBundeslaender und enthält drei Felder: das Primärschlüsselfeld FeiertagBundeslandID, das Fremdschlüsselfeld FeiertagID und das Fremdschlüsselfeld BundeslandID.

Beide Felder legen Sie als Nachschlagefelder aus. Das Feld FeiertagID bezieht die Werte des Nachschlagefeldes aus den Feldern FeiertagBasisID und Feiertag der Tabelle tblFeiertageBasis, die Schlüsselspalte FeiertagBasisID soll ausgeblendet werden. Auf diese Weise zeigt das Nachschlagefeld nur die Bezeichnungen der Feiertage an.

Das Feld BundeslandID ist ähnlich aufgebaut: Es verwendet die Felder BundeslandID und Bundesland der Tabelle tblBundeslaender zum Füllen des Nachschlagefeldes. Auch hier wird die Schlüsselspalte nicht angezeigt.

Schließlich wollen wir noch sicherstellen, dass die Tabelle keine Kombination auf Feiertag und Bundesland mehrfach aufnimmt. Dazu definieren Sie einen eindeutigen Index, der aus den beiden Feldern FeiertagID und BundeslandID zusammengesetzt wird. Diesen Index legen Sie im Entwurf der Tabelle mithilfe des Indizes-Dialogs an. Dort befindet sich zumindest bereits der Index für das Primärschlüsselfeld der Tabelle. Fügen Sie einen neuen Index namens UniqueKey hinzu und wählen Sie untereinander die beiden Felder FeiertagID und BundeslandID aus. Markieren Sie dann wieder die erste Zeile, in der Sie auch den Indexnamen eingetragen haben, und stellen Sie die Eigenschaft Eindeutig im unteren Bereich auf Ja ein (siehe Bild 5).

Verknüpfungstabelle für Feiertage und Bundesländer

Bild 5: Verknüpfungstabelle für Feiertage und Bundesländer

Nachdem die beiden Tabellen tblFeiertageBasis und tblBundeslaender mit Daten gefüllt wurden, können Sie die gewünschten Verknüpfungen zwischen Feiertagen und Bundesländern anlegen. Bild 6 verdeutlicht, dass die Beziehung eigentlich über in der Tabelle tblFeiertageBundeslaender enthaltene Zahlenwerte hergestellt wird – hier haben wir die Feldeigenschaften so eingestellt, dass die Felder nicht die Werte der verknüpften Tabelle, sondern die tatsächlich in den Feldern Feiertag­ID und BundeslandID gespeicherten Werte anzeigen.

Verknüpfung von Feiertagen und Bundesländern

Bild 6: Verknüpfung von Feiertagen und Bundesländern

Feiertage und Bundesländer verwalten

Nun benötigen wir ein Formular, mit dem wir die Feiertage verwalten können. Die Bundesländer geben wir einfach direkt in die Tabelle ein – aktuell ist ja nicht absehbar, dass neue Bundesländer hinzukommen oder Bundesländer wegfallen. Daher soll kein eigenes Formular zur Verwaltung der Bundesländer vorgesehen werden.

Das Formular heißt frmFeiertage und verwendet die Tabelle tblFeiertageBasis als Datenherkunft. Ziehen Sie alle Felder dieser Tabelle in den Formularentwurf und ordnen Sie diese etwa wie in Bild 7 an. Je nach dem Wert im Kombinationsfeld FeiertagArtID sollen entweder die beiden Felder Tag und Monat oder das Feld TageBisStichtag aktiviert sein.

Entwurf des Formulars frmFeiertage

Bild 7: Entwurf des Formulars frmFeiertage

Die Steuerelementnamen der vier Textfelder und des Kombinationsfeldes haben wir um die Präfixe txt beziehungsweise cbo erweitert.

Eingabefelder aktivieren und deaktivieren

Je nachdem, welche Feiertagsart ausgewählt ist, soll das Formular die Textfelder für die Eingabe des fixen Datums oder der Anzahl der Tage vor oder nach dem Stichtag aktivieren oder deaktivieren.

Dies soll also entweder beim Anzeigen eines Datensatzes oder nach der Änderung des Inhalts des Kombinationsfeldes cboFeiertagArtID geschehen. In beiden Fällen sollen die gleichen Schritte ausgeführt werden, also legen wir für diese Anweisungen eine eigene Prozedur an, die von zwei Ereignisprozeduren aus ausgelöst wird.

Damit diese Prozedur zu den passenden Gelegenheiten aufgerufen wird, legen Sie zwei Ereignisprozeduren an. Die erste soll beim Anzeigen eines jeden Datensatzes ausgelöst werden. Dazu stellen Sie für die Eigenschaft Beim Anzeigen des Formulars in der Entwurfsansicht den Wert [Ereignisprozedur] ein und klicken auf die Schaltfläche mit den drei Punkten. Die nun im VBA-Editor erscheinende Prozedur ergänzen Sie wie folgt:

Private Sub Form_Current()

     Call TextfelderAktivieren

End Sub

Die einzige Anweisung dieser Prozedur ruft die Routine TextfelderAktivieren auf. Genauso sieht es bei der Prozedur aus, die Sie für die Eigenschaft Nach Aktualisierung des Kombinationsfeldes cboFeiertagArtID hinterlegen:

Private Sub cboFeiertagArtID_AfterUpdate()

     Call TextfelderAktivieren

End Sub

Die Prozedur TextfelderAktivieren sieht wie folgt aus und kann im gleichen Klassenmodul wie die beiden zuvor erzeugten Prozeduren eingefügt werden:

Private Sub TextfelderAktivieren()

     Select Case Me!cboFeiertagArtID

         Case 1

             Me!txtMonat.Enabled = True

             Me!txtTag.Enabled = True

             Me!txtTageBisStichtag.Enabled = False

         Case 2, 3

             Me!txtMonat.Enabled = False

             Me!txtTag.Enabled = False

             Me!txtTageBisStichtag.Enabled = True

     End Select

End Sub

Die Prozedur prüft in einer Select Case-Bedingung, welchen Wert das Kombinationsfeld cboFeiertagArt­ID aufweist. Für den Wert 1 (für fixe Feiertagdaten) sollen die beiden Textfelder txtTag und txtMonat aktiviert und das Textfeld txtTageBisStichtag deaktiviert werden, für die Werte 2 und 3 (Abhängigkeit vom Ostersonntag beziehungsweise vom vierten Advent) ist es umgekehrt (siehe Bild 8).

Das Formular frmFeiertage mit aktivierten und deaktivierten Feldern.

Bild 8: Das Formular frmFeiertage mit aktivierten und deaktivierten Feldern.

Bundesländer zu Feiertagen zuweisen

Nun kommt der kompliziertere Teil: Wir benötigen eine Möglichkeit, den Feiertagen die Bundesländer zuzuweisen, in denen diese gefeiert werden.

Dazu legen Sie zwei Listenfelder namens lstIstFeiertagIn und lstIstKeinFeiertagIn an. Diese fügen Sie wie in Bild 9 in das Formular ein. Die Schaltflächen zwischen den Listenfeldern heißen cmdAlleHinzufuegen, cmdAuswahlHinzufuegen, cmdAuswahlEntfernen und cmdAlleEntfernen.

Listenfelder zur Anzeige der zugeordneten Feiertage und Schaltflächen zum Hinzufügen und Entfernen der Einträge

Bild 9: Listenfelder zur Anzeige der zugeordneten Feiertage und Schaltflächen zum Hinzufügen und Entfernen der Einträge

Ein Doppelklick auf einen der Listenfeldeinträge soll diesen Eintrag in das jeweils andere Listenfeld verschieben. Die Schaltflächen sollen jeweils alle Einträge oder den markierten verschieben.

Stellen Sie die Eigenschaften Spaltenanzahl und Spaltenbreiten der beiden Listenfelder auf die Werte 2 und 0cm ein. Nun legen Sie zunächst die Datensatzherkunft für das Listenfeld lstIstFeiertagIn fest. Dieses Listenfeld soll alle Einträge der Tabelle tblBundeslaender anzeigen, für die es in der Tabelle tblFeiertageBundeslaender einen Eintrag gibt, dessen Wert im Feld FeiertagID gerade im Feld FeiertagBasisID des Formulars angezeigt wird.

Um eine entsprechende Abfrage anzulegen, markieren Sie die Eigenschaft Datensatzherkunft des Listenfeldes und klicken Sie auf die Schaltfläche mit den drei Punkten – es erscheint nun eine leere Abfrage mit dem Dialog zum Hinzufügen der benötigten Tabellen.

Die Abfrage baut auf den beiden Tabellen tblBundeslaender und tblFeiertageBundeslaender auf. Das Listenfeld soll die beiden Felder BundeslandID und Bundesland enthalten, wobei das erste nur als gebundene Spalte dient und ausgeblendet wird – nur das Bundesland soll angezeigt werden. Diese beiden Felder können Sie also schon einmal in das Entwurfsraster ziehen.

Nun müssen wir noch sicherstellen, dass das linke Listenfeld auch nur diejenigen Einträge der Tabelle tblBundeslaender anzeigt, die auch über die Tabelle tblFeiertageBundeslaender dem aktuell im Hauptformular angezeigten Feiertag zugeordnet sind. Hier kommt die zweite Tabelle der Datenherkunft der Abfrage ins Spiel. Ziehen Sie das Feld FeiertagID dieser Tabelle ebenfalls in das Entwurfsraster. Deaktivieren Sie das Kontrollkästchen in der Zeile Anzeigen für dieses Feld, denn der Inhalt soll nicht angezeigt werden. Dann fügen Sie als Kriterium einen Verweis auf das Feld FeiertagBasisID des Formulars frmFeiertage hinzu. Dieses referenzieren Sie mit diesem Ausdruck:

[Forms]![frmFeiertage]![FeiertagBasisID]

Das Ergebnis finden Sie in Bild 10. Schließen Sie die Abfrage und wechseln Sie in die Formularansicht. Sofern Sie dem aktuellen Feiertag bereits mindestens ein Bundesland zugewiesen haben, wird dieses nun im linken Listenfeld angezeigt.

Datensatzherkunft für das Listenfeld lstIstFeiertagIn

Bild 10: Datensatzherkunft für das Listenfeld lstIstFeiertagIn

Nun wenden wir uns dem rechten Listenfeld zu. Seine Datensatzherkunft ist etwas aufwendiger. Das liegt daran, dass das Listenfeld genau diejenigen Datensätze der Tabelle tblBundeslaender anzeigen soll, die nicht im linken Listenfeld erscheinen. Das Ergebnis sieht komplizierter aus, als es ist. Fügen Sie die Tabelle tblBundeslaender zu einer Abfrage hinzu, die Sie für das Listenfeld lstIstKeinFeiertagIn anlegen. Ziehen Sie die beiden Felder BundeslandID und Bundesland in das Entwurfsraster.

Nun müssen Sie der Abfrage nur noch mitteilen, welche der Datensätze der Tabelle tblBundeslaender im Listenfeld landen sollen. Dies sollen alle sein, die nicht im Listenfeld lstIstFeiertagIn erscheinen, und dies lässt sich fast wortwörtlich mit dem folgenden Kriterium formulieren:

Nicht In (

SELECT tblBundeslaender.BundeslandID

FROM tblBundeslaender

INNER JOIN tblFeiertageBundeslaender

ON tblBundeslaender.BundeslandID

= tblFeiertageBundeslaender.BundeslandID

Sie haben das Ende des frei verfügbaren Teil dieses Artikels erreicht!

Wenn Sie mehr lesen und auf viele weitere Artikel zugreifen möchten, melden Sie sich als Abonnent unter Login an. Falls nicht, bestellen Sie doch einfach ein Jahresabonnement!