Jahresübersicht per Bericht

Eine Jahresübersicht kann man für viele Anwendungen gebrauchen. Diese sollte dann natürlich nach Wunsch erweiterbar sein – etwa, um bestimmte Tage farbig zu markieren oder diese anderweitig hervorzuheben. Die Jahresübersicht dieses Beitrags soll die Monate eines Jahres untereinander mit einem Monat pro Zeile anzeigen. Die Wochentage sollen jeweils in einer Spalte angelegt werden, dadurch wird der jeweilige Monatserste natürlich mal mehr, mal weniger eingerückt dargestellt.

Grundlage: die Datumstabelle

Einen Bericht wie den geplanten erstellen Sie am einfachsten, wenn es eine Datenherkunft gibt, welche alle darzustellenden Tage zur Verfügung stellt. Das heißt, dass für die Darstellung eines kompletten Jahres eine Tabelle mit allen Tagen des Jahres vorliegen sollte. Diese muss zumindest die Datumsangaben enthalten und, soweit geplant, noch weitere Informationen, um Tage nach Wunsch farbig zu markieren oder auch um zusätzliche Texte hinzuzufügen.

Als Beispiel verwenden wir die Tabelle tblArbeitstage aus dem Beitrag Schichtplaner (www.access-im-unternehmen.de/906). Diese enthält neben dem Primärschlüsselfeld ArbeitstagID zunächst lediglich ein weiteres Feld namens Arbeitstag.

Berichtseinstellungen

Der Bericht soll circa 30 bis 40 Elemente nebeneinander anzeigen und ca. 13 übereinander – das bedeutet, dass wir mit dem Querformat besser als mit dem Hochformat fahren werden. Nehmen Sie diese Einstellung gleich nach dem Anlegen des neuen, leeren Berichts vor (unter Access 2010 beispielsweise mit dem Ribbon-Eintrag Seite einrichten|Sei-ten-lay-out|Querformat).

Alternierende Hintergrundfarbe

Für unseren Zweck benötigen wir keine alternierende Hintergrundfarbe. Daher stellen Sie die Eigenschaft Alternative Hintergrundfarbe für den Detailbereich des Berichts auf die gleiche Farbe ein, die auch die Eigenschaft Hintergrundfarbe aufweist (in der Regel Weiß).

Datenherkunft und Steuerelemente

Als Datenherkunft stellen wir nicht die Tabelle tblArbeitstage ein, sondern eine Abfrage namens qryJahresuebersicht. Diese enthält zunächst die beiden Felder DatumID und DatumWert, die je nach der zu verwendenden Tabelle durch entsprechende Ausdrücke auf die eigentlichen Felder umgebogen werden.

Auf diese Weise programmieren wir zunächst den Bericht gegen eine generische Abfrage, in der Sie die der eigentlichen Anwendung zugrunde liegende Tabelle und die gewünschten Felder angeben können. Später kommen weitere Felder hinzu – beispielsweise zum Markieren des jeweiligen Tages in einer bestimmten Farbe oder für weitere Eigenschaften.

Die Abfrage sieht im aktuellen Stadium wie in Bild 1 aus.

Diese Abfrage dient als Grundlage für die Jahresübersicht.

Bild 1: Diese Abfrage dient als Grundlage für die Jahresübersicht.

Wenn Sie den Bericht namens rptJahresuebersicht erstellt haben, fügen Sie die Abfrage als Datenherkunft hinzu. Ziehen Sie außerdem das Feld DatumWert in den Detailbereich des Berichts und löschen Sie das automatisch hinzugefügte Bezeichnungsfeld. Das Zwischenergebnis sieht wie in Bild 2 aus.

Der Bericht mit einem einzigen Textfeld in der Entwurfsansicht

Bild 2: Der Bericht mit einem einzigen Textfeld in der Entwurfsansicht

Erfahrungsgemäß zeigt der Bericht seine Datensätze nun untereinander an (s. Bild 3). Dies müssen wir nun ändern – die Tage eines Monats sollen alle nebeneinander angezeigt werden. Erst mit Beginn eines neuen Monats soll der Bericht eine neue Zeile beginnen.

