Microsoft Access

Datenaustausch zwischen Berichten und Formularen

03.05.2007 von Helma  Spona
Zwar haben Berichte und Formulare in Microsoft Access verschiedene Aufgaben, dennoch ist es sehr häufig notwendig, Informationen zwischen den beiden auszutauschen. Welche Möglichkeiten Sie haben, zeigt dieser Workshop.

Berichte und Formulare haben in Microsoft Access verschiedene Aufgaben. Formulare dienen vor allem zur Eingabe von Daten und Berichte sollen die vorgehaltenen Daten in einer bestimmten Form darstellen. Das kann die Ausgabe als einfache Tabelle oder Liste sein, aber Access bietet auch die komplexe Darstellung von Daten in Berichten.

Dabei stellen sich mitunter einige Fragen: Wie kommen die richtigen Daten in den Bericht? Wie lässt sich beispielsweise aus einem Formular heraus nur der aktuelle Datensatz in einem Bericht darstellen und um Daten ergänzen, die nicht aus der Abfrage oder Tabelle hervorgehen, auf der der Bericht beruht?

Der umgekehrte Weg, also die Übergabe von Daten aus einem Bericht an ein Formular ist auf gleichem Weg möglich, kommt aber so in der Praxis eher selten vor, weil ein Bericht ja auch keine Steuerelemente hat, über die beispielsweise ein Formular aufgerufen werden kann.

Wir stellen Ihnen in diesem Workshop eine Reihe von Verfahren vor, mit denen Sie eine Interaktion zwischen Berichten und Formularen erreichen können.

Die Möglichkeiten im Überblick

Berichte und Formulare basieren in der Regel beide auf einer Datenquelle. Dies kann eine Abfrage oder eine Tabelle sein. Abfragen bieten dabei die Möglichkeit, Parameter zu definieren, mit deren Hilfe Sie die Ergebnisse der Abfrage steuern können. Durch passende Parameterübergabe an die Abfrage, die einem Bericht zugrunde liegt, können Sie also festlegen, welche Daten im Bericht angezeigt werden. Die Alternative sind einfache Filter, die Sie an den Bericht übergeben und die das Ergebnis der Datenquelle noch einmal einschränken.

Es gibt allerdings auch Situationen, in denen Daten, die in einem Bericht gedruckt werden sollen, gar nicht in einer Tabelle gespeichert sind, oder zumindest nicht eindeutig und fest mit den Daten des Berichts verknüpft werden können und sollen. In diesen Fällen benötigen Sie Funktionen, um die Daten im Bericht anzeigen zu lassen. Um diese Daten zunächst festzulegen, damit die Funktionen sie ermitteln und anzeigen können, können Sie wahlweise globale Variablen oder Methoden und Eigenschaften verwenden. Damit gibt es die folgenden Möglichkeiten Daten zwischen zwei Formularen oder zwischen Formularen und Berichten zu übertragen:

Abfrage-Parameter nutzen

Haben Sie einen tabellarischen Bericht erstellt, der auf einer Abfrage beruht (siehe Bild) müssen Sie nicht für verschiedene Auswahlkriterien verschiedene Abfragen und Berichte erstellen. Möchten Sie beispielsweise nicht alle Aufträge anzeigen lassen, sondern mal nur die Rechnungen und mal nur die Gutschriften, können Sie dazu die Abfrage um einen Parameter erweitern.

Komplettansicht: Nicht immer will man alle Datensätze sehen...

Öffnen Sie dazu die Abfrage in der Entwurfsansicht und wählen Sie Abfrage/Parameter aus dem Menü aus. Geben Sie dann den Namen für den Parameter und den Datentyp in die erste freie Zeile des Dialogs ein.

Filter: ...deswegen lassen sich Abfragen parametrisieren.

Tragen Sie dann den Namen des Parameters als Vergleichwert in die Zeile Kriterien ein. Heißt Ihr Parameter beispielsweise FILTER und soll der Wert des Feldes dem Parameterwert entsprechend, geben Sie beispielsweise =[FILTER] ein. Achten Sie bei der Eingabe des Filterkriteriums aber darauf, dass Sie es gemäß des Datentyps des Parameters verwenden. Dies gilt insbesondere bei Vergleichen von Zeichenfolgen und Datumsangaben.

Speichern Sie nun die Abfrage und führen Sie sie aus, werden Sie aufgefordert den Parameterwert einzugeben. Das passiert auch dann, wenn die Abfrage Datenquelle eines Formulars oder Berichts ist. Dem Benutzer wird dazu ein Dialogfeld angezeigt. Er muss dann allerdings selbständig einen korrekten Wert eingeben, was manchmal viel verlangt ist.

