Termine in Berichten darstellen

Was die Darstellung von Terminen und Kalendern angeht, ist Outlook der Platzhirsch. Es gibt kaum eine Ansicht, die sich damit nicht verwirklichen lässt. Oder doch Nun: Ihre Kunden oder Sie selbst haben bestimmt Ideen, die selbst Outlooks Berichts-Engine an die Leistungsgrenze bringen. Und hier kommt Access ins Spiel: Verwenden Sie Berichte und bringen Sie Access dazu, Ihre Termine ganz nach Wunsch anzuzeigen.

Die Anzeige von Terminen in Access-Berichten ist seit jeher mit Bastelei verbunden – außer Sie begnügen sich damit, die Termine einfach tabellarisch aufzulisten. Dann brauchen Sie wirklich nicht viel mehr als einen handelsüblichen Bericht, in dessen Detailbereich Sie die vorliegenden Termine eintragen. Anspruchsvoller wird es dann schon, wenn der Bericht die Termine und deren Zeitaufwand hübsch grafisch aufbereitet darstellen soll – genau so, wie es auch beispielsweise in der Tagesübersicht von Outlook der Fall ist (s. Abb. 1).

pic001.png

Abb. 1: Anzeige der Termine in der Tagesübersicht von Outlook

Auch erfahrenen Berichtsdesignern dürfte der Nachbau eines solchen Layouts leichte Sorgenfalten auf die Stirn legen, ist man doch normalerweise gewohnt, die Daten schön untereinander anzuordnen und eventuelle Feinheiten durch Gruppierungen oder Unterberichte abzudecken. Wer schon in unseren Beitrag Berichte manuell füllen (Shortlink 659) hineingeschaut hat, ahnt bereits, dass es hier nicht mit rechten Dingen – äh, Steuerelementen – zuging, sondern dass wir hier von Berichtsmethoden wie Print und Line Gebrauch gemacht haben.

Das allein reicht allerdings längst nicht aus, um Termine so wie unter Outlook darzustellen (genau genommen werden wir nicht jedes Detail nachbilden, doch die wichtigsten Elemente berücksichtigen wir natürlich).

Beginnen wir jedoch bei den Daten, die unserem Bericht zugrunde liegen – und die sind bei Weitem das am wenigsten Komplizierte dieser Lösung.

Die Tabelle tblTermine sieht wie in Abb. 2 aus und enthält die folgenden Felder:

pic002.png

Abb. 2: Die Tabelle tblTermine in der Entwurfsansicht

  • ID: Primärschlüsselfeld
  • Termin: Beschreibung des Termins
  • Termindatum: Datum, an dem der Termin stattfindet
  • Startzeit: Zeit, zu welcher der Termin beginnt
  • Endzeit: Zeit, zu welcher der Termin endet
  • FarbeID: Fremdschlüsselfeld zur Tabelle tblFarben; legt die Hintergrundfarbe für den Termin im Bericht fest
  • Bereich: Für das Layout des Kalenderberichts ist es wichtig zu wissen, ob Termine ein- oder mehrspaltig angezeigt werden. Termine, die in einem mehrspaltigen Bereich liegen, sind durch den gleichen Wert in diesem Feld zu erkennen.
  • Spalte: Gibt an, in welcher Spalte sich dieser Termin befindet.
  • Spaltenzahl: Gibt an, wieviele Spalten der Bereich umfasst, in dem sich dieser Termin befindet.

Die Funktion der letzten drei Felder wird weiter hinten erläutert, außerdem erfahren Sie dort, wie diese Felder gefüllt werden. Aktuell reicht es, wenn Sie wissen, dass die in diesem Beitrag vorgestellte Lösung Ihnen diese Aufgabe abnimmt.

Den Aufbau der Tabelle tblFarben entnehmen Sie Abb. 3. Sie enthält neben dem Primärschlüsselfeld ID ein Feld zur Bezeichnung der Farbe (Farbe) sowie ein Feld mit dem Zahlenwert, der die Farbe repräsentiert (Farbwert).

pic003.png

Abb. 3: Diese Tabelle speichert die Hintergrundfarben für die Termine im Bericht.

Das war schon fast alles, was Sie zum Modellieren eines Berichts wie in Abb. 5 benötigen – es fehlen nur noch ein paar Hilfstabellen, Abfragen und einige Zeilen VBA-Code, um den Bericht zu füllen.

pic004.png

Abb. 5: Beispiel für einen Terminbericht mit überlappenden Terminen

Termineingabe

Auf die Beschreibung von Formularen zur Eingabe der Termine verzichten wir in diesem Beitrag aus Platzgründen. Sie können die Termine allerdings in ein handelsübliches Formular eingeben oder diese auch aus Outlook importieren. Wie das geht, erfahren Sie beispielsweise im Beitrag Outlook-Termine im Griff (Shortlink 439).