Anzeige der Datumsangaben untereinander

Bild 3: Anzeige der Datumsangaben untereinander

Verantwortlich dafür, ob ein Datensatz in einem Bericht in einer neuen Zeile angezeigt wird, ist die Eigenschaft MoveLayout. Hat diese den Wert True, was dem Standardwert entspricht, zeigt der Bericht die Steuerelemente für den folgenden Datensatz in einer neuen Zeile an. Stellen Sie diesen Wert jedoch auf False ein, nimmt Access keinen Wechsel zu einer neuen Zeile vor – der Datensatz wird in der gleichen Zeile gedruckt wie der vorherige. Wo aber stellen wir diese Eigenschaft ein und wie gelingt es, dass der Bericht nur zu Beginn eines neuen Monats eine neue Zeile beginnt

Dies erreichen wir in der Prozedur, die durch das Ereignis Beim Formatieren des Detailbereichs des Formulars ausgelöst wird. Um in diesem Ereignis zu ermitteln, ob das Datum im aktuellen Datensatz sich im gleichen Monat befindet wie das des vorherigen Datensatzes, vergleichen wir das aktuelle Datum mit dem Datum des letzten Tages des aktuellen Monats. Nur in diesem Fall soll die Eigenschaft MoveLayout nicht auf False eingestellt und der folgende Datensatz somit in der nächsten Zeile gedruckt werden.

Die Prozedur Detailbereich_Format aus Listing 1 vergleicht also das Datum des aktuellen Datensatzes mit einem Ausdruck, der den letzten Tag des Monats des aktuellen Datums ermittelt, und stellt MoveLayout auf False ein, wenn beide Ausdrücke nicht übereinstimmen.

Private Sub Detailbereich_Format(Cancel As Integer, FormatCount As Integer)
     If Not Me!DatumWert = DateSerial(Year(Me!DatumWert), Month(Me!DatumWert) + 1, 1) - 1 Then
         Me.MoveLayout = False
     End If
End Sub

Listing 1: Diese Prozedur sorgt dafür, dass alle Datensätze zu einem Monat in der gleichen Zeile des Berichts landen.

Das Ergebnis sieht wie in Bild 4 aus. Die Datensätze eines Monats werden nun zwar in einer Zeile angezeigt, aber leider alle übereinander.

Anzeige der Datensätze eines Monats in einer Zeile, aber übereinander

Bild 4: Anzeige der Datensätze eines Monats in einer Zeile, aber übereinander

Dies ändern wir im folgenden Schritt. In der Ereignisprozedur Detailbereich_Format können wir nämlich auch festlegen, an welcher Position ein Steuerelement angezeigt werden soll (s. Listing 2). In unserem Fall sollen die Datumsangaben eines Monats jeweils um die Breite des Textfeldes des vorherigen Datums nach rechts verschoben werden.

Private Sub Detailbereich_Format(Cancel As Integer, FormatCount As Integer)
     If Not Me!DatumWert = DateSerial(Year(Me!DatumWert), Month(Me!DatumWert) + 1, 1) - 1 Then
         Me.MoveLayout = False
     End If
     If Day(Me!DatumWert) = 1 Then
         sngLeft = (Weekday(Me!DatumWert, vbMonday) - 1) * Me!txtDatumWert.Width
     Else
         sngLeft = sngLeft + Me!txtDatumWert.Width
     End If
     Me!txtDatumWert.Left = sngLeft
End Sub

Listing 2: Diese Anpassung sorgt dafür, dass die Tage an der richtigen horizontalen Position erscheinen.

Gleichzeitig formatieren wir den Inhalt des Textfeldes bereits so, dass nur noch der Tag angezeigt wird – die Bezeichnung des Monats basteln wir später als Zeilenüberschrift hinzu. Gleiches gilt für den Wochentag, der in einer ersten Zeile über der übersicht angezeigt werden soll.

Im gleichen Zuge wollen wir direkt sicherstellen, dass die einzelnen Wochentage bereits untereinander abgebildet werden – der erste Montag des Monats Januar soll also genau unter dem ersten Montag des Monats Februar landen.