Filter verwenden

Besser sind daher Filter: Die einem Bericht oder Formular zugrunde liegende Abfrage oder Tabelle liefert zunächst einmal die maximale Anzahl Daten. Per Filterausdruck beim Aufruf des Berichtes oder Formulars können Sie die Datensätze dann auf eine bestimmte Auswahl begrenzen.

Access bietet dazu zwei Möglichkeiten: Zum einen können Sie einen Filter erstellen und dem Bericht über die Filter-Eigenschaft zuweisen. Oder Sie übergeben einfach per VBA einen Ausdruck, wie er als WHERE-Klausel in einer SQL-SELECT-Anweisung verwendet wird, um das Abfrageergebnis einzuschränken. Um einen Bericht aufrufen und nur die Datensätze darzustellen, die im Feld TypKuerzel der Abfrage den Wert "RE" stehen haben, öffnen Sie den Bericht mit der Methode OpenReport des Objekts DoCmd und übergeben als vierten Parameter den Filter-Ausdruck:

Private Sub bttFilter_Click()
Dim stDocName As String
stDocName = "berAuftragsListe2"
DoCmd.OpenReport stDocName, acPreview, , "TypKuerzel=""RE"""
End Sub

Wichtig ist dabei natürlich, dass Sie im Filterausdruck vorkommende Anführungszeichen verdoppeln müssen, damit Access diese nicht als Ende der Filter-Zeichenkette erkennt. Wenn Sie mit diesem Code beispielsweise in einem Formular den Bericht öffnen, werden dort nur noch Rechnungen statt alle Aufträge angezeigt.

Nur Rechnungen: Der Filter wirkt und beschränkt die Ausgabe auf Rechnungen.

Mehr Komfort für den Benutzer

Der Vorteil an Filterausdrücken ist, dass der Benutzer keine Eingaben in ein Dialogfeld machen muss. Sie können den Wert einfach per VBA übergeben. Ob Sie ihn vorab berechnen oder beispielsweise dem Benutzer im Formular eine Auswahlliste für die möglichen Werte zur Verfügung stellen, können Sie im Einzelfall selbst bestimmen.

Sie können beispielsweise in das Formular ein Kombinationslistenfeld einfügen und in dessen Change-Ereignisprozedur den Bericht mit dem gewählten Filterkriterium ausführen. So muss der Benutzer einfach nur den Auftragstyp auswählen.

Komfortabel: Der Benutzer verändert die Auswahlliste und erhält den neuen Bericht.