Grundlagen des Kalenderberichts

Glücklicherweise gibt es auch Tage ohne Termine, und daher enthält ein Kalender auch nicht für jeden Tag Aufzeichnungen oder Einträge. Der Terminbericht sollte aber trotzdem für jeden Tag eine eigene Seite anzeigen – allein, damit man nicht immer auf das Datum schauen muss, wenn man den Kalender am Bildschirm oder auch in ausgedruckter Form durchblättert. Nach Montag soll Dienstag folgen und nicht schon der Mittwoch, wenn es am Dienstag keine Termine gibt.

Wie aber bringen wir Access dazu, ganz banal einen 365-seitigen Bericht als Grundlage für den Terminkalender eines Jahres zu liefern – ohne dass für jeden Tag ein Termin angelegt wäre

Nun, das geht ganz einfach: Wir brauchen einfach nur eine Datenherkunft, die tatsächlich alle 365 Tage liefert. Die Tabelle tblKalenderdaten ist eine solche Datenherkunft: Sie enthält für jeden Tag des Jahres 2009 einen eigenen Datensatz mit einem Primärschlüssel und einem Datumsfeld (s. Abb. 4). Wenn Sie möchten, so können Sie diese Tabelle durch weitere Spalten wie Werktag oder Feiertag ergänzen und solche Tage später im Bericht anders formatieren.

pic005.png

Abb. 4: Diese Tabelle liefert die Grundlage für einen ganzjährigen Kalenderbericht.

Für Letzteres sollten Sie unbedingt einen eindeutigen Schlüssel festlegen, damit die Tabelle kein Datum doppelt enthalten kann. Damit das Füllen der Tabelle nicht soviel Arbeit macht, übernimmt die Routine aus Listing 1 diese Aufgabe. Sie erwartet das Start- und das Enddatum als Parameter und legt Datensätze für den angegebenen Zeitraum an.

Listing 1: Füllen der Tabelle tblKalenderdaten

Public Sub KalenderdatenFuellen(datStart As Date, datEnde As Date)
Dim dat As Date
Dim db As DAO.Database
Dim rst As DAO.Recordset
Set db = CurrentDb
db.Execute "DELETE FROM tblKalenderdaten", dbFailOnError
Set rst = db.OpenRecordset("tblKalenderdaten", dbOpenDynaset)
For dat = CDate(datStart) To CDate(datEnde)
 rst.AddNew
    rst!Kalenderdatum = dat
    rst.Update
Next dat
End Sub

Bericht anlegen

In den folgenden Absätzen erfahren Sie, wie Sie den Bericht aus Abb. 5 anlegen und diesen mit Inhalt füllen. Damit Sie den Bericht Ihren Bedürfnissen anpassen können, bauen wir ihn Stück für Stück auf.

Den Start macht ein leerer Bericht, dem Sie übergangsweise die Tabelle tblKalenderdaten als Datenherkunft zuweisen.

Eine Seite pro Tag

Der Kalender soll jeden Tag auf einer eigenen Seite anzeigen. Daher reicht es nicht aus, einfach nur das Feld Kalenderdatum aus der Datenherkunft in den Detailbereich des Berichts zu ziehen. Sie müssen auch noch dafür sorgen, dass nach (oder vor) jedem Datensatz ein Seitenwechsel erfolgt. Theoretisch würde es reichen, den Detailbereich einfach groß genug zu gestalten.

Allerdings soll der Detailbereich möglichst nur den Kalender selbst enthalten, daher benötigen wir einen anderen Berichtsbereich als Unterkunft für das Feld Kalenderdatum (das ja im Bericht auch das Datum anzeigen soll).

Der Seitenbereich wäre eine gute Wahl, aber auch diesen sparen wir für eventuelle Elemente wie eine Überschrift auf. Die Kalenderdaten sollen in der richtigen Reihenfolge angezeigt werden, was Sie durch Anlegen einer Sortierung für das Feld Kalenderdatum im Bericht erreichen.

Und wenn Sie schon einmal dabei sind, können Sie auch gleich eine Gruppierung daraus machen und das Feld Kalenderdatum im Gruppenkopf unterbringen.

Dem Gruppenkopfbereich weisen Sie dann noch über das Setzen des Werts Vor Bereich für die Eigenschaft Neue Seite einen Seitenumbruch hinzu und stellen so sicher, dass jedes Datum auf einer neuen Seite angezeigt wird (s. Abb. 6).

pic006.png

Abb. 6: Dieser Bericht zeigt jeden Tag auf einer neuen Seite an.