Die Prozedur ergänzt die vorherige Prozedur um einen Teil, der die aktuelle Position für das Textfeld ermittelt und dieses in der Variablen sngLeft speichert.

Diese Variable deklarieren wir im Kopf des Klassenmoduls des Berichts, da diese von Prozeduraufruf zu Prozeduraufruf weitergenutzt werden soll:

Dim sngLeft As Single

Der Wert für sngLeft wird auf zwei verschiedene Arten ermittelt – abhängig vom aktuellen Datum:

  • Handelt es sich um den ersten Tag des Monats, wird die horizontale Position initial ermittelt und in sngLeft gespeichert. Die Position entspricht dabei einem Vielfachen der Textfeldbreite, wobei der Faktor vom Wochentag des ersten Tages des Monats abhängt. Für einen Montag soll sngLeft den Wert 0 erhalten, für einen Dienstag die Breite des Textfeldes mal 1, für einen Mittwoch die Breite des Textfeldes mal 2 und so weiter.
  • Handelt es sich um einen der folgenden Tage des Monats, wird der Wert von sngLeft jeweils um die Breite des Textfeldes vergrößert.

Die abschließende Anweisung weist den Wert von sngLeft der Eigenschaft Left des Textfeldes zur Anzeige des aktuellen Datums zu.

Das Ergebnis sieht nun wie in Bild 5 aus.

Anzeige der Tage der Monate

Bild 5: Anzeige der Tage der Monate

Monatsnamen hinzufügen

Als Nächstes fügen wir die Monatsnamen hinzu. Diese sollen in jeder Zeile vor den Tagestextfeldern erscheinen.

Also passen wir zunächst den Entwurf des Berichts an, indem wir das Textfeld txtDatumWert etwas nach rechts verschieben und links davon ein neues Textfeld namens txtMonat einfügen.

Für dieses stellen Sie die Eigenschaft Steuerelementinhalt auf den Wert =Format(DatumWert;”mmmm”) ein (s. Bild 6).

Hinzufügen des Textfeldes zur Anzeige des Monats als Zeilenkopf

Bild 6: Hinzufügen des Textfeldes zur Anzeige des Monats als Zeilenkopf

Außerdem muss eine Zeile der Prozedur Detailbereich_Format angepasst werden, und zwar diejenige, welche die Position des ersten Textfeldes mit einem Datum für den jeweiligen Monatsersten ermittelt. Diese ergänzen Sie um die Breite des Textfeldes txtMonat:

sngLeft = Me!txtMonat.Width + (Weekday(Me!DatumWert, vbMonday) - 1) * Me!txtDatumWert.Width

Wenn Sie nun in die Seitenansicht des Berichts wechseln, löst dies möglicherweise den Fehler aus Bild 7 aus (gegebenenfalls ist Ihnen dies auch schon bei einem der vorherigen Schritte passiert). In diesem Fall verkleinern Sie einfach die Breite des Textfeldes txtDatumWert so weit, bis der Fehler nicht mehr auftritt. Das Zwischenergebnis aus Bild 8 liefert die Monatsnamen als Spaltenüberschrift.

Dieser Fehler wird ausgelöst, wenn Textfelder außerhalb des bedruckbaren Bereichs des Berichtes verschoben werden sollen.

Bild 7: Dieser Fehler wird ausgelöst, wenn Textfelder außerhalb des bedruckbaren Bereichs des Berichtes verschoben werden sollen.

Jahresübersicht mit Monatsnamen

Bild 8: Jahresübersicht mit Monatsnamen

Den aktuellen Zwischenstand haben wir unter rptJahresuebersicht01 gespeichert.

Wochenenden markieren

Damit sich der Benutzer des Kalenders besser zurechtfinden kann, sollen die Tage des Wochenendes farbig markiert werden. Dies erledigen wir mit der bedingten Formatierung. Markieren Sie das Textfeld txtDatumWert und wählen Sie aus dem Kontextmenü den Eintrag Bedingte Formatierung… aus.

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

den kompletten Artikel im PDF-Format mit Beispieldatenbank

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar