Home > Artikel > Ausgabe 1/2018 > Berichtsansicht im Unterformular

Berichtsansicht im Unterformular

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).

In den Artikeln Berichtsansicht und Aufgabenplaner haben wir uns mit der Berichtsansicht beschäftigt. Diese wird umso interessanter, da man sie über ein Unterformular-Steuerelement in einem Formular integrieren kann. Dies schauen wir uns in diesem Artikel genauer an. Wir bauen dabei die Lösung aus dem Artikel Aufgabenplaner weiter aus, indem wir den dort vorgestellten Bericht als Unterformular in ein Formular einbetten, mit dem wir weitere Funktionen zur Lösung hinzufügen.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1801_BerichtsansichtImUnterformular.accdb.

Berichte im Unterformular

In Access-Versionen älter als Access 2010 war es nicht möglich, Berichte im Unterformular anzuzeigen. Dies gelingt nun jedoch recht einfach – und zwar genau wie das Hinzufügen eines Unterformulars zu einem Formular.

In diesem Fall wollen wir direkt auf der Lösung aus dem Artikel Aufgabenplaner aufsetzen, in dem wir eine kleine Lösung basierend auf einem Bericht als Benutzeroberfläche gebaut haben. Diesen Bericht wollen wir nun in einem Unterformular zu einem Formular namens frmAufgabenplaner hinzufügen.

Dieses Formular bereiten wir vorher kurz vor: Da es nicht an eine Datenquelle gebunden sein soll und somit auch keine Daten anzeigt, stellen wir die Eigenschaften Bildlaufleisten, Navigationsschaltflächen, Datensatzmarkierer und Trennlinien auf Nein und die Eigenschaft Automatisch zentrieren auf Ja ein. Danach ziehen wir einfach den Bericht rptAufgabenplaner aus dem Navigationsbereich in den Entwurf des Formulars hinein.

Das Ergebnis sieht etwa wie in Bild 1 aus. Was ist hier geschehen? Access hat beim Fallenlassen des Berichts rptAufgabenplaner automatisch ein Unterformular-Steuerelement zum Formular hinzufügt und für die Eigenschaft Herkunftsobjekt dieses Steuerelements den Wert Bericht.rptAufgabenplaner eingestellt. Dadurch zeigt das Unterformular nun den Entwurf des Berichts rptAufgabenplaner an.

Hinzufügen eines Berichts zu einem Formular als Unterformular

Bild 1: Hinzufügen eines Berichts zu einem Formular als Unterformular

Kleine Korrekturen

Wie Sie sehen, zeigt dieses oben im Seitenkopfbereich die Überschrift Aufgabenplaner an, die wir in diesem Kontext nicht benötigen. Außerdem bietet der Seitenkopfbereich noch die Schaltfläche cmdNeu zum Hinzufügen neuer Aufgaben zur Tabelle tblAufgaben. Wir wollen den Seitenkopf-Bereich nun komplett aus dem Bericht entfernen. Die Überschrift können wir ersatzlos löschen, die Schaltfläche fügen wir dem Hauptformular hinzu. Außerdem wollen wir, dass sich die Höhe des Unterberichts automatisch an die Höhe des Formulars anpasst, wozu wir die Eigenschaft Vertikaler Anker des Unterformular-Steuerelements auf den Wert Beide einstellen. Eine Anpassung des horizontalen Ankers ist in diesem Fall nicht nötig, da die Steuer­elemente im Bericht selbst nicht angepasst werden können – es gibt im Bericht schlicht keine passenden Eigenschaften. In der Entwurfsansicht sieht das Formular nun wie in Bild 2 aus.

Ausgerichteter Unterbericht

Bild 2: Ausgerichteter Unterbericht

Den Code der Schaltfläche cmdNeu müssen wir etwas anpassen, da wir nach dem Anlegen der neuen Aufgabe ja nicht mehr das Objekt aktualisieren wollen, in dem die Prozedur ausgeführt wird, sondern den im Unterformular-Steuerelement befindlichen Bericht. Dies sieht dann wie folgt aus:

Private Sub cmdNeu_Click()

DoCmd.OpenForm "frmAufgabe", WindowMode:=acDialog, DataMode:=acFormAdd

Me!rptAufgabenplaner.Report.Requery

End Sub

Die Requery-Methode wird also für das Report-Objekt im Unterformular-Steuerelement rptAufgabenplaner ausgelöst. Das das Unterformular-Steuerelement mit rptAufgabenplaner benannt wurde, liegt schlicht daran, dass die Unterformular-Steuerelemente für Objekte, die aus dem Navigationsbereich in ein Formular gezogen werden, automatisch den Namen des gezogenen Objekts erhalten.

Interessanterweise gibt es aber für im Unterformular-Steuerelement befindliche Berichte eine eigene Eigenschaft zum Referenzieren, nämlich Report.

Aus optischen Gründen haben wir auch noch die Eigenschaft Rahmenart des Unterformular-Steuerelements auf Transparent eingestellt, sodass das Formular in der Formularansicht wie in Bild 3 aussieht.

Der neu gestaltete Bericht im Hauptformular mit Neu-Schaltfläche

Bild 3: Der neu gestaltete Bericht im Hauptformular mit Neu-Schaltfläche

Benutzerdefinierter Filter

Warum nun den Bericht in der Berichtsansicht im Hauptformular unterbringen? Ganz einfach: Weil wir benutzerdefinierte Filter festlegen wollen, mit den wir beispielsweise nach der Bezeichnung der Aufgabe, der Katgorie oder dem Datum filtern können. Das gelingt zwar auch schon über die Benutzeroberfläche mit Bordmitteln, aber diese sind nicht direkt erreichbar. Wenn wir wissen, wonach der Benutzer filtern will, können wir die notwendigen Steuer­elemente auch direkt sichtbar im Formular anlegen.

Beginnen wir mit einem Filter, der die im Bericht im Unterformular befindlichen Aufgaben nach der Bezeichnung der Aufgabe filtert. Dazu fügen wir dem Hauptformular ein Textfeld namens txtFilter hinzu sowie eine Schaltfläche namens cmdFiltern, mit der wir den Filter anwenden können. Außerdem fügen wir noch eine Schaltfläche hinzu, mir der wir den angewendeten Filter wieder aufheben können. Der Entwurf des Formulars sieht dann wie in Bild 4 aus.

Steuer­elemente zum Filtern und zum Aufheben des Filters

Bild 4: Steuer­elemente zum Filtern und zum Aufheben des Filters

Um den Filter anzuwenden, fügen die der Schaltfläche cmdFiltern die folgende Prozedur hinzu:

Private Sub cmdFiltern_Click()

Dim strFilter As String

strFilter = "Bezeichnung LIKE '" & Me!txtFilter & "'"

With Me!rptAufgabenplaner.Report

.Filter = strFilter

.FilterOn = True

End With

End Sub

Diese ermittelt den Inhalt des Textfeldes txtFilter und stellt eine Bedingung zusammen, die beispielsweise Bezeichnung LIKE 'Artikel*' lautet. Dieser wird dann an die Eigenschaft Filter des Berichts im Unterformular übergeben. Außerdem stellen wir die Eigenschaft FilterOn des gleichen Elements auf True ein. Damit werden nun nur noch die der Bedingung entsprechenden Elemente im Bericht im Unterformular angezeigt (siehe Bild 5).

Filtern nach der Bezeichnung einer Aufgabe

Bild 5: Filtern nach der Bezeichnung einer Aufgabe

Praktischerweise bleiben nun auch die Datumsangaben und die Kategorien erhalten.

Um den Filtern wieder aufzuheben, fügen wir eine weitere Schaltfläche namens cmdKeinFilter hinzu. Diese löst die folgende Prozedur aus:

Private Sub cmdKeinFilter_Click()

Me!txtFilter = ""

With Me!rptAufgabenplaner.Report

.Filter = ""

.Requery

End With

End Sub