Private Sub Kombinationsfeld2_Change()
Dim stDocName As String
stDocName = "berAuftragsListe2"
DoCmd.OpenReport stDocName, acPreview, ,"TypKuerzel=""" & Me.Kombinationsfeld2.Text & """"
End Sub

Globale Variablen für die Datenübergabe nutzen

Jedoch besteht die Kommunikation zwischen Formularen und Berichten oder zwischen Formularen untereinander nicht immer darin, dass die angezeigten Daten ermittelt oder eingeschränkt werden sollen. Es gibt auch Situationen, in denen andere Arten von Daten in einen Bericht eingefügt werden sollen, wie beispielsweise der Benutzername oder eine Lizenznummer der Software. Ebenfalls denkbar ist, dass abhängig von der Lizenz, die der Benutzer verwendet, Informationen im Bericht ein- oder ausgeblendet oder Steuerelemente in Formularen deaktiviert werden sollen.

In allen Fällen, in denen die Daten, die zwischen Berichten und Formularen ausgetauscht werden sollen, nicht in der Datenquelle zu finden sind, kommen globale Variablen für den Datenaustausch in Frage.

Variablen definieren

Globale Variablen müssen Sie zwingend in einem normalen Modul, also nicht im Modul des Formulars oder Berichts definieren, damit alle Datenbankobjekte darauf zugreifen können.

Wenn die Variablen initialisiert und deren Werte beispielsweise aus der Registry ausgelesen werden müssen, sollten Sie im gleichen Modul auch eine Prozedur erstellen, die das übernimmt. Dann brauchen Sie im Code des Formulars oder Berichtes nur noch diese Prozedur aufzurufen.

Global Const strLizenz = "Demo"
Global strLizenznehmer As String

Sub INIT()
strLizenznehmer = GetSetting("MeineAnw", "Einstellungen", "Lizenznehmer", "Mustermann AG")
End Sub

Variablen nutzen

Sie können nun beispielsweise die Konstante strLizenz dazu nutzen, in Formularen ein Labelfeld namens lblDemo einzublenden, wenn die Konstante den Wert "Demo" hat. In allen anderen Fällen blenden Sie das Labelfeld aus, damit der Schriftzug nicht sichtbar ist, der die kommerzielle Nutzung des Berichts verhindern soll.

Dazu erstellen Sie eine Ereignisprozedur für das Format-Ereignis des Berichtsabschnittes (hier der Detailbereich), in dem sich das Labelfeld befindet. Innerhalb der Prozedur können Sie die Konstante abfragen und abhängig von deren Wert das Labelfeld ausblenden, indem Sie die Eigenschaft Visible auf False setzen.

Demo: Anhängig von globalen Variablen lassen sich Berichte verschieden gestalten.

Falls Variablen initialisiert werden müssen, rufen Sie die Prozedur INIT in der Ereignisprozedur Open des Berichts auf.

Private Sub Detailbereich_Format(Cancel As Integer, FormatCount As Integer)
If Not (strLizenz = "Demo") Then
Me.lblDemo.Visible = False
End If
End Sub

Private Sub Report_Open(Cancel As Integer)
INIT
End Sub

Variablenwerte in Berichten anzeigen

Falls Sie die Werte aus Variablen und Konstanten in Berichten anzeigen lassen möchten, geht das nicht direkt. Sie müssen sich dazu entweder im Bericht selbst oder in einem normalen Modul eine Funktion erstellen, die die Variable zurückgibt. Die Funktion können Sie in ein Textfeld innerhalb des Berichts eingeben. Mit der folgenden Funktion geben Sie beispielsweise den Namen des Lizenznehmers zurück:

Function getLizenznehmer() As String
getLizenznehmer = strLizenznehmer
End Function

Um den Rückgabewert innerhalb eines Textfeldes im Bericht anzeigen zu lassen, geben Sie für das Textfeld =getLizenznehmer() als Feldwert ein.

Variablen ausgeben: Innerhalb von Berichten können Sie auch den Inhalt einer Variablen ausgeben lassen.

Eigenschaften und Methoden zur Datenübergabe nutzen

Benötigen Sie Daten in verschiedenen gleichen Berichten oder Formularen, lassen sich diese auch in Form von Methoden und Eigenschaften kapseln. Möchten Sie beispielsweise innerhalb eines Berichts ein Wasserzeichen mit einem Schriftzug anzeigen, das in Demo-Versionen die Nutzung des Berichtes verhindern soll, können Sie ein Label-Feld verwenden. Den anzuzeigenden Text setzen Sie über eine Methode oder Eigenschaft des Berichts und rufen diese über das Objekt auf, das beim Laden des Formulars aus der Klasse erzeugt wird.

Bei der Übergabe eines Werts an den Bericht spielt es im Prinzip keine Rolle, ob Sie dafür eine Methode (öffentliche Prozedur oder Funktion) erstellen oder eine Eigenschaft. Beide Varianten definieren Sie innerhalb des Klassenmoduls des Berichts mit dem Label-Feld. Eine Eigenschaft, die nur geschrieben und nicht gelesen werden soll können, definieren Sie via Property Let und weisen den Parameterwert einfach dem Labelfeld als Aufschrift zu.

Public Property Let DemoText(strText As String)
Me.lblDemo.Caption = strText
End Property

Eine Methode definieren Sie als Prozedur (Sub) oder Funktion (Function). Auch hier übergeben Sie den zu setzenden Wert als Parameter.

Public Sub setDemoText(strText As String)
Me.lblDemo.Caption = strText
End Sub

Aufruf der Methode

Das wichtigste ist nun der korrekte Aufruf der Methode oder Eigenschaft. Sie benötigen dazu eine Variable, der Sie als Typ den Namen des Klassenmoduls des Berichts zuweisen. Heißt der Bericht berAuftragsListe2, geben Sie als Datentyp Report_berAuftragsListe2 an. Danach weisen Sie der Variablen den Bericht zu. Das Objekt ist bereits vorhanden, weil es automatisch von Access erzeugt wird. Sie weisen der Variablen also einfach das Objekt mittels Set objBericht = Report_berAuftragsListe2 zu.

Anschließend können Sie die Methoden und Eigenschaften aufrufen. Erst danach zeigen Sie den Bericht mit der Methode OpenReport an:

Private Sub bttKlassen_Click()
Dim objBericht As Report_berAuftragsListe2
Dim stDocName As String
stDocName = "berAuftragsListe2"
Set objBericht = Report_berAuftragsListe2
objBericht.setDemoText ("test")
objBericht.DemoText = "Test2"
DoCmd.OpenReport stDocName, acPreview, , "TypKuerzel=""RE"""
End Sub