In der Seitenansicht sieht der Bericht nun wie in Abb. 7 aus und liefert die erwarteten Datumsangaben auf je einer eigenen Seite.

pic007.png

Abb. 7: Die Grundlage für den Terminkalender mit Tagesübersicht

Stundenplan hinzufügen

Im nächsten Schritt fügen wir das Raster hinzu, das den Tag beziehungsweise den Detailbereich in 24 Elemente aufteilt und diese mit den entsprechenden Stundenangaben versieht (s. Abb. 8).

pic008.png

Abb. 8: Der Terminkalender besitzt nun ein Raster, in das man nur noch die Termine einfügen muss.

Dies geschieht in einer Routine, die im Ereignis Beim Drucken des Detailbereichs des Berichts ausgelöst wird:

Private Sub Detailbereich_Print(Cancel As Integer, PrintCount As Integer)
    UhrzeitrasterAnlegen
    End Sub

Die Routine UhrzeitrasterAnlegen (Listing 2) deklariert zunächst vier Variablen namens sngRepX1, sngRepX2, sngRepY1 und sngRepY2. Darin speichert sie die Koordinaten des Detailbereichs relativ zur linken oberen Ecke, die sie aus den Eigenschaften ScaleTop, ScaleWidth, ScaleLeft und ScaleHeight erhält.

Listing 2: Herstellen eines Rasters zur optischen Unterstützung der anschließend hinzugefügten Termine

Private Sub UhrzeitrasterAnlegen
    'Koordinaten für den Bericht
    Dim sngRepX1 As Single
    Dim sngRepX2 As Single
    Dim sngRepY1 As Single
    Dim sngRepY2 As Single
    Dim i As Integer
    Dim lngColor As Long
    With Me
    sngRepY1 = .ScaleTop
    sngRepX1 = .ScaleLeft
    sngRepX2 = .ScaleWidth
    sngRepY2 = .ScaleHeight
    'Raster mit Zeiten bauen
    For i = 1 To 25
        lngColor = RGB(225, 225, 225)
        Me.Line (sngRepX1, _
        sngRepY1 + (i - 1) * (sngRepY2 - sngRepY1) / 24) _
        -(sngRepX2, _
        sngRepY1 + (i - 1) * (sngRepY2 - sngRepY1) / 24), _
        lngColor
        CurrentX = 0
        If i < 25 Then
            lngColor = RGB(0, 0, 0)
            Me.ForeColor = lngColor
            Me.FontSize = 9
            Me.Print Format(DateAdd("h", i - 1, 0), "hh");
            Me.FontSize = 5
            Me.Print Format(DateAdd("h", i - 1, 0), " nn")
        End If
    Next i
    End With
    End Sub

Danach baut die Routine auch schon die Linienstruktur und die darin enthaltenen Stundenzahlen auf, und zwar in einer Schleife, welche die Werte 1 bis 25 durchläuft – immerhin gibt es 24 Stunden, von denen jede oben und unten durch eine Linie begrenzt werden möchte.

Beschriftungen brauchen wir aber ebenfalls nur 24, weshalb der untere Teil der Schleife nur ausgeführt wird, solange die Zählervariable einen Wert kleiner 25 aufweist. Man hätte auch zwei Schleifen aufbauen können – das ist aber sicher Geschmackssache.

Innerhalb der Schleife sorgt die Line-Anweisung zunächst dafür, dass 25 Linien sorgfältig auf die Höhe des Detailbereichs aufgeteilt werden. Die Breite wird dabei durch den ersten und dritten Parameter angegeben, wobei der erste den Wert 0 und der dritte einen Wert aufweist, welcher der Breite des Detailbereichs entspricht.

Die vertikale Position der Linie geben der zweite und der vierte Parameter der Line-Funktion an, welche die gleiche Formel enthalten. Diese liefert den dem Wert von i entsprechenden Anteil der Gesamthöhe des Detailbereichs in der aktuellen Einheit, standardmäßig also in Twips.

Termine vorbereiten

Nun geht es an den Teil des Berichts, in dem eine Menge Gehirnschmalz steckt – zumindest, wenn man dem Benutzer ermöglichen möchte, auch sich überschneidende Termine in den Kalender einzutragen. Man könnte nun sagen, dass dies keinen Sinn macht, da man normalerweise immer nur eine Tätigkeit zur gleichen Zeit betreibt – aber möglicherweise möchte der Benutzer ja auch weitere Ereignisse im Terminkalender unterbringen.

Sie haben das Ende des frei verfügbaren Textes erreicht. Möchten Sie ...

Workplace

Jahresabonnement TestzugangOder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:

Schreibe einen Kommentar