Wenn Sie bereits einmal unter VBA mit Filtern gearbeitet haben, sollte das kein Problem sein. Allerdings gibt es einen kleinen Haken: Allein das Einstellen der Eigenschaft Filter auf eine leere Zeichenfolge oder der Eigenschaft FilterOn auf False bewirkt nicht das Aufheben des aktuell angewendeten Filters wie es in Formularen der Fall ist. Wir müssen hier zusätzlich die Requery-Methode des Berichts im Unterformular aufrufen, damit dieser auch aktualisiert wird. Die Prozedur leert außerdem noch das Textfeld zur Eingabe des Filters.

Nach Datum filtern

Als Nächstes wollen wir nach dem Datum einer Aufgabe filtern. Dazu fügen wir dem Hauptformular zwei Schaltflächen namens txtDatumVon und txtDatumBis hinzu. Die Prozedur für die Schaltfläche cmdFiltern ändern wir wie in Listing 1. Die Prozedur prüft nacheinander die Inhalt der Felder txtFilter, txtDatumVon und txtDatumNach und fügt nur dann ein entsprechendes Element zum Kriterium hinzu, wenn das Textfeld einen Wert enthält. Am Ende entfernt es das führende AND des Kriteriums und übergibt den Ausdruck an die Filter-Eigenschaft des Bericht-Objekts.

Private Sub cmdFiltern_Click()

     Dim strFilter As String

     If Len(Me.txtFilter) > 0 Then

         strFilter = " AND Bezeichnung LIKE '" & Me!txtFilter & "'"

     End If

     If Len(Me!txtDatumVon) > 0 Then

         strFilter = strFilter & " AND ErledigenAm >= " & SQLDatum(Me!txtDatumVon)

     End If

     If Len(Me!txtDatumBis) > 0 Then

         strFilter = strFilter & " AND ErledigenAm < " & SQLDatum(CDate(Me!txtDatumBis) + 1)

     End If

     If Len(strFilter) > 0 Then

         strFilter = Mid(strFilter, 6)

     End If

     With Me!rptAufgabenplaner.Report

         .Filter = strFilter

         .FilterOn = True

     End With

End Sub

Listing 1: Filtern nach dem Aufgabentext und dem Datum

Die Datumsangaben formatieren wir mit der Hilfsfunktion SQLDatum aus dem Modul mdlTools in ein Format nach dem Schema #YYYY.MM.DD#, das sicher verarbeitet werden kann.

Bei der Verarbeitung des Feldes txtDatumBis ist zu beachten, dass wir das im Kriterium verwendete Datum in String-Form zunächst mit der CDate-Funktion in den Datentyp Date umwandeln. Dann addieren wir den Wert 1 hinzu und passen erst dann das Format an. Die gefilterten Datensätze sollen im Feld ErledigenAm einen Wert kleiner als dieses Datum aufweisen. Warum aber addieren wir den Wert 1? Wenn der Benutzer beispielsweise zwei Mal das gleiche Datum eingibt, also ans Start- und als Enddatum, dann soll die Bedingung alle Datensätze liefern, deren Datum zu diesem Tag gehört. Sollte der Benutzer nun für eine Aufgabe nicht nur ein Datum, sondern auch noch eine Uhrzeit angegeben haben, würde es nicht reichen, einfach nur nach allen Datensätzen zu filtern, deren Datum im Feld ErledigenBis genau gleich dem Filterdatum ist. Datumsangaben entsprechenden Double-Werten, wobei der Teil vor dem Komma die Tage und der Teil nach dem Komma die Uhrzeit wiedergibt. Bei Datumsangaben ohne Uhrzeit erhalten wir also eine ganze Zahl, mit Uhrzeit erhalten wir eine Dezimalzahl, für den 1.1.2018 um 12:00 Uhr beispielsweise 43101,5. Filtern nach Datumsangaben, die größer gleich 1.1.2018 und kleiner als 1.1.2018 sind, liefert also nur Datumsangaben mit der Uhrzeit 0:00 Uhr – also ohne Nachkommastellen. Deshalb zählen wir in diesem Fall den Wert 1 zum Wert aus txtDatumBis hinzu und ermitteln damit alle Einträge, deren Datum größer oder gleich 1.1.2018 und kleiner als 2.1.2018 sind.

Fehlersuche

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!