Lies diesen Artikel und viele weitere mit einem kostenlosen, einwöchigen Testzugang.
Manfred Hoffbauer, Düsseldorf
Der Entwurf von Berichten durch den bloßen Einsatz von Menübefehlen und der Maus ist eine herausragende Stärke von Access. Bei den Anhängern anderer Programmiersysteme können Sie damit immer wieder neidvolle Blicke ernten. Wenn Sie dann noch in die VBA-Trickkiste greifen, bringen Sie das Fass zum überlaufen. Microsoft hat die Programmiersprache nahtlos in Berichte integriert.
Eine typische Anwendung für Berichte ist der Ausdruck einer Rechnung. Die Beispieldatenbanken RechnungenMitBerichten97.mdb beziehungsweise RechnungenMitBerichten2000.mdb zu diesem Beitrag enthalten unter dem Namen repRechnungen ein Rechnungslayout, das auf den Daten der Nordwind-Datenbank basiert. Lediglich die Tabelle tblBestellungen wurde um das Feld MwSt erweitert. Es hat den Datentyp Double und das Format Prozentzahl.
Informationen im Kopfbereich
Den Bericht zum Ausdruck von Rechnungen finden Sie im Register Berichte unter dem Namen repRechnungen. Der Bericht druckt eine Rechnung passend zu einer vorhandenen Bestellung. Er hat folgenden Aufbau: Im Kopfbereich der Rechnung befinden sich Logo, Name und Anschrift des Absenders. Um die Rechnung in einem Fensterumschlag versenden zu können, wird die Anschrift des Rechnungsempfängers meistens im unteren, linken Bereich des oberen Drittels angeordnet. Am rechten Rand befinden sich Zusatzinformationen wie beispielsweise Kunden- und Bestellnummer.
Datenherkunft des Berichts
Die Daten des Berichts stammen aus mehreren Tabellen, die über eine Abfrage zusammengefügt werden. Um sich die Daten anzusehen, öffnen Sie in der Entwurfsansicht das Eigenschaftsfenster des Berichts. Klicken Sie in den Berichtseigenschaften auf das Register Daten und auf die Eingabehilfe-Schaltfläche der Eigenschaft Datenherkunft.
Access zeigt dann einen Abfrageentwurfsbereich mit der Datenherkunft des Berichts an (siehe Bild 1). Die Kopfdaten der Rechnung stammen aus den Tabellen Bestellungen und Versandfirmen. Die Daten für die Rechnungspositionen entnimmt der Bericht aus der Tabelle Bestelldetails.
Bild 1: Die Datenherkunft des Berichts besteht aus drei verknüpften Tabellen.
Gruppierung
Wegen der Verknüpfung der Tabellen Bestellungen und Bestelldetails enthält das Abfrageergebnis für jede Rechnungsposition einen Datensatz. Bei einer Rechnung mit mehreren Positionen werden die Kopfdaten pro Position wiederholt.
Bild 2: Im Fußbereich der Gruppierung sehen Sie die Frachtkosten und den Rechnungsbetrag.
Innerhalb des Berichts müssen Sie die Positionen einer Rechnung zu einer Gruppe zusammenfassen. Mit dem Befehl Ansicht/Sortieren und gruppieren öffnen Sie ein Fenster, mit dem die Gruppierung nach dem Feld Bestell-Nr eingestellt ist. Wegen dieser Einstellung druckt Access die Positionen einer Rechnung – soweit der Platz ausreicht – auf einer Seite aus (siehe Bild 2).
Der Detailbereich des Berichts enthält Steuerelemente zur Anzeige der Rechnungspositionsdaten.
Dies sind der Artikelname, der Einzelpreis, die Anzahl und der Rabatt. Eine Besonderheit ist das Textfeld txtPreis.
Es hat die folgende Formel als Steuerelementinhalt:
=[txtEinzelpreis]*[txtAnzahl]*(1-[txtRabatt])
Diese Berechnung ermittelt aus dem Einzelpreis, der Menge und dem Rabatt den Preis für eine Rechnungsposition. Das Beispiel verzichtet auf die Berechnung der Mehrwertsteuer. Aus einem Preis von 100 EUR, einer Menge von 1 und einem Rabatt von 10% berechnet sich ein Preis von90 EUR.
Rechnungssumme ermitteln
Die Rechnungssumme berechnet sich aus der Summe der Einzelpositionen. Die Berechnung erfolgt in einem Textfeld im Fußbereich der Gruppe Bestellung-Nr. Eine nahe liegende Idee wäre nun, das Textfeld mit folgendem Ausdruck auszustatten:
=Summe([txtPreis])
Dieser Ausdruck funktioniert aber leider nicht. Access öffnet bei einem Wechsel in die Seitenansicht einen Dialog zur Eingabe eines Wertes für txtPreis. Der Grund dafür ist, dass sich die Summenfunktion auf die Werte eines Steuerelements aus einem anderen Bereich (in diesem Fall aus dem Detailbereich) nicht anwenden lässt. Auch der Ausdruck Summe([txtEinzelpreis] * [txtAnzahl] * (1-[txtRabatt])) führt entweder zu einer Fehlermeldung oder zu fehlerhaften Werten. Es ist deshalb empfehlenswert, den Preis pro Position im Detailbereich des Berichts zu aggregieren. Das Textfeld txtSummeEinzelpositionen hat folgenden Steuerelementinhalt:
=[txtEinzelpreis]*[txtAnzahl]*(1-[txtRabatt])
oder einfacher
=[txtPreis]
Außerdem ist die Eigenschaft Laufende Summe für dieses Textfeld auf über Gruppe eingestellt. Das führt dazu, dass Access den Wert des Feldes über alle Rechnungspositionen aggregiert. Erst beim Wechsel zur nächsten Bestellung beginnt die Summenbildung wieder bei 0. Damit der Rechnungsbetrag im Gruppenfuß angezeigt werden kann, erhält das Textfeld txtSumme folgenden Ausdruck:
=txtSummeEinzelpositionen
Es zeigt also einfach den Wert des Feldes txtSummeEinzelpositionen, also die Summe aller Rechnungspositionen an.
Rechnungsposition hinzufügen
Bei Rechnungen mit mehreren Positionen kann es manchmal hilfreich sein, wenn sich einzelne Posten im Gespräch mit anderen Personen einfach identifizieren lassen. Aus diesem Grund enthält der Detailbereich das Textfeld txtPosition.
Bild 3: über das Register Ereignis geben Sie die Prozedur für das Beim Drucken-Ereignis ein.
Rechnungspositionen zählen
Der Steuerelementinhalt dieses Textfeldes ist leer. Es erhält seinen Wert über VBA-Befehle, die den Wert des Textfeldes pro Position um eins erhöhen. Zur Eingabe des VBA-Befehls öffnen Sie das Eigenschaftsfenster des Detailbereichs. Klicken Sie auf das Register Ereignis und die Eingabehilfe-Schaltfläche für das Ereignis Beim Drucken (siehe Bild 2)
Ergänzen Sie die Prozedur mit der folgenden Anweisung:
If PrintCount = 1 Then txtPosition = txtPosition + 1
Diese Anweisung erhöht den Wert des Textfeldes txtPosition um den Wert 1. Access durchläuft die Ereignisprozedur für das Beim Drucken-Ereignis unter bestimmten Umständen mehrfach und erhöht dabei jeweils den Wert der Variablen PrintCount. Mit der Bedingung If PrintCount = 1 erreichen Sie, dass die Positionsnummern nur einmal pro Seite addiert werden.
Zähler zurücksetzen
Eine wichtige Anforderung an die Rechnungsposition besteht darin, dass die Zählung bei jeder Bestellung mit Eins beginnt. Andernfalls würden Sie mit dem Steuerelement die Anzahl der Positionen von der ersten bis zur letzten Rechnung fortlaufend nummerieren.
Um die Positionsnummer für jede neue Rechnung zurückzusetzen, müssen Sie die folgende Anweisung für die Ereigniseigenschaft Beim Drucken des Bereichs Bestell-Nr-Kopfbereich eingeben:
txtPosition = 0
Access führt diesen VBA-Code für jede neue Bestellnummer einmal aus.
Praxis-Tipp
Statt mit VBA können Sie die Rechnungsposition auch als laufende Summe realisieren. Fügen Sie dem Detailbereich ein Feld namens txtRechnungsposition und dem Steuerelementinhalt =1 hinzu. öffnen Sie das Eigenschaftsfenster für dieses Steuerelement und wählen Sie für die Eigenschaft Laufende Summe den Wert über Gruppe.
Bei Rechnungen mit vielen Positionen kann wie in Bild 4 der Fall eintreten, dass die Summenzeilen auf die zweite Druckseite rutschen, obwohl dort keine Rechnungspositionen zu drucken sind. Die Ursache für diesen unschönen Effekt ist schnell gefunden: Beim Ausdruck der Rechnung versucht Access so viele Positionen wie möglich auf eine Seite zu drucken. Der verfügbare Platz berechnet sich aus der Seitenhöhe abzüglich der Höhen von Gruppenkopf-, Gruppenfuß-, Seitenkopf- und Seitenfußbereich, wobei der Gruppenfußbereich natürlich nur dann eine Rolle spielt, wenn er auf der aktuellen Seite auch gedruckt wird.
Bild 4: Wenn nur die Summenzeilen auf die zweite Seite rutschen, dann sieht das nicht gerade elegant aus.
Im Fall der Rechnung ist es aber gewünscht, dass der verbleibende Platz nicht vollständig durch Wiederholungen des Detailbereichs verbraucht wird. Um beispielsweise auf jeder Seite nur 10 Datensätze zu drucken, benötigen Sie nur ein kleines VBA-Programm. Ein Beispiel finden Sie in dem Bericht repRechnungen10.
Ein Zähler für Datensätze
Das Zählen der Rechnungsdatensätze pro Seite erfolgt über die Integervariable AnzahlDatensätze. Damit das Beispiel mit den weiter oben beschriebenen Lösungen konform läuft, sollte das Zählen der Datensätze beim Formatieren des Berichts erfolgen.
Die Addition des Zählers übernimmt die folgende Anweisung:
AnzahlDatensätze = AnzahlDatensätze + 1
Fügen Sie diese Anweisung in die Ereignisprozedur Beim Formatieren des Detailbereichs ein. Außerdem sollten Sie die Variable im Kopfbereich des Moduls definieren:
Dim AnzahlDatensätze As Integer
Aber zurück zum Detailbereich. Der Zähler ermittelt die Anzahl der Wiederholungen des Detailbereichs. Wenn die Zahl 10 erreicht ist, dann soll Access einen Seitenumbruch durchführen. Dies erreichen Sie mit folgender Anweisung:
Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...
Testzugang
eine Woche kostenlosen Zugriff auf diesen und mehr als 1.000 weitere Artikel
diesen und alle anderen Artikel mit dem Jahresabo