Vorwort Möchten Sie gerne schnell und ohne Frust mit Access programmieren lernen? Dann ist dieses Buch genau das richtige für Sie. Sie werden hier Schritt für Schritt mit vielen anschaulichen Beispielen an das Programmieren mit Access herangeführt. Wie in allen echt-einfach-Büchern gibt es eine Comicfigur als Führer, die Ihnen über die ersten Klippen beim Umgang mit dem Programm hilft. Sie steht Ihnen mit Tipps und Tricks zur Seite und ermöglicht so einen problemlosen Einstieg. Die kinderleichten Computerbücher der echt-einfach-Reihe sind keineswegs Kinderbücher. In allen Büchern werden Funktionen und Möglichkeiten des Programms kompetent erklärt. Dabei konzentrieren sich die Autorinnen und Autoren auf das, was Sie wirklich brauchen. Überflüssiger Ballast wird weggelassen. Ohne PC-Chinesisch oder Technogeschwafel, dafür aber leicht verständlich, ermöglichen Ihnen die echt-einfach-Bücher sehr schnell den sicheren Umgang mit dem Computer.
Inhaltsverzeichnis
5
Inhaltsverzeichnis 1
2
3
4
5
6
6
Einleitung
10
1.1
Worum geht es in diesem Buch?
11
1.2
Kein Buch mit sieben Siegeln
11
1.3
Die Beispieldatenbank CasaMaria
12
Los geht´s
16
2.1
Makro1 meldet sich
16
2.2
Alles klar mit VBA
19
Access-Funktionen clever nutzen
24
3.1
Bedingte Formatierung in Formularen
24
3.2
Direkt im Formular rechnen lassen
34
3.3
Bedingte Formatierung in Berichten
35
3.4
Direkt im Bericht rechnen lassen
39
Makros ausprobieren
44
4.1
Erstellen Sie ein neues Makro
44
4.2
Makro über Schaltfläche im Formular starten
47
4.3
Makro für aktuellen Datensatz im Formular
49
Makros besser verstehen
54
5.1
Makro-Grundlagenwissen
54
5.2
Makros an Ereignisse binden
60
5.3
Bedingte Ausführung von Makros
68
5.4
Gruppenmakros
77
5.5
Schreibweise für Verweise
79
Mit Makros suchen und filtern
84
6.1
84
Clever suchen mit Kombinationsfeld
6.2
Makro mit Suchfunktion
6.3
Mit Makros filtern
Inhaltsverzeichnis
88 100
7
8
9
10
11
Synchronisation, Kombination, Unterformular
104
7.1
Zwei Formulare per Makro synchronisieren
104
7.2
Nachschlagen mit Kombinationsfeld
107
7.3
Unterformular einbinden
109
7.4
Anwendungsbeispiel für erstellte Formulare
111
Makro-Praxisbeispiel
112
8.1
Was haben Sie bisher ohne Makro getan?
112
8.2
Ausdrücke finden und Abläufe vorbereiten
113
8.3
Ausdruck im Makro verwenden
117
Makros in Berichten
120
9.1
Makros an Ereignisse des Berichts binden
120
9.2
Ereignisse in Unterbereichen des Berichts
122
Anwenderfreundlich mit Makros
124
10.1 Meldung mit Auswahlmöglichkeit
124
10.2 Grundeinstellungen für die Datenbank
126
10.3 Ungebundenes Formular als Startformular
130
10.4 Eigene Symbolleisten
134
VBA ausprobieren
136
11.1 Warum überhaupt VBA?
136
11.2 Eingetragenen VBA-Code ändern
136
11.3 VBA-Code neu erstellen für InputBox
139
11.4 Aktuelle Uhrzeit im Formular anzeigen
144
11.5 Makro in VBA umwandeln
146
Inhaltsverzeichnis
7
12
13
14
15
8
VBA Grundlagenwissen
150
12.1 Der Visual Basic-Editor
150
12.2 Programmieren in Access
152
12.3 Variablen besser verstehen
156
12.4 Gültigkeit von Variablen
170
12.5 Operatoren
171
12.6 Bedingte Abfragen und Verzweigungen
176
12.7 Wiederholte Anweisungen: Schleifen
181
12.8 Springen mit GoTo
185
Unterprogramme erstellen
186
13.1 Function-Prozeduren
187
13.2 Sub-Prozeduren
191
13.3 Variablenübergabe
193
Vordefinierte Funktionen
196
14.1 MsgBox-Funktion als einführendes Beispiel
196
14.2 Funktionen für Zeichenketten
201
14.3 Funktionen für Dateioperationen
202
14.4 Funktionen für Verzeichnisoperationen
203
14.5 Konvertierung
204
14.6 Datums- und Zeitfunktionen
204
14.7 Informationsfunktionen
206
14.8 Finanzfunktionen
207
Fehler finden und behandeln
208
15.1 Fehlerarten
208
15.2 Der Debugger zur Fehlersuche
209
15.3 Vermeidung von Fehlern
220
15.4 Fehlerbehandlung
222
15.5 Fehlerbehandlungsbefehle
224
15.6 Beispielhafte Fehlerbehandlung
227
Inhaltsverzeichnis
16
17
DAO und andere Objekte
228
16.1 Was ist ein Objekt?
228
16.2 Wozu sind Objekte gut?
230
16.3 Der With-Befehl
231
16.4 Auflistungen
232
16.5 Makroaktionen über DoCmd-Objekt nutzen
233
16.6 Datenbankzugriff mit DAO
234
VBA-Praxisbeispiel
240
17.1 Wie sollen Buchungen aufgenommen werden?
240
17.2 Was steckt hinter dem Formular?
241
17.3 Listing
245
Index
250
Inhaltsverzeichnis
9
1 Einleitung »A me un paese di sole, una casa leggera, un canto di fontana giù nel cortile. E un sedile di pietra. E schiamazzo di bimbi, un orticello e giorni senza nome è la certezza di vivere. Ein Dorf in der Sonne, ein einfaches Haus, der Gesang eines Brunnens unten im Hof. Und ein Sitz aus Stein. Und Lärm von Kindern, ein Garten und Tage ohne Namen geben mir die Gewissheit zu leben.«
Makkaroni? Makros? VBA-Programmierung mit Access 2002? Für meine köstlichen Makkaroni-Gerichte bin ich schon öfter gelobt worden, aber auch das mit den Makros oder der VBA-Programmierung erkläre ich Ihnen gerne. Um Ihnen den Einstieg so leicht wie möglich zu machen, habe ich ein durchgehendes Beispiel gewählt: die Access 2002-Datenbank der Ferienappartementsiedlung Casa Maria. Sie bekommen alles anschaulich gezeigt und können die vorgestellten Lösungen leicht auf Ihre Datenbanken übertragen. Die Ferienappartementsiedlung Casa Maria liegt im schönsten Teil der Toskana und hat neben einer interessanten Access-Datenbank auch die besten Nudelspeisen weit und breit zu bieten. Nicht dass ich Ihnen den Mund wässrig machen möchte – aber trocken muss ein Buch über Programmierung doch nicht sein, oder? Stellen Sie sich einfach vor, ich wäre eine Italienerin namens Rosella (genau genommen: Rosinante Estrella Jolanta di Cainero!) und ich würde zusammen mit meiner Schwester Maria d‘Agostino die besagte Casa-Maria-Feriensiedlung betreiben. Beim Arbeiten mit Access sind mir all die alten italienischen Sprichwörter wieder in den Sinn gekommen, die ich dann als Motto für die einzelnen Kapitel gewählt habe. (Sie sehen, ich bin wirklich die geborene Italienerin!)
10
Kapitel 1: Einleitung
1.1
Worum geht es in diesem Buch?
Um dieses Buch zu lesen, müssen Sie weder Informatik studiert, noch eine Automechanikerlehre gemacht haben. Auch wenn Sie keine Computer-Fachzeitschrift abonniert haben, fernsteuerbare Spielzeugautos blöd finden und lieber chinesisch als italienisch essen, sollten Sie das Buch nicht zur Seite legen. In den folgenden Kapiteln bekommen Sie einen schnellen Einstieg in das Thema Programmierung mit Access 2002. Wenn Sie schon erste Erfahrungen mit Access 2002 gesammelt haben und nun neugierig darauf sind, wie und was Sie weiter verbessern können, sind Sie hier goldrichtig. Im nächsten Kapitel gibt es in einem Crash-Kurs schon mal eine erste Begegnung mit Makros und Visual Basic für Applikationen oder kurz VBA. In Kapitel 3 folgen dann einige Tipps, wie Sie Ihre Datenbank auch ohne Programmierung aufwerten können. Um das Ausprobieren von Makros geht es im vierten Kapitel. Die folgenden drei Kapitel dienen dann mit unterschiedlichen Schwerpunkten zur Vertiefung Ihrer Kenntnisse. Nach einem Praxisbeispiel in Kapitel 8 und dem Thema Makros in Berichten, zeige ich Ihnen in Kapitel 10, wie Sie Ihre Datenbank mit Makros anwenderfreundlicher machen. Ab dem elften Kapitel beginnt der VBA-Teil des Buches. Auch hier steht das Ausprobieren am Anfang. In den Kapiteln 12 bis 16 folgt dann eine gründliche Vertiefung. Den Abschluss bildet ein VBAPraxisbeispiel aus der Casa Maria.
1.2
Kein Buch mit sieben Siegeln
Damit Sie sich hier im Buch besser zurechtfinden, habe ich es nach einem einfachen Prinzip aufgebaut. Dabei können Sie sich an den Schriftarten und der Textgestaltung orientieren. Programmbezeichnungen wie Access oder allgemein Dateinamen werden kursiv geschrieben. Meldungen von Programmen und Menütexte werden in dieser SCHRIFT angezeigt.
1.1 Worum geht es in diesem Buch?
11
Andere Texte, vor allem die, die Sie selber eingeben sollen, erscheinen in Schreibmaschinenschrift. Wenn ich Ihnen etwas Schritt für Schritt erkläre, können Sie so deutlich erkennen, was als Nächstes zu tun ist. Gibt es entweder die eine, oder die andere Möglichkeit,
behalten Sie in dieser Form den Überblick. Als ich unsere CasaMaria-Datenbank mit Makros und VBA aufgemöbelt habe, sind mir viele Dinge aufgefallen.
Ein Tipp oder Trick Immer wenn ich Sie auf eine köstliche Entdeckung hinweisen möchte, die für Sie bei der Access-Programmierung nützlich sein kann, weise ich Sie in dieser Form darauf hin.
Warnung Bevor ich Sie blindlings in Schwierigkeiten kommen lasse, bewaffne ich mich lieber mit dem Nudelholz, um Ihnen einzubläuen, was Sie beim Programmieren lieber nicht tun sollten.
12
Kapitel 1: Einleitung
1.3
Die Beispieldatenbank CasaMaria
Die Beispiele in diesem Buch beziehen sich immer auf die Datenbank, die ich zusammen mit meiner Schwester Maria für die Verwaltung unseres Ferienclubs angelegt habe. Wenn Sie das Access 2002-echt-einfach-Buch gelesen haben, wird Ihnen der Aufbau der Datenbank bekannt vorkommen. Bild 1.1: Aufbau der Beispieldatenbank CasaMaria
Namensregeln für Access Wie Sie sehen, wurde den Bezeichnungen der Tabellen das Kürzel »tbl« vorangestellt. Das heißt, die Tabelle Preisgruppen wird jetzt als tblPreisgruppen bezeichnet. Dies dient lediglich dazu, später die Übersicht zu behalten, wenn Sie mit vielen ähnlich benannten Tabellen, Abfragen und Formularen hantieren, denn die bekommen dann alle ihre eigenen Kürzel:
Datenbankobjekt
Vorsilbe
Englischer Name
Tabellen
tbl
tables
Abfragen
qry
queries
Formulare
frm
forms
Berichte
rpt
reports
1.3 Die Beispieldatenbank CasaMaria
Tabelle 1.1: Namenskonvention für Datenbankobjekte
13
Ich habe sehr gute Erfahrungen mit diesen Abkürzungen gemacht, auch wenn ich am Anfang lieber aus dem Italienischen abgeleitete Kürzel verwendet hätte. Aber diese englischen Vorsilben haben den Vorteil, dass sie einem internationalen Standard entsprechen (der so genannten RVBA-Konvention), an dem sich andere Programmierer orientieren.
1.3.2 Beispieldatenbanken von CD-ROM kopieren Die CD-ROM enthält die Beispiele zum Buch. Für jedes Kapitel des Buches finden Sie einen Ordner mit einer Beispieldatenbank. Kopieren Sie die Datenbanken in Ordner Ihrer Wahl auf Ihre Festplatte. Beachten Sie dabei, dass Dateien, die von einer CD-ROM kopiert werden, schreibgeschützt sind. Sie können den Schreibschutz der kopierten Dateien im Windows-Explorer über DATEI EIGENSCHAFTEN aufheben. Die Beispieldatenbanken enthalten die Ergebnisse des jeweiligen Kapitels. Wenn Sie die Beispiele eines Kapitels selber ausprobieren möchten, müssen Sie dafür also die Beispieldatenbank des vorangegangenen Kapitels laden! Genug der Vorrede. Legen Sie los! Bei uns sagt man »Chi ben comincia è a metà dell'opera. – Gut begonnen ist halb gewonnen.«
Ciao
14
Kapitel 1: Einleitung
1.3 Die Beispieldatenbank CasaMaria
15
2 Los geht´s »Chi non è contento di quello che ha, non sarebbe contento neanche se avesse ciò che non ha. – Wer nicht mit dem zufrieden ist, was er hat, wäre auch nicht zufrieden, wenn er das hätte, was er nicht hat.« In diesem Sinne sollten Sie dieses Einstiegskapitel genießen. Verschaffen Sie sich einen ersten Eindruck von Makros und VBA. Das eigentliche Ausprobieren beginnt dann für Makros in Kapitel 4 und für VBA in Kapitel 11.
Als Einstieg in das Thema des Buches möchte ich Ihnen gleich zeigen, wie Sie ein kleines Makro definieren, das sich mit einem Mel-
dungsfenster meldet, wie Sie für das Makro eine Verknüpfung auf das Desktop legen und so einen schnellen Zugriff auf die Datenbank haben, wie Sie mit einem kleinen VBA-Programm eine Warnmeldung erstellen, die erscheint, wenn Sie in einem Formular daneben klicken. Verwenden Sie als Grundlage die Beispieldatenbank CasaMaria aus dem Ordner Kap01 von der beiliegenden CD-ROM. Öffnen Sie die Datenbank, nachdem Sie sie, wie am Ende des letzten Kapitels beschrieben, auf Ihre Festplatte kopiert haben.
2.1
Makro1 meldet sich
Ein kleines Makro zu schreiben ist keine Kunst. Dazu wählen Sie einfach im Datenbankfenster auf der Objektleiste den Objekttyp MAKROS aus und klicken auf die Schaltfläche NEU. Im geöffneten Entwurfsfenster geben Sie nun das neue Makro ein.
16
Kapitel 2: Los geht´s
Klicken Sie in die erste Zeile unter AKTION und wählen Sie über den Listenpfeil am Ende der Zeile die Makroaktion MELDUNG aus. Bild 2.1: Ein neues Makro im Entwurfsfenster eingeben
Nun können Sie im unteren Bereich im Eingabefeld MELDUNG Ihren Meldungstext eintippen: Casa Maria meldet sich per Makro. Bild 2.2: Meldungstext eintippen
Schließen Sie Ihr neues Makro mit einem Klick auf das SCHLIEßEN-Kreuz rechts oben im Makroentwurfsfenster. Im nun er-
2.1 Makro1 meldet sich
17
scheinenden Dialogfeld beantworten Sie die Frage, ob Sie speichern wollen, mit Klick auf JA. Bild 2.3: Ja, Sie wollen speichern
Auch den dann vorgeschlagenen Namen MAKRO1 akzeptieren Sie mit OK. Bild 2.4: Makro1 klingt OK
Das gerade neu entworfene Makro ist nun im Datenbankfenster unter dem Namen MAKRO1 zu finden. Wenn Sie auf MAKRO1 doppelklicken, erscheint die von Ihnen definierte Meldung auf dem Bildschirm.
Makro-Verknüpfung zum Starten der Datenbank nutzen Wenn Ihr Access-Programmfenster im Vollbildmodus angezeigt wird, verkleinern Sie es, klicken Sie auf Ihr MAKRO1 und ziehen Sie es mit gedrückter Maustaste in einen freien Bereich auf dem Desktop. Dort wird eine Verknüpfung zum Makro erzeugt. Wenn Sie auf die Verknüpfung klicken, wird automatisch Access gestartet (falls Sie es noch nicht geöffnet haben), die CasaMaria-Datenbank wird geladen und die Meldung erscheint auf dem Bildschirm. Sie können Ihr neues Makro also zum direkten Starten der CasaMaria-Datenbank nutzen!
18
Kapitel 2: Los geht´s
Bild 2.5: Auch ein Klick auf die Verküpfung ruft die Meldung auf
2.2
Alles klar mit VBA
Auch mit VBA können Sie eine Meldung auf dem Bildschirm erscheinen lassen. Als Beispiel soll eine Meldung angezeigt werden, wenn im Formular frmBelegung irgendwo außerhalb der Eingabefelder in den Detailbereich geklickt wird. Dazu öffnen Sie das Formular frmBelegung in der Entwurfsansicht und klicken mit der rechten (!) Maustaste auf eine freie Stelle im Detailbereich des Formulars. Im erscheinenden Kontextmenü klicken Sie auf EREIGNIS.
2.2 Alles klar mit VBA
19
Bild 2.6: Im Kontextmenü des Detailbereichs auf EREIGNIS klicken
Im folgenden Dialogfeld wählen Sie CODE-GENERATOR. Bild 2.7: CODE-GENERATOR wählen
Es öffnet sich das Fenster mit der VBA-Entwicklungsumgebung des Visual Basic-Editors. Lassen Sie sich von den vielen Bereichen nicht erschrecken. Im oberen Bereich sehen Sie die Einfügemarke blinken.
20
Kapitel 2: Los geht´s
Bild 2.8: Visual-Basic-Editor
Beginnen Sie der Übersichtlichkeit halber mit der 圵-Taste und schreiben Sie dann einfach folgende Zeile: msgbox "Daneben! Bitte in eines der Eingabefelder klicken!"
Direkthilfe meldet sich automatisch Msgbox ist die Abkürzung für MessageBox und steht für Meldungsfenster. Sowie Sie das Leerzeichen hinter msgbox eintippen,
wird die Direkthilfe geöffnet, die Sie eigentlich bei der Eingabe unterschiedlicher Einstellungsmöglichkeiten für das Meldungsfenster unterstützen soll. Es ist aber auch möglich, einfach nur in Anführungszeichen den gewünschten Meldungstext einzutragen. Und genau das sollten Sie tun! Auf die weiteren Einstellungsmöglichkeiten komme ich noch einmal im VBA-Teil des Buches.
2.2 Alles klar mit VBA
21
Bild 2.9: Eingabe mit Direkthilfe
Sobald Sie Ihren Eintrag beendet haben und dann in eine andere Zeile klicken, wird das klein geschriebene msgbox automatisch in MsgBox umgewandelt. Schließen Sie den Visual Basic-Editor mit Klick auf das SCHLIEßEN-Kreuz. Wenn Sie nun im Formular frmBelegung in der Formularansicht irgendwo in den freien Bereich klicken, erscheint die von Ihnen geschriebene Meldung: Bild 2.10: Meldung nach Klick in freien Bereich des Formulars
Wenn Sie das Formular schließen wollen, erscheint ein Dialogfeld, in dem Sie gefragt werden, ob Sie die Änderungen speichern möchten. Wenn Sie auf JA klicken, wird Ihr zuvor eingegebener VBA-Code zusammen mit dem Formular gespeichert.
22
Kapitel 2: Los geht´s
Bild 2.11: Ihr VBA-Code wird mit dem Formular gespeichert
Wie Sie sehen, brauchen Sie vor Makros und VBA keinen falschen Respekt zu haben. Bevor Sie ein Makro oder VBA-Programm schreiben, sollten Sie sich trotzdem vergewissern, ob sich das, was Sie vorhaben, nicht auch noch einfacher realisieren lässt. Denn mit Access 2002 lassen sich viele Verbesserungen auch ohne Programmierung umsetzen. Mehr dazu im nächsten Kapitel.
2.2 Alles klar mit VBA
23
3 Access-Funktionen clever nutzen Dieses Kapitel steht unter dem Motto: »Meglio un uovo oggi che una gallina domani. – Besser heute ein Ei als morgen eine Henne.« Warten Sie nicht darauf, dass Sie morgen (oder übermorgen) alles über Makros und VBA wissen. Fangen Sie gleich heute an, Ihre Formulare und Berichte zu verbessern. Entdecken Sie, wie einfach das auch ohne Programmierkenntnisse geht. (Wenn Sie sich gleich auf Entdeckungsreise machen, dann denken Sie daran: auch Columbus hat mal mit einem Ei angefangen!)
In diesem Kapitel lernen Sie die Möglichkeiten kennen, die Ihnen die so genannte »bedingte Formatierung« bietet und Sie erfahren, wie Sie direkt in Ihren Formularen und Berichten Berechnungen ausführen lassen können. Unter anderem zeige ich Ihnen, wie Sie in einem Formular das Feld mit dem Geburtsdatum so
einrichten, dass es farbig markiert wird, wenn derjenige Geburtstag hat, wie Sie Datumsfelder so definieren, dass Samstage und Sonntage schon an der Farbe zu erkennen sind, wie Sie Eintragungen in einem Feld nur unter bestimmten Bedingungen ermöglichen, wie Sie sofort im Formular sehen, wieviel Euro Ihrem gerade eingegebenen DM-Betrag entsprechen, wie Sie dem Ausdruck einer Geburtstagskarte für Kinder, Männer und Frauen jeweils automatisch eine andere Farbe geben.
3.1
Bedingte Formatierung in Formularen
Bedingte Formatierung – klingt trocken, ist aber klasse! Ich bin darauf gestoßen, als ich nach einer Möglichkeit gesucht habe, die besonders positiven Eigenschaften eines Appartements direkt im Fomular deutlich zu kennzeichnen.
24
Kapitel 3: Access-Funktionen clever nutzen
Um das Prinzip der bedingten Formatierung zu verstehen, müssen Sie sich klar machen, dass sich das Aussehen (also die Formatierung) eines Formularfeldes ändern lässt. Es muss nicht immer schwarze Schrift auf weißem Hintergrund sein. Bei der bedingten Formatierung wird nun nicht etwa allen Feldern eines Formulars ein grüner Hintergrund verpasst, sondern es wird festgelegt, unter welchen Bedingungen sich das Aussehen eines Feldes ändern soll. Wofür das gut sein kann und wie es funktioniert, möchte ich Ihnen nun zeigen.
3.1.1
Fokussierte Felder in Fettschrift setzen
Wenn Sie in einem Formular mit der Maus in ein Feld klicken oder ein Feld mit der 圵-Taste anspringen, dann hat dieses Feld den Fokus. Der Begriff Fokussierung taucht später bei den Makros und bei der Programmierung wieder auf, von daher ist es gut, sich an ihn zu gewöhnen. Sie können jetzt eine Bedingung definieren, die dafür sorgt, dass die Schrift eines Feldes fett dargestellt wird, sobald das Feld den Fokus hat. Öffnen Sie Ihre CasaMaria-Datenbank. Öffnen Sie das Formular frmAppartements in der Entwurfsansicht und markieren das Steuerelement BAUJAHR. Rufen Sie mit dem Menübefehl FORMAT BEDINGTE FORMATIERUNG das zugehörige Dialogfeld auf. Dort wählen Sie FELD HAT FOKUS als Bedingung und FETT als Schriftart.
3.1 Bedingte Formatierung in Formularen
25
Möglichkeit zur Bearbeitung in Formularansicht ausschalten In Access 2002 haben Sie normalerweise die Möglichkeit, die Eigenschaften eines Feldes auch direkt in der Formularansicht zu ändern, es sei denn, diese Möglichkeit wird in den Formulareigenschaften mit der Eigenschaft ENTWURFSÄNDERUNGEN ZULASSEN ausgeschaltet. Und genau das habe ich getan, um zu verhindern, dass die Formulare bei der Nutzung durch andere versehentlich geändert werden. (Die Formulareigenschaften öffnen Sie z.B., indem Sie in der Entwurfsansicht links oben auf das kleine Rechteck, den so genannten Formularmarkierer doppelklicken.)
Bild 3.1: In der Entwurfsansicht geöffnetes Formular
Im nächsten Abschnitt zeige ich Ihnen, wie Sie mit HINZUFÜGEN weitere Bedingungen für das Feld definieren können. (FELD HAT FOKUS kann aber nur als erste Bedingung definiert werden!)
26
Kapitel 3: Access-Funktionen clever nutzen
Bild 3.2: Bedingung für fett formatiertes, fokussiertes Feld
Schließen Sie das Dialogfeld BEDINGTE FORMATIERUNG mit OK. Wenn Sie zurück in die Formularansicht wechseln und dort das Feld BAUJAHR anklicken, erscheint das Baujahr fett formatiert. Wenn Sie nun auch für die anderen Felder des Formulars eine entsprechende bedingte Formatierung definieren, erreichen Sie, dass immer die Schrift des Feldes, das gerade den Fokus hat, fett gesetzt wird.
Bedingte Formatierungen für mehrere Felder gleichzeitig definieren Markieren Sie in der Entwurfsansicht mit gedrückter 圶-Taste mehrere Felder, dann können Sie für alle Felder gleichzeitig eine bedingte Formatierung festlegen. Die andere Möglichkeit wäre, die Formatierung eines Feldes mit der Schaltfläche FORMAT ÜBERTRAGEN für ein anderes Feld zu übernehmen.
Wenn es darum geht, Formulare auch für andere Anwender verständlich zu machen, ist es natürlich praktisch, wenn wichtige Werte sofort auffallen. Auch dafür lassen sich bedingte Formatierungen nutzen.
3.1.2
Der Wert des Feldes ändert seine Farbe
Was ist der Wert eines Feldes? Felder nehmen unterschiedliche Werte an. Der Wert des Feldes BAUJAHR im Formular frmAppartements kann z.B. 2002 sein. Oder kleiner oder größer. Sie können
3.1 Bedingte Formatierung in Formularen
27
nun in Abhängigkeit vom Wert des Feldes (also hier von der Jahreszahl) ein besonderes Aussehen für das Feld definieren. Diese Möglichkeit habe ich genutzt, um unsere neuen Appartements hervorzuheben. Anfang 2001 wurden in unserem Ferienclub vier neue Appartements fertig gestellt. Mit einer bedingten Formatierung habe ich erreicht, dass im Formular frmAppartements das Feld BAUJAHR bei diesen Appartements mit rotem Hintergrund erscheint und so sofort in's Auge springt! Um einmal auszuprobieren, wie das funktioniert, öffnen Sie wieder das Formular frmAppartements in der Entwurfsansicht, markieren das Steuerelement BAUJAHR und rufen mit dem Menübefehl FORMAT BEDINGTE FORMATIERUNG wieder das zugehörige Dialogfenster auf. Im Dialogfenster BEDINGTE FORMATIERUNG klicken Sie auf HINZUFÜGEN. Als zweite Bedingung definieren Sie: Feldwert ist größer als oder gleich 2001 und weisen den damit ausgewählten neuen Appartements dann über die Schaltfläche FÜLL-/ HINTERGRUNDFARBE eine Feldfarbe zu. (Mit LÖSCHEN können Sie Bedingungen auch wieder entfernen.) Bild 3.3: Bei neuen Appartements wird der Hintergrund bunt
Schließen Sie das Dialogfenster BEDINGTE FORMATIERUNG mit OK. Wenn Sie zurück in die Formularansicht wechseln, ist das Feld BAUJAHR jetzt bei den ab 2001 gebauten Appartements farbig hin-
terlegt.
28
Kapitel 3: Access-Funktionen clever nutzen
Eingabe bei Felddatentyp Datum/Uhrzeit Wenn Sie für Felder mit dem Felddatentyp DATUM/UHRZEIT Bedingungen definieren, müssen Sie das Datum (wie Sie es schon von Abfragen kennen) in Rauten (#) setzen. (Wenn für das BAUJAHR eine Jahreszahl angegeben wird, wurde dem Feld nicht der Felddatentyp DATUM/UHRZEIT, sondern TEXT zugewiesen.) Mit der Bedingung: Feldwert ist größer als #1.1.2001# können Sie für das Feld LETZTERENOVIERUNG eine Formatierung definieren, mit der Sie die Felder aller nach dem 1.1.2001 renovierten Appartements kennzeichnen. Noch besser wäre es natürlich, wenn keine Kennzeichnung mehr erscheint, sobald die Renovierung länger als ein Jahr zurückliegt. Auch das lässt sich machen.
Bedingte Formatierung immer aktuell Die Funktion Datum() gibt das aktuelle Datum an (vielleicht haben Sie sie schon bei Abfragen genutzt). Wenn Sie diese Funktion in eine Bedingung für die Formatierung eines Datumsfeldes einfügen, bleibt die im Formular angezeigte Kennzeichnung immer auf dem neusten Stand. Die Bedingung Feldwert ist größer als Datum()-365 umfasst beispielsweise die letzten 365 Tage. Mit dieser Bedingung können Sie im Formular frmAppartements die Felder LETZTERENOVIERUNG derjenigen Appartements auffällig formatieren, die innerhalb des letzten Jahres renoviert wurden.
Bild 3.4: So ist die bedingte Formatierung immer aktuell
Nach demselben Muster könnten Sie auch mit der Bedingung Feldwert ist größer als Datum()-3650 für das Feld GEBURTSDATUM im Formular frmAdressen Deutschland eine Formatierung festlegen, mit der das Feld bei Kindern bis 10 Jahren gekennzeichnet wird (3650 sind 10 Jahre in Tagen).
3.1 Bedingte Formatierung in Formularen
29
3.1.3
Ausdrücke für spezielle Effekte
Manchmal lässt sich der gewünschte Effekt nicht in der eben beschriebenen Art direkt aus dem Wert des betreffenden Feldes ableiten. Mit der Bedingungsvariante AUSDRUCK IST... kommen Sie jedoch noch ein ganzes Stück weiter.
Wochenenden ausdrücklich markieren Für die Felder ANREISE und ABREISE im Formular frmBuchungen möchte ich die Samstage und Sonntage andersfarbig markieren. Dafür gibt es eine einfache Lösung, die sich aber nicht direkt vom Feldwert ableiten lässt. Stattdessen müssen Sie einen Ausdruck mit einer Funktion bilden, die den Wochentag zu einem beliebigen Datum angibt. Die Funktion lautet Wochentag(Zahl;Typ). Wenn Sie als Zahl ein Datum eingeben, erhalten Sie als Ergebnis eine Zahl von 1 bis 7, die den Wochentag angibt, wobei standardmäßig von Sonntag = 1 bis Samstag = 7 gezählt wird. Diese Standardzählweise entspricht Typ 1.
Access ergänzt Typ der Wochentagszählung automatisch Wenn Sie keinen Typ angeben, wählt Access automatisch den Standardtyp. Wenn Sie als Typ 2 eintragen, wird von Montag = 1 bis Sonntag = 7 gezählt, bei Typ 3 von Montag = 0 bis Sonntag = 1. Im Augenblick reicht aber der Standardtyp.
Als Bedingung zum Erfassen von Samstagen im Feld ANREISE des Formulars frmBuchungen geben Sie also ein: Ausdruck ist Wochentag([Anreise])=7. Ist der Ausdruck wahr, d.h. handelt es sich bei dem Datum der Anreise um einen Samstag, wird für das Feld ANREISE die gewählte Formatierung angezeigt. In einer weiteren Bedingung habe ich einfach statt der 7 eine 1 in den Ausdruck geschrieben und damit die Formatierung für Sonntage festgelegt. Sonntage sollen in einem hellen Orange, Samstage in einem hellen Gelb erscheinen.
30
Kapitel 3: Access-Funktionen clever nutzen
Bild 3.5: Ausdrücke für ein farbig formatiertes Wochenende
Wenn Sie nun noch für das Feld ABREISE des Formulars eine entsprechende bedingte Formatierung definieren, in der Sie lediglich [Anreise] durch [Abreise] ersetzen, erscheinen Wochenenden in den beiden Feldern bunt hinterlegt. Bild 3.6: Helle Samstage und dunkle Sonntage sofort erkennen
Heutigen Geburtstag markieren Ich finde es praktisch, wenn ich im Formular sofort sehe, dass ein Gast heute Geburtstag hat. Deshalb habe ich eine bedingte Formatierung definiert, die im Formular frmAppartements das Datum im Feld GEBURTSDATUM am Geburtstag des Gastes in roter, fetter Schrift zeigt. Stimmen Monat und Tag von Geburtsdatum und aktuellem Datum überein, hat derjenige heute Geburtstag. Das aktuelle Datum ermitteln Sie wieder mit Datum() und das Geburtsdatum finden
3.1 Bedingte Formatierung in Formularen
31
Sie im gleichnamigen Feld. Die Funktionen Monat(Datum) bzw. Tag(Datum) geben den Monat bzw. Tag eines Datums aus. Die Heute-ist-Geburtstag-Bedingung für das Feld GEBURTSDATUM im Formular frmAppartements muss also heißen: Ausdruck ist Monat(Datum())=Monat([Geburtsdatum])Und Tag(Datum())=Tag([Geburtsdatum]).
Bild 3.7: Die Heute-istGeburtstag-Bedingung
Wenn Sie testen wollen, ob Ihre bedingte Geburtstags-Formatierung auch funktioniert, geben Sie einfach eine neue Adresse ein von jemandem, der heute Geburtstag hat oder für den Sie ein entsprechendes Geburtsdatum eintragen.
3.1.4
Bedingte Aktivierung eines Feldes
Im Dialogfenster BEDINGTE FORMATIERUNG gibt es die links abgebildete Schaltfläche AKTIVIERT, mit der sich erreichen lässt, dass ein Feld nur unter den definierten Bedingungen aktiviert wird. Diese Möglichkeit möchte ich wie folgt nutzen: In der Tabelle tblAppartements und im Formular frmAppartements kann im Feld KLEINKINDZUSÄTZLICHERLAUBT angegeben werden, ob im betreffenden Appartement zusätzlich ein Kleinkind untergebracht werden kann. In den Fällen, wo dies möglich ist, möchte ich noch eine kurze Anmerkung dazuschreiben, wo das Kinderbett am besten aufgestellt werden kann. Eine neue Spalte mit dem Namen KLEINKINDANMERKUNG habe ich bereits in die Tabelle tblAppartements aufgenommen. Nun möchte ich ein entsprechendes Eingabefeld auch in das Formular frmAppartements einbinden, wobei nur dann Eintragungen in diesem Feld möglich sein sollen, wenn ein Kleinkind zusätzlich erlaubt ist. Zunächst soll das gewünschte Feld in das Formular eingefügt werden. Dazu öffnen Sie bitte das Formular frmAppartements in der Entwurfsansicht.
32
Kapitel 3: Access-Funktionen clever nutzen
Lassen Sie sich die FELDLISTE anzeigen, indem Sie den Menübefehl ANSICHT FELDLISTE aufrufen. Wählen Sie KLEINKINDANMERKUNG aus der FELDLISTE und ziehen Sie das Feld an die gewünschte Stelle im Formular. Das Bezeichnungsfeld, das automatisch mit erzeugt wird, können Sie löschen. Bild 3.8: Neues Feld in Formular übernehmen
Klicken Sie in das neue Textfeld, um es zu markieren, und wählen Sie wie gewohnt den Menübefehl FORMAT BEDINGTE FORMATIERUNG. Im Dialogfenster BEDINGTE FORMATIERUNG definieren Sie nun die Bedingung: Ausdruck ist [KleinkindZusätzlichErlaubt]= Nein und klicken dann auf die Schaltfläche AKTIVIERT. Bild 3.9: Ein Feld gezielt deaktivieren
Mit dieser Formatierung erreichen Sie, dass im Anmerkungsfeld nur Eintragungen möglich sind, wenn das Kontrollkästchen neben KLEINKINDER? aktiviert ist. Zum Abschluss sollten Sie das Feld KLEINKINDANMERKUNG noch in der Aktivierreihenfolge so verschieben, dass es direkt hinter dem Feld KLEINKINDZUSÄTZLICHERLAUBT angesprungen wird, wenn Sie mit
3.1 Bedingte Formatierung in Formularen
33
der 圵-Taste durch das Formular laufen. (Zur Erinnerung: Die Aktivierreihenfolge können Sie ändern, wenn Sie in der Entwurfsansicht den Menübefehl ANSICHT AKTIVIERREIHENFOLGE aufrufen.)
3.2
Direkt im Formular rechnen lassen
Lassen Sie Ihren Rechner rechnen – und zwar direkt im Formular!
Preise von DM in Euro umrechnen In unserem Ferienclub kommen die meisten Gäste aus Deutschland. Für die Zeit während der Euro-Umstellung sollen im Formular sowohl die Euro- als auch die DM-Werte angezeigt werden. Ich habe das vorhandene Formular frmPreisgruppen zu diesem Zweck um ein Feld erweitert, in dem der vorhandene DM-Tagespreis automatisch in Euro umgerechnet und angezeigt werden soll. Dazu musste ich nur an der richtigen Stelle angeben, dass man den DM-Betrag durch 1,95583 teilen muss, um den Betrag in Euro zu erhalten. Das Ergebnis lasse ich dann auf glatte Beträge runden. Für die ganze Aktion sind nur wenige Arbeitsschritte erforderlich, die Sie im Folgenden problemlos nachvollziehen können: Öffnen Sie das Formular frmPreisgruppen in der Entwurfsansicht. Wenn die Toolbox nicht angezeigt wird, blenden Sie diese mit dem Menübefehl ANSICHT TOOLBOX ein. Wählen Sie das Werkzeug TEXTFELD aus, ziehen Sie auf dem Formularentwurf an der gewünschten Stelle ein neues Textfeld auf und löschen Sie das zugehörige Bezeichnungsfeld. Klicken Sie zweimal hintereinander in das Textfeld. Jetzt blinkt die Einfügemarke und Sie können folgende Formel eingeben (beginnend mit dem Gleichheitszeichen): =Runden([PreisDMproTag]/1,95583;0). Mit der Funktion Runden wird das Ergebnis auf Null Stellen hinter dem Komma gerundet. Nachdem Sie außerhalb des Textfeldes geklickt haben, markieren Sie das neue Textfeld und öffnen das zugehörige Eigenschaftenfenster. Auf dem Registerblatt ALLE sehen Sie im Eingabefeld hinter STEUERELEMENTINHALT die eben eingetragene
34
Kapitel 3: Access-Funktionen clever nutzen
Formel. Sie können die Formel ändern oder nächstes Mal direkt hier eintragen. Geben Sie im Eingabefeld NAME (in der obersten Zeile) PreisEuroProTag ein und im Eingabefeld der dritten Zeile wählen Sie EURO als FORMAT. Die DEZIMALSTELLENANZEIGE können Sie auf 0 setzen. In einem Feld mit einer Formel können keine Daten per Hand eingegeben werden, es rechnet nur nach der angegebenen Formel Werte aus. Damit es nicht mit der 圵-Taste angesprungen werden kann, sollten Sie es deaktivieren (AKTIVIERT: NEIN) und Sperren (GESPERRT: JA). Bild 3.10: Eigenschaftenfenster des neuen Textfeldes
Bild 3.11: Die Umrechnung in Euro direkt im Formular
Wenn Sie jetzt in die Formularansicht wechseln, sollten Sie dort nach Änderungen in den DM-Feldern immer den zugehörigen Euro-Wert angezeigt bekommen. Denn immer dann, wenn Sie in einem der DM-Felder eine Eingabe oder Veränderung vornehmen oder wenn Sie auf einen neuen Datensatz weiterblättern, werden die zugehörigen berechneten Textfelder mit den Euro-Preisen aktualisiert.
3.3
Bedingte Formatierung in Berichten
Ähnlich wie für Formulare, lassen sich auch für Berichte bedingte Formatierungen definieren. Dabei können Sie das Erscheinungsbild wie gewohnt vom Wert eines Feldes abhängig machen, oder Sie fassen Ihre Bedingung wieder in einen Ausdruck. Wenn Sie sich einen Bericht so vorstellen, wie er auch meistens aussieht, nämlich als ein bedrucktes Stück Papier, dann ist klar,
3.3 Bedingte Formatierung in Berichten
35
dass Sie hier die Möglichkeiten der Fokussierung und Aktivierung von Feldern nicht nutzen können – deswegen stehen diese Ihnen bei der Definition von bedingten Formatierungen in Berichten auch nicht zur Verfügung.
3.3.1
Wertvolle Felder färben
Was Sie vorhin bei Formularen an bedingten Formatierungen in Abhängigkeit vom Feldwert festgelegt haben, lässt sich ganz einfach auf Berichte übertragen. Öffnen Sie den Bericht rptAppartements in der Entwurfsansicht und markieren Sie das Feld BAUJAHR mit einem (!) Klick (Doppelklick öffnet Schreibmodus!). Mit dem Menübefehl FORMAT BEDINGTE FORMATIERUNG öffnen Sie nun das bekannte Dialogfeld. Hier tragen Sie dieselbe Bedingung ein wie vorhin im entsprechenden Formular (Feldwert ist größer als oder gleich 2001) und wählen die gewünschte Formatierung. Bestätigen Sie mit OK und betrachten Sie das Ergebnis in der Seitenansicht des Berichtes. In derselben Weise können Sie auch die bedingte Formatierung für das Feld RENOVIERUNG? übernehmen (Feldwert ist größer als Datum()-365).
3.3.2
Ausdrückliche Formatierung in Berichten
Als Beispiel für die Verwendung von Ausdrücken in bedingten Formatierungen für Berichte habe ich damit Geburtstagsaufkleber erstellt, die automatisch unterschiedlich gefärbt werden, je nachdem, ob sie für ein Kind, eine Frau oder einen Mann sind. Vor längerer Zeit hatten wir mit dem ETIKETTEN-ASSISTENTEN Aufkleber entworfen für das kleine Präsent des Hauses, das diejenigen Gäste erhalten, die in der Casa Maria Geburtstag haben. (Den ETIKETTEN-ASSISTENTEN rufen Sie mit dem Menübefehl EINFÜGEN BERICHT ETTIKETTEN-ASSISTENT auf.)
36
Kapitel 3: Access-Funktionen clever nutzen
Wenn Sie nachvollziehen wollen, wie ich diesen Aufkleber mit bedingter Formatierung aufgewertet habe, öffnen Sie zunächst den Bericht rptEtikettenGeburtstage in der Entwurfsansicht und markieren Sie das Feld, in dem Vorname und Nachname erscheinen. Bild 3.12: Das gewünschte Feld des Berichts ist markiert
Mit dem Menübefehl FORMAT BEDINGTE FORMATIERUNG öffnen Sie nun das bekannte Dialogfenster. Um für alle Kinder bis 10 Jahre eine eigene Formatierung zu wählen, tragen Sie eine Bedingung ein, die ich Ihnen so ähnlich schon bei Formularen vorgestellt hatte: Ausdruck ist Datum()-[Geburtsdatum]<3650. Damit legen Sie fest, dass zwischen dem Geburtsdatum und dem heutigen Datum nicht mehr als 10 Jahre in Tagen vergangen sein dürfen. Wählen Sie nun noch eine Formatierung – z.B. einen gelben Hintergrund und rote, fett gesetzte Schrift – fertig! Wenn es Ihnen nicht zu bunt wird, können Sie auch die Etiketten von Männern und Frauen unterschiedlich färben. Dazu klicken Sie zweimal auf HINZUFÜGEN und geben Ausdruck ist [Anrede]="Frau" als zweite Bedingung und Ausdruck ist [Anrede]="Herr" als dritte Bedingung ein.
3.3 Bedingte Formatierung in Berichten
37
Bild 3.13: Gelb für Kinder, rot für Frauen, blau für Männer?
Schauen Sie sich Ihren Entwurf aber besser noch einmal in der SEITENVORSCHAU an, bevor Sie ihn ausdrucken.
Reihenfolge der Bedingungen beachten Die eben vorgestellte dreistufige bedingte Formatierung funktioniert so nur, wenn die Bedingung für Kinder an erster Stelle steht! Access arbeitet die Bedingungen nur so lange ab, bis die erste zutrifft. Sobald dies der Fall ist, werden die folgenden Bedingungen nicht mehr angewandt! Da in unserer CasaMaria-Datenbank das Geschlecht eines Gastes der Einfachheit halber über das Feld ANREDE mit erfasst wird, ist bei Jungen pro forma »Herr« und bei Mädchen »Frau« eingetragen. Auf jede Adresse trifft also entweder die Bedingung »Herr« oder die Bedingung »Frau« zu. Wenn diese Bedingung gleich an erster Stelle abgefragt wird, wird eine an zweiter oder dritter Stelle stehende Kinderbedingung nicht mehr geprüft.
38
Kapitel 3: Access-Funktionen clever nutzen
3.4
Direkt im Bericht rechnen lassen
Ich habe die Geburtstagsetiketten noch um die Angabe ergänzt, um den wievielten Geburtstag es sich handelt, so dass sie jetzt z.B. so aussehen: Bild 3.14: Thomas Alt wird 2002 Neunundvierzig
Ob Thomas Alt sich jetzt mehr über den Aufkleber freut als vorher, habe ich noch nicht ausprobiert. Zumindest will ich Ihnen nicht vorenthalten, wie Sie den Neunundvierzigsten und all die anderen Jahreszahlen auf die Etiketten bekommen. Ich habe dafür im Bericht – ähnlich wie vorhin bei den Formularen – eine Formel eingegeben. Hierbei gibt es wieder die Möglichkeit, die mit einem Gleichheitszeichen beginnende Formel direkt in der Entwurfsansicht in das neue Textfeld zu schreiben oder die Eintragung im Eigenschaftenfenster unter STEUERELEMENTINHALT zu machen.
Die Formel für den Neunundvierzigsten Zum Entwickeln der gesuchten Formel fügen Sie zum Bericht rptEtikettenGeburtstage ein neues Textfeld hinzu, das am Ende dann wieder gelöscht wird.
3.4 Direkt im Bericht rechnen lassen
39
Bild 3.15: Noch ist es ungebunden, das kleine Textfeld
Klicken Sie in das markierte Textfeld und schreiben Sie =Jahr([Geburtsdatum]) hinein. Die von Ihnen eingetragene Funktion Jahr(Datum) gibt die Jahreszahl eines Datums aus. Schauen Sie sich das Ergebnis einmal in der Seitenvorschau an. Wenn Sie den Ausdruck nun zu =Jahr(Datum())-Jahr([Geburtsdatum])ergänzen, können Sie aus dem GEBURTSDATUM ermitteln, wie alt jemand dieses Jahr wird. Wenn Sie dann noch einen Punkt hinzufügen, wird beispielsweise der 49. ausgegeben. Der Ausdruck lautet dann: =Jahr(Datum())-Jahr([Geburtsdatum])&"."
Bei längeren Ausdrücken den Ausdrucks-Generator nutzen Wollen Sie längere oder kompliziertere Ausdrücke in ein Feld eingeben, sollten Sie den Ausdrucks-Generator nutzen. Dazu öffnen Sie das Eigenschaftenfenster des Feldes, klicken dort in das STEUERELEMENTINHALT-Eingabefeld und dann auf das Feld mit den drei Punkten am Ende der Zeile. Das funktioniert sowohl in Berichten als auch in Formularen (s. Bild 3.10).
40
Kapitel 3: Access-Funktionen clever nutzen
Bild 3.16: Ausdrucks-Generator für längere Formeln nutzen
Gefundene Formel in Geburtstagsetiketten einbinden Jetzt müssen Sie die Formel nur noch an der richtigen Stelle in den Geburtstagsetiketten einfügen. Weil Sie die Formel ja in einen bestehenden Ausdruck einbinden wollen, kopieren Sie sie bitte ohne Gleichheitszeichen (am besten geht das Markieren im Ausdrucks-Generator). Und jetzt kommt das Einfügen. Dazu öffnen Sie den Bericht rptEtikettenGeburtstag in der Entwurfsansicht. Klicken Sie in das Feld, in dem ="zum Geburtstag" steht, und öffnen Sie das Feld im Ausdrucks-Generator. Schaffen Sie folgendermaßen eine Lücke für Ihre Formel: ="zum"& &"Geburtstag" und fügen Sie die Formel in der Mitte zwischen den beiden &-Zeichen ein. Zur besseren Übersichtlichkeit lassen sich mit 圸 Zeilenumbrüche einfügen.
3.4 Direkt im Bericht rechnen lassen
41
Bild 3.17: Schon ziemlich gut, die Formel!
Das zu Beginn eingefügte Textfeld können Sie nun aus der Entwurfsansicht des Berichts löschen. Wenn Sie sich das Ergebnis in der Seitenansicht anschauen, werden Sie sehen, dass es nur noch einen winzigen Haken gibt: Wenn nämlich kein Geburtstag in der Tabelle eingetragen ist (wie z.B. bei Petra Klein) erscheint der Punkt trotzdem. Dagegen hilft am einfachsten die WENN-Funktion, nach dem Motto: Wenn kein Geburtstag eingetragen ist, soll ein Leerzeichen und sonst ein Punkt erscheinen. Übersetzt heißt das dann: Wenn([Geburtsdatum] Ist Null;"";"."). Nach dieser Verbesserung sieht der Ausdruck jetzt so aus: ="zum " & Jahr(Datum())-Jahr([Geburtsdatum]) & Wenn([Geburtsdatum] Ist Null;"";".") & " Geburtstag!"
Bild 3.18: So gibt es gute Etiketten für den 49. und den Rest
42
Kapitel 3: Access-Funktionen clever nutzen
Wer die WENN-Funktion nicht kennt, kann eingebaute Funktionen nutzen Sie können die WENN-Funktion natürlich auch über die eingebauten Funktionen aufrufen. Dies bietet sich an, wenn Sie sich mit der Schreibweise der Funktion unsicher sind. Dazu wählen Sie im Ausdrucks-Generator: FUNKTIONEN EINGEBAUTE FUNKTIONEN ALLE WENN. Aber vergessen Sie nach Ihren Eintragungen nicht, alle überflüssigen <
>-Platzhalter wieder zu entfernen. Wenn Sie viel mit der WENN-Funktion arbeiten, dann ist das direkte Eintippen schneller.
Es kann gefeiert werden! Zumindest an den Geburtstags-Etiketten soll‘s nicht liegen – die können Sie jetzt ausdrucken, wenn Sie den obigen Ausdruck übernommen haben. Wenn Ihnen jetzt vor lauter Ausdrucken und Ausdrücken der Kopf schwirrt, gibt es nur eins: Ausschalten den PC, zumachen das Buch und lieber ein wenig durch die Toscana spazieren!
3.4 Direkt im Bericht rechnen lassen
43
4 Makros ausprobieren Getreu dem Motto: »Val più la pratica che la grammatica – Die Praxis ist mehr wert als die Grammatik« haben Sie jetzt zuerst einmal die Gelegenheit, die Funktionsweise von Makros auszuprobieren. Erst im nächsten Kapitel folgt dann etwas mehr Theorie.
In diesem Kapitel zeige ich Ihnen wie Sie mit einem Makro einen Bericht ausdrucken lassen, wie Sie eine Befehlsschaltfläche in ein Formular einbinden, auf
die Sie dann nur zu klicken brauchen, um Ihr Makro auszuführen und den Bericht ausdrucken zu lassen, wie Sie das Makro so anpassen, dass nach Klick auf die Befehlsschaltfläche der Bericht nur für den gerade im Formular angezeigten Datensatz ausgedruckt wird. Als konkretes Beispiel dient dabei der Ausdruck von Geburtstagsetiketten. Am Ende zeige ich Ihnen dann, wie Sie auf dieselbe Weise auch einzelne Adressetiketten ausdrucken lassen können.
4.1
Erstellen Sie ein neues Makro
Im letzten Kapitel habe ich Ihnen den Bericht zum Ausdrucken der Geburtstagsetiketten vorgestellt. Manchmal brauchte ich nur mal schnell ein einzelnes Geburtstagsetikett, müsste dafür aber den ganzen Bericht ausdrucken. In diesem Kapitel zeige ich Ihnen, wie ich das Problem mit einem Makro gelöst habe, so dass es jetzt möglich ist, mit einem Klick nur das Geburtstagsetikett für den gerade im Formular angezeigten Datensatz ausdrucken zu lassen. Aber der Reihe nach. Als ersten Schritt können Sie ausprobieren, wie Sie ein Makro definieren, das einen Bericht ausdruckt. Das geht ganz einfach, denn Abläufe, die Sie in Access sonst per Mausklick oder Tastatureingabe auslösen, können Sie auch von einem Makro ausführen lassen.
44
Kapitel 4: Makros ausprobieren
Das Erstellen des Makros geht so ähnlich, wie Sie es schon von Ihrem ersten Makro aus Kapitel 2 kennen: Wählen Sie im Datenbankfenster auf der Objektleiste den Objekttyp MAKROS und klicken Sie auf die Schaltfläche NEU. Klicken Sie im geöffneten Entwurfsfenster des Makros in die erste Zeile unter AKTION und wählen Sie im Kombinationsfeld den Makrobefehl ÖFFNEN BERICHT aus. Sie sehen, dass jetzt im unteren Bereich als Ansicht AUSDRUCK eingetragen ist, d.h., beim Öffnen des Berichts wird er gleich ausgedruckt. Klicken Sie in das Eingabefeld neben BERICHTSNAME und wählen Sie RPTETIKETTENGEBURTSTAGE als Bericht. Klicken Sie in die erste Zeile unter KOMMENTAR und geben Sie einen Kommentar zur gewählten Aktion ein (z.B. GeburtstagsEtiketten ausdrucken). Bild 4.1: Die erste Makro-Aktion ist eingegeben
Klicken Sie auf das SCHLIEßEN-Kreuz rechts oben im Makrofenster. In einem Dialogfeld werden Sie zum Speichern aufgefordert. Bestätigen Sie mit JA. Geben Sie dem Makro im Dialogfeld SPEICHERN UNTER den Namen mcrDruckenEtikettenGeburtstage und bestätigen Sie mit OK. Bild 4.2: Dem Makro einen Namen geben
4.1 Erstellen Sie ein neues Makro
45
Das Makro mcrDruckenEtikettenGeburtstage steht nun im Datenbankfenster. Ein Klick auf den Eintrag und der Bericht rptEtikettenGeburtstag wird ausgedruckt.
Sie müssen einem Makro nicht „mcr“ voranstellen Access führt Ihr Makro auch aus, wenn Sie es z.B. GeburtstagsEtiketten schön ausdrucken nennen. Das Kürzel mcr am Anfang und das Zusammenschreiben der Wörter soll in erster Linie für mehr Übersichtlichkeit sorgen. Am Anfang des Buches hatte ich Ihnen diese Schreibweise, die sich an der »Reddick-Konvention« orientiert, nahegelegt. Access ist es egal, ob Sie sich an diese Schreibweise halten. (Access ist es allerdings auch egal, wenn Sie den Überblick verlieren!)
Bild 4.3: Neues Makro im Datenbankfenster
Zum Testen des Makros SEITENANSICHT wählen Wenn Sie jetzt mit dem neuen Makro etwas herumprobieren wollen und nicht bei jedem Versuch einen Ausdruck machen möchten, wählen Sie SEITENANSICHT, dann sehen Sie das Erscheinungsbild des Ausdrucks als Seitenvorschau am Bildschirm – ohne Papierverschwendung.
46
Kapitel 4: Makros ausprobieren
Bild 4.4: Zum Ausprobieren SEITENANSICHT wählen
Bisher haben Sie im Datenbankfenster auf ein Makro doppelgeklickt, um es auszuführen. Es ist aber auch möglich, ein Makro per Mausklick direkt von einem Formular aus zu starten. Dazu müssen Sie lediglich eine entsprechende Befehlsschaltfläche zum Formular hinzufügen. Wie das geht, zeige ich Ihnen jetzt.
4.2
Makro über Schaltfläche im Formular starten
Access erlaubt es, ganz einfach eine Befehlsschaltfläche zu einem Formular hinzuzufügen, die dann nach einem Klick das gewünschte Makro ausführt. Dazu öffnen Sie das Formular in der Entwurfsansicht und ziehen das Makro mit der Maus aus dem Datenbankfenster in das Formular – und schon ist die Befehlsschaltfläche da! Wenn Sie beispielsweise das gerade erstellte Makro mcrDruckenEtikettenGeburtstage auf das Formular frmAdressenDeutschland einfügen wollen, öffnen Sie das Formular frmAdressenDeutschland in der Entwurfsansicht, klicken Sie in der Objektleiste auf MAKROS und ziehen Sie das Makro mcrDruckenEtikettenGeburtstage mit gedrückter Maustaste aus dem Datenbankfenster an die gewünschte Stelle im Formular.
4.2 Makro über Schaltfläche im Formular starten
47
Bild 4.5: Befehlsschaltfäche für Makro mit der Maus einfügen
Die Befehlsschaltfläche erhält nun automatisch den Namen des Makros als Bezeichnung – in unserem Fall also: mcrDruckenEtikettenGeburtstage, wobei nur ein Teil angezeigt wird, weil der Name zu lang ist. Wenn Sie möchten, können Sie die Schaltfläche entsprechend verlängern, so dass der ganze Name darauf passt. Ich würde Ihnen aber vorschlagen, eine eigene Bezeichnung für die Schaltfläche zu vergeben. Dazu klicken Sie (in der Entwurfsansicht) auf die neue Befehlsschaltfläche, überschreiben Sie die vorgegebene Beschreibung (z.B. mit Geburtstagsetikett ausdrucken) und passen Sie die Größe der Schaltfläche entsprechend an. Ändern Sie gegebenenfalls die Position der Schaltfläche. Zum Ausprobieren wechseln Sie zur Formularansicht und klicken auf die neue Befehlschaltfläche. Das im letzten Abschnitt definierte Makro wird aufgerufen und der Bericht mit den Geburtstagsetiketten wird ausgedruckt (oder am Bildschirm angezeigt, wenn Sie als Ansicht noch SEITENVORSCHAU gewählt haben).
48
Kapitel 4: Makros ausprobieren
Bild 4.6: Ein Klick auf die Befehlsschaltfläche startet das Makro
Allerdings wird nun der ganze Bericht ausgedruckt. Ich möchte aber, dass nur das Geburtstagsetikett für den gerade im Formular angezeigten Datensatz ausgedruckt wird. Dazu ist nur eine kleine Änderung im Makro erforderlich, die ich Ihnen gleich beschreibe.
4.3
Makro für aktuellen Datensatz im Formular
Wenn Sie per Makro nur für den im Formular angezeigten Datensatz einen Bericht ausdrucken wollen, dann müssen Sie Access in einer Bedingung mitteilen, dass das Makro nicht für alle Datensätze ausgeführt werden soll, sondern nur unter der Bedingung, dass der Datensatz im Formular und im Bericht übereinstimmen. Ich möchte Ihnen jetzt zeigen, wie Sie eine solche Bedingung für das Makro definieren, um damit das Formular und den Bericht zu synchronisieren.
Synchronisieren? Ja, das ist der Begriff, der in diesem Zusammenhang immer fällt. Wenn Sie also jemand fragt, was Sie gerade machen, dann können Sie entweder antworten, dass Sie ein Etikett für Peter Wegmann ausdrucken wollen, oder Sie sagen, dass Sie gerade ein Formular und einen Bericht mithilfe eines Makros synchronisieren!
4.3 Makro für aktuellen Datensatz im Formular
49
Der Datensatz, der im Bericht angezeigt werden soll, muss dieselbe GÄSTENUMMER haben wie der im Formular angezeigte Datensatz. Denn in der Tabelle ist ein Datensatz über den Primärschlüssel GÄSTENUMMER eindeutig definiert. Und auf dieser Tabelle basieren sowohl das Formular frmAdressenDeutschland als auch der Bericht rptAdressenDeutschland (das erkennen Sie daran, dass die Tabelle tblAdressenDeutschland in den Eigenschaften des Berichtes und des Formulars als DATENHERKUNFT eingetragen ist). In der Bedingung muss also computergerecht formuliert werden, dass die GÄSTENUMMER des zu öffnenden Berichts mit der GÄSTENUMMER des im Formular angezeigten Datensatzes übereinstimmt. Öffnen Sie dazu das Makro mcrDruckenEtikettenGeburtstage in der Entwurfsansicht. Klicken Sie unten in das Eingabefeld neben BEDINGUNG und tragen Sie hier den Namen des Berichtsfeldes ein, für das eine Bedingung definiert werden soll – in unserem Fall also Gästenummer (die eckigen Klammern ergänzt Access automatisch, sobald Sie in ein anderes Feld klicken). Bild 4.7: Nach Eintragung auf die drei Punkte klicken
Klicken Sie dann auf die drei Punkte am Ende der Zeile, um zur Unterstützung bei der Eingabe den Ausdrucks-Generator zu öffnen. Bild 4.8: Der fertig eingegebene Ausdruck
50
Kapitel 4: Makros ausprobieren
Klicken Sie auf die Schaltfläche mit dem Gleichheitszeichen. Klicken Sie links unten in der Ordnerhierarchie nacheinander auf FORMULARE, dann auf ALLE FORMULARE und schließlich auf frmAdressenDeutschland. Doppelklicken Sie im mittleren Bereich auf GÄSTENUMMER. Der Ausdruck wird nun in der richtigen Form im oberen Bereich hinzugefügt (s. Bild 4.8). Übernehmen Sie den Gesamtausdruck mit OK. Speichern und schließen Sie das Makro. Wenn Sie jetzt im Formular frmAdressenDeutschland auf die neue Befehlsschaltfläche GEBURTSTAGSETIKETT AUSDRUCKEN klicken, wird nur das Etikett für den im Formular angezeigten Datensatz ausgedruckt und nicht mehr der ganze Bericht!
Geändertes Makro funktioniert nur bei geöffnetem Formular Wenn Sie das Makro nicht mit einem Klick auf die Befehlsschaltfläche im Formular aufrufen, sondern bei geschlossenem Formular im Datenbankfenster auf mcrDruckenEtikettenGeburtstage klicken, fragt Access nach fehlenden Parametern! Denn bei geschlossenem Formular ist kein Datensatz ausgewählt und es fehlt die Information, welche Gästenummer der auszudruckende Datensatz hat. Wenn Sie aber im dann erscheinenden Dialogfeld PARAMETERWERTE EINGEBEN eine Gästenummer eintippen, für die ein Datensatz existiert, wird hierfür das Geburtstagsetikett ausgedruckt.
Nach demselben Muster Adressetiketten drucken Makros zum Ausdrucken eines Berichts werden sehr häufig eingesetzt. Nach demselben Muster wie eben beschrieben können Sie z.B. auch einzelne Adressenetiketten ausdrucken lassen.
4.3 Makro für aktuellen Datensatz im Formular
51
Makro zum Ausdrucken eines Berichts mit der Maus erstellen Sie können ein Makro zum Ausdrucken eines Berichts auch mit der Maus erstellen. Dazu ziehen Sie den Bericht aus dem Datenbankfenster in die gewünschte Zeile des geöffneten Makrofensters und lassen ihn dort los. Schon ist in der Zeile eine Makroaktion zum Ausdrucken des Berichts eingetragen!
Wenn Sie nun auf diese Weise ein Makro zum Ausdrucken der Adressetiketten erstellen wollen, öffnen Sie das Entwurfsfenster eines neuen Makros über den oben beschriebenen Weg über das Datenbankfenster oder mit dem Menübefehl: EINFÜGEN MAKRO. Klicken Sie im Datenbankfenster in der Objektleiste auf BERICHTE und ziehen Sie den Bericht rptEtikettenAdressenDeutschland mit gedrückter Maustaste in das geöffnete Entwurfsfenster des neuen Makros. Lassen Sie die Maustaste an der gewünschten Stelle (z.B. in der ersten Zeile) los. Der Bericht wird automatisch als Makroaktion zum Ausdrucken des Berichts eingetragen.
Makrofenster und Datenbankfenster nebeneinander anzeigen Am einfachsten geht das Herüberziehen, wenn Sie alle Fenster außer dem Datenbankfenster und dem Makrofenster schließen und dann den Menübefehl FENSTER NEBENEINANDER wählen, um beide nebeneinander anzeigen zu lassen.
Schließen Sie das Makro und geben Sie ihm dabei den Namen mcrDruckenEtikettenAdressenDeutschland.
52
Kapitel 4: Makros ausprobieren
Öffnen Sie das Formular frmAdressenDeutschland in der Entwurfsansicht und schaffen Sie mit dem Menübefehl FENSTER NEBENEINANDER wieder mehr Übersicht. Jetzt ziehen Sie das Makro mit gedrückter Maustaste in das in der Entwurfsansicht geöffnete Formular frmAdressenDeutschland und ändern Sie die Bezeichnung der neuen Befehlsschaltfläche auf Adressetikett ausdrucken. Damit nur das Adressetikett des aktuell im Formular angezeig-
ten Datensatzes gedruckt wird, ergänzen Sie im Makro mcrDruckenEtikettenAdressenDeutschland als Bedingung wieder: [Gästenummer]=[Formulare]![frmAdressenDeutschland]![Gäs tenummer]
Jetzt können Sie direkt im Formular mit einem Klick auf eine der eingefügten Schaltflächen ein Adress- oder ein Geburtstagsetikett für den im Formular angezeigten Datensatz ausdrucken. Bild 4.9: Mit Klick auf die Schaltfläche ein Adressetikett drucken
Auch wenn Grammatik nicht so wichtig ist wie Praxis, so ist es doch manchmal ganz praktisch, von Grammatik etwas zu verstehen, denn sonst sind Sie mit Ihrem Latein ganz schnell am Ende! In diesem Sinne sollten Sie sich das folgende Kapitel nicht entgehen lassen, auch wenn es etwas theoretischer ist.
4.3 Makro für aktuellen Datensatz im Formular
53
5 Makros besser verstehen Ich hoffe, dass Sie durch das letzte Kapitel neugierig geworden sind, denn: »La curiosità e la madre della speranza – Neugier ist die Mutter der Weisheit«. Ob Sie allerdings am Ende dieses Kapitels weise sein werden? – Zumindest wird es Ihnen mit dem erworbenen Hintergrundwissen leichter fallen, Makros einzusetzen!
Sie erhalten einen zusammenfassenden Überblick über die
Makro-Grundlagen, Sie lernen, Makros an Ereignisse zu binden, und erhalten da-
mit eine wichtige Basis für das Automatisieren von Abläufen, Sie üben am Beispiel der Eingabeprüfung für Formulare, wie
Sie Bedingungen definieren, unter denen Makros ausgeführt werden sollen, und Sie erfahren, wie Sie mehrere Makros zu einer Gruppe zusammenfassen.
5.1
Makro-Grundlagenwissen
Den grundsätzlichen Aufbau von Makros haben Sie schon kennen gelernt: Im Makrofenster werden Aktionen eingetragen, die dann ausgeführt werden, wenn das Makro aufgerufen wird.
5.1.1
Standardansicht des Makrofensters
Im Makrofenster werden nebeneinander eine Aktions- und eine Kommentarspalte angezeigt. Sollten bei Ihnen außerdem Spalten mit der Bezeichnung BEDINGUNG oder MAKRONAME zu sehen sein, können Sie diese mit den Menübefehlen ANSICHT BEDINGUNGEN bzw. ANSICHT MAKRONAMEN wieder ausblenden. Auf die Spalte BEDINGUNG komme ich in Abschnitt 5.3 zu sprechen und um die Spalte MAKRONAME geht es in Abschnitt 5.4.
54
Kapitel 5: Makros besser verstehen
Bild 5.1: Entwurfsfenster
Aktionen und Kommentare Zu den Aktionen, die Sie in der Aktionsspalte auswählen, können Sie in der daneben liegenden Spalte einen Kommentar schreiben.
Aktionsargumente Die Angaben, die Sie im unteren Teil des Makrofensters zur jeweiligen Aktion machen, werden als Aktionsargumente bezeichnet. In Kapitel 2 haben Sie für Ihr MAKRO 1 bei der Aktion MELDUNG hier z.B. den Meldungstext eingetragen. Für die Makros aus dem letzten Kapitel haben Sie hier für die Aktion BERICHT ÖFFNEN gewählt, ob der Bericht in der SEITENANSICHT angezeigt oder zum AUSDRUCK geöffnet werden soll.
Erläuterungen Zu dem Feld, in dem Sie gerade eine Eintragung machen (d.h. in dem die Einfügemarke blinkt), wird im rechten unteren Teil des Makrofensters eine kurze Erläuterung eingeblendet.
Zeilenweiser Aufbau von Makros Bisher haben Sie immer nur eine einzelne Aktion von einem Makro ausführen lassen. Im Makrofenster können aber mehrere Aktionen eingetragen werden, die dann von oben nach unten abgearbeitet werden. Um das auszuprobieren, können Sie z. B. mit folgendem Makro nacheinander zwei Berichte ausdrucken und vorher eine Meldung
5.1 Makro-Grundlagenwissen
55
anzeigen lassen, die Sie daran erinnert, den Drucker einzuschalten: Öffnen Sie ein neues Makrofenster (z. B. mit dem Menübefehl EINFÜGEN MAKRO). Wählen Sie in der ersten Zeile als Aktion MELDUNG. Als erstes Aktionsargument geben Sie dann im unteren Bereich im Eingabefeld MELDUNG den Meldungstext ein – so wie Sie es schon aus Kapitel 2 kennen. Schreiben Sie: Bitte Drucker einschalten! Ergänzend können Sie noch weitere Aktionsargumente eingeben. Wählen Sie z. B. als TYP Warnmeldung (!) und geben Sie als TITEL Achtung! ein. Bild 5.2: Gewählte Aktionsargumente für die Aktion MELDUNG
In der zweiten und dritten Zeile wählen Sie als Aktion ÖFFNEN BERICHT, wobei Sie in der zweiten Zeile RPTETIKETTENGEBURTSTAGE und in der dritten Zeile RPTETIKETTENADRESSENDEUTSCHLAND als Aktionsargument im Eingabefeld BERICHTSNAME eintragen. Oder Sie ziehen einfach – wie im letzten Kapitel beschrieben – die Berichte nacheinander aus dem Datenbankfenster mit gedrückter Maustaste direkt in die zweite bzw. dritte Zeile des Makrofensters! Nutzen Sie die Kommentarspalte, um Anmerkungen zu den einzelnen Schritten einzutragen. Bei längeren Makros finden Sie sich dann leichter zurecht, wenn Sie später einmal nachvollziehen wollen, wie das Makro aufgebaut ist. Speichern Sie das Makro unter dem Namen mcrDruckenAdressUndGeburtstagsEtiketten.
56
Kapitel 5: Makros besser verstehen
Bild 5.3: Erläuternde Kommentare eingeben
Wenn Sie nun das Makro ausführen, wird zuerst die Meldung angezeigt und danach werden die beiden Berichte gedruckt.
Leerzeilen stören Makroausführung nicht Das Makro funktioniert auch, wenn Sie zwischen den einzelnen Zeilen Leerzeilen gelassen haben, denn Leerzeilen werden beim Ausführen des Makros einfach übersprungen. Bei längeren Makros ist es zur besseren Übersicht sinnvoll, das Makro mit Leerzeilen zu unterteilen und zu gliedern.
5.1.2
Makros erstellen und bearbeiten
Ähnlich, wie Sie es vom Tabellenentwurf kennen, ist es auch im Makrofenster möglich, einzelne Zeilen zu bearbeiten.
Zuerst gewünschte Aktionszeilen markieren Klicken Sie mit der Maus auf die Schaltfläche am linken Rand der Aktionszeile. Dadurch wird die gesamte Aktionszeile ausgewählt und mit einem Pfeil markiert (die Schaltfläche wird deshalb auch als Aktionszeilenmarkierer bezeichnet).
5.1 Makro-Grundlagenwissen
57
Bild 5.4: Auch mehrere Zeilen lassen sich markieren
Um mehrere Aktionszeilen zu markieren, klicken Sie auf den Aktionszeilenmarkierer der ersten Zeile und ziehen den Mauszeiger mit gedrückter Maustaste über die folgenden Zeilen, bis der gewünschte Bereich markiert ist. Oder Sie halten die 圶-Taste gedrückt, nachdem Sie die erste Zeile markiert haben und klicken dann auf den Aktionszeilenmarkierer der letzten Zeile.
Aktionszeilen verschieben Um eine oder mehrere markierte Zeilen zu verschieben, klicken Sie auf einen Aktionszeilenmarkierer im markierten Bereich und halten die Maustaste gedrückt. Jetzt können Sie die markierte Zeile bzw. den markierten Bereich an eine neue Position verschieben. Eine horizontale Linie zeigt Ihnen dabei an, an welcher Position eingefügt wird, wenn Sie die Maustaste loslassen. Oder Sie verschieben die markierten Aktionszeilen mit dem Menübefehl BEARBEITEN AUSSCHNEIDEN in die Zwischenablage. Klicken Sie dann in eine freie Zeile und fügen Sie die zuvor ausgeschnittenen Zeilen mit BEARBEITEN EINFÜGEN wieder ein.
Aktionszeilen kopieren oder löschen Mit BEARBEITEN KOPIEREN werden markierte Aktionszeilen in die Zwischenablage kopiert und nach Klick in die gewünschte freie Aktionszeile mit BEARBEITEN EINFÜGEN wieder eingefügt. Markierte Aktionszeilen löschen Sie mit dem Menübefehl BEAR LÖSCHEN oder indem Sie auf das entsprechende Symbol in der Symbolleiste klicken.
BEITEN
Einfügen leerer Aktionszeilen Wollen Sie mitten in einem bestehenden Makro weitere Aktionen einfügen, können Sie an der gewünschten Stelle im Makro Leerzeilen einfügen, um so Platz für die neuen Aktionszeilen zu schaffen.
58
Kapitel 5: Makros besser verstehen
Dazu klicken Sie in die Aktionszeile, über der die Leerzeile eingefügt werden soll und wählen dann den Menübefehl EINFÜGEN ZEILEN. Oder Sie klicken auf das entsprechende Symbol in der Symbolleiste.
Mit dem Kontextmenü kopieren, verschieben, löschen und einfügen Wenn Sie mit der rechten Maustaste in eine markierte Aktionszeile klicken, können Sie im erscheinenden Kontextmenü die folgenden Befehle auswählen: ZEILEN EINFÜGEN, ZEILEN LÖSCHEN, AUSSCHNEIDEN, KOPIEREN und EINFÜGEN (wenn die Zwischenablage gefüllt ist). Sind mehrere Zeilen markiert, dürfen Sie Ihren Rechtsklick zum Aufrufen des Kontextmenüs überall im markierten Bereich machen, nur nicht auf einen einzelnen Aktionszeilenmarkierer, da sonst nur noch diese Zeile markiert wird!
Bild 5.5: Kontextmenü zum Bearbeiten von markierten Aktionszeilen
5.1.3
Ausführen eines Makros
Um ein Makro direkt auszuführen, gibt es eine Reihe von Möglichkeiten: Im Datenbankfenster auf das Makro doppelklicken. Das Makro im Datenbankfenster mit einfachem Klick markie-
ren und dann auf AUSFÜHREN klicken. Ist das Makro zum Entwurf im Makrofenster geöffnet, klicken
Sie in der Symbolleiste auf AUSFÜHREN, oder Sie rufen den Menübefehl AUSFÜHREN AUSFÜHREN auf.
5.1 Makro-Grundlagenwissen
59
Neben den beschriebenen Möglichkeiten, Makros direkt auszu-
führen, gibt es auch noch die Variante, Makros an Ereignisse zu binden. Was es damit auf sich hat, darum geht es im folgenden Abschnitt.
Einzelschritt wieder ausschalten Mit dem Menübefehl AUSFÜHREN EINZELSCHRITT (bzw. mit dem entsprechenden Symbol auf der Symbolleiste) schalten Sie in den Einzelschrittmodus. Jetzt wird das Makro nach Klick auf AUSFÜHREN immer nur eine Zeile – also einen Einzelschritt weiter ausgeführt. Der nächste Schritt folgt immer erst, wenn Sie im Dialogfeld EINZELSCHRITT auf die Schaltfläche SCHRITT klicken. Der Einzelschrittmodus wird z.B. bei längeren Makros zur Fehlersuche eingesetzt (in Kapitel 6 zeige ich Ihnen dafür ein Beispiel). Im Augenblick müssen Sie vor allem darauf achten, vor dem Speichern Ihres Makros einen von Ihnen aktivierten Einzelschrittmodus mit erneutem Klick auf das EINZELSCHRITT-Symbol wieder auszuschalten, damit Ihr Makro im normalen Modus ausgeführt wird!
5.2
Makros an Ereignisse binden
Im letzten Kapitel haben Sie bereits ein Makro an ein Ereignis gebunden! Ohne dass Sie sich darum kümmern mussten, wurde eine solche Bindung erstellt, als Sie in das Formular frmAdressenDeutschland die Befehlsschaltfäche zum Ausführen des Makros mcrDruckenEtikettenGeburtstage eingefügt haben. Bevor wir uns gleich anschauen, wie diese Bindung aussieht, möchte ich kurz versuchen zu erklären, um was es hier eigentlich geht.
5.2.1
Beim Klicken ereignet sich was
Dass beim Klicken auf eine Schaltfläche etwas passiert, ist für Sie wahrscheinlich nichts Besonderes mehr. Trotzdem handelt es sich
60
Kapitel 5: Makros besser verstehen
hierbei um ein Ereignis. Und zwar um das BEIM KLICKEN-Ereignis. Immer beim Klicken auf eine Schaltfläche in Ihrem Access-Formular tritt dieses BEIM KLICKEN-Ereignis ein. Sobald dies der Fall ist, „weiß“ Access in gewissem Sinne, dass gerade geklickt wird und kann eine für diesen Fall vorgesehene Aktion starten – also z.B. ein Makro.
5.2.2
Was soll sich beim Klicken ereignen?
Um ein bestimmtes Makro beim Klicken auf eine Befehlsschaltfläche ausführen zu lassen, muss es an das BEIM KLICKEN-Ereignis der Schaltfläche gebunden werden. Dazu wird es im Eigenschaftenfenster der Schaltfläche auf dem Registerblatt EREIGNIS in der Zeile des BEIM KLICKEN-Ereignisses eingetragen – in Abschnitt 5.2.4 werden Sie sehen, wie einfach das geht.
5.2.3
So sieht die Bindung aus
Jetzt werfen wir erst einmal einen Blick auf das Eigenschaftenfenster der Befehlsschaltfläche, bei der im letzten Kapitel automatisch ein Makro an das BEIM KLICKEN-Ereignis gebunden wurde. Öffnen Sie dazu das Formular frmAdressenDeutschland in der Entwurfsansicht. Klicken Sie mit der rechten Maustaste auf die Schaltfläche, die Sie zum Ausdrucken der Geburtstagsetiketten eingefügt hatten und wählen Sie im Kontextmenü EIGENSCHAFTEN. Im Eigenschaftenfenster wechseln Sie zum Registerblatt EREIGNIS. Hier sind die Ereignisse aufgelistet, die für die Befehlsschaltfläche eintreffen können.
5.2 Makros an Ereignisse binden
61
Bild 5.6: Das Makro ist an das Ereignis BEIM KLICKEN gebunden
Rechts neben dem Ereignis BEIM KLICKEN sehen Sie das Makro mcrDruckenEtikettenGeburtstage eingetragen – so sieht es im Eigenschaftenfenster aus, wenn ein Makro an ein Ereignis gebunden ist! Als Sie im letzten Kapitel die Befehlsschaltfläche zum Auslösen des Makros erstellt haben, wurde dabei automatisch das Makro hier eingetragen. Und deshalb passiert das, was Sie wollten: Das Makro wird beim Klicken auf die Befehlsschaltfläche ausgeführt.
5.2.4
Makro an ein anderes Ereignis binden
Probieren Sie einmal aus, was passiert, wenn Sie das Makro an das Ereignis BEIM DOPPELKLICKEN binden: Klicken Sie in das Eingabefeld neben dem Ereignis BEIM DOPPELKLICKEN und wählen Sie über den Listenpfeil das Makro MCRDRUCKENETIKETTENGEBURTSTAGE.
Klicken Sie in das Eingabefeld neben dem Ereignis BEIM KLICKEN, markieren Sie den dortigen Eintrag und löschen Sie ihn mit der 圪-Taste. Jetzt ist das Makro nur noch BEIM DOPPELKLICKEN eingetragen.
62
Kapitel 5: Makros besser verstehen
Wechseln Sie in die Formularansicht. Wenn Sie jetzt einmal auf die Befehlsschaltfläche klicken, geschieht nichts. Erst wenn Sie doppelklicken, wird der Bericht ausgedruckt. Oder anders ausgedrückt: Das Makro wird erst ausgeführt, wenn das Ereignis BEIM DOPPELKLICKEN, an das es gebunden ist, eintritt.
5.2.5
Lange Listen von möglichen Ereignissen
Im Eigenschaftenfenster sehen Sie, dass es noch eine ganze Reihe weiterer Ereignisse gibt, die für eine Befehlsschaltfläche eintreffen können. Im Augenblick sollten Sie sich von den langen Ereignislisten nicht irritieren lassen. Viele der Ereignisse werden erst interessant, wenn es um die absolute Feinarbeit geht. Zu den meisten Ereignissen bekommen Sie einen Hilfetext angezeigt, wenn Sie in der entsprechenden Zeile auf 囟 klicken.
5.2.6
Weitere Ereignisse bei Textfeldern
Bisher ging es um Ereignisse, die für eine Befehlsschaltfläche eintreten können. Anders als bei einer Befehlsschaltfläche, können in Textfeldern Eintragungen gemacht und geändert werden. Deshalb gibt es hier auch eine Reihe weiterer möglicher Ereignisse. Öffnen Sie das Formular frmAdressenDeutschland in der Entwurfsansicht und lassen Sie sich das Eigenschaftenfenster des Textfeldes PLZ anzeigen. Bild 5.7: Mögliche Ereignisse bei Textfeldern
5.2 Makros an Ereignisse binden
63
In einem Textfeld ist es möglich, ein Makro alleine dadurch aufzurufen, dass neue Eintragungen in dem Feld gemacht wurden. Dazu müssen Sie das Makro nur an das Ereignis NACH AKTUALISIERUNG binden.
Das Ereignis Nach Aktualisierung Das Ereignis NACH AKTUALISIERUNG tritt ein, sobald neue, in dem Feld gemachte Eingaben übernommen wurden, die Daten also aktualisiert wurden.
Beispiel: Meldung anzeigen nach Änderung der PLZ Nachdem eine neue Postleitzahl eingetragen wurde, sollen Sie über ein Makro in einer Meldung aufgefordert werden zu überprüfen, ob auch ein neuer Ort eingetragen werden muss.
Makro direkt vom Eigenschaftenfenster aus erstellen Um Ihr neues Makro zu erstellen, das an das Ereignis NACH AKTUALISIERUNG gebunden werden soll, müssen Sie nicht zum Datenbankfenster wechseln. Klicken Sie einfach im Eigenschaftenfenster auf die Schaltfläche mit den drei Punkten am Ende der zugehörigen Eingabezeile (s. Bild 5.7). Wählen Sie dann im Dialogfeld GENERATOR AUSWÄHLEN den MAKRO-GENERATOR und geben Sie dem Makro im Dialogfeld SPEICHERN UNTER einen Namen. Danach haben Sie ein leeres Makrofenster vor Augen.
Bild 5.8: Wählen Sie den MAKRO-GENERATOR
64
Kapitel 5: Makros besser verstehen
Bild 5.9: Geben Sie dem Makro den Namen mcrPlzNeuMeldung
Nachdem Sie das neue Makrofenster auf die beschriebene Weise geöffnet haben, können Sie wie gewohnt die Makro-Aktion MELDUNG eintragen. Als Aktionsargumente geben Sie im Eingabefeld MELDUNG folgenden Meldungstext ein: PLZ wurde geändert. Bitte Ort überprüfen! Als Typ wählen Sie Warnmeldung (!) und als Titel geben Sie Achtung! ein. Wenn Sie möchten, ergänzen Sie noch einen Kommentar. Bild 5.10: Das MeldungsMakro wird erstellt
Sobald Sie das Makro gespeichert und geschlossen haben, ist es als an das Ereignis NACH AKTUALISIERUNG gebundenes Makro eingetragen. Bild 5.11: Das neue Makro ist bereits gebunden
Wechseln Sie jetzt einmal in die Formularansicht und ändern Sie bei einem Datensatz die eingetragene Postleitzahl. Solange Sie noch beim Ändern sind, geschieht nichts. Erst wenn Sie in ein anderes Feld geklickt oder nachdem Sie die 圸-Taste gedrückt haben, wird der Datenbestand mit der geänderten PLZ aktualisiert und das Ereignis NACH AKTUALISIERUNG tritt ein. In diesem Augenblick ruft das an das Ereignis NACH AKTUA-
5.2 Makros an Ereignisse binden
65
LISIERUNG
gebundene Makro mcrPlzNeuMeldung die Warnmeldung
auf. Bild 5.12: Die Meldung erscheint, nachdem die PLZ geändert wurde
Auch gebundene Makros sind nicht verschwunden Auch ein gebundenes Makro, das Sie auf die beschriebene Weise vom Eigenschaftenfenster aus erstellt haben, ist ein ganz normales Makro. Deshalb ist das eben erstellte Makro mcrPlzNeuMeldung, wie alle anderen Makros, auch im Datenbankfenster eingetragen! Klicken Sie im Datenbankfenster auf der Objektleiste auf MAKROS und schauen Sie einmal nach!
5.2.7
Auch für Formulare gibt es Ereignisse
Auch für ein Formular als Ganzes können Ereignisse eintreffen, an die sich Makros binden lassen. Das Öffnen eines Formulars ist z.B. schon ein solches Ereignis. Unsere Casa-Maria-Formulare habe ich schon öfter überarbeitet. Damit unsere Casa-Maria-Mitarbeiter und -Mitarbeiterinnen sich beim Öffnen eines Formulars nicht wundern, dass es anders aussieht als noch vor ein paar Tagen, habe ich immer eine kleine Informationsmeldung an das BEIM ÖFFNEN-Ereignis gebunden, in der auf die Änderung des Formulars hingewiesen wird. Um eine Meldung als Makroaktion an das Ereignis BEIM ÖFFNEN des Formulars frmBuchungen zu binden, öffnen Sie das Formular frmBuchungen in der Entwurfsansicht und lassen Sie sich das Eigenschaftenfenster des Formulars anzeigen (dazu klicken Sie links oben im Formular auf den
66
Kapitel 5: Makros besser verstehen
Formularmarkierer und dann in der Symbolleiste auf EIGENSCHAFTEN). Lassen Sie per Klick das EREIGNIS-Registerblatt anzeigen und klicken Sie dort in das BEIM ÖFFNEN-Feld. Nach Klick auf die drei Punkte am Ende der Zeile wählen Sie wieder den MAKROGENERATOR und speichern das Makro unter dem Namen mcrFormularNeuMeldung. Im Makrofenster geben Sie dann wieder MELDUNG als Makroaktion ein. Als Meldungstext tippen Sie z.B. ein: Das Formular wurde am 11.11.2001 geändert und sieht jetzt anders aus! Als Typ wählen Sie Information und als Titel geben Sie Neues frmBuchungen Formular! ein und ergänzen Sie Ihren
Kommentar. Speichern und schließen Sie das Makro. Es ist dann an das Ereignis BEIM ÖFFNEN gebunden. Bild 5.13: Auch an Formularereignisse lassen sich Makros binden
Speichern und schließen Sie das Formular. Wenn Sie das Formular nun erneut öffnen, tritt das BEIM ÖFFNENEreignis ein und die Meldung wird angezeigt. Das BEIM ÖFFNENEreignis tritt übrigens wirklich beim Öffnen ein, d.h. bevor das Formular angezeigt wird. Deshalb erscheint also zuerst die an das Ereignis gebundene Meldung. Erst wenn Sie in der Meldung auf OK geklickt haben, wird das Formular angezeigt. Bisher wurden Ihre an ein Ereignis gebundenen Makros immer nach Eintreffen des Ereignisses ausgeführt. Im nächsten Abschnitt zeige ich Ihnen, wie Sie festlegen, dass ein Makro nicht jedesmal beim Eintreffen eines Ereignisses ausgeführt wird, sondern nur unter bestimmten Bedingungen.
5.2 Makros an Ereignisse binden
67
5.3
Bedingte Ausführung von Makros
Im Makrofenster kann für jede Zeile eine Bedingung festgelegt werden, die erfüllt sein muss, bevor die in der Zeile stehende Makroaktion ausgeführt wird. Die Bedingungen werden in eine eigene Spalte eingegeben. Am Anfang dieses Kapitels hatte ich schon einmal kurz die Spalte BEDINGUNG erwähnt und Sie gebeten, die Spalte zunächst auszublenden. Jetzt ist es an der Zeit, die Bedingungsspalte einzublenden. Dazu öffnen Sie zunächst ein neues Makrofenster (z.B. mit dem Menübefehl EINFÜGEN MAKRO). Klicken Sie dann in der Symbolleiste auf die Schaltfläche BEDINGUNGEN oder setzen Sie mit dem Menübefehl ANSICHT BEDINGUNGEN ein Häkchen vor dem Menüpunkt BEDINGUNGEN. Bild 5.14: Die Bedingungsspalte ist eingeblendet
Ist in der Bedingungsspalte ein Bedingungsausdruck eingetragen, wird die in der Zeile stehende Makroaktion nur ausgeführt, wenn dieser Bedingungsausdruck wahr ist. Am konkreten Beispiel können Sie nun ausprobieren, wie eine Bedingung für ein Makro eingesetzt werden kann.
5.3.1
Makro zur zwanglosen Gültigkeitsprüfung
Mit Makros, die nur unter bestimmten Bedingungen ausgeführt werden, können Sie z. B. die Eingabe in Formularen überprüfen und zwar auch in Fällen, in denen Sie mit einer Gültigkeitsregel nicht weiterkommen.
68
Kapitel 5: Makros besser verstehen
Gültigkeitsregeln haben ihre Grenzen Bei der Eingabe von Adressen passiert es mir immer wieder, dass ich vergesse, die Hausnummer einzutippen. Zunächst hatte ich versucht, das Problem mit einer Gültigkeitsregel zu lösen. Für das Feld STRAßE des Formulars frmAdressenDeutschland hatte ich auf dem Registerblatt ALLE des Eigenschaftenfensters als GÜLTIGKEITSREGEL folgenden Ausdruck eingegeben: [Straße] Wie "*#*" . Die Raute in dem Ausdruck steht für eine beliebige Zahl. Sobald also im Feld Straße keine Zahl enthalten war, traf die GÜLTIGKEITSREGEL nicht zu, die von mir definierte GÜLTIGKEITSMELDUNG erschien und ich wurde zur Eingabe einer Hausnummer aufgefordert. Oder besser gesagt genötigt – denn auch in Fällen, in denen mir gar keine Hausnummer bekannt war, konnte ich das Feld STRAßE nicht verlassen, ohne eine Zahl einzutragen! Deshalb habe ich die Gültigkeitsregel wieder entfernt.
Ein Makro hilft weiter Mit einem Makro ist es hingegen möglich, eine Meldung anzuzeigen ohne den Zwang zum Eintrag. Tragen Sie im vorhin geöffneten neuen Makro als Aktion MELDUNG ein. Als Meldungstext geben Sie ein: Wollen Sie keine Hausnummer eintragen? Als Typ wählen Sie Warnmeldung (?), als Titel geben Sie Eingetragene Straße prüfen! ein und schreiben Sie Ihre erläuternde Anmerkung in die Kommentarspalte. Da das Makro ausgeführt werden soll, wenn keine Zahl enthalten ist, muss der für die Gültigkeitsregel verwendete Ausdruck um ein Nicht ergänzt werden. Er lautet dann: [Straße] Nicht Wie "*#*" .
5.3 Bedingte Ausführung von Makros
69
Bild 5.15: Die Meldung erscheint nur, wenn die Bedingung zutrifft
Speichern Sie das Makro unter dem Namen mcrHausnummer. Um das Makro an das richtige Ereignis zu binden, öffnen Sie zunächst das Formular frmAdressenDeutschland in der Entwurfsansicht. Danach öffnen Sie das Eigenschaftenfenster des Feldes STRAßE. Dort wechseln Sie zum Registerblatt EREIGNIS und klicken in das Eingabefeld NACH AKTUALISIERUNG. Bild 5.16: Das erstellte Makro auswählen
Am Ende der Zeile klicken Sie auf den kleinen Listenpfeil und wählen Ihr eben erstelltes Makro mcrHausnummer aus der Liste aus. Schließen Sie das Eigenschaftenfenster und wechseln Sie in die Formularansicht. Wenn Sie nun eine neue Adresse eingeben und im Feld STRAßE nur Buchstaben eintippen, erscheint nach dem Wechsel in ein anderes Feld eine Meldung, die Sie daran erinnert, dass Sie keine Hausnummer eingetragen haben. Bild 5.17: Meldung erscheint – aber kein Eingabezwang
70
Kapitel 5: Makros besser verstehen
Nachdem Sie in der Meldung auf OK geklickt haben, steht es Ihnen frei, die Hausnummer nachzutragen oder dort weiterzumachen, wo Sie stehen geblieben waren. Einen Zwang zum Eintrag – wie bei der Gültigkeitsprüfung – gibt es jetzt nicht.
5.3.2
Einträge in zwei Feldern vergleichen
Wenn die Eintragungen in zwei Feldern verglichen werden sollen, treten beim Einsatz einer Gültigkeitsregel ganz ähnliche Schwierigkeiten auf, wie im letzten Abschnitt beschrieben. Zur Lösung bietet sich auch jetzt ein bedingt auszuführendes Makro an. Allerdings muss das Makro etwas anders aufgebaut sein und an ein anderes Ereignis gebunden werden, als das Makro aus dem letzten Abschnitt. Am besten erkläre ich Ihnen das Ganze am konkreten Beispiel.
Die Anreise muss vor der Abreise liegen Wenn Sie z.B. für das Formular frmBuchungen sicherstellen möchten, dass eine Fehlermeldung erscheint, wenn das eingetragene Abreisedatum vor dem Anreisedatum liegt, lässt sich dies erreichen, indem Sie für das Feld ABREISE die Gültigkeitsregel [Abreise]>=[Anreise] und eine entsprechende Gültigkeitsmeldung eintragen.
Lösung mit Gültigkeitsregel hat einen Haken Wenn Sie dann ein Abreisedatum eintragen, das vor dem Anreisedatum liegt, erscheint die Meldung und Sie müssen das Abreisedatum korrigieren. So weit, so gut. Die Meldung erscheint allerdings auch, wenn Ihr eingetragenes Abreisedatum an sich richtig ist, Sie aber zuvor ein falsches, nach dem Abreisedatum liegendes Anreisedatum eingetragen haben. Dann hängen Sie im Feld ABREISE fest. Sie müssen nun zuerst das richtige Abreisedatum ändern, um zum falschen Anreisedatum wechseln zu können. Wenn Sie dann das richtige Anreisedatum eingetragen haben, müssen Sie noch einmal zum Abreisedatum wechseln, um es auf den richtigen Wert zurückzusetzen.
5.3 Bedingte Ausführung von Makros
71
Zwangloses Makro ist in diesem Fall zu zwanglos Wenn Sie stattdessen im Formular frmBuchungen an das Ereignis NACH AKTUALISIERUNG des Feldes ABREISE ein Makro binden, das unter der Bedingung [Abreise]<[Anreise] eine Meldung aufruft, gibt es zwar keinen Zwang zum Eintrag mehr, allerdings ist es dann auch möglich, ein offensichtlich falsches Abreise- bzw. Anreisedatum stehen zu lassen, ohne es zu korrigieren. Probieren Sie einmal aus, ein entsprechendes Makro zu erstellen. Orientieren Sie sich dabei einfach an der Beschreibung aus Abschnitt 5.3.1. Geben Sie dem Makro den Namen mcrBuchungen. Bild 5.18: Makro muss noch an anderes Ereignis gebunden werden
Bedingt auszuführendes Makro mit Eintragungszwang Ähnlich wie beim Einsatz einer Gültigkeitsregel, können Sie auch per Makro erreichen, dass die Meldung so lange erscheint, bis der falsche Eintrag korrigiert wurde. Dazu müssen Sie den Punkt abpassen, bevor die Daten eingetragen werden. Sie dürfen also nicht bis zum Ereignis NACH AKTUALISIERUNG warten, sondern müssen Ihr Makro an das Ereignis VOR AKTUALISIERUNG binden. Dazu lassen Sie sich im Formular frmBuchungen das Registerblatt EREIGNIS des Eigenschaftenfensters des Feldes ABREISE anzeigen, klicken in das Feld NACH AKTUALISIERUNG und löschen den dortigen Eintrag MCRBUCHUNGEN (falls Sie ihn zuvor beim Erstellen des Makros dort eingefügt hatten). Klicken Sie in das Feld VOR AKTUALISIERUNG und wählen Sie über den Listenpfeil am Ende der Zeile das Makro mcrBuchungen aus.
72
Kapitel 5: Makros besser verstehen
Ohne die Makroaktion ABBRECHEN EREIGNIS ändert sich nichts Wenn Sie Ihr Makro nun ausprobieren, werden Sie feststellen, dass sich bisher gar nichts geändert hat. Das liegt daran, dass die Ereignisse VOR AKTUALISIERUNG und NACH AKTUALISIERUNG aufeinander folgen. Wenn Sie also nach dem Ereignis VOR AKTUALISIERUNG nicht die Notbremse ziehen, folgt automatisch das Ereignis NACH AKTUALISIERUNG. Die Notbremse ziehen Sie mit der Makroaktion ABBRECHENEREIGNIS.
Öffnen Sie das Makrofenster des Makros mcrBuchungen (indem Sie auf die drei Punkte am Ende der Zeile VOR AKTUALISIERUNG des Eigenschaftenfensters des Feldes ABREISE klicken). In der 2. Zeile wählen Sie ABBRECHENEREIGNIS als Makroaktion. Da das Ereignis nur abgebrochen werden soll, wenn ein vor dem Anreisedatum liegendes Abreisedatum eingetragen wurde, muss auch in dieser Zeile die Bedingung [Abreise]<[Anreise] in die Bedingungsspalte geschrieben werden.
Um Bedingung in Folgezeile zu wiederholen, reichen drei Punkte Es
ist nicht nötig, die vollständige Bedingung [Abreise]<[Anreise] in die Zeile einzutragen. Es reicht, wenn Sie stattdessen einfach drei Punkte eintippen. Damit gilt die Bedingung aus der vorigen Zeile auch für diese Zeile.
5.3 Bedingte Ausführung von Makros
73
Bild 5.19: Die Bedingung gilt auch für ABBRECHENEREIGNIS
Wenn Sie das so geänderte Makro nach dem Speichern ausprobieren, haben Sie genau das gleiche Problem, wie bei einer Gültigkeitsregel: Sie hängen möglicherweise im falschen Feld fest.
Makro an Formularereignis binden Das Problem lösen Sie, indem Sie das Makro nicht an die Eigenschaften eines einzelnen Feldes, sondern an das Ereignis VOR AKTUALISIERUNG des Formulars binden. Wie Sie aus Abschnitt 5.2.7 bereits wissen, können Makros auch an Ereignisse gebunden werden, die für ein Formular eintreffen. Wenn Sie das Makro mcrBuchungen an das Ereignis VOR AKTUALISIERUNG des Formulars frmBuchungen binden, haben Sie beides: Sie können direkt in das zu ändernde Feld klicken und Sie erhalten so lange eine Meldung angezeigt, bis die Bedingung
[Abreise]<[Anreise] nicht mehr zutrifft.
Um dies auszuprobieren, entfernen Sie zunächst den Eintrag MCRBUCHUNGEN aus dem Ereignisfeld VOR AKTUALISIERUNG des Formularfeldes ABREISE. Dann öffnen Sie das Eigenschaftenfenster des Formulars frmBuchungen. Auf dem Registerblatt EREIGNIS wählen Sie MCRBUCHUNGEN als neuen Eintrag im Feld VOR AKTUALISIERUNG. Speichern Sie die Änderung. Jetzt wird die Bedingung für das Ausführen des Makros geprüft, wenn für das Formular das Ereignis VOR AKTUALISIERUNG eintritt. Das Ereignis VOR AKTUALISIERUNG tritt aber für das Formular erst ein, wenn Sie zu einem anderen Datensatz wechseln oder das Formular schließen wollen. Hatten Sie zuvor ein vor dem Anreise-
74
Kapitel 5: Makros besser verstehen
datum liegendes Abreisedatum eingetragen, erscheint nun die Meldung. Sie können jetzt entweder in das Feld ANREISE oder in das Feld ABREISE klicken, um es zu ändern. Ein Wechsel zu einem anderen Datensatz ist aber erst möglich, wenn das eingetragene Abreisedatum nach dem Anreisedatum liegt.
5.3.3
Mehrere bedingte Aktionen nacheinander
In einem Makro können mehrere Makroaktionen aufeinander folgen, die unter unterschiedlichen Bedingungen ausgeführt werden. Auch hierzu wieder ein Beispiel aus der Casa Maria.
Beispiel: Appartements mit samstags An- und Abreise Im Makro mcrBuchungen habe ich eine weitere Makroaktion hinzugefügt, die bei bestimmten Appartements eine Meldung anzeigt, wenn An- und Abreise nicht an einem Samstag liegen. Denn für die begehrten Appartements mit den Nummern 3, 6 und 9 kann immer nur von Samstag bis Samstag gebucht werden, wodurch wir eine optimale Auslastung ermöglichen wollen. Um sicherzustellen, dass für diese Appartements in den Feldern ANREISE und ABREISE nur Samstage eingetragen werden können, fügen Sie im geöffneten Makrofenster des Makros mcrBuchungen in einer neuen Zeile die Makroaktion MELDUNG ein und vergeben als Meldungstext: Bei diesem Appartement müssen Anund Abreise an einem Samstag liegen!
Als Bedingung geben Sie ein: ([Appartementnummer]=3 Oder [Appartementnummer]=6 Oder [Appartementnummer]=9 Und (Wochentag([Abreise])<>7 Oder Wochentag([Anreise])<>7))
5.3 Bedingte Ausführung von Makros
75
Mit Aktion STOPPMAKRO jeweils nur eine Meldung anzeigen Bei einem Makro mit mehreren bedingten Fehlermeldungen sollten Sie diese jeweils mit einer STOPPMAKRO-Aktion abschließen. Denn ohne die STOPPMAKRO-Aktion würden alle Fehlermeldungen nacheinander angezeigt, die Sie sich dann alle merken müssten, bevor Sie die Möglichkeit zur Korrektur hätten. Fügen Sie also im Makro mcrBuchungen nach der ersten ABBRECHENEREIGNIS-Zeile die Aktion STOPPMAKRO ein. Damit erreichen Sie, dass das Makro an dieser Stelle stoppt, wenn die Bedingung zutrifft. Erst wenn Sie den Eintrag im Formular korrigiert haben, läuft das Makro weiter und auch die zweite Bedingung wird geprüft.
Tragen Sie in der nächsten Zeile drei Punkte in die Bedingungsspalte ein und wählen Sie ABBRECHENEREIGNIS als Aktion. Speichern Sie das Makro und probieren Sie es aus. Bild 5.20: Wegen STOPPMAKRO immer nur eine Meldung zurzeit
76
Kapitel 5: Makros besser verstehen
5.4
Gruppenmakros
Access bietet die Möglichkeit, ein Makro in eine Gruppe von Untermakros zu unterteilen. Ein Makro, das Untermakros enthält, wird als Gruppenmakro bezeichnet. Der Name eines Untermakros wird im Makrofenster in einer eigenen Spalte eingetragen. Zum Einblenden der Spalte rufen Sie den Menübefehl ANSICHT MAKRONAMEN auf oder klicken Sie in der Symbolleiste auf das Symbol MAKRONAMEN.
5.4.1
Das Prinzip verstehen
Um das Prinzip eines Gruppenmakros zu verstehen, öffnen Sie bitte ein neues Makrofenster und blenden mit dem Menübefehl ANSICHT MAKRONAMEN die Spalte MAKRONAME ein. Wählen Sie in der ersten und vierten Zeile jeweils MELDUNG als Makroaktion. Als Meldungstext tragen Sie einfach bei der ersten Meldung Meldung 1 und bei der zweiten Meldung Meldung 2 ein. Speichern Sie das Makro unter dem Namen mcrGruppentest. Wenn Sie das Makro ausführen, erscheinen nacheinander die beiden Meldungen. Das ändert sich, wenn Sie die zweite Meldung als Untermakro definieren. Dazu tragen Sie einfach in der vierten Zeile in die Spalte MAKRONAME den Namen Beispiel ein und speichern das Makro. Bild 5.21: Beispiel-Untermakro
in Spalte MAKRONAME eingetragen
5.4 Gruppenmakros
77
Jetzt erscheint nur noch die erste Meldung, wenn Sie das Makro ausführen. Die Zeilen ab dem Eintrag in der Spalte MAKRONAME werden als eigenes Untermakro aufgefasst, das gesondert aufgerufen werden muss. Um das Untermakro zu starten, rufen Sie den Menübefehl EXTRAS MAKRO MAKRO AUSFÜHREN auf, wählen im Dialogfeld MAKRO AUSFÜHREN den Eintrag TEST.BEISPIEL und klicken auf OK.
MCRGRUPPEN-
Bild 5.22: Untermakro per Menübefehl starten
Auf diese Weise haben Sie direkt das Untermakro ausgeführt und nur die zweite Meldung erscheint auf dem Bildschirm. Makros und Untermakros können Sie auch mit der Makroaktion AUSFÜHRENMAKRO starten. In der zweiten Zeile des Makros mcrGruppentest wählen Sie die Makroaktion AUSFÜHRENMAKRO. Als
Aktionsargument
MAKRONAME
wählen
Sie
MCRGRUPPEN-
TEST.BEISPIEL
Bild 5.23: Aktionsargumente für Makroaktion AUSFÜHRENMAKRO
Führen Sie Ihr Makro nach dem Speichern erneut aus, werden nun wieder beide Meldungen angezeigt.
78
Kapitel 5: Makros besser verstehen
5.4.2
Die praktische Anwendung
Mit einem Gruppenmakro können Sie z.B. für mehr Übersichtlichkeit sorgen, indem Sie inhaltlich verwandte Makros zusammenfassen. Im nächsten Kapitel zeige ich Ihnen, wie Sie unterschiedliche Suchfunktionen in einem Gruppenmakro bündeln.
5.5
Schreibweise für Verweise
Wenn Sie mit Makros arbeiten, kommt es immer wieder vor, dass Sie den Wert eines Steuerelements abfragen oder für ein Steuerelement einen neuen Wert setzen müssen. Dabei ist es wichtig, in der richtigen Form auf das Steuerelement zu verweisen. Am einfachsten stellen Sie sich vor, dass jedes Steuerelement seine eigene Adresse hat. Die Schreibweise dieser Adresse müssen Sie genau beachten, wenn Sie auf das Steuerelement verweisen wollen. Der Ausdrucks-Generator unterstützt Sie dabei, die richtige Schreibweise einzuhalten.
5.5.1
Schreibweise eines Ausdrucks analysieren
Anhand eines Beispiels möchte ich Ihnen den Aufbau eines solchen Verweises erklären. Dazu werden wir uns gleich einen mit dem Ausdrucks-Generator erstellten Ausdruck einmal näher anschauen. Dazu öffnen Sie ein neues Makrofenster und wählen SETZENWERT als Makroaktion. Mit dieser Aktion können Sie den Wert eines Steuerelements ändern. Als Aktionsargument ELEMENT muss das zu ändernde Feld eingetragen werden. Öffnen Sie den Ausdrucks-Generator, indem Sie in das Feld ELEMENT und dann auf die drei Punkte am Ende des Feldes klicken.
5.5 Schreibweise für Verweise
79
Bild 5.24: Verweis auf das Feld ABREISE im Formular frmBuchungen
Klicken Sie links unten in der Ordnerhierarchie nacheinander auf FORMULARE, dann auf ALLE FORMULARE und schließlich auf FRMBUCHUNGEN. Doppelklicken Sie im mittleren Bereich auf ABREISE. Der Ausdruck wird nun im oberen Bereich angezeigt. Übernehmen Sie den Ausdruck mit OK. Der Ausdruck, mit dem Sie auf das Feld ABREISE im Formular frmBuchungen verweisen, lautet also: Formulare![frmBuchungen]![Abreise]. Am Anfang steht die allgemeine Bezeichnung Formulare, dann folgen der Name des Formulars und der Name des Feldes. Um auf das Feld ANREISE des Formulars frmBuchungen zu verweisen, müsste der Ausduck also lauten: Formulare![frmBuchungen]![Anreise]. Tragen Sie diesen Ausdruck als Aktionsargument in das Feld AUSDRUCK ein (diesmal ohne den Umweg über den AusdrucksGenerator). Mit der eingetragenen SETZENWERT-Aktion wird nun im Formular frmBuchungen das Feld ABREISE auf den Wert des Feldes ANREISE gesetzt. Um das Makro auszuprobieren, schließen Sie das fertige Makro und geben Sie ihm den Namen mcrAbreiseSetzen.
80
Kapitel 5: Makros besser verstehen
Öffnen Sie das Formular frmBuchungen in der Entwurfsansicht und binden Sie das Makro an das Ereignis NACH AKTUALISIERUNG des Feldes ANREISE. Wenn Sie ein Datum in das Feld ANREISE eingetragen haben und in ein anderes Feld wechseln, wird das Datum in das Feld ABREISE übernommen.
Eine sinnvolle Anwendung für das Testmakro Viele Casa-Maria-Gäste buchen ihre Appartements für zwei Wochen. Deshalb soll mithilfe von mcrAbreiseSetzen nach einem Eintrag im Feld ANREISE automatisch ein zwei Wochen später liegendes Datum im Feld ABREISE eingetragen werden. Dazu sind nur wenige Änderungen erforderlich. Dem Aktionsargument AUSDRUCK fügen Sie +14 hinzu. Der neue Ausdruck lautet dann Formulare![frmBuchungen]![Anreise]+14. Damit die Makroaktion SETZENWERT nur ausgeführt wird, wenn
noch kein Abreisedatum eingetragen wurde, ergänzen Sie die Bedingung Formulare![frmBuchungen]![Abreise]ist Null.
Auch Kurzform ist möglich Wenn Sie auf ein Feld auf demselben Formular verweisen, müssen Sie nicht den kompletten Ausdruck Formulare![frmBuchungen]![Abreise] schreiben, es reicht auch die Kurzform [Abreise].
5.5 Schreibweise für Verweise
81
Bild 5.25: Makro mit Ausdrücken in Langform
5.5.2
Eigenschaften eines Feldes ändern
Mit einer winzigen Erweiterung können Sie auch Eigenschaften eines Feldes ändern und es zum Beispiel von sichtbar auf unsichtbar setzen. Dabei wird die Eigenschaft nach einem Punkt an den Verweis angehängt. Im folgenden Beispiel sieht das dann so aus: [cmdGeburtstagsDruck].Sichtbar
Im Formular frmAdressenDeutschland soll die Schaltfläche zum Ausdrucken der Geburtstagsetiketten nur angezeigt werden, wenn für den Datensatz ein Geburtsdatum eingetragen wurde. (Da nur auf das Formular selber verwiesen wird, kann die Kurzschreibweise verwendet werden.) Öffnen Sie das Formular frmAdressenDeutschland in der Entwurfsansicht. Die Befehlsschaltfläche hat bisher den automatisch vergebenen Namen (BEFEHL 23 o.ä.) Ändern Sie den Namen im Eigenschaftenfenster zu cmdGeburtstagsDruck. Binden Sie nun an das Ereignis NACH AKTUALISIERUNG des Feldes GEBURTSTAG ein neues Makro mit dem Namen mcrUnsichtbar. In der ersten Zeile des Makros wählen Sie als Makroaktion SETZENWERT. Als ELEMENT tragen Sie ein: [cmdGeburtstagsDruck].Sichtbar. Wenn Sie nun Nein als AUSDRUCK eintragen, wird die Befehlsschaltfläche auf »nicht sichtbar« gesetzt. In der zweiten Zeile tragen Sie die gleiche Makroaktion mit dem Ausdruck Ja ein.
82
Kapitel 5: Makros besser verstehen
In die erste Zeile schreiben Sie als BEDINGUNG [Geburtsdatum] ist Null, damit die Befehlsschaltfläche ausgeblendet wird, wenn kein Geburtstag eingetragen wurde. In der zweiten Zeile tragen Sie stattdessen [Geburtsdatum] ist Nicht Null ein, damit die Befehlsschaltfläche nach Eintrag eines Geburtsdatums angezeigt wird. Bild 5.26: Ein Makro, das sichtbar und unsichtbar macht
Die Befehlsschaltfläche soll normalerweise nicht angezeigt werden. Deshalb setzen Sie die Eigenschaft SICHTBAR der Befehlsschaltfläche CMDGEBURTSTAGSDRUCK auf Nein. Bei einem neuen Datensatz wird die Schaltfläche erst sichtbar, wenn ein Geburtsdatum eingetragen wird. Damit das Makro auch für die schon eingetragenen Datensätze funktioniert, müssen Sie es zusätzlich noch an das Ereignis BEIM ANZEIGEN des Formulars binden. Wenn Sie dann die Adressen durchgehen, sehen Sie, dass bei Petra Klein keine Schaltfläche zum Ausdrucken von Geburtstagsetiketten angezeigt wird, weil auch kein Geburtsdatum eingetragen wurde.
Schreibweise – Verweise -weise? Und? Was ist jetzt mit der Weisheit? Ich weiß nur eins: Jetzt folgt nicht der Weisheit letzter Schluss, sondern nur das Ende dieses Kapitels!
5.5 Schreibweise für Verweise
83
6 Mit Makros suchen und filtern Zwar heißt es bei uns: »Non cercare la falce quando è già tempo di mietere – Suche nicht die Sense, wenn schon Zeit zum Mähen ist.« – trotzdem muss ja manchmal etwas gesucht werden. Zum Beispiel ein Datensatz in einer Access-Datenbank!
In diesem Kapitel zeige ich Ihnen, wie Sie die mit einem Kombinationsfeld ausgewählten Daten-
sätze im Formular anzeigen lassen, wie Sie mit einem Makro eine Suchfunktion realisieren, bei der auch Teile des gesuchten Wortes als Suchbegriff gewählt werden können, wie Sie mit einem Makro Datensätze nach bestimmten Kriterien herausfiltern können und wie Sie den Filter ganz einfach wieder entfernen.
6.1
Clever suchen mit Kombinationsfeld
Auch ein Kombinationsfeld können Sie als Suchhilfe einsetzen. Für eine einfache Suchfunktion bietet sich diese Lösung an und Sie brauchen möglicherweise gar kein Makro zu schreiben.
6.1.1
Kombinationsfeld einfügen
Am Beispiel einer Suchhilfe für das Formular frmAdressenDeutschland zeige ich Ihnen, wie es geht. Öffnen Sie das Formular frmAdressenDeutschland in der Entwurfsansicht. Das Kombinationsfeld soll im Fußbereich des Formulars untergebracht werden. Sollte bei Ihnen für das Formular kein Fußbereich angezeigt werden, erstellen Sie mit dem Menübefehl ANSICHT FORMULARKOPF/-FUß einen neuen Fußbereich und schieben den gleichzeitig hinzugefügten Kopfbereich wieder zusammen.
84
Kapitel 6: Mit Makros suchen und filtern
Bild 6.1: Kombinationsfeld soll in den Fußbereich
Aktivieren Sie in der TOOLBOX den STEUERELEMENT-ASSISTENTEN und erstellen Sie im Fußbereich ein neues Kombinationsfeld. Wählen Sie im ersten Schritt des KOMBINATIONSFELD-ASSISTENTEN die dritte Option. Klicken Sie WEITER. Bild 6.2: Die dritte Option wählen
Wählen Sie im nächsten Schritt zuerst das Feld NACHNAME und dann VORNAME aus. Klicken Sie auf WEITER. Passen Sie im folgenden Schritt gegebenenfalls die Breite an. Die Schlüsselspalte soll ausgeblendet bleiben. Klicken Sie WEITER.
6.1 Clever suchen mit Kombinationsfeld
85
Bild 6.3: Breite der Spalten anpassen
Im letzten Schritt tragen Sie Name suchen als Bezeichnung ein und klicken auf FERTIG STELLEN. Wenn Sie jetzt im Kombinationsfeld einen Namen wählen, wird der zugehörige Datensatz sogleich im Formular angezeigt. Bild 6.4: Ausgewählter Name wird im Formular angezeigt
6.1.2
Kombinationsfeld nachbessern
Sie können das Kombinationsfeld nachträglich ändern und beispielsweise die Sortierreihenfolge der angezeigten Namen ändern.
Alphabetische Sortierung einstellen Im Kombinationsfeld werden die einzelnen Datensätze normalerweise in der Reihenfolge angezeigt, in der sie eingegeben wurden.
86
Kapitel 6: Mit Makros suchen und filtern
Für die Suchfunktion wäre natürlich eine alphabetische Sortierung besser. Um die Sortierreihenfolge entsprechend zu ändern, lassen Sie sich im Eigenschaftenfenster des neuen Kombinationsfeldes das Registerblatt DATEN anzeigen. Klicken Sie in das Eingabefeld DATENSATZHERKUNFT und dann auf die drei Punkte am Ende der Zeile. Dadurch öffnet sich eine so genannte SQL-Anweisung. Diese können Sie wie eine normale Abfrage ändern. Bild 6.5: SQL-Anweisung lässt sich wie normale Abfrage ändern
Für die Felder NACHNAME und VORNAME wählen Sie AUFSTEIGEND als SORTIERUNG. Um die Änderung zu übernehmen, brauchen Sie das Fenster nur zu schließen und die folgende Meldung mit JA zu bestätigen. Bild 6.6: Ja, Sie wollen die Sortierreihenfolge ändern
Jetzt sind im Kombinationsfeld die Nachnamen und als Untersortierung die Vornamen in alphabetischer Reihenfolge aufgelistet. Wenn Sie nur einen kleinen Datenbestand haben, reicht diese Suchmöglichkeit sicher vollkommen aus.
6.1 Clever suchen mit Kombinationsfeld
87
Die Grenzen der Kombinationsfeld-Suchfunktion Eine Suche nach Teilen eines Namens ist im Kombinationsfeld nicht möglich. Wenn Sie sich also z.B nur noch erinnern, dass der gesuchte Name auf ...hut endet, kommen Sie mit der Kombinationsfeld-Suche nicht weiter. Mit einem Makro ist es hingegen möglich, eine solche Suchfunktion zu erstellen.
6.2
Makro mit Suchfunktion
Mit der Makroaktion SUCHENDATENSATZ lässt sich eine Suchfunktion erstellen, bei der auch nach Teilen eines Namens gesucht werden kann. Die Suchmöglichkeiten dieser Makroaktion entsprechen denen, die Sie bei der Suche mit dem Menübefehl BEARBEITEN SUCHEN haben. Bild 6.7: Auch per Makro können Sie in dieser Form suchen
6.2.1
Makroaktion SuchenDatensatz nutzen
Um auszuprobieren, wie eine Suche per Makro funktioniert, öffnen Sie das Formular frmAdressenDeutschland in der Entwurfsan-
88
Kapitel 6: Mit Makros suchen und filtern
sicht, entfernen das Kombinationsfeld und fügen stattdessen im Fußbereich mithilfe der Toolbox ein ungebundenes Textfeld ein.
Ungebundenen Textfeldern wird die Abkürzung txt vorangestellt Ähnlich wie ich Ihnen nahegelegt hatte, z.B. Formularen das Kürzel frm voranzustellen, sollten Sie bei ungebundenen Textfeldern das Präfix txt verwenden. Auf diese Weise können Sie (und andere) sich besser in Ihrer Datenbank zurechtfinden.
Öffnen Sie also das Eigenschaftenfenster des neuen Textfeldes, tragen Sie auf dem Registerblatt ALLE txtSuchfeld als NAME ein und klicken Sie in der Symbolleiste auf SPEICHERN. Bild 6.8: Ungebundenes Textfeld als txtSuchfeld benennen
Löschen Sie das zum Textfeld gehörende Bezeichnungsfeld. Stattdessen fügen Sie eine Befehlsschaltfläche ein, nachdem Sie den Steuerelement-Assistenten in der Toolbox mit einem Klick ausgeschaltet haben (der Assistent bietet sich erst an, wenn bereits ein Makro erstellt wurde – siehe Abschnitt 6.2.2). Klicken Sie auf die Befehlsschaltfläche, tragen Sie Name suchen: als neue Bezeichnung ein und passen Sie die Größe entsprechend an.
6.2 Makro mit Suchfunktion
89
Öffnen Sie das Eigenschaftenfenster der Befehlsschaltfläche und tragen Sie auf dem Registerblatt ALLE als neuen Namen cmdSuche ein (das Präfix cmd steht für »command button«). Bild 6.9: Suchen-Befehlsschaltfläche vorbereiten
Klicken Sie auf dem Registerblatt EREIGNIS in das Feld BEIM KLICKEN und erstellen Sie mit dem Makro-Generator ein neues Makro mit dem Namen mcrSuchenName. In der ersten Makrozeile wählen Sie GEHEZUSTEUERELEMENT als Makroaktion und tragen Nachname als Aktionsargument ein, da nach Nachnamen gesucht werden soll. In der nächsten Zeile wählen Sie SUCHENDATENSATZ als Makroaktion.
Einstellungsmöglichkeiten
wie
im
Dialogfeld
SUCHEN
UND
ERSETZEN
Die Aktionsargumente der Makroaktion SUCHENDATENSATZ entsprechen den Einstellungsmöglichkeiten, wie Sie sie aus dem Dialogfeld SUCHEN UND ERSETZEN (s. Bild 6.7) kennen. Hinzu kommt das Feld AM ANFANG BEGINNEN. Hier ist standardmäßig JA eingetragen, womit sichergestellt ist, dass die Datensätze immer von Anfang an durchsucht werden.
Als Suchbegriff soll jetzt die Eintragung aus dem Feld TXTSUCHFELD verwendet werden. Deshalb tragen Sie als Aktionsargument =[txtSuchfeld] im Feld SUCHE NACH ein. Im Feld VERGLEICHEN wählen Sie TEIL DES FELDINHALTES. Damit muss der eingetragene Suchbegriff nur mit einem Teil des Feld-
90
Kapitel 6: Mit Makros suchen und filtern
inhaltes übereinstimmen. Somit wird ein Name auch dann gefunden, wenn nur ein Teil als Suchbegriff eingegeben wird. Bild 6.10: Suchbegriff wird aus dem neuen Suchfeld übernommen
Fehlermeldung, wenn kein Suchbegriff eingetragen wurde Wenn Sie Ihr Makro jetzt ausprobieren, erscheint eine Fehlermeldung, wenn Sie nichts in das Suchfeld eintragen. Dem wirken Sie entgegen, indem Sie die Bedingung [txtSuchfeld] ist nicht Null in die Bedingungsspalte der Makroaktion SUCHENDATENSATZ schreiben. Jetzt wird die SUCHENDATENSATZ-Aktion nur ausgeführt, wenn im Suchfeld etwas eingetragen wurde.
Nachdem Sie Makro und Formular gespeichert haben, können Sie Ihre neue Makro-Suchfunktion jetzt testen. Geben Sie hut in das neue Textfeld ein und klicken Sie auf die Befehlsschaltfläche NAME SUCHEN. Jetzt wird der Datensatz von Hanna Wumphut angezeigt. Um auch den Eintrag von Torsten Wumphut angezeigt zu bekommen, muss jetzt noch eine Möglichkeit zum Weitersuchen ergänzt werden. Hierzu steht die Makroaktion SUCHENWEITER zur Verfügung. Mit der Makroaktion SUCHENWEITER wird der nächste Datensatz gesucht, der den Kriterien einer zuvor durchgeführten SUCHENDATENSATZ-Aktion entspricht.
6.2 Makro mit Suchfunktion
91
6.2.2
Suchfunktionen in Gruppenmakro sammeln
Statt nun für die Makroaktion SUCHENWEITER ein neues Makro anzulegen, sollen beide Suchaktionen in einem Makro zusammengefasst werden. Dazu öffnen Sie das Makrofenster des Makros mcrSuchenName, lassen zur besseren Übersicht eine Leerzeile, wählen in der vierten Zeile als Makroaktion GEHEZUSTEUERELEMENT und tragen wieder Nachname als STEUERELEMENTNAME ein. In der Folgezeile wählen Sie die Makroaktion SUCHEWEITER. Als Bedingung tragen Sie für diese Zeile wieder [txtSuchfeld] ist nicht Null ein. Blenden Sie nun mit dem Menübefehl ANSICHT MAKRONAMEN die Spalte MAKRONAME ein und tragen Sie hier in der vierten Zeile Weitersuchen ein. Speichern und schließen Sie das Makro.
Weitersuchen-Schaltfläche hinzufügen Erstellen Sie nun eine Befehlsschaltfläche zum Aufrufen des Untermakros. Dazu aktivieren Sie diesmal den Steuerelement-Assistenten der Toolbox. Beim Einfügen der Befehlsschaltfläche müssen Sie im ersten Schritt des Befehlsschaltflächen-Assistenten DIVERSE als Kategorie und MAKRO AUSFÜHREN als Aktion wählen. Bild 6.11: Schaltfläche für Makro mit Assistent einfügen
Im nächsten Schritt wählen Sie dann das Untermakro mcrSuchenName.Weitersuchen. Klicken Sie sich mit der WEITER-Schaltfläche
92
Kapitel 6: Mit Makros suchen und filtern
durch die folgenden Schritte des Assistenten und vergeben Sie dabei als TEXT für die Befehlsschaltfläche Weitersuchen und als NAMEN cmdWeitersuchen. Am Ende klicken Sie auf FERTIG STELLEN. Bild 6.12: Formular mit eingebundener MakroSuchfunktion
Wenn Sie jetzt hut in das Suchfeld eintippen, wird nach Klick auf NAME SUCHEN wie gehabt Hanna Wumphut angezeigt. Wenn Sie dann auf WEITERSUCHEN klicken, erscheint der Datensatz von Torsten Wumphut.
Suchfunktion vereinfachen Eigentlich brauchen Sie zum Suchen nur die WEITERSUCHENSchaltfläche. Denn nachdem Sie den Suchbegriff in das Suchfeld eingetragen haben, ist eigentlich klar, dass nach diesem Begriff gesucht werden soll. Deshalb brauchen Sie nicht extra auf eine Schaltfläche zu klicken, sondern es reicht, wenn Sie das Feld verlassen und irgendwo anders hinklicken. Denn dabei treten verschiedene Ereignisse ein, die sich abfangen lassen. Sie können das Makro mcrSuchenName z.B. an das Ereignis NACHAKTUALISIERUNG des Feldes TXTSUCHFELD binden. Dann wird die Suche gestartet, wenn Sie einen neuen Begriff eingetragen haben und dann in ein anderes Feld klicken. Sie können auch auf die WEITERSUCHEN-Schaltfläche klicken, denn das NACHAKTUALISIERUNG-Ereignis vom TXTSUCHFELD tritt vor dem BEIMKLICKEN-Ereignis der Schaltfläche ein, d.h. auch in diesem Fall wird eine neue Suche gestartet! Wenn Sie die Suchfunktion in dieser Form nutzen, gibt es noch einen kleinen Nachteil. Denn immer, wenn Sie für einen bereits
6.2 Makro mit Suchfunktion
93
eingetragenen Suchbegriff erneut eine Suche starten wollen, müssen Sie den Suchbegriff ändern bzw. neu schreiben, denn nur in diesem Fall tritt das Ereignis NACHAKTUALISIERUNG ein. Wenn Sie das Makro mcrSuchenName stattdessen an das Ereignis BEIMVERLASSEN binden, reicht ein Klick in das Feld TXTSUCHFELD, um die Suche beim Verlassen des Feldes erneut zu starten.
6.2.3
Suche nach Vor- und Nachname
Am besten wäre es natürlich, wenn man entweder den Nachnamen, den Vornamen oder beides eintragen könnte – je nachdem, an was man sich erinnert. Zum Erstellen einer solchen Suchfunktion bedarf es eines kleinen Tricks, den ich Ihnen jetzt vorstellen möchte.
Der Trick mit dem Doppelfeld Um die beschriebene Suchfunktion zu ermöglichen, ist es am geschicktesten, ein Feld einzufügen, in dem Vorname und Nachname zusammengefasst sind und die Suche dann in diesem Doppelfeld durchzuführen. Zum Zusammenfassen von Vor- und Nachname in einem neuen Feld bietet sich eine Abfrage an. Bleibt nur die Frage, wie Sie das neue Feld in das Formular einbinden können. Wie Sie wissen, basiert das Formular frmAdressenDeutschland auf der Tabelle tblAdressenDeutschland. Das Formular frmAdressenDeutschland würde genau so gut funktionieren, wenn Sie eine Abfrage definieren würden, die alle im Formular enthaltenen Felder umfasst und diese Abfrage dann statt der Tabelle tblAdressenDeutschland als neue Datensatzherkunft für das Formular festlegen würden. Ergänzen Sie die Abfrage um das neue Doppelfeld aus Vorname und Nachname, dann können Sie das Feld ganz einfach für die Suchfunktion nutzen. Noch einmal Schritt für Schritt: Erstellen Sie eine Abfrage, in die Sie zunächst alle Felder der Tabelle tblAdressenDeutschland aufnehmen. Definieren Sie mit dem Ausdruck VollerName: [Vorname]&" "&[Nachname] zusätzlich das neue Doppelfeld. Speichern Sie die Abfrage unter dem Namen qryAdressenDeutschland.
94
Kapitel 6: Mit Makros suchen und filtern
Bild 6.13: Abfrage erstellen
Öffnen Sie das Eigenschaftenfenster des Formulars frmAdres-
senDeutschland und wählen Sie qryAdressenDeutschland auf dem Registerblatt DATEN als neue Datenherkunft. Bild 6.14: Abfrage als neue Datenherkunft
Öffnen Sie das Formular frmAdressenDeutschland in der Entwurfsansicht, fügen Sie das Feld VOLLERNAME aus der Feldliste hinzu und entfernen Sie das zugehörige Bezeichnungsfeld. Öffnen Sie das Eigenschaftenfenster des Feldes VOLLERNAME und ändern Sie auf dem Registerblatt FORMAT die Einträge für Hintergrund, Rahmenart und Spezialeffekt, um das Feld von den anderen Feldern abzuheben. Außerdem können Sie auf dem Registerblatt ALLE die Eigenschaft in REIHENFOLGE auf NEIN setzen.
6.2 Makro mit Suchfunktion
95
Nur ein sichtbares und aktiviertes Feld kann durchsucht werden Die AKTIVIERT- und die SICHTBAR-Eigenschaft des Feldes muss auf JA eingestellt sein, da das Feld sonst bei der Suche ignoriert wird! Wie Sie auch ein unsichtbares Feld durchsuchen können, zeige ich Ihnen im nächsten Abschnitt.
Hiermit ist die Vorbereitung des Formulars abgeschlossen und Sie können die Änderungen speichern.
Makro anpassen Jetzt müssen Sie nur noch in dem Makro mcrSuchenName einstellen, dass nicht das Feld NACHNAME, sondern das neue Feld VOLLERNAME durchsucht werden soll. Dazu öffnen Sie das Makrofenster des Makros mcrSuchenName. Der neue Steuerelementname, den Sie als Aktionsargument zu den beiden GEHEZUSTEUERELEMENT-Aktionen eintragen, muss jetzt nicht mehr Nachname, sondern VollerName heißen.
Neue Suchfunktion testen Jetzt können Sie im Suchfeld nur wenige Buchstaben oder einen kompletten Namen eintragen. Mit dem Suchbegriff Peter Stein finden Sie nach Klick auf NAME SUCHEN nur den einen eingetragenen Peter Stein. Wenn Sie hingegen nur Peter als Suchbegriff wählen, finden Sie mit Klick auf NAME SUCHEN zunächst Peter Wegmann und mit Klick auf WEITERSUCHEN unter anderem auch Thorsten Petermann.
96
Kapitel 6: Mit Makros suchen und filtern
Bild 6.15: Suche in Vorund Nachname
Auch der Einsatz von Platzhaltern ist möglich. Mit T*orsten finden Sie Thorsten und Torsten. Mit L???s finden Sie sowohl Lovis als auch Lukas, aber auch Sybille Schulze und andere, die beide Buchstaben zufällig im richtigen Abstand in Vor- und Nachname haben. Wenn Sie den Suchbegriff um ein Leerzeichen und ein weiteres Fragezeichen zu L???s ? ergänzen, finden Sie nur noch die gesuchten Vornamen.
6.2.4
Auch unsichtbare Felder durchsuchen
Wie Sie aus Kapitel 5 wissen, ist es mit der SETZENWERT-Aktion möglich, die Eigenschaften eines Feldes per Makro zu ändern. Diese Möglichkeit können Sie nutzen, um auch ein Feld zu durchsuchen, das im Formular nicht sichtbar ist. Nachdem Sie die Eigenschaft SICHTBAR des Feldes VOLLERNAME auf NEIN gestellt haben, können Sie diese mit der folgenden SETZENWERT-Aktion für die Suche kurzzeitig auf JA setzen.
Feld-Eigenschaften setzen Am einfachsten ist es, wenn Sie den Ausdrucks-Generator zu Hilfe nehmen. Öffnen Sie zunächst das Makro mcrSucheName und fügen Sie am Anfang eine SETZENWERT-Aktion hinzu. Als Aktionsargument ELEMENT wählen Sie nach Klick auf die drei Punkte am Ende der Zeile mit dem Ausdrucks-Generator VOLLERNAME aus.
6.2 Makro mit Suchfunktion
97
Bild 6.16: Ausdruck zum Ändern der SICHTBAR-Eigenschaft
In der rechten Spalte des Ausdrucks-Generators können Sie dann Eigenschaften wählen, die für das Feld geändert werden sollen. Wählen Sie hier SICHTBAR. Übernehmen Sie die Eintragungen aus dem Ausdrucks-Generator mit OK. Als AUSDRUCK tragen Sie JA ein, da das Feld ja für die Suche sichtbar werden soll. Nach der Makroaktion SUCHENDATENSATZ fügen Sie eine entsprechende SETZENWERT-Aktion ein, mit der Sie jetzt die Eigenschaft SICHTBAR des Feldes VOLLERNAME wieder auf NEIN setzen.
Feld darf bei Eigenschaftenänderung mit SETZENWERT nicht den Fokus haben Da Sie die Eigenschaften eines Feldes mit SETZENWERT nur ändern können, wenn das Feld nicht den Fokus hat, müssen Sie nach der SUCHENDATENSATZ-Zeile noch eine GEHEZUSTEUERELEMENT-Aktion einfügen, um zu einem anderen Feld (z.B. VORNAME) zu wechseln.
Entsprechende SETZENWERT-Aktionen fügen Sie dann auch vor und nach der WEITERSUCHEN-Aktion hinzu. Das ergänzte Makro sieht dann folgendermaßen aus:
98
Kapitel 6: Mit Makros suchen und filtern
Bild 6.17: Für die Suche wird das Feld VOLLERNAME kurz sichtbar
Wenn Sie beim Ausprobieren des Makros genau hinschauen, können Sie sogar sehen, wie das Feld VOLLERNAME bei der Suche immer kurz aufflackert.
6.2.5
Makro testen und korrigieren
Je mehr Zeilen ein Makro hat, desto leichter kann sich ein Fehler einschleichen, und wenn es nur ein Tippfehler ist. Am besten, Sie schalten dazu in den Einzelschrittmodus und gehen das Makro Schritt für Schritt durch. Öffnen Sie das Makrofenster und wählen Sie den Menübefehl AUSFÜHREN EINZELSCHRITT. Ab jetzt werden Ihre Makros nur schrittweise ausgeführt. Schließen Sie das Makro und öffnen Sie das Formular. (Wenn Sie ein Makro an das Ereignis BEIM ÖFFNEN gebunden hätten, würde auch dieses jetzt Schritt für Schritt ausgeführt.) Wenn Sie im Formular frmAdressenDeutschland auf WEITERSUCHEN klicken, wird das von Ihnen erstellte Suchmakro aufgerufen. Im Einzelschrittmodus erscheint das Dialogfeld EINZELSCHRITT, in dem Makroname, Bedingung, Aktionsname und Aktionsbedingungen aufgeführt sind. Um die angezeigte Makroaktion auszuführen, müssen Sie auf die Schaltfläche SCHRITT klicken.
6.2 Makro mit Suchfunktion
99
Bild 6.18: Makros Schritt für Schritt im Einzelschrittmodus
Im Dialogfeld EINZELSCHRITT können Sie keine Änderungen an den Eintragungen vornehmen. Außerdem lesen Sie im Feld ARGUMENTE z.B. FORMS statt Formulare, da hier die englischen Bezeichnungen verwendet werden (ein kleiner Vorgriff auf das noch viel englischere VBA). Trotzdem können Sie in längeren Makros den Punkt, an dem der Fehler auftritt, bei diesem schrittweisen Vorgehen besser eingrenzen. Vergessen Sie nicht, am Ende den Einzelschrittmodus wieder auszuschalten, indem Sie ein Makro öffnen und erneut auf das EINZELSCHRITT-Symbol klicken.
6.3
Mit Makros filtern
Um per Makro einen Filter zu aktivieren, steht die Makroaktion ANWENDENFILTER zur Verfügung. Am Beispiel des Formulars frmAppartements zeige ich Ihnen, wie Sie mit der ANWENDENFILTER-Aktion nur die frisch renovierten Appartements herausfiltern.
6.3.1
Umschaltfläche in Formular erstellen
Zum Ein- und Ausschalten des Filters soll eine Umschaltfläche in das Formular integriert werden. Öffnen Sie das Formular frmAppartements in der Entwurfsansicht und fügen Sie mithilfe der Toolbox eine neue Umschaltfläche hinzu.
100
Kapitel 6: Mit Makros suchen und filtern
Klicken Sie in die Umschaltfläche, schreiben Sie hinein Nur frisch renovierte Appartements anzeigen und passen Sie die Größe der Umschaltfläche entsprechend an. Tragen
Sie
im
Eigenschaftenfenster
der
Umschaltfläche
tglFilter als neuen Namen ein. (Das Präfix tgl steht für
»toggle button«.) Binden Sie an das Ereignis BEIM KLICKEN ein neues Makro, dem Sie den Namen mcrFilternAppartements geben. In der ersten Zeile des Makros wählen Sie die Makroaktion ANWENDENFILTER. Als Aktionsargument BEDINGUNG tragen Sie den Ausdruck [LetzteRenovierung]>Datum()-365 ein, der nur auf Appartements zutrifft, die innerhalb des letzten Jahres renoviert wurden (der Ausdruck entspricht ungefähr dem, den Sie in Kapitel 3 für die bedingte Formatierung des Feldes definiert hatten). In der zweiten Zeile wählen Sie ANZEIGENALLEDATENSÄTZE als Aktion. Für beide Zeilen muss nun jeweils eine Bedingung eingefügt werden, die das Ausführen der Makroaktion vom Zustand der Umschaltfläche abhängig macht.
Umschaltflächen können den Wert Wahr und Falsch annehmen Ist die neue Umschaltfläche gedrückt, gilt [tglFilter]=Wahr. Im nicht gedrückten Zustand gilt hingegen [tglFilter]=Falsch. Diese Ausdrücke können Sie als Bedingungen für die beiden Makroaktionen einsetzen.
Fügen Sie also als Bedingung in der ersten Spalte [tglFilter]=Wahr und in der zweiten Spalte [tglFilter]=Falsch ein. Speichern Sie Makro und Formular.
6.3 Mit Makros filtern
101
Bild 6.19: Das fertige Filtermakro
Filter mit einem Klick setzen und entfernen Wenn Sie jetzt im Formular auf die Umschaltfläche klicken, wird das Makro mcrFilternAppartements aufgerufen, die Bedingung [tglFilter]=Wahr ist erfüllt und die Makroaktion ANWENDENFILTER wird ausgeführt, so dass nur die der Bedingung [LetzteRenovierung]>Datum()-365 entsprechenden Datensätze herausgefiltert werden. Je nachdem, an welchem Datum Sie Ihren Filterversuch starten, können bei Ihnen natürlich mehr oder weniger Appartements herausgefiltert werden, als im folgenden Bild. Bild 6.20: Mit Klick auf Umschaltfläche Filter setzen und entfernen
Nach erneutem Klick auf die Umschaltfläche tritt der entgegengesetzte Fall ein und die Makroaktion ANZEIGENALLEDATENSÄTZE entfernt den Filter wieder.
102
Kapitel 6: Mit Makros suchen und filtern
Filter hin, Filter her – dieses Kapitel ist jetzt zu Ende. Aber wenn Sie möchten, filtern Sie sich doch eben einen Kaffee, um damit die Pause bis zum nächsten Kapitel zu überbrücken.
6.3 Mit Makros filtern
103
7 Synchronisation, Kombination, Unterformular »Tutte le strade portano a Roma. – Alle Straßen führen nach Rom.« Ja, es gibt viele Wege, ein Ziel zu erreichen. Auch wenn Sie gleichzeitig auf Angaben aus unterschiedlichen Formularen zugreifen wollen, haben Sie dafür mehrere Möglichkeiten.
In diesem Kapitel zeige ich Ihnen, wie Sie eine Synchronisation zweier Formulare auch mit einem
Makro realisieren, wie Sie mit einem Kombinationsfeld Informationen aus einem
anderen Formular einblenden und wie Sie Ihr verbessertes Formular als Unterformular in ein
ebenfalls bestehendes Hauptformular einbinden.
7.1
Zwei Formulare per Makro synchronisieren
In Kapitel 4 hatte ich Ihnen bereits gezeigt, wie Sie mit einem Makro die Daten in einem Bericht und einem Formular synchronisieren können, um gezielt nur den im Formular angezeigten Datensatz auszudrucken. Nach demselben Prinzip lassen sich auch zwei Formulare per Makro aufeinander abstimmen. Um zu dem im Formular frmAppartements angezeigten Appartement gleichzeitig die für dieses Appartement eingetragenen Buchungen im Blick zu haben, soll es mit dem Formular frmBuchungen synchronisiert werden. Dazu muss definiert werden, dass im Formular frmBuchungen der Datensatz mit der im Formular FRMAPPARTEMENTS angezeigten Appartementnummer erscheint. Öffnen Sie zunächst ein neues Makrofenster und speichern Sie das Makro unter dem Namen mcrBuchungAppartementSynchro.
104
Kapitel 7: Synchronisation, Kombination, Unterformular
Ziehen Sie aus dem Datenbankfenster das Formularsymbol frmBuchungen in die erste Zeile des Makros. Tragen Sie als Aktionsargument zur ÖFFNENFORMULAR-Makroaktion Appartementnummer in das Feld BEDINGUNG und klicken Sie auf die drei Punkte am Ende, um den Ausdrucks-Generator zu öffnen. Bild 7.1: Synchronisationsbedingung als Aktionsargument eintragen
Im Ausdrucks-Generator ergänzen Sie zunächst ein Gleich-
heitszeichen. Dann klicken Sie links unten in der Ordnerhierarchie nacheinander auf FORMULARE, dann auf ALLE FORMULARE und schließlich auf frmAppartements. Doppelklicken Sie im mittleren Bereich auf APPARTEMENTNUMMER und übernehmen Sie den Gesamtausdruck mit OK. Bild 7.2: Synchronisationsbedingung erstellen
Schließen und speichern Sie das Makro.
7.1 Zwei Formulare per Makro synchronisieren
105
Synchronisationsbedingung wird als Aktionsargument eingetragen Verwechseln Sie die Bedingung, die zum Synchronisieren eingetragen wird, nicht mit den in Kapitel 5 behandelten Bedingungen für Makroaktionen. Eine Synchronisationsbedingung wird immer im unteren Bereich als Aktionsargument eingetragen.
Öffnen Sie das Eigenschaftenfenster des Formulars frmAppartements, binden Sie das eben erstellte Makro an das Ereignis BEIM ANZEIGEN und speichern Sie das Formular. Bild 7.3: Die beiden synchronisierten Formulare
Das Ereignis BEIM ANZEIGEN tritt ein, wenn das Formular geöffnet wird oder wenn zu einem anderen Datensatz gewechselt wird. Zu dem im Formular frmAppartements eingetragenen Appartement bekommen Sie jetzt im Formular frmBuchungen immer die hierfür eingetragenen Buchungen herausgefiltert.
106
Kapitel 7: Synchronisation, Kombination, Unterformular
7.2
Nachschlagen mit Kombinationsfeld
Mit einem Kombinationsfeld können Sie sehr einfach zusätzliche Werte in einem Formular anzeigen. Auf diese Weise lassen sich z.B. im Formular frmBelegung zusätzliche Buchungsinformationen einblenden. Öffnen Sie das Formular frmBelegung in der Entwurfsansicht. Löschen Sie das Feld BUCHUNGSNUMMER und erstellen Sie stattdessen auf dem Formular mit Unterstützung des Steuerelement-Assistenten ein neues Kombinationsfeld. Übernehmen Sie im Assistenten alle vier Felder aus der Tabelle tblBuchungen. Lassen Sie die Schlüsselspalte mit der BUCHUNGSNUMMER eingeblendet. Bild 7.4: Alle Felder der Tabelle tblBuchungen übernehmen
Wählen Sie im nächsten Schritt das Feld BUCHUNGSNUMMER und legen Sie im folgenden Schritt fest, dass der Wert im Feld BUCHUNGSNUMMER gespeichert werden soll. Als Bezeichnung tragen Sie Buchungsnummer ein. Klicken Sie am Ende auf FERTIG STELLEN. Öffnen Sie das Eigenschaftenfenster des Kombinationsfeldes und geben Sie ihm den Namen CBOBUCHUNGSNR (die Abkürzung steht für »combo-box«, dem englischen Ausdruck für Kombinationsfeld).
7.2 Nachschlagen mit Kombinationsfeld
107
Bisher können Sie bei zugeklapptem Kombinationsfeld außer der Buchungsnummer keine weiteren Werte sehen. Mit einem Trick lassen sich die Angaben im Formular sichtbar machen. Legen Sie ein neues Textfeld an und tragen Sie im dazugehörigen Bezeichnungsfeld Anreise ein, denn in diesem Feld soll das Anreisedatum angezeigt werden. Dazu geben Sie im Eigenschaftenfenster des Textfeldes als Steuerelementinhalt =[cboBuchungsNr].Column(2) ein. Wenn Sie jetzt zur Formularansicht wechseln, sehen Sie das zur ausgewählten Buchungsnummer gehörende Anreisedatum im neuen Textfeld angezeigt. Der eingetragene Ausdruck übernimmt die Spalte Nummer 2 des Kombinationsfeldes, wobei Sie beachten müssen, dass die erste Spalte die Spalte Null ist. Die Abreise steht also in Spalte 3 und die Appartementnummer in Spalte 1. Bild 7.5: Zauberformel zum Einblenden unsichtbarer Spalten
Ergänzen Sie nun zwei weitere Textfelder, in denen Sie die Ausdrücke =[cboBuchungsNr].Column(1) und =[cboBuchungsNr].Column(3) eintragen. Machen Sie die entsprechenden Eintragungen in den Bezeichnungsfeldern und ändern Sie die Hintergrundfarbe der Felder, um kenntlich zu machen, dass hier keine Angaben geändert werden können. Bild 7.6: Mehr Infos dank Kombinationsfeld
108
Kapitel 7: Synchronisation, Kombination, Unterformular
Zu den eingetragenen Datensätzen erhalten Sie nun die ergänzenden Angaben aus den Buchungsfeldern angezeigt.
7.3
Unterformular einbinden
Das eben geänderte Formular frmBelegung soll nun als Unterformular in das Formular frmAdressenDeutschland eingebaut werden. Benennen Sie das Formular zunächst in subfrmBelegung um (mit subfrm kennzeichnen Sie alle Unterformulare). Dann ziehen Sie einfach das Objekt subfrmBelegung mit gedrückter Maustaste aus dem Datenbankfenster in das in der Entwurfsansicht geöffnete Formular frmAdressenDeutschland. Klicken Sie nun auf den Rand des Unterformulars und öffnen Sie das zugehörige Eigenschaftenfenster. Wechseln Sie auf das Registerblatt DATEN. Dort klicken Sie in das Feld VERKNÜPFEN VON und dann auf die drei Punkte am Ende. Jetzt startet der FELDVERKNÜPFUNGSASSISTENT FÜR UNTERFORMULARE. Hier bestätigen Sie die vorgeschlagene Verknüpfung über das Feld GÄSTENUMMER mit OK. Damit haben Sie Haupt- und Unterformular synchronisiert.
7.3 Unterformular einbinden
109
Bild 7.7: Das herübergezogene Unterformular nachbearbeiten
Passen Sie nun das Aussehen des Unterformulars dem Hauptformular an. So können Sie z.B. im Unterformular die Gästenummer samt Bezeichnungsfeld löschen. Bild 7.8: Buchungsdaten werden gleich mit angezeigt
110
Kapitel 7: Synchronisation, Kombination, Unterformular
7.4
Anwendungsbeispiel für erstellte Formulare
Mit den erstellten Formularen ist es nun bequemer möglich, Buchungen für unsere Casa-Maria-Appartements entgegenzunehmen. Wenn ich ein Appartement heraussuche, für das eine Buchung
aufgenommen werden soll, erhalte ich im synchronisierten Formular frmBuchungen automatisch einen Überblick über die Zeiträume, in denen das Appartement bereits belegt ist. Im Formular frmAdressenDeutschland kann ich dann mit der Suchfunktion schnell die Adresse eines Stammgastes aufrufen oder ich nehme die Adresse eines neuen Gastes auf. Die zuvor eingetragene Buchung kann ich dann einfach über das Kombinationsfeld übernehmen, wobei die Buchungsdaten gleich im Formular angezeigt werden. Natürlich gibt es trotzdem noch eine Reihe von Verbesserungsmöglichkeiten. Aber bis zum Ende des Buches ist ja noch etwas Zeit! Im nächsten Kapitel zeige ich Ihnen erst mal, wie mithilfe von Makros die Vergabe der Buchungsnummer automatisiert werden kann.
7.4 Anwendungsbeispiel für erstellte Formulare
111
8 Makro-Praxisbeispiel Ein altes italienisches Sprichwort sagt: »A settembre chi è esperto – non viaggia mai scoperto – Wer klug ist, reist im September niemals leicht bekleidet.« Ob klug und mit Wollpullover oder nicht so klug mit T-Shirt, bei uns reisen das ganze Jahr über Gäste an, die ein Casa-Maria-Appartement gebucht haben.
Für die Buchungen vergeben wir Buchungszahlen, an denen sofort die Jahreszahl und der Monat der Buchung abgelesen werden können. Z.B. verbirgt sich hinter der Buchungsnummer 200206002 (von rechts gelesen) die zweite Buchung (002) im 06. Monat des Jahres 2002. Das Eintragen der Buchungsnummer war allerdings immer recht umständlich. Ein Makro soll nun dafür sorgen, dass die Buchungsnummer automatisch vergeben wird. Dabei möchte ich Ihnen zeigen, wie ich die Schritte, die ich bisher per Hand gemacht habe, auf das Makro übertragen habe.
8.1
Was haben Sie bisher ohne Makro getan?
Wenn Sie Ihre Arbeitsabläufe mit Access automatisieren wollen, ist es wichtig, dass Sie sich vorher genau klar machen, welche Schritte dabei aufeinander folgen. Das mag banal klingen, aber je gründlicher Sie hierbei sind, desto einfacher wird hinterher das Übersetzen in einzelne Makroaktionen. Am Anfang steht aber immer erst einmal eine grobe Beschreibung.
Grobe Beschreibung für die Erstellung der Buchungsnummer Folgende Arbeitsschritte waren bisher nötig:
112
Kapitel 8: Makro-Praxisbeispiel
Zuerst habe ich die vierstellige Jahreszahl des Anreisedatums eingetragen, die folgenden zwei Ziffern habe ich für den Monat des Anreisedatums vergeben und die letzten drei Ziffern waren reserviert, um die Buchungen des jeweiligen Monats durchzunummerieren. Jahreszahl und Monat waren schnell eingetragen, aber für die letzten drei Ziffern musste ich immer erst heraussuchen, wie viele Buchungsnummern in diesem Monat bereits vergeben waren.
8.2
Ausdrücke finden und Abläufe vorbereiten
Zunächst knöpfen wir uns aber mal den einfacheren, ersten Teil der Buchungsnummer vor.
8.2.1
Ausdrücke für Jahreszahl und Monat finden
Um aus dem Eintrag im Feld ANREISE den Monat herauszufiltern, verwenden Sie den Ausdruck Monat([Anreise]) und für das Jahr Jahr([Anreise]). Erstellen Sie zum Testen der Ausdrücke einfach mit der Toolbox auf dem Formular frmBuchungen ein ungebundenes Textfeld als Testfeld.
Ungebundenes Textfeld dient nur als Testfeld für Ausdrücke Dieses Testfeld dient nur als schnelle Überprüfungsmöglichkeit für die zu findenden Ausdrücke. Wenn Sie am Ende den kompletten Ausdruck erstellt haben, wird das Testfeld wieder gelöscht.
8.2 Ausdrücke finden und Abläufe vorbereiten
113
In der Entwurfsansicht tragen Sie im Eigenschaftenfenster des neuen Testfeldes als STEUERELEMENTINHALT nach einem Gleichheitszeichen die entsprechenden Ausdrücke ein und betrachten das Ergebnis in der Formularansicht. Schneller geht es, wenn Sie den Ausdruck in der Entwurfsansicht direkt in das Feld tippen. Bild 8.1: Feld zum Testen der Ausdrücke erstellen
Format-Funktion nutzen
Wenn Sie den Ausdruck für den Anfang der Buchungsnummer in folgender Form bilden: Jahr([Anreise]) & Monat([Anreise]), gibt es das Problem, dass bei einzahligen Monaten auch nur eine Ziffer angefügt wird, womit das System der Buchungsnummer verschoben werden würde. Mit der Format-Funktion ist es möglich, hier eine feste Stellenzahl vorzugeben.
Der Ausdruck lautet dann: =Format(Jahr([Anreise]);"0000") & Format(Monat([Anreise]);"00").
8.2.2
Größte Nummer des Monats finden
Um die letzten drei Stellen der Buchungsnummer vergeben zu können, müssen wir für den betreffenden Monat die Buchungsnummer herausfinden, deren letzte drei Stellen den größten Wert haben. Wenn bisher in dem Monat z.B. drei Buchungen eingetra-
114
Kapitel 8: Makro-Praxisbeispiel
gen wurden, wäre dies die Buchungsnummer mit 003 am Ende. Die neue Buchungsnummer müsste also auf 004 enden.
Abfrage erstellen Übersetzt in eine Abfrage bedeutet dies, dass der maximale Wert der drei letzten Stellen (von rechts) ermittelt werden soll, wobei die Angaben von Monat und Jahr des Anreisedatums aus dem Formular frmBuchungen übernommen werden sollen. Erstellen Sie auf Grundlage der Tabelle tblBuchungen eine Abfrage, der Sie den Namen qryBuchungsnummer geben. Tragen Sie folgenden Ausdruck in die erste Spalte ein: RechterTeil: Rechts([Anreise];3). Als Funktion zur Ermittlung des größten Wertes wählen Sie Max. Nach dem Speichern und Schließen findet eine automatische Umwandlung in folgenden Ausdruck statt: RechterTeil: Max(Rechts([Buchungsnummer];3)). Ergänzen Sie zwei Spalten mit der Funktion Bedingung. Einmal tragen Sie Jahr: Jahr([Anreise]) und einmal Monat: Monat([Anreise]) ein.
Als Kriterien sollen entsprechende Ausdrücke eingetragen werden, die das im Formular frmBuchungen eingetragene Anreisedatum enthalten. Verwenden Sie hierfür die vollständige Schreibweise. (Über die Schaltfläche AUFBAUEN können Sie zur Unterstützung den Ausdrucks-Generator aufrufen.) Die Ausdrücke lauten: Jahr([Formulare]![frmBuchungen]![Anreise]) und Monat([Formulare]![frmBuchungen]![Anreise]). Bild 8.2: Abfrage ermittelt größte Buchungsnummer des Monats
8.2 Ausdrücke finden und Abläufe vorbereiten
115
Ausdruck in Formular übernehmen Um in einem Formular den Wert eines Feldes anzuzeigen, das sich nicht in der Datenquelle des Formulars befindet, steht die Funktion DomWert zur Verfügung. Um das Ergebnis der oben erstellten Abfrage im Formular frmBuchungen einzublenden, erstellen Sie ein weiteres ungebundenes Textfeld und geben dort den folgenden Ausdruck ein: =DomWert("RechterTeil";"qryBuchungsnummer"). Bild 8.3: Komplette Ausdrücke für beide Buchungsnummernteile
Mit dem gewählten Ausdruck erhalten Sie die letzten drei Stellen der größten, im betreffenden Monat vergebenen Buchungsnummer. Bild 8.4: Anzeige bei größter Buchungsnummer des Anreisemonats
Für die nächste neu zu vergebende Buchungsnummer muss also noch Eins hinzuaddiert werden. Mit dem Ausdruck =DomWert("RechterTeil";"qryBuchungsnummer")+1 bekommen Sie allerdings kein dreistelliges Ergebnis (es sei denn, dass es bereits die hundertste Buchung ist). Hier hilft wieder die Format-Funktion weiter: Format((DomWert("RechterTeil";"qryBuchungsnummer") +1);"000").
8.2.3
Kompletten Ausdruck erstellen
Aus den beiden gefundenen Teilen fügen Sie nun den kompletten Ausdruck zusammen: =Format(Jahr([Anreise]);"0000") & Format(Monat([Anreise]);"00") & Format((DomWert("RechterTeil";"qryBuchungsnummer")+1);"000"). Auch diesen Ausdruck
sollten Sie in einem der Testfelder ausprobieren.
116
Kapitel 8: Makro-Praxisbeispiel
001 wird nicht angezeigt Wenn im Anreisemonat noch keine Buchung eingetragen ist, gibt der DomWert-Ausdruck den Wert NULL aus und es wird keine Zahl angezeigt. Eigentlich müsste aber an dieser Stelle die Endung 001 eingetragen werden. Dieses Problem lösen wir gleich bei der Definition des Makros.
8.3
Ausdruck im Makro verwenden
Jetzt geht es darum, die gefundenen Einzelteile in ein Makro zu übernehmen. Da die Buchungsnummer von den Eintragungen im Feld ANREISE im Formular frmBuchungen abhängt, ist es sinnvoll, das Makro an das Ereignis NACH AKTUALISIERUNG dieses Feldes zu binden. Öffnen Sie das Formular frmBuchungen in der Entwurfsansicht und binden Sie im Eigenschaftenfenster des Feldes ANREISE an das Ereignis NACH AKTUALISIERUNG ein neues Makro, dem Sie den Namen mcrBuchungsnummer geben. Tragen Sie im Makro eine SETZENWERT-Aktion ein, wobei Sie als ELEMENT das Feld BUCHUNGSNUMMER angeben. Im Feld AUSDRUCK übernehmen Sie den im letzten Abschnitt gefundenen Komplettausdruck, wobei Sie das Gleichheitszeichen am Anfang weglassen. Die Makroaktion soll nicht ausgeführt werden, wenn der DomWert-Ausdruck Null ausgibt (was passiert, wenn im betreffenden Monat noch kein Buchungsdatum eingetragen wurde). Deshalb tragen Sie den Ausdruck: DomWert("RechterTeil";"qryBuchungsnummer") Ist Nicht Null in die Bedingungsspalte ein.
8.3 Ausdruck im Makro verwenden
117
Bild 8.5: Extra Zeile für erste Buchungsnummer des Monats
Kopieren Sie die Makrozeile in die folgende Zeile und ändern Sie die Bedingung zu DomWert("RechterTeil";"qryBuchungsnummer") Ist Null.
Beim Ausdruck der SETZENWERT-Aktion entfernen Sie den Teil hinter dem zweiten &-Zeichen und fügen stattdessen "001" hinzu: Format(Jahr([Anreise]);"0000") & Format(Monat([Anreise]);"00") & "001".
Makro mcrAbreiseSetzen per Makro aufrufen Bisher war das Makro mcrAbreiseSetzen an das Ereignis NACH AKTUALISIERUNG des Feldes ANREISE gebunden. Um das Makro auch weiterhin ausführen zu lassen, ergänzen Sie beim Makro mcrBuchungsnummer eine AUSFÜHRENMAKRO-Aktion und tragen als Aktionsargument den Makronamen mcrAbreiseSetzen ein.
Speichern und schließen Sie das Makro. Jetzt können Sie die Testfelder entfernen und Ihr neues Makro ausprobieren. Wenn Sie alles richtig gemacht haben, wird jetzt nach dem Eintragen oder Ändern des Abreisedatums automatisch eine passende Buchungsnummer vergeben. Die Eigenschaften des Feldes BUCHUNGSNUMMER im Formular frmBuchungen sollten Sie nun so einstellen, dass es nicht mehr
118
Kapitel 8: Makro-Praxisbeispiel
von Hand überschrieben werden kann. Dazu wählen Sie AKTIVIERT: NEIN, GESPERRT: JA und IN REIHENFOLGE: NEIN.
Kleines Makro – große Wirkung Am Beispiel des Makros zum automatischen Eintragen der Buchungsnummer kann man erkennen, dass ein gutes Makro nicht unbedingt besonders viele Makroaktionen umfassen muss. Manchmal schafft auch ein kleines Makro eine große Arbeitserleichterung – die Casa-Maria-Mitarbeiter und -Mitarbeiterinnen sind auf jeden Fall begeistert!
8.3 Ausdruck im Makro verwenden
119
9 Makros in Berichten Natürlich ist es richtig, wenn es heißt: »Se aprile produce il fiore è maggio che se ne fa l'onore. – Der April macht die Blum‘ und der Mai hat den Ruhm.« Und doch ist der Mai in der Toscana immer ein ganz besonderes Ereignis. Um besondere Ereignisse ganz anderer Art geht es in diesem Kapitel – nämlich um Ereignisse, die nur für Berichte eintreffen können.
Im Folgenden zeige ich Ihnen Beispiele für die mögliche Bindung von Makros an diese Ereignisse. Dabei müssen Sie beachten, dass es für den gesamten Bericht andere Ereignisse gibt als für die einzelnen Bereiche des Berichts.
9.1
Makros an Ereignisse des Berichts binden
Zunächst werfen Sie bitte einmal einen Blick auf die Ereignisse, die für den Bericht als Ganzes eintreten können. Öffnen Sie dazu den Bericht rptAdressenDeutschland in der Entwurfsansicht und lassen Sie sich nach Klick auf den Berichtsmarkierer die Eigenschaften des Berichts anzeigen. Klicken Sie auf dem Registerblatt EREIGNIS in das Feld BEI OHNE DATEN und dann auf die drei Punkte am Ende.
120
Kapitel 9: Makros in Berichten
Bild 9.1: Eigenschaftenfenster des Berichts rptAdressenDeutschland
Erstellen Sie ein Makro, dem Sie den Namen mcrDruckenOhneDaten geben. Wählen Sie die Makroaktion MELDUNG mit dem Meldungstext Es liegen keine Daten vor! und speichern und schließen Sie Makro und Bericht. Das Ereignis BEI OHNE DATEN tritt ein, wenn beim Ausdrucken oder Anzeigen des Berichts keine Daten vorhanden sind. Dieser Fall tritt z.B. ein, wenn Sie im Formular frmAdressenDeutschland auf die Schaltfläche ADRESSETIKETT DRUCKEN klicken, bevor Sie einen neuen Datensatz eingetragen haben. Wenn Sie nach Erscheinen der Fehlermeldung auf OK klicken, wird trotzdem ein Datensatz mit #FEHLER-Einträgen ausgedruckt.
9.1 Makros an Ereignisse des Berichts binden
121
Bild 9.2: Das Ereignis BEI OHNE DATEN ist eingetreten
Um dies zu vermeiden, müssen Sie zu Ihrem Makro noch eine ABBRECHENEREIGNIS-Aktion hinzufügen. Bild 9.3: Das fertige Makro
9.2
Ereignisse in Unterbereichen des Berichts
Auch für die anderen Bereiche eines Berichts gibt es Ereignisse, an die Sie ein Makro binden können.
122
Kapitel 9: Makros in Berichten
Lassen Sie sich in dem in der Entwurfsansicht geöffneten Bericht rptAppartements einmal im Eigenschaftenfenster des Berichtskopfes das Registerblatt EREIGNIS anzeigen. Bild 9.4: Ereigniseigenschaften des Berichtskopfes
Binden Sie an das Ereignis BEIM DRUCKEN ein Makro, dem Sie den Namen mcrDruckenBerichtskopf geben. Als Makroaktion wählen Sie wieder MELDUNG, diesmal mit dem Text Berichtskopf wird gedruckt. Speichern und schließen Sie das Makro. Wenn Sie jetzt den Bericht ausdrucken, erscheint vor dem Ausdrucken die Meldung. Nach Bestätigung wird der Berichtskopf und der ganze folgende Bericht gedruckt.
Verbesserungswünsche Besser wäre es natürlich, wenn Sie beim Erscheinen der Meldung die Möglichkeit hätten, den Berichtskopf nicht zu drucken. Mit einer Meldung, wie Sie sie bisher einsetzten, ist dies allerdings nicht möglich. Im nächsten Kapitel zeige ich Ihnen unter anderem, wie Sie für Ihren Bericht eine Meldung mit verschiedenen Auswahlmöglichkeiten einblenden können. Also: Bleiben Sie dran!
9.2 Ereignisse in Unterbereichen des Berichts
123
10 Anwenderfreundlich mit Makros »Ogni bel gioco dura poco. – Alles Schöne hat einmal ein Ende.« Dies ist das letzte Kapitel, das sich schwerpunktmäßig mit Makros beschäftigt. Aber keine Angst, VBA ist ja auch noch da!
Die Casa-Maria-Datenbank soll so gestaltet werden, dass auch Mitarbeiter damit zurecht kommen, die sich bisher nicht mit Access beschäftigt haben und weder wissen, was eine Abfrage, noch was ein Berichtskopf ist. Ein Mittel, um die Handhabung für die Mitarbeiter einfacher zu machen, ist es, Informationen in Dialogfeldern abzufragen, in denen dann nur mit ja oder nein geantwortet zu werden braucht. In diesem Kapitel zeige ich Ihnen, wie Sie Meldungen erstellen, die die Schaltflächen JA und NEIN enthalten. Außerdem zeige ich Ihnen, wie Sie ein Makro automatisch beim Starten von Access aus-
führen lassen, wie Sie beim Start von Access ein Formular anzeigen lassen,
das dem Anwender auch ohne Datenbankfenster den Aufruf weiterer Formulare zu den einzelnen Arbeitsbereichen ermöglicht, wie Sie das Datenbankfenster ausblenden, wie Sie weitere Start-Einstellungen vornehmen und z.B. den Eintrag in der Titelleiste ändern und wie Sie eine eigene Symbolleiste erstellen.
10.1 Meldung mit Auswahlmöglichkeit Wie Sie am Ende des letzten Kapitels gesehen haben, gibt es Gelegenheiten, bei der Sie mit der Makroaktion MELDUNG nicht weiterkommen. Im letzten Kapitel fehlte die Möglichkeit, den Ausdruck des im Berichtskopf enthaltenen Deckblattes abzubrechen. Besser
124
Kapitel 10: Anwenderfreundlich mit Makros
wäre eine Meldung, in der Sie sich gegen einen Ausdruck des Deckblattes entscheiden könnten. Bild 10.1: So müsste die Meldung aussehen
Eine solche Meldung müsste dann nach Klick auf NEIN die Makroaktion ABBRECHENEREIGNIS ausführen. Aber wie soll es möglich sein, die ABBRECHENEREIGNIS-Aktion nur unter der Bedingung auszuführen, dass in einer Meldung auf NEIN geklickt wurde? Um den gewünschten Effekt zu erreichen, müssen Sie eine Bedingung definieren, die unterschiedliche Werte annimmt, je nachdem, auf welche Schaltfläche in einer Meldung geklickt wurde. Um eine Meldung wie in Bild 10.1 zu erzeugen, ersetzen Sie in dem im letzten Kapitel erstellten Makro mcrDruckenBerichtskopf die Makroaktion MELDUNG durch die ABBRECHENEREIGNIS-Aktion, tragen Sie in der Bedingungsspalte folgenden Ausdruck ein: Meldung ("Soll das Deckblatt gedruckt werden?";4;"Achtung")=7 und speichern und schließen Sie das Makro. Bild 10.2: Das geänderte Makro mcrDruckenBerichtskopf
Da das Makro mcrDruckenBerichtskopf an das Ereignis BEIM DRUdes Berichtskopfes gebunden ist, erscheint die Meldung, wenn Sie den Bericht ausdrucken. Das Ganze funktioniert übrigens auch, wenn Sie den Bericht in der Seitenvorschau anzeigen lassen, denn auch in diesem Fall tritt das Ereignis BEIM DRUCKEN ein. CKEN
10.1 Meldung mit Auswahlmöglichkeit
125
Funktion Meldung statt Makroaktion Meldung Es gibt also zwei unterschiedliche Möglichkeiten, eine Meldung anzuzeigen: Für eine einfache Meldung, die nur mit OK bestätigt werden
kann, tragen Sie die Makroaktion MELDUNG ein. Wollen Sie eine Meldung mit mehreren Schaltflächen anzeigen,
tragen Sie einen Ausdruck mit der Funktion Meldung in die Bedingungsspalte ein.
Wie funktioniert die Funktion Meldung? Die Funktion Meldung hat den folgenden Aufbau: Meldung (<Meldungstext>;;<Titeltext>). Bei dem im obigen Beispiel eingetragenen Typ 4 werden die Schaltflächen JA und NEIN angezeigt. Wenn Sie stattdessen für Typ 1 eine 1 eintragen, werden die Schaltflächen OK und ABBRECHEN angezeigt. Wenn die Schaltfläche NEIN gedrückt wird, liefert die Funktion Meldung den Wert 7 zurück. Damit die Makroaktion ABBRECHENEREIGNIS beim Klicken auf NEIN ausgeführt wird, musste der Ausdruck für die Bedingung im obigen Beispiel deshalb um =7 ergänzt werden. Ein Klick auf JA gibt den Wert 6 zurück. Wenn Sie Typ 1 gewählt haben, erhalten Sie für OK den Rückwert 1 und für ABBRECHEN den Wert 2 oder 3.
10.2 Grundeinstellungen für die Datenbank Sie haben die Möglichkeit, nach dem Öffnen einer Datenbank automatisch ein Makro zu starten oder ein Formular aufzurufen. Im Folgenden beschreibe ich Ihnen diese und weitere Möglichkeiten, das Aussehen und die Funktionen Ihrer Datenbank anwenderfreundlicher zu gestalten.
126
Kapitel 10: Anwenderfreundlich mit Makros
10.2.1
AutoExec-Makro
Soll ein Makro automatisch beim Laden der Datenbank ausgeführt werden, müssen Sie ihm lediglich den Namen AutoExec geben.
Beispielmakro zeigt Anzahl der belegten Appartements Als Beispiel für ein AutoExec-Makro habe ich ein Makro erstellt, das eine Meldung mit der Zahl der am aktuellen Datum gebuchten Appartements anzeigt. Wenn Sie die erforderlichen Schritte nachvollziehen wollen, erstellen Sie zunächst eine Abfrage, der Sie den Namen qryAppartementsHeuteBelegt geben. Unter der Bedingung, dass das heutige Datum größer oder gleich dem Anreisedatum und kleiner oder gleich dem Abreisedatum ist, wird die Anzahl der Appartementnummern ausgegeben (siehe folgendes Bild): Bild 10.3: Abfrage als Grundlage für Beispielmakro
Bild 10.4: Mögliches Abfrageergebnis
Geben Sie einem neuen Makro den Namen AutoExec und fügen Sie als Aktion eine MELDUNG hinzu. Als Aktionsargument tragen Sie im Feld MELDUNG den folgenden Ausdruck ein: ="Zur Zeit belegte Appartements: " & DomWert("[AnzahlvonAppartementnummer]";"qryAppartementsHeuteBelegt").
10.2 Grundeinstellungen für die Datenbank
127
Das Gleichheitszeichen bewirkt, dass der Ausdruck nicht direkt als Meldungstext angezeigt wird, sondern die einzelnen Teile zuerst zusammengesetzt werden. Mit der DomWert-Funktion (die Sie ja bereits in Kapitel 8 eingesetzt haben) wird der Wert aus dem Ergebnisfeld [ANZAHLVONAPPARTEMENTS] aus der Abfrage qryAppartementsHeuteBelegt in den Meldungstext übernommen. Bild 10.5: Für Meldungstext wurde längerer Ausdruck eingetragen
Speichern Sie das neue Makro und schließen Sie die Datenbank. Wenn Sie die Datenbank erneut öffnen, wird das AutoExec-Makro automatisch gestartet und die Meldung mit der Anzahl der belegten Appartements erscheint auf dem Bildschirm (siehe Bild 10.11).
10.2.2
Start-Einstellungen
Mit dem Menübefehl EXTRAS START rufen Sie das Dialogfeld START auf. Hier haben Sie eine Reihe von Einstellungsmöglichkeiten. Bild 10.6: Hier können Sie die START-Eigenschaften ändern
128
Kapitel 10: Anwenderfreundlich mit Makros
Anwendungstitel Im Feld ANWENDUNGSTITEL können Sie die Bezeichnung eintragen, die statt MICROSOFT ACCESS in der Titelleiste erscheinen soll. Bei mir steht dort jetzt Casa Maria (siehe Bild 10.11).
Datenbankfenster und Statusleiste ausblenden Wenn Sie das Häkchen vor DATENBANKFENSTER ANZEIGEN entfernen, wird das Datenbankfenster ausgeblendet. In der geöffneten Datenbank können Sie das Datenbankfenster mit 囩 wieder einblenden. Wenn Sie nicht möchten, dass ein ausgeblendetes Datenbankfenster auf diese Weise eingeblendet werden kann, entfernen Sie zusätzlich das Häkchen vor ACCESS-SPEZIALTASTEN VERWENDEN. Zum Ausblenden der Statuszeile am unteren Rand des Programmfensters entfernen Sie einfach das Häkchen vor STATUSLEISTE ANZEIGEN.
Formular/Seite anzeigen Wollen Sie, dass direkt nach dem Start ein Formular geöffnet wird, können Sie dieses im Feld FORMULAR/SEITE ANZEIGEN auswählen.
AutoExec-Makro startet erst nach Öffnen des Startformulars Wenn Sie sowohl ein Startformular als auch ein AutoExec-Makro einsetzen, wird zuerst das Startformular geöffnet und danach das AutoExec-Makro ausgeführt.
Im nächsten Abschnitt zeige ich Ihnen, wie Sie ein Startformular erstellen, das mehrere Schaltflächen enthält, mit denen zu den einzelnen Formularen gewechselt werden kann.
10.2 Grundeinstellungen für die Datenbank
129
10.3 Ungebundenes Formular als Startformular Das Formular, auf dem die Schaltflächen gesammelt werden, bezieht sich nicht auf eine Tabelle oder Abfrage. Es hat keine Datenbasis. Ein solches Formular wird als ungebundenes Formular bezeichnet. Zum Erstellen eines ungebundenen Formulars klicken Sie einfach im Datenbankfenster auf den Eintrag ERSTELLT EIN FORMULAR IN DER ENTWURFSANSICHT. Bild 10.7: Ein ungebundenes Formular
Dass es sich um ein ungebundenes Formular handelt, erkennen Sie daran, dass im Eigenschaftenfenster des Formulars im Feld DATENHERKUNFT nichts eingetragen ist. Setzen Sie die Eigenschaften DATENSATZMARKIERER, NAVIGATIONSSCHALTFLÄCHEN und TRENNLINIEN auf NEIN, denn diese Eigenschaften brauchen Sie bei einem ungebundenen Formular nicht. Auch die BILDLAUFLEISTEN können Sie ausschalten. Indem Sie die Eigenschaft MIT SYSTEMMENÜFELD auf NEIN setzen, enfernen Sie die Fensterschaltflächen, die normalerweise rechts oben im Fenster angezeigt werden. Als RAHMENART wählen Sie DIALOG, um das Formular mit einer für Dialogfelder typischen dünnen, nicht veränderbaren Linie zu umranden. Als BESCHRIFTUNG tragen Sie Casa Maria ein.
130
Kapitel 10: Anwenderfreundlich mit Makros
Formular automatisch zentrieren Wenn Sie die Eigenschaft AUTOMATISCH ZENTRIEREN auf JA stellen, wird das Formular beim Öffnen automatisch in der Mitte des Bildschirms platziert.
Besondere Bedeutung der Eigenschaft GEBUNDEN Die Eigenschaft GEBUNDEN, die Sie auf dem Registerblatt ALLE des Eigenschaftenfensters finden, hat nichts damit zu tun, ob das Formular an eine Tabelle oder Abfrage gebunden ist. Ist bei GEBUNDEN JA eingetragen, können Sie zu keinem anderen Formular wechseln. Lassen Sie für das Startformular NEIN eingetragen.
Wie in Kapitel 5 beschrieben, erstellen Sie nun für die Formulare frmAdressenDeutschland, frmBuchungen und frmAppartements jeweils ein Makro, das in einer ÖFFNENFORMULAR-Aktion das entsprechende Formular aufruft. Dann ziehen Sie die Makros aus dem Datenbankfenster in das in der Entwurfsansicht geöffnete neue Formular, um auf diese Weise die Schaltflächen zu erstellen. Die Bezeichnung der Schaltflächen ändern Sie zu Appartements bzw. Adressen. Auf entsprechende Weise fügen Sie eine Schaltfläche hinzu, die den Bericht rptAppartements ausdruckt.
10.3 Ungebundenes Formular als Startformular
131
Für Schaltflächen Quick-Infos vergeben In den Eigenschaften der Befehlsschaltflächen können Sie durch einen Eintrag im Feld STEUERELEMENT TIP-TEXT den Text vergeben, der angezeigt wird, wenn Sie mit der Maus über die Schaltfläche fahren.
Dann fügen Sie aus der Toolbox mit Unterstützung des Assistenten eine Befehlsschaltfläche zum Beenden von Access hinzu. Dabei wählen Sie im Assistenten ANWENDUNG BEENDEN. Bild 10.8: Befehlsschaltfläche hinzufügen: Schritt 1
Wählen Sie in den folgenden Schritten das Symbol mit der Tür und klicken Sie auf WEITER. Bild 10.9: Befehlsschaltfläche hinzufügen: Schritt 2
132
Kapitel 10: Anwenderfreundlich mit Makros
Im dritten Schritt vergeben Sie den Namen cmdSchließen und klicken dann auf FERTIG STELLEN. Ändern Sie die Namen der anderen zuvor hinzugefügten Schaltflächen von den automatisch vergebenen Bezeichnungen (BEFEHL8 etc.) zu passenden Namen mit dem Präfix cmd. Wenn Sie möchten, fügen Sie noch eine Grafik ein. Bild 10.10: Grafik hinzufügen
Auch mit Klick auf Grafik lassen sich Makros ausführen Auch in den Eigenschaften einer Grafik finden Sie das BEIM KLICKEN-Ereignis, an das Sie ein Makro binden können. Bei mir wird das Makro AutoExec beim Klicken auf die Grafik aufgerufen. Als STEUERELEMENT TIP-TEXT habe ich eingetragen: Anzahl der zur Zeit gebuchten Appartements anzeigen.
Schließen Sie das Formular und geben Sie ihm den Namen frmStart. Jetzt müssen Sie das Formular nur noch im Dialogfeld START im Feld FORMULAR/SEITE ANZEIGEN auswählen, damit es automatisch beim nächsten Start angezeigt wird.
10.3 Ungebundenes Formular als Startformular
133
Bild 10.11: Startformular und Meldung durch AutoExec-Makro
10.4 Eigene Symbolleisten Sie haben auch die Möglichkeit, Ihre Formulare über einen Eintrag in einer eigenen Symbolleiste zu öffnen. Dazu öffnen Sie das Dialogfeld ANPASSEN mit dem Menübefehl ANSICHT SYMBOLLEISTEN ANPASSEN. Im linken Bereich können Sie Symbolleisten zur Anzeige markieren oder ausblenden. Bild 10.12: Eigene Symbolleiste definieren
134
Kapitel 10: Anwenderfreundlich mit Makros
Klicken Sie auf dem Registerblatt SYMBOLLEISTEN auf NEU und geben Sie der neuen Symbolleiste einen Namen. Wechseln Sie zum Registerblatt BEFEHLE und klicken Sie dort auf ALLE FORMULARE. Ziehen Sie eines Ihrer im rechten Bereich aufgeführten Formulare in die noch winzig kleine Symbolleiste. Klicken Sie mit rechts auf das eingetragene Symbol, wählen Sie im Kontextmenü die Option SCHALTFLÄCHENSYMBOL MIT TEXT und ändern Sie den im Kontextmenü eingetragenen Namen der Schaltfläche. Bild 10.13: Schaltflächen mit Text in neuer Symbolleiste erstellen
Nach diesem Muster fügen Sie weitere Formulare (oder auch Makros zum Ausdrucken eines Berichts etc.) hinzu. Am Ende schließen Sie das Dialogfeld ANPASSEN. Jetzt haben Sie eine eigene Symbolleiste erstellt, die einen direkten Zugriff auf die gewünschten Objekte ermöglicht. Wenn Sie möchten, blenden Sie die anderen Symbolleisten aus. Bild 10.14: Die eigene Symbolleiste ist fertig
Mit den beschriebenen Änderungen haben Sie Ihre Datenbank nun ein ganzes Stück freundlicher, vielleicht sogar anwenderfreundlicher gemacht!
10.4 Eigene Symbolleisten
135
11 VBA ausprobieren »Chi lascia la strada vecchia per la nuova, sa quel che lascia ma non quel che trova. – Wer die alte Straße wegen der neuen verlässt, weiß, was er verlässt, aber nicht, was er findet.« In diesem Kapitel werden Sie neue Wege beschreiten und Ihre ersten Schritte in der VBA-Programmierung machen. Dabei steht das Ausprobieren im Mittelpunkt. Ab Kapitel 12 folgt dann etwas mehr Theorie.
11.1 Warum überhaupt VBA? Wenn Sie jetzt mit Makros gut zurechtkommen, stellt sich natürlich die Frage, warum Sie sich überhaupt mit VBA beschäftigen sollen. Die Antwort ist einfach: Wenn Sie Ihre Access-Datenbanken weiter verbessern und professioneller gestalten möchten, gelangen Sie irgendwann an einen Punkt, an dem Sie mit Makros nicht weiterkommen. Deshalb sollten Sie sich frühzeitig an den Umgang mit VBA gewöhnen. Sie werden sehen, dass das Erlernen von VBA gar nicht so schwer ist, zumal Sie einiges aus den Erfahrungen ableiten können, die Sie mit Makros gesammelt haben. Und ich kann Ihnen sagen, dass auch die englischen Schreibweisen (die mir als Italienerin am Anfang so in‘s Auge sprangen) schnell ihren Schrecken verlieren.
11.2 Eingetragenen VBA-Code ändern Am Ende des letzten Kapitels hatte ich Sie gebeten, dem Startformular frmStart eine Befehlsschaltfläche hinzuzufügen, mit der die Anwendung beendet, d.h. Access geschlossen wird. Der Assistent hatte dabei automatisch einige Programmzeilen in VBA erstellt. Diesen VBA-Code wollen wir gleich einmal anschauen und ändern.
136
Kapitel 11: VBA ausprobieren
Als Arbeitserleichterung frmStart zur eigenen Symbolleiste hinzufügen Da Sie in diesem Kapitel viele Dinge anhand des Startformulars frmStart ausprobieren werden, lohnt es sich, für dieses Formular zu Ihrer eigenen Symbolleiste eine Schaltfläche hinzuzufügen. Gehen Sie dabei vor wie im letzten Kapitel beschrieben.
Öffnen Sie bitte das Formular frmStart in der Entwurfsansicht, markieren Sie die Befehlsschaltfläche cmdSchließen und lassen sich in den Eigenschaften das Registerblatt EREIGNIS anzeigen. Bild 11.1: Die eingetragene Ereignisprozedur wird geöffnet
Klicken Sie in die Zeile BEIM KLICKEN und dann auf die drei Punkte am Ende. Damit wechseln Sie zum VBA-Entwurfsfenster. (Die einzelnen Komponenten des VBA-Entwurfsfensters beschreibe ich Ihnen im nächsten Kapitel.)
11.2 Eingetragenen VBA-Code ändern
137
Bild 11.2: Der VBA-Code soll geändert werden
Die entscheidende VBA-Zeile lautet: DoCmd.Quit. Mit Quit wird festgelegt, dass das Programm geschlossen wird. Entfernen Sie Quit und den Punkt davor. Dann fügen Sie den Punkt wieder hinzu. In diesem Augenblick bekommen Sie eine Liste mit möglichen Einträgen angezeigt. Bild 11.3: Wählen Sie Close statt Quit
Wenn Sie in der Liste auf Close doppelklicken, wird damit eingetragen, dass nur noch das Formular geschlossen und nicht mehr das ganze Programm beendet werden soll.
138
Kapitel 11: VBA ausprobieren
Wird bei Ihnen keine Liste mit Vorschlägen angezeigt? Falls Sie wie beschrieben vorgegangen sind, aber trotzdem keine Vorschlagsliste angezeigt bekommen, überprüfen Sie bitte unter EXTRAS OPTIONEN, ob dort alle Häkchen gesetzt sind.
Bild 11.4: Zur Eingabeunterstützung alle Häkchen setzen
Schließen Sie das VBA-Entwurfsfenster, speichern Sie das Formular frmStart. Der eingetragene VBA-Code wird dabei automatisch mitgespeichert. Wenn Sie nun in der Formularansicht auf die Schaltfläche mit der Tür klicken, wird nur noch das Formular geschlossen und nicht mehr Access beendet.
11.3 VBA-Code neu erstellen für InputBox In Kapitel 2 haben Sie bereits mit VBA ein Meldungsfenster aufrufen lassen. Auch im Makroteil des Buches haben Sie ausgiebig von der Möglichkeit Gebrauch gemacht, Angaben in Form von Meldungen auszugeben. Im letzten Kapitel habe ich Ihnen auch gezeigt, wie Sie die Meldungsbedingung in Makros nutzen können, um vom Anwender z.B. Ja-Nein-Entscheidungen abzufragen.
11.3 VBA-Code neu erstellen für InputBox
139
Mit der InputBox, die ich Ihnen jetzt vorstellen möchte, ist es auf einfache Weise möglich, Eingaben aufzunehmen, die dann weiter verarbeitet werden können.
11.3.1
InputBox nimmt Eintragungen auf
Beim Öffnen des Startformulars frmStart soll in einer InputBox das Motto des Tages abgefragt werden. Das Motto soll dann im Formular erscheinen. Statt eines Makros binden Sie nun einfach eine Ereignisprozedur an das BEIM ÖFFNEN-Ereignis des Formulars. Dazu öffnen Sie bitte das Formular frmStart in der Entwurfsansicht, klicken im Eigenschaftenfenster auf dem Registerblatt EREIGNIS in die Zeile BEIM ÖFFNEN und wählen dann nach Klick auf die drei Punkte am Ende den CODE-GENERATOR aus. Sie sehen im oberen Teil den Code, den Sie aus dem letzten Abschnitt kennen. Unten finden Sie die blinkende Einfügemarke zwischen Private Sub und End Sub. Hier schreiben Sie den folgenden Text: inputbox ("Motto des Tages:") und rücken den Text für die bessere Lesbarkeit mit der 圵-Taste ein. Klicken Sie in die nächste Zeile. Wenn Sie sich nicht vertippt haben, erscheint InputBox jetzt groß geschrieben. Bild 11.5: InputBox ist eingetragen
140
Kapitel 11: VBA ausprobieren
Wenn Sie nun erneut das Formular frmStart öffnen, wird die InputBox angezeigt. Übrigens müssen Sie das VBA-Entwurfsfenster dazu nicht schließen – wechseln Sie einfach über den Eintrag in der Taskleiste oder klicken Sie ganz links in der Symbolleiste auf das Symbol ANSICHT MICROSOFT ACCESS. Bild 11.6: InputBox fordert zur Eingabe auf
11.3.2
Eingabe aus InputBox weiterverarbeiten
Bisher werden die Angaben, die Sie in der InputBox machen, noch nirgends angezeigt. Das soll sich jetzt ändern.
Angaben in MessageBox anzeigen Am einfachsten bekommen Sie die Eintragung mit einer Meldung (bzw. MessageBox) auf den Bildschirm. In Kapitel 2 hatten Sie die MessageBox mit MsgBox aufgerufen. Jetzt probieren Sie einmal Folgendes aus: Öffnen Sie das Formular frmStart wieder in der Entwurfsansicht, klicken Sie im Eigenschaftenfenster auf dem Registerblatt EREIGNIS in die Zeile BEIM ÖFFNEN und dort auf die drei Punkte am Ende. (Wenn Sie das VBA-Entwurfsfenster vorhin geöffnet gelassen hatten, reicht es, wieder dorthin zu wechseln!) Schreiben Sie einfach msgbox an den Anfang der Zeile, in der Sie die InputBox definiert hatten – fertig! Wenn Sie möchten, können Sie den Teil (InputBox ("Motto des Tages:")) noch in Klammern fassen, damit deutlicher sichtbar ist, dass der in der InputBox erfasste Text in der MessageBox angezeigt wird. Bild 11.7: Nicht die beste Lösung, aber es funktioniert
11.3 VBA-Code neu erstellen für InputBox
141
Wenn Sie nun erneut das Formular frmStart öffnen, erscheint zuerst die InputBox. Nachdem Sie das Motto des Tages eingetragen und auf OK geklickt haben, erscheint das Motto des Tages gleich danach in einer MessageBox. Bild 11.8: Hier rein ...
Bild 11.9: ... da raus!
Schon mal eine Variable deklarieren Dasselbe passiert, wenn Sie den in der InputBox eingegebenen Wert zwischenspeichern: Bild 11.10: So wird es besser
Mit der Schreibweise im obigen Bild haben Sie festgelegt, dass der Eintrag aus der InputBox in strMotto gespeichert wird. In der MessageBox wird dann der Inhalt von strMotto ausgegeben. Diese Schreibweise hat unter anderem den Vorteil, dass es nun ganz leicht ist, den in strMotto gespeicherten Wert auch in anderer Form auszugeben. Ein solcher Zwischenspeicher wird übrigens als Variable bezeichnet. Die mit Dim beginnende Zeile dient zur Deklaration der Variablen strMotto. Das Deklarieren von Variablen ist ein Thema, auf das ich im nächsten Kapitel noch genauer eingehen werde. Jetzt geht es erst einmal um ein praktisches Beispiel: Um zu verhindern, dass mehr Text gespeichert wird als später angezeigt werden kann, soll für die Variable strMotto festgelegt werden, dass
142
Kapitel 11: VBA ausprobieren
sie Text von maximal 50 Zeichen aufnehmen soll. Für diese Festlegung wird die Variable mit dem Ausdruck Dim strMotto As String * 50 deklariert.
Ausgabe in Bezeichnungsfeld Fügen Sie zum Formular frmStart ein neues Bezeichnungsfeld hinzu, in das Sie als Platzhalter ein beliebiges Zeichen, z.B. ein Leerzeichen eintragen und dem Sie z.B. den Namen lblMotto geben. Mit der Vorsilbe lbl für »label« werden Bezeichnungsfelder gekennzeichnet. Jetzt können Sie mit lblMotto.Caption = strMotto das in der InputBox eingetragene Motto im Bezeichnungsfeld anzeigen lassen. Dazu müssen Sie den obigen Ausdruck nur in einer weiteren Zeile zur oben erstellten Ereignisprozedur hinzufügen (s. Bild 11.11). Sobald Sie bei der Eingabe den Punkt vor Caption gesetzt haben, wird wieder eine Liste mit Auswahlmöglichkeiten aufgeführt, aus der Sie per Doppelklick Caption auswählen können. (Caption steht übrigens für Überschrift bzw. Titel.)
Ausgabe als neue Beschriftung einer Befehlsschaltfläche Nach demselben Muster können Sie auch die Beschriftung einer Befehlsschaltfläche ändern. Wenn Sie eine Befehlsschaltfläche mit der Bezeichnung cmdMotto hinzugefügt haben, müssen Sie den Ausdruck cmdMotto.Caption = strMotto in die Ereignisprozedur einfügen (s. Bild 11.11).
Ausgabe als neuer Eintrag in der Titelleiste Auch der Eintrag in der Titelleiste des Formulars lässt sich auf diese Weise mit dem Ausdruck Form_frmStart.Caption = strMotto ändern (s. Bild 11.11).
11.3 VBA-Code neu erstellen für InputBox
143
Bild 11.11: Vier Ausgabebeispiele für den InputBox-Eintrag
Bild 11.12: So würde das Motto des Tages im Formular erscheinen
Mir persönlich gefällt das Motto des Tages am besten im Titel des Startformulars. Deshalb lösche ich die Zeilen für das Bezeichnungsfeld (lblMotto.Caption = strMotto), für die Befehlsschaltfläche (cmdMotto.Caption = strMotto) und für die MessageBox (MsgBox (strMotto)) aus der Prozedur. Die Befehlsschaltfläche cmdMotto entferne ich wieder aus dem Formular und das Bezeichnungsfeld lblMotto benenne ich in lblZeit um, denn hier soll die aktuelle Zeit angezeigt werden. Wie das geht, zeige ich Ihnen jetzt.
11.4 Aktuelle Uhrzeit im Formular anzeigen Um im Formular frmStart im Bezeichnungsfeld Zeit einzublenden,
LBLZEIT
die aktuelle
tragen Sie in den Eigenschaften des Formulars auf dem Registerblatt ALLE als ZEITGEBERINTERVALL den Zeittakt 1000 ein. Damit wird die sekundengenaue Anzeige eingestellt. (Der Wert wird in
144
Kapitel 11: VBA ausprobieren
Millisekunden angegeben – mit 60000 stellen Sie einen Zeittakt von einer Minute ein.) Klicken Sie in die Zeile BEI ZEITGEBER und dann auf die drei Punkte am Ende, um den Code-Generator aufzurufen. Bild 11.13: Für frmStart Zeitgeberintervall eintragen
In der neuen Ereignisprozedur fügen Sie die Zeile lblZeit.Caption = Now ein. Bild 11.14: So wird die Zeit im Standardformat angezeigt
Wenn Sie jetzt das Formular frmStart in der Formularansicht anzeigen, wird die Zeit im Bezeichnungsfeld LBLZEIT im Format angezeigt, das in den Systemeinstellungen festgelegt ist. Um Datum und Uhrzeit in einem eigenen Format anzuzeigen, nutzen Sie die Format-Funktion, die Sie ja schon aus den Makro-Kapiteln kennen. Allerdings müssen Sie jetzt die englische Schreibweise wählen (mit d für day als Tag und y für year als Jahr). In den folgenden beiden Bildern sehen Sie, wie ich das Format angegeben habe und wie das Ergebnis im Formular aussieht. Bild 11.15: Auch ein eigenes Format kann definiert werden
11.4 Aktuelle Uhrzeit im Formular anzeigen
145
Bild 11.16: Datums- und Uhrzeitanzeige im eigenen Format
Außerdem habe ich noch eingestellt, dass es zur vollen Stunde piepst – oder genauer gesagt: Es ertönt ein Beep. Wie im nächsten Bild zu sehen, habe ich dazu einen If...Then-Ausdruck hinzugefügt. Dieser Wenn...Dann-Ausdruck besagt, dass es piepsen soll, wenn sowohl die Sekunden als auch die Minuten der aktuellen Zeit gleich Null sind, denn dann handelt es sich um eine volle Stunde. Bild 11.17: Zur vollen Stunde piepst es
Zum Ausprobieren können Sie den Teil And Minute(Now) = 0 einfach entfernen, dann piepst es jede Minute! Wenn es bei Ihnen überhaupt nicht piepsen soll und Sie auch keine Zeit im Startformular angezeigt bekommen möchten, dann löschen Sie den gesamten Code von Private Sub Form_Timer () bis End Sub und entfernen das Bezeichnungsfeld LBLZEIT aus dem Startformular.
11.5 Makro in VBA umwandeln Selbst erstellte Makros lassen sich einfachin Visual Basic umwandeln. Um das Makro mcrAdressenDrucken zu konvertieren,
146
Kapitel 11: VBA ausprobieren
markieren Sie es im Datenbankfenster und rufen Sie den Menübefehl EXTRAS MAKROS MAKROS BASIC KONVERTIEREN auf.
ZU
VISUAL
Bild 11.18: Makro zu Visual Basic konvertieren
Ein Dialogfeld erscheint, in dem Sie wählen können, ob die Kommentare, die Sie im Makro gemacht haben, mit übernommen werden sollen und ob automatisch eine Fehlerbehandlung integriert werden soll. Wenn Sie beide Häkchen setzen, wird der erstellte VBA-Code etwas länger und für Sie möglicherweise etwas unübersichtlicher. Dafür ist dann auch alles Nötige enthalten. Klicken Sie auf OK. Die Meldung, dass das Makro fertig konvertiert wurde, bestätigen Sie ebenfalls mit OK. Das konvertierte Makro finden Sie, wenn Sie im Datenbankfenster auf der Objektleiste den Objekttyp MODULE wählen. Konvertierten Makros wird vor dem Namen des Makros der Text KONVERTIERTES MAKRO vorangestellt. Das eben erstellte Makro heißt also Konvertiertes Makro- mcrAdressenDrucken. Bild 11.19: Konvertiertes Makro im Datenbankfenster
Wenn Sie auf den Eintrag im Datenbankfenster doppelklicken, wird der erstellte Code im VBA-Entwurfsfenster angezeigt. Die zentrale Zeile beginnt mit DoCmd.OpenReport, diese VBA-Funktion entspricht der Makroaktion ÖFFNEN BERICHT. Die meisten der restlichen Zeilen dienen zur Fehlerbehandlung und regeln, was passieren soll, wenn ein Fehler auftritt.
11.5 Makro in VBA umwandeln
147
Bild 11.20: So sieht der erstellte Code aus
Von Makros konvertierter Code ist nicht unbedingt der beste Der beim Konvertieren von Makros zu VBA erstellte Code gibt nicht unbedingt die beste aller Lösungen wieder. Wenn Sie etwas mehr Erfahrung mit VBA haben, können Sie den konvertierten Code als Grundlage nehmen und ihn dann selber überarbeiten.
Konvertiertes Makro aufrufen Wollen Sie ein konvertiertes Makro aus einem Formular heraus aufrufen, brauchen Sie nur den Namen der Funktion (also in unserem Beispiel mcrAdressenDrucken) in eine an das gewünschte Ereignis gebundene Prozedur einzufügen. Um mit Klick auf die ADRESSETIKETTEN-Schaltfläche nicht mehr das Ursprungsmakro, sondern die neue Prozedur auszuführen, öffnen Sie das Formular frmStart in der Entwurfsansicht und löschen Sie in den Eigenschaften auf dem Registerblatt EREIGNIS den Eintrag in der Zeile BEIM KLICKEN.
148
Kapitel 11: VBA ausprobieren
Klicken Sie auf die drei Punkte am Ende der Zeile und wählen Sie den Code-Generator. Bild 11.21: BEIM KLICKEN-Eintrag löschen und CodeGenerator wählen
In der neuen Prozedur tragen Sie jetzt den Namen der Funktion ein, die bei konvertierten Makros dem Namen des Ursprungsmakros entspricht. Bild 11.22: Namen der Funktion eintragen
Wenn Sie nun im Formular frmStart auf die Schaltfläche ADRESSETIKETTEN klicken, wird zum Ausdrucken des Berichts die neu konvertierte Prozedur ausgeführt.
Ausblick auf die nächsten Kapitel Nachdem Sie in diesem Kapitel schon einige praktische Erfahrungen im Umgang mit VBA gesammelt haben, folgt in den nächsten Kapiteln nun etwas Theorie. Damit erhalten Sie das nötige Hintergrundwissen, um sich sicherer auf den neuen VBA-Pfaden zu bewegen.
11.5 Makro in VBA umwandeln
149
12 VBA Grundlagenwissen Nachdem Sie nun bereits einige VBA-Programmiererfahrung gesammelt haben, möchte ich Ihnen in diesem und den nächsten Kapiteln das Handwerkszeug vorstellen, das Sie zum Programmieren brauchen. Keine Angst – auch hier gibt es wieder neben aller Theorie eine ganze Reihe praktischer Beispiele. Und denken Sie daran: »Anche i pesci del re hanno spine – Auch die Fische des Königs haben Gräten.« Also: Lassen Sie sich auch dieses Kapitel (trotz aller theoretischer Gräten) ein königliches Vergnügen sein!
12.1 Der Visual Basic-Editor Das Fenster des Visual Basic-Editors haben Sie schon kennen gelernt. Dies ist die VBA-Entwicklungsumgebung, in der Sie Ihren VBA-Code entwickeln. Bild 12.1: Die VBA-Entwicklungsumgebung mit allem Drum und Dran
150
Kapitel 12: VBA Grundlagenwissen
Im Fenster des Visual Basic-Editors sind standardmäßig drei Unterfenster zu sehen: Tabelle 12.1: Standardfenster des Visual Basic-Editors
Element
Beschreibung
Code-Fenster
Hier erstellen Sie Ihr Programm.
Projekt-Explorer
Hier sind alle Teile des aktuellen Programmierobjekts aufgelistet, also Module sowie Code für Formulare und Berichte.
Eigenschaften-Fenster
Hier werden die Eigenschaften des Objekts angezeigt, für das Sie gerade Code erfassen.
Über das Menü ANSICHT können bei Bedarf aufgerufen werden:
Tabelle 12.2: Weitere Fenster über das Menü ANSICHT
Element
Beschreibung
Direktfenster
Hier können Sie Befehle eingeben und direkt ausführen lassen, z.B. um das Programm zu testen.
Lokal-Fenster
Hier lassen sich Inhalte von Variablen einsehen.
Überwachungsfenster
Hier können Sie bestimmte Variablen überwachen.
Alle sechs Fenster lassen sich in Anordnung und Größe verändern oder schließen und über das Menü ANSICHT ein- und ausblenden. Zusätzlich lässt sich noch der Objektkatalog anzeigen, auf den ich in Kapitel 16 eingehe. Wie Sie im letzten Kapitel gemerkt haben, werden Sie zunächst vor allem mit dem Code-Fenster zu tun haben, in dem der Programmcode eingetragen wird.
Ansicht des Code-Fensters Links unten im Code-Fenster finden Sie die beiden kleinen Schaltflächen mit den Bezeichnungen PROZEDURANSICHT und VOLLSTÄNDIGE MODULANSICHT, mit denen Sie zwischen den gleichnamigen Ansichten wechseln können. In der Prozeduransicht wird im Code-Fenster jeweils nur eine einzelne Prozedur angezeigt. Mit der Tastenkombination 圳+䝣 wechseln Sie zur vorigen bzw. mit 圳+䝤 zur folgenden Prozedur.
12.1 Der Visual Basic-Editor
151
12.2 Programmieren in Access Im Prinzip ist ein Programm nichts anderes als eine Sammlung von Befehlen, die so angeordnet sind, dass sich mit ihnen eine bestimmte Aufgabe lösen lässt. Beim Programmieren mit VBA wird die vom Programm zu erledigende Aufgabe in einzelne Teilaufgaben zerlegt. Zur Lösung einer Teilaufgabe werden einige Befehle zu einer so genannten Prozedur zusammengefasst. Im Programmablauf werden die einzelnen Teilaufgaben dann von den jeweiligen Prozeduren abgearbeitet. Im Zusammenspiel der einzelnen Prozeduren wird damit letztlich die Gesamtaufgabe gelöst.
12.2.1
Was wird programmiert?
Ähnlich wie bei Makros ist es auch möglich, VBA-Code entweder direkt an ein Formular- oder Berichtsereignis zu binden oder auch unabhängig von Formularen und Berichten aufzurufen.
Code behind Forms Im letzten Kapitel haben Sie sich vor allem mit direkt einem Formular zugeordnetem Code beschäftigt (man spricht hier auch von code behind forms). Wie Sie vielleicht schon gemerkt haben, können Sie diesen VBA-Code nicht direkt über das Access-Datenbankfenster aufrufen. Hier besteht also ein Unterschied zu Makros, denn diese konnten auch dann direkt im Datenbankfenster gestartet werden, wenn sie an ein Formular gebunden waren.
Eigenständige Module Lediglich das im letzten Kapitel vom Makro konvertierte Modul ist als eigenständiges Modul im Datenbankfenster abgelegt. Zum Erstellen eines neuen eigenständigen Moduls rufen Sie einfach den Menübefehl EINFÜGEN MODUL auf, woraufhin sich der VBA-Editor öffnet. Rufen Sie im VBA-Editor den Menübefehl EINFÜGEN PROZEDUR auf und geben Sie der Prozedur den Namen ToscanaTest.
152
Kapitel 12: VBA Grundlagenwissen
Bild 12.2: Die TOSCANATESTProzedur
Nachdem Sie mit OK bestätigt haben, tragen Sie in die Prozedur Msgbox ("Ich bin ein eigenständiges Modul") ein. Speichern Sie das Modul unter der vorgeschlagenen Bezeichnung Modul1. Wenn Sie nun im Datenbankfenster auf MODUL1 klicken, wird nicht der Programmcode ausgeführt, sondern die Prozedur wird im VBA-Editor angezeigt. Um die Prozedur ausführen zu lassen, schreiben Sie ToscanaTest in das Direktfenster und drücken danach die 圸-Taste. Bild 12.3: Prozedur über Direktfenster testen
12.2 Programmieren in Access
153
Jetzt erscheint die von Ihnen in der TOSCANATEST-Prozedur definierte Messagebox auf dem Bildschirm. Noch einfacher testen Sie eine Prozedur, indem Sie den Mauszeiger irgendwo innerhalb der Prozedur positionieren und dann die 団-Taste drücken oder in der Symbolleiste auf das Symbol SUB/USER FORM AUSFÜHREN klicken.
12.2.2
Wie wird programmiert?
Eine Prozedur wird mit der Zeile Sub name() begonnen und endet mit End Sub. Sub, End, Private usw. sind spezielle Ausdrücke von Visual Basic, so genannte Schlüsselwörter. Sie werden automatisch groß geschrieben und am Bildschirm blau dargestellt.
Schlüsselwörter grundsätzlich in Kleinbuchstaben eingeben! Verlassen Sie dann eine Zeile, sollten alle Schlüsselwörter dieser Zeile automatisch in die richtige Groß-/Kleinschreibung umgesetzt werden. Geschieht dies nicht, ist das ein deutliches Zeichen dafür, dass Sie sich bei einem Schlüsselwort verschrieben haben.
Bei Prozeduren, die Sie für ein Steuerelement erstellen, wird der Name automatisch vergeben. Er besteht aus dem Namen des Steuerelements und des Ereignisses, das ausgeführt werden soll, um die Prozedur zu aktivieren, wie Private Sub cmdSchliessen_Click() für die Ereignisprozedur für einen Mausklick auf die Schaltfläche cmdSchliessen. Für Prozeduren, die nicht direkt mit einem Steuerelement verbunden sind, können Sie den Namen der Prozedur im Prinzip frei wählen. Wird ein Prozedurname aus mehreren Wörtern zusammengesetzt, sollten Sie den Wortbeginn jeweils mit einem großen Buchstaben kennzeichnen, wie ToscanaTest. Zwischen den beiden Zeilen, die den Beginn und das Ende einer Prozedur kennzeichnen, finden Sie die eigentlichen Anweisungszeilen. Dabei kann ein Programm im Prinzip aus einer einzigen Zeile oder aus hunderten von Zeilen bestehen.
154
Kapitel 12: VBA Grundlagenwissen
Einrückung der Anweisungszeilen Um ein Programm möglichst übersichtlich zu schreiben, rückt man zusammengehörende Zeilen ein. So wird beispielsweise alles, was innerhalb der Zeilen Sub name() und End Sub steht, eingerückt. Im folgenden Bild sehen Sie im Beispiel aus dem letzten Kapitel, dass auch die Anweisungszeilen, die innerhalb einer If...End If-Struktur stehen, eingerückt sind. Manchmal sagt man, dass Strukturen wie Sub...End Sub, If...End If, aber auch Schleifen, wie Sie sie noch kennen lernen werden, den dazwischen liegenden Programmcode »klammern«. Bild 12.4: Eingerückte Anweisungszeilen
Kommentarzeilen Damit Sie auch in ein paar Wochen noch verstehen können, was Sie einmal programmiert haben, ist es sinnvoll, so genannte Kommentarzeilen zwischen den Anweisungszeilen einzufügen. Manche Programmierer sagen sogar, ein gutes Programm enthält ebenso viele Kommentar- wie Anweisungszeilen. Bild 12.5: Kommentiertes Programm
Beginnen Sie die Kommentarzeile mit einem Hochkomma »'«. Sobald Sie die Zeile verlassen, wird sie grün dargestellt. Kurzkommentare können Sie auch am Ende einer Anweisungszeile schreiben, da alles nach einem Hochkomma als Kommentar angesehen wird.
12.2 Programmieren in Access
155
Zeilenfortführung Wird eine Zeile so lang, dass sie nicht mehr vernünftig im CodeFenster angezeigt wird, können Sie solche Anweisungen auf zwei oder noch mehr Zeilen aufteilen. Wichtig ist dann nur, dass Sie jede Zeile, die fortgesetzt werden soll, mit einem Leerzeichen und einem Unterstrich »_« beenden.
12.3 Variablen besser verstehen Im letzten Kapitel hatten Sie schon eine Variable definiert. Dabei hatten Sie die Variable als praktischen Zwischenspeicher kennen gelernt. Allgemein werden Variablen in Programmen eingesetzt, um Werte, Zeichenketten und anderes ablegen zu können, damit Sie später im Programm wieder darauf zugreifen können. Variablen erhalten innerhalb Ihres Programms einen Namen, über den Sie auf den Inhalt der Variablen zugreifen können. Inhalt von Variablen können Zahlen, aber auch Datumsangaben, Uhrzeiten, Texte oder Bilder sein. Variablen haben eine begrenzte Lebensdauer. In der Regel behalten sie ihren Wert höchstens so lange, bis die Prozedur beendet ist.
12.3.1
Variablendeklaration
Man sollte die Variablen, die in einem Programm verwendet werden, zu Beginn des Programms deklarieren und ihren Datentyp festlegen. Mit dem Vorgang des Deklarierens reserviert man sozusagen für die Variable Speicherplatz. Das ist zwar nicht unbedingt notwendig, hilft aber, Fehler zu verhindern. Zwei unterschiedliche Arten der Variablendeklaration sind möglich, die explizite und die implizite Deklaration. Eine explizite Deklaration erfolgt dadurch, dass Sie zu Beginn des Programms eine Variable mit Dim deklarieren. Bei einer impliziten Deklaration erfolgt die Deklaration in dem Augenblick, in dem der Variablenname das erste Mal im Programm auftaucht, ohne dass Sie etwas dazu beitragen müssen.
156
Kapitel 12: VBA Grundlagenwissen
Das klingt erst einmal nach Arbeitserleichterung, ist es aber unter Umständen gar nicht. Das Problem dabei ist nämlich, dass jede Schreibvariante einer Variablen automatisch als neue Variable angenommen wird. Falls Sie sich also versehentlich vertippen, haben Sie automatisch zwei verschiedene Variablen deklariert mit fast identischen Namen. Daher ist es empfehlenswert, auf dem Registerblatt EDITOR (EXTRAS OPTIONEN) das Kontrollkästchen VARIABLENDEKLARATION ERFORDERLICH anzuklicken. Das zwingt Sie in neuen Projekten zur expliziten Variablendeklaration. Sie können das daran erkennen, dass der Code für ein neues Projekt mit der Zeile Option Explicit beginnt (siehe z.B. Bild 12.3). Werden im Programm Variablen ohne vorherige Deklaration verwendet, wird der Variablenname nicht erkannt und Sie erhalten sofort eine Fehlermeldung. Dadurch lassen sich sehr leicht Tippfehler vermeiden.
Variablen richtig benennen Variablen sollen so benannt werden, dass ihr Name möglichst kurz und prägnant sowie leicht zu behalten ist. Zudem muss ein Variablenname mit einem Buchstaben beginnen, darf maximal 256 Zeichen lang sein und außer dem »_« keine Sonderzeichen enthalten. Wird ein Variablenname aus mehreren Wörtern zusammengesetzt, so sollte jedes Wort gemäß der schon vorgestellten Namenskonvention groß geschrieben werden. Der Name lässt sich so leichter lesen, wie EuroBetrag oder AppartementAnzahl.
Verwenden Sie keine Visual Basic-Schlüsselwörter! Achten Sie strikt darauf, dass Sie keine Schlüsselwörter, Objektoder Eigenschaftennamen als Namen für Ihre Variable verwenden.
12.3 Variablen besser verstehen
157
12.3.2
Datentypen für Variablen
Außer den Speicherplatz durch die Deklaration zu reservieren, ist es auch sinnvoll, von vornherein festzulegen, um was für einen Datentyp es sich bei der Variablen handelt – ist es ein Text, eine Zahl, ein Datums- oder ein Wahrheitswert? Soll beispielsweise ein Text – wie »Franzis« – im Programm in einer Variablen abgelegt werden, so können Sie diese Variable durch Dim Verlag As String
deklarieren. Mit dem Zusatz As String wird für die Variable der Datentyp »String«, Zeichenkette, festgelegt. Sie können dann mit Verlag = "Franzis"
den Text in den Anführungszeichen der Variablen zuweisen. Die folgende Tabelle zeigt die wichtigsten Datentypen für Variablen in Access.
Tabelle 12.3: Datentypen in Visual Basic
Datentyp
Art
Wertebereich
Byte
Ganze Zahlen
0 ... 255
Integer
Ganze Zahlen
-32.768 ... 32.767
Long
Ganze Zahlen
-2.147.483.648 ... 2.147.483.647
Single
Dezimalzahlen
Zahlen mit insgesamt 8 Stellen
Double
Dezimalzahlen
Zahlen mit insgesamt 16 Stellen
Currency
Dezimalzahlen für Währung
15 Vor- und 4 Dezimalstellen
Boolean
Wahrheitswerte
TRUE oder FALSE
Date
Datums-Zeit-Werte
1.1.100 bis 31.12.9999
String
Texte
kann 2 Milliarden Zeichen enthalten
Variant
kann beliebigen Datentyp enthalten (s.u.)
Die Datentypen, die Sie in der Tabelle finden, sind nicht alle gleich wichtig. So verwendet man für ganze Zahlen, also Zahlen ohne Nachkommastellen, in der Regel den Datentyp Integer. Nur dann, wenn ganz sicher ist, dass die Zahlen immer kleiner als 255 sind,
158
Kapitel 12: VBA Grundlagenwissen
würde man den Datentyp Byte verwenden, da dieser Datentyp sehr viel weniger Speicherplatz benötigt. Und nur dann, wenn Zahlen größer als 32.000 sind, wird der Datentyp Long verwendet. Möchten Sie Zahlen mit Nachkommastellen verwenden, werden diese Zahlen normalerweise als Double deklariert. Geben Sie nicht explizit den gewünschten Datentyp an, wird eine Variable als Variant gespeichert. Eine Variable vom Datentyp Variant kann alles sein, ein Text, eine Zahl, ein Datum etc. Dieser Datentyp hat aber den Nachteil, dass er sehr viel mehr Speicherplatz benötigt als beispielsweise eine als Datum oder als Zahl deklarierte Variable. Zudem hilft auch das Festlegen des korrekten Datentyps Fehler zu vermeiden. Wird nämlich einer Variablen, die beispielsweise als Zahl festgelegt wurde, ein Text zugewiesen, erhalten Sie eine Fehlermeldung.
Dim-Anweisungen platzsparend Bei Bedarf können Sie auch mehrere Dim-Anweisungen durch Komma getrennt in eine Zeile schreiben, wie Dim strName As String, strKurs As String, dblBeitrag As Double
Dabei ist allerdings darauf zu achten, dass man nicht versucht, zu viel Schreibarbeit zu sparen. Die Anweisung Dim strName, strKurs As String, dblBeitrag As Double
nämlich würde strName als Variant deklarieren. Zudem ist es sinnvoll, sich bei Variablennamen an die Namenskonventionen zu halten und den Datentyp einer Variablen durch eine Buchstabenkombination zu Beginn zu kennzeichnen. Die zu entsprechenden Abkürzungen finden Sie in folgender Tabelle.
Datentyp
Kürzel
Beispiel
Byte
byt
Dim bytStatus As Byte
Integer
int
Dim intZähler As Integer
Long
lng
Dim lngEinwohner As Long
Single
sng
Dim sngKurs As Single
12.3 Variablen besser verstehen
Tabelle 12.4: Kürzel für Variablen entsprechend der Namenskonvention
159
Tabelle 12.4 (Forts.): Kürzel für Variablen entsprechend der Namenskonvention
Datentyp
Kürzel
Beispiel
Double
dbl
Dim dblBetrag As Double
Currency
cur
Dim curDMBetrag As Currency
Boolean
f
Dim fMitglied As Boolean
Date
dat
Dim datGeburtsdatum As Date
String
str
Dim strName As String
Variant
var
Dim varDiverses As Variant
Beispiel: Euro-Umrechnung mit Variablen Im folgenden Beispiel geht es um die Euro-Umrechnung. Dazu wurde das Formular frmEuroUmrechnung erstellt. Sowohl die Zahleneingabe als auch die Ergebnisanzeige erfolgen im Textfeld TXTBETRAG, dem das Format STANDARDZAHL MIT ZWEI DEZIMALSTELLEN zugewiesen wurde. Die Optionsgruppe FRAEURODM gibt an, ob von DM in Euro oder umgekehrt gerechnet werden soll (das Präfix FRA der Optionsgruppe steht für frame, also Rahmen). Bild 12.6: Euro-Umrechnung
Das folgende Programm wurde an das BEIM KLICKEN-Ereignis der Befehlsschaltfläche CMDUMRECHNEN gebunden. Die Umrechnung wird mithilfe der beiden Variablen dblBetrag und dblKurs ausgeführt. Private Sub cmdUmrechnen_Click() Dim dblKurs As Double, dblBetrag As Double If IsNull(txtBetrag) Then txtBetrag = 0 End If
160
Kapitel 12: VBA Grundlagenwissen
dblBetrag = txtBetrag dblKurs = 1.95583 If fraEuroDM = 1 Then dblBetrag = dblBetrag / dblKurs Else dblBetrag = dblBetrag * dblKurs End If txtBetrag = Format(dblBetrag, "#,##0.00") End Sub
Im Programm wurden die Variablen als Double deklariert. Das ist nicht unbedingt nötig gewesen, gerade der Kurswert mit seinen sechs Stellen hätte genauso gut als Single vereinbart werden können. Aber in der Regel ist der Speicherplatz heutzutage nicht mehr so knapp, dass man bei der Deklaration das Letzte herausholen muss. Bevor den beiden Variablen die Werte übergeben werden, wird festgelegt, dass das Textfeld den Wert 0 annimmt, wenn nichts eingetragen ist. Dies ist erforderlich, damit der Variablen DBLBETRAG nicht der Wert Null zugeordnet werden kann, was einen Fehler verursachen würde. Der Variablen dblKurs wird dann der Umrechnungskurs von 1,95583 (in der amerikanischen Schreibweise mit ».« anstelle dem Dezimalkomma) zugewiesen. Der Variablen dblBetrag wird der Inhalt des Textfeldes zugeordnet. Je nach der Eingabe in das Textfeld ist der Wert der Variablen dblBetrag unterschiedlich groß. Danach gibt es für die Umrechnung zwei Möglichkeiten: Entweder ist für die Umrechnung von DM in Euro das Optionsfeld OPTDMEURO angeklickt, dann nimmt die Optionsgruppe FRAEURODM den Wert 1 an, oder es soll von Euro in DM umgerechnet werden, das Optionsfeld OPTEURODM ist angeklickt und FRAEURODM hat den Wert 2. Zuletzt erfolgt hinter der If...End If-Konstruktion die Formatierung des errechneten Wertes als Zahl mit zwei Nachkommastellen und einem Tausenderpunkt (auch hier die Formatanweisung wieder in amerikanischer Schreibweise).
12.3 Variablen besser verstehen
161
Mathematik gegen Informatik Ist Ihnen in obigem Beispiel die Zeile dblBetrag = dblBetrag * dblKurs
aufgefallen? Hier steht links und rechts des Gleichheitszeichens dblBetrag. Betrachten wir diese Formel mathematisch, so kann die Gleichung nach dblKurs aufgelöst werden und dblKurs = 1. Das ist natürlich Blödsinn, denn wir betrachten das Ganze mit den Augen der Informatik. Hier wird die Zeile wie folgt gelesen: Nimm den Wert, der im Speicher des Computers an der Stelle mit dem Namen dblBetrag steht, multipliziere ihn mit dblKurs und schreibe das Ergebnis wieder an den Speicherplatz dblBetrag.
Formatieren von Zahlen Die Format-Funktion, die bereits mehrfach verwendet wurde, regelt die Darstellung von Zahlen. Die Formatierungsanweisung für Zahlen wird durch einen optionalen (#) und einen Mussplatzhalter (0) geregelt. Möchten Sie beispielsweise vier Nachkommastellen erzwingen, können Sie dies mit der Formatanweisung "0.0000" tun. Soll eine Zahl ohne Nachkommastellen, aber mit Tausenderpunkt formatiert werden, verwenden Sie "#,##0". Hierbei werden optionale Platzhalter verwendet, weil mit diesem Format nur Zahlen versehen werden sollen, die auch wirklich größer als 1.000 sind. Bei der Formatierung von Zahlen sind zwei Dinge zu beachten: Zum einen ist immer die amerikanische Schreibweise (also mit vertauschtem Punkt und Komma) zu verwenden (was man leicht vergisst), zum anderen wird durch die Format-Funktion aus der Zahl eine Zeichenkette, also ein String.
Der Datentyp Boolean Wahrheitswerte (False und True) werden mithilfe von Variablen des Typs Boolean verwaltet. In den folgenden Fragmenten einer
162
Kapitel 12: VBA Grundlagenwissen
Prozedur wurde das Ergebnis der Checkbox (einem Kontrollkästchen) einer Variablen vom Typ Boolean zugewiesen. Im Programm wird die Variable fDMEuro deklariert, der dann der Inhalt des Kontrollkästchens chkDMEuro zugewiesen wird. Dabei wird der Wert 1, den das Kontrollkästchen zurückgibt, wenn es aktiviert wurde, automatisch in True umgewandelt. Der Wert 0 wird zu False. Daher lautet die Abfrage If fDMEuro = True Then. Private Sub cmdUmrechnen_Click() ... Dim fDMEuro As Boolean ... fDMEuro = chkDMEuro If fDMEuro = True Then ... Else ... End If ... End Sub
Wahrheitswerte in If-Abfragen Verwenden Sie einen Wahrheitswert in einer If-Abfrage, können Sie auch kürzer If fDMEuro Then schreiben. Diese Bedingung ist dann erfüllt, wenn fDMEuro True ist.
Angenommen, Sie möchten dem Wahrheitswert fFall den Wert True dann zuordnen, wenn eine bestimmte Bedingung, wie intAuswahl=4, erfüllt ist. So könnten Sie If intAuswahl = 4 Then fFall = True
schreiben oder kürzer fFall=(intAuswahl=4)
12.3 Variablen besser verstehen
163
Dabei wird zunächst die Klammer ausgewertet. Ist intAuswahl=4, wird fFall True zugeordnet; ergibt die Auswertung der Klammer, dass die Gleichung nicht erfüllt ist, wird fFall auf den Wert False gesetzt.
Der Datentyp Date Datumswerte können das Zeitintervall vom 1. Januar 100 bis zum 31. Dezember 9999 abdecken. Uhrzeiten werden von 00:00:00 bis 23:59:59 dargestellt. Möchten Sie der Variablen datEintrittsdatum vom Typ Date ein bestimmtes Datum zuweisen, so muss dieses Datum in »#« eingeschlossen werden. Sie können dabei ein Datum nicht so eingeben, wie Sie es gewohnt sind. Bei der Eingabe eines Datumswertes in Ihrem Programm ist eine der folgenden Schreibweisen zu verwenden: datEintrittsdatum datEintrittsdatum datEintrittsdatum datEintrittsdatum
= = = =
#1 2 02# #1 February 02# #1 Feb 02# #1,2,02#
Alternativ können Sie auch vierstellige Jahreszahlen verwenden. Sowie Sie diese Zeile verlassen, wird die Zeile automatisch in die amerikanische Schreibweise umgewandelt: datEintrittsdatum = #2/1/02# bzw. datEintrittsdatum = #2/1/2002#
Achten Sie dabei darauf, dass die Reihenfolge des Tages und des Monats vertauscht wird. In der amerikanischen Schreibweise wird erst der Monat, dann der Tag genannt.
164
Kapitel 12: VBA Grundlagenwissen
Die Anzeige eines Datums erfolgt standardmäßig in der in der Ländereinstellung gewählten kurzen Datumsform. Möchten Sie eine andere Formatierung für Ihr Datum verwenden, benutzen Sie die Format-Funktion, so wie Sie es im letzten Kapitel für die Formatierung des im Formular angezeigten Datums gemacht haben. Dabei sind dann wieder die amerikanischen Abkürzungen zu verwenden: yyyy für Jahr q für Quartal (1 bis 4) m für Monat (1 bis 12) d für Monatstag (1 bis 31) y für Kalendertag (1 bis 366) w für Wochentag (1 bis 7) ww für Kalenderwoche (1 bis 53) Setzen Sie so beispielsweise "dddd, dd.mmmm yyyy" für ein langes Datum in der Form Mittwoch, 08.August 2001 zusammen.
Möchten Sie Uhrzeiten verwenden, sind diese ebenso in »#« einzuschließen. Dabei kann allerdings die gewohnte Schreibweise wie datZeit = #7:00# oder datZeit = #19:00# verwendet werden. Die Uhrzeiten werden dann in datZeit = #7:00:00 AM# bzw. datZeit = #7:00:00 PM# umgesetzt. Die Ausgabe entspricht dem in der Ländereinstellung ausgewählten Uhrzeitformat.
Anzeige der Uhrzeiten Standardmäßig wird zur Darstellung von Uhrzeiten die in der Ländereinstellung dargestellte Form »hh:mm:ss« verwendet. Um eine Uhrzeit anders zu formatieren, müssen Sie in der Format-Funktion die Zeichen h für Stunde, n für Minute und s für Sekunde verwenden. Möchten Sie also eine Zeit ohne Sekunden angeben, verwenden Sie "hh:nn". (Verwenden Sie lieber n zur Formatierung von Minuten, um Verwechslungen mit der Formatierung von Monaten zu vermeiden.)
12.3 Variablen besser verstehen
165
Der Datentyp String Variablen, die Texte enthalten sollen, sollten mit dem Datentyp String deklariert werden. Zur Übergabe eines Textes an eine Variable wird der Text in »"« eingeschlossen.
Leerer String Ein leerer String – eine Zeichenkette, die kein Zeichen enthält – wird einfach durch »""« dargestellt.
Im folgenden Beispiel wird beim Öffnen des Formulars frmStringVerarbeitung der Inhalt zweier Strings, die einen Nachnamen und einen Vornamen enthalten, zu einem Gesamtnamen zusammengesetzt. Schließlich werden die Variablen an Textfelder übergeben und die entsprechenden Namen darin dargestellt. Private Dim Dim Dim
Sub Form_Load() strVorname As String strNachname As String strZusammengesetzterName As String
strVorname = "Carla Louise" strNachname = "Klein" strZusammengesetzterName = strNachname & ", " & _ strVorname txtVorname = strVorname txtNachname = strNachname txtZusammengesetzterName = strZusammengesetzterName End Sub
Bild 12.7: Beim Öffnen des Formulars wurde zusammengefügt
166
Kapitel 12: VBA Grundlagenwissen
12.3.3
Konstanten
Im Prinzip sind Konstanten ein Sonderfall von Variablen. Konstanten wie Const conPi = 3.14159265 Const conEuro = 1.95583 Const conAnzahl As Integer = 20
ändern sich während der Laufzeit eines Programms nicht. Konstanten erhalten zur Kennzeichnung die Vorsilbe »con«. Warum sollten Sie Konstanten verwenden? Stellen Sie sich vor, Sie verwenden in Ihrem Programm an 20 verschiedenen Stellen die Zahl 11 für die Anzahl der zu Beginn am Euro teilnehmenden Nationen. Nun kommen im Laufe der Zeit neue Länder hinzu. Sie müssten jetzt an allen entsprechenden Stellen die 11 beispielsweise gegen eine 16 austauschen, wenn jetzt 16 Länder den Euro eingeführt hätten. Diese Ersetzung darf natürlich nur an den richtigen Positionen vorgenommen werden, Sie sollten keine 11 ersetzen, die gar nicht die Anzahl der Euro-Länder beschreibt. Der Aufwand für eine solche Änderung lässt sich vereinfachen, indem Sie Konstanten verwenden. Definieren Sie Const conEuroLänder = 11
und nutzen Sie diese Konstante anstelle der 11 in Ihrem Programm, so müssen Sie bei der Euro-Erweiterung auf 16 Länder Ihr Programm nur an einer Stelle ändern, nämlich nur die Definition der Konstante.
12.3.4
Felder
Ähnliche Werte werden üblicherweise in Feldern – auch Arrays genannt – zusammengefasst. Alle Werte eines Feldes können dann mit demselben Namen, aber über ihre Position im Feld – als Index bezeichnet – angesprochen werden. Bei der Deklaration eines Feldes legt man gleich seine Größe fest. So steht beispielsweise die Zeile Dim adblMwSt(2) As Double
12.3 Variablen besser verstehen
167
für ein Feld mit drei Komponenten. Felder beginnen bei 0 zu zählen, damit sind für adblMwSt drei Elemente erlaubt, nämlich adblMwSt(0), adblMwSt(1) und adblMwSt(2). Um im Variablennamen zu kennzeichnen, dass es sich um ein Feld handelt, wird dem Typkürzel ein »a« vorangestellt, das für die englische Bezeichnung array für ein Feld steht. Die Zuweisung zu den einzelnen Werten eines Feldes erfolgt mithilfe der Indizes. Angenommen, Sie arbeiten mit den drei Mehrwertsteuersätzen 0%, 7% und 16%, dann schreiben Sie: adblMwSt(0) = 0 adblMwSt(1) = 0.07 adblMwSt(2) = 0.16
Beispiel: MwSt-Berechnung mit Feldern Im Formular frmMwSt habe ich die Optionsgruppe FRAMWST eingefügt, die Werte zwischen 0 und 2 annehmen kann, je nachdem, welches Optionsfeld angeklickt wurde. Daneben gibt es noch die Textfelder TXTNETTO für die Eingabe des Nettowertes und TXTBRUTTO für die Ausgabe des berechneten Bruttowertes. Beiden habe ich das Format Währung gegeben. Ein Klick auf die Schaltfläche CMDBERECHNEN startet die Berechnung für den gewählten Mehrwertsteuersatz. Dazu habe ich die folgende Prozedur an das BEIM KLICKEN-Ereignis der Schaltfläche gebunden: Private Sub cmdBerechnen_Click() Dim dblBrutto As Double, dblNetto As Double Dim intIndex As Integer Dim adblMwSt(2) As Double ' MwSt-Werte zuordnen adblMwSt(0) = 0 adblMwSt(1) = 0.07 adblMwSt(2) = 0.16 ' Sicherstellen, dass nicht Null übergeben wird If IsNull(txtNetto) Then txtNetto = 0 End If intIndex = fraMwSt
168
Kapitel 12: VBA Grundlagenwissen
dblNetto = txtNetto dblBrutto = dblNetto * adblMwSt(intIndex) + dblNetto txtBrutto = dblBrutto End Sub
Die Array-Funktion Zum Füllen von Feldern können Sie auch die Array-Funktion verwenden. Der Vorteil besteht darin, dass die Werte einer ArrayFunktion in Form einer Liste zugeordnet werden, was Schreibarbeit spart. Die Werte eine Array-Feldes sind immer vom Datentyp Variant. Ein Array-Feld müssen Sie deklarieren, es braucht aber nicht dimensioniert werden. So wäre beispielsweise Dim avarMwSt As Variant
ausreichend. Um das Feld mit Werten zu füllen, schreiben Sie avarMwSt = Array(0, 0.07, 0.16)
Die einzelnen Werte der Liste werden dabei durch Kommata voneinander getrennt.
12.4 Gültigkeit von Variablen In diesem Abschnitt soll die Frage »Wie lange lebt eine Variable?« geklärt werden.
12.4.1
Gültigkeit auf Prozedurebene
Werden Variablen innerhalb einer Prozedur deklariert, sind sie nur innerhalb dieser Prozedur bekannt; man sagt, sie gelten auf Prozedurebene. Man bezeichnet solche Variablen auch als lokale Variablen. In einer anderen Prozedur ist die entsprechende Variable unbekannt, dort muss sie neu deklariert werden. Allerdings ist es dabei
12.4 Gültigkeit von Variablen
169
nicht möglich, auf den Wert einer Variablen von einer anderen Prozedur her zuzugreifen.
12.4.2
Gültigkeit auf privater Modulebene
Benötigen Sie Variablen nicht nur in einer Prozedur, sondern müssen mehrere Prozeduren auf dieselbe Variable zugreifen, muss eine solche Variable auf Modulebene deklariert werden. Sie gilt dann in allen Prozeduren eines Formulars. Solche Variablen werden direkt unter der Zeile Option Explicit vor den eigentlichen Prozeduren mit dem Zusatz Private anstelle von Dim deklariert. (Es ist auch möglich, zur Deklaration einer Variablen auf privater Modulebene Dim zu verwenden, allerdings macht die Verwendung von Private die Gültigkeitsebene deutlicher und ist daher vorzuziehen.) Bild 12.8: Modulweite Deklaration
Zur Kennzeichnung der modulweiten Gültigkeit sollten Sie ein »m« vor das eigentliche Typkürzel stellen.
12.4.3
Gültigkeit auf öffentlicher Modulebene
Soll eine Variable nicht nur innerhalb eines Moduls gelten, sondern in einer gesamten Anwendung, wird sie auf öffentlicher Modulebene deklariert. Sie können sowohl aus Formularen oder Berichten als auch anderen Modulen darauf zugreifen. Öffentliche Variablen werden im Deklarationsbereich eines Moduls mit Public deklariert und erhalten zur Kennzeichnung den Buchstaben »g« für global. Sie werden auch als globale Variablen bezeichnet.
12.4.4
Variablen mit gleichem Namen
Was geschieht, wenn eine Variable mit gleichem Namen, die auf Prozedurebene – also lokal – in zwei unterschiedlichen Prozeduren deklariert wurde, verwendet wird? Das ist in diesem Fall kein Pro-
170
Kapitel 12: VBA Grundlagenwissen
blem, da eine lokale Variable nur innerhalb der Prozedur, in der sie deklariert wurde, bekannt ist. Wird eine zweite Prozedur aufgerufen und eine Variable mit demselben Namen verwendet, so weiß diese nichts von der anderen Variablen. Entsprechend ist der Wert der Variablen – falls ihr in der zweiten Prozedur nicht explizit ein Wert zugewiesen wird – gleich Null. Was geschieht, wenn eine Variable mit gleichem Namen, zum einen auf Modulebene, zum anderen lokal auf Prozedurebene deklariert wird? (Verwenden Sie für modulweite Variablen die Kennzeichnung »m«, kann das eigentlich gar nicht passieren.) In einem solchen Fall gilt innerhalb der Prozedur, in der die lokale Variable deklariert ist, nur diese. Die modulweit deklarierte Variable wird ignoriert. Das bedeutet für den Wert der lokalen Variablen, dass sie unabhängig vom Wert der modulweiten Variablen gleich Null ist, bis ihr in der Prozedur ein Wert zugewiesen wird.
12.5 Operatoren Möchten Sie beim Programmieren Formeln verwenden, so müssen Sie natürlich auch die Operatoren kennen lernen, die in den Formeln eingesetzt werden können. Einige der Operatoren des folgenden Überblicks haben Sie bei Ihrer Arbeit mit Access schon kennen gelernt, wie »+«, »/« und »*«.
12.5.1
Welche Operatoren gibt es?
Grob kann man die Operatoren in arithmetische (oder mathematische), logische, Vergleichs- und Verkettungsoperatoren unterscheiden.
Arithmetische Operatoren Die folgende Tabelle zeigt eine Zusammenfassung der arithmetischen Operatoren, die zu Berechnungen benötigt werden.
12.5 Operatoren
171
Tabelle 12.5: Arithmetische Operatoren
Operator
Operation
+
Addition
-
Subtraktion
*
Multiplikation
/
Division
\
führt eine ganzzahlige Division durch. Dabei wird das Ergebnis nicht gerundet, sondern die Nachkommastellen einfach abgeschnitten, so dass beispielsweise 29\5 den Wert 5 ergibt.
^
Potenzierung
Mod
führt eine ganzzahlige Division durch. Dieser Operator gibt dann den ganzzahligen Rest zurück, so dass beispielsweise 29 Mod 5 den Wert 4 ergibt.
Vergleichsoperatoren Mithilfe von Vergleichsoperatoren werden Werte oder Ausdrücke miteinander verglichen, wie intAnzahl < 100. Vergleichsoperatoren benötigen Sie in If-Abfragen oder Select Case-Anweisungen (siehe Abschnitt 12.6).
Tabelle 12.6: Vergleichsoperatoren
Operator
Operation
=
überprüft auf Gleichheit
<, >
kleiner als bzw. größer als
<=, >=
kleiner oder gleich bzw. größer oder gleich
<>
ungleich
Logische Operatoren In Bedingungen können nicht nur Vergleichsoperatoren, sondern auch logische Operatoren verwendet werden, wie Sie sie in der folgenden Tabelle sehen.
172
Kapitel 12: VBA Grundlagenwissen
Tabelle 12.7: Logische Operatoren
Operator
Beispiel
Bedeutung
And
IntAnzahl > 10 And intAnzahl < 90
intAnzahl soll größer 10 und kleiner 90 sein, also zwischen 10 und 90 liegen.
Or
IntAnzahl < 10 Or intAnzahl > 20
intAnzahl soll entweder kleiner als 10 oder größer als 20 sein.
Not
Not (intAnzahl < 10)
intAnzahl soll nicht kleiner als 10 sein, also soll intAnzahl größer oder gleich 10 sein.
Zwei mit Or verbundene Bedingungen sind dann erfüllt, wenn eine der beiden erfüllt ist. Im Unterschied dazu ist eine mit And verbundene Bedingung nur dann erfüllt, wenn beide Bedingungen wahr sind. Es besteht zudem die Möglichkeit, mehrere logische Operatoren zusammen in einer Bedingung zu verwenden, wie in Not (intAnzahl < 10) And Not (intAnzahl > 90)
Da es nicht immer ganz einfach ist festzulegen, wie welcher Operator arbeitet, soll die folgende Tabelle mit einer Zusammenfassung des Zusammenspiels der einzelnen Operatoren helfen. Dabei bedeutet die Bedingung True, dass die angegebene Bedingung erfüllt ist. Ist das Ergebnis gleich True, heißt das, dass die Verkettung der beiden Bedingungen als wahr angegeben wird.
Bedingung1
Operator
Bedingung 2
Ergebnis
True
And
True
True
True
And
False
False
False
And
True
False
False
And
False
True
True
Or
True
True
True
Or
False
True
False
Or
True
True
False
Or
False
False
Not
True
False
Not
False
True
12.5 Operatoren
Tabelle 12.8: Zusammenspiel der logischen Operatoren
173
Verkettungsoperatoren Es gibt zwei Verkettungsoperatoren: »+« und »&«. Mit dem »+«-Operator werden allgemein Ausdrücke und Werte miteinander verkettet, wie intAnzahl + intZuwachs. Es handelt sich hierbei um den Additionsoperator. Der Operator »&« hingegen verkettet Zeichenfolgen, wie strGanzerName = strVorname & strName
oder strWohnort = "85586 " & "Poing"
12.5.2
Reihenfolge der Auswertung von Operatoren
Operatoren untereinander sind nicht gleichwertig. Beispielsweise wird im Ausdruck dblTeilSumme1 + dblTeilSumme2 / dblKurs zuerst die Division und erst dann die Summe ausgewertet. Ganz allgemein werden zuerst die arithmetischen Operatoren bzw. die Verknüpfungsoperatoren für Zeichenketten ausgewertet, dann die Vergleichsoperatoren und zum Schluss die logischen. Befinden sich in einem Ausdruck mehrere gleichwertige Operatoren, so werden sie von links nach rechts berücksichtigt. Die folgende Tabelle zeigt die Reihenfolge der arithmetischen Operatoren untereinander.
Tabelle 12.9: Reihenfolge der arithmetischen Operatoren
174
^
Potenzierung
-
Negation
* bzw. /
Multiplikation bzw. Division
\
Ganzzahldivision
Mod
Restwert
+ bzw. -
Addition bzw. Subtraktion
Kapitel 12: VBA Grundlagenwissen
Die Vergleichsoperatoren sind untereinander alle gleichwertig. Für die logischen Operatoren gilt die folgende Reihenfolge:
Not And
Tabelle 12.10: Reihenfolge der logischen Operatoren
Or
Wünschen Sie eine andere Reihenfolge der Auswertung? Dann verwenden Sie Klammern! Soll in obigem Beispiel zuerst die Summe der Teilsummen berechnet werden und dann die Division, können Sie (dblTeilSumme1 + dblTeilSumme2) / dblKurs schreiben.
12.6 Bedingte Abfragen und Verzweigungen Mithilfe von Abfragen können Sie in Ihrem Programm erreichen, dass nur bestimmte Teile ausgeführt werden. Dazu lassen sich Bedingungen angeben, die regeln, welche Teile in einem Durchlauf ausgeführt werden und welche nicht. Hierzu die beiden wichtigsten Strukturen sind If-Abfragen und Select Case-Anweisungen.
12.6.1
If-Abfragen
Mithilfe einer If-Abfrage lassen Sie einen bestimmten Teil Ihres Programms nur dann ablaufen, wenn die angegebene Bedingung erfüllt ist. Die einfachste Form einer If-Abfrage lautet If Bedingung Then Anweisung
12.6 Bedingte Abfragen und Verzweigungen
175
Eine solche einzeilige If-Anweisung besteht aus den Schlüsselwörtern If und Then. Dazwischen wird eine Bedingung angegeben. Für die Bedingung stehen Ihnen die im vorherigen Abschnitt besprochenen Operatoren zur Verfügung. Ist die Bedingung erfüllt, wird die Anweisung ausgeführt, die hinter dem Schlüsselwort Then aufgeführt ist, sonst nicht. Beispielsweise könnten Sie eine solche Bedingung dann verwenden, wenn If intVerkaufteExemplare > 10000 Then dblRabatt = 0.03
Mehr Flexibilität erhält man mit mehrzeiligen, geschachtelten Abfragen: If Bedingung Then [Anweisungen] [ElseIf Bedingung 1 Then [SonstWennAnweisungen]] [ElseIf Bedingung 2 Then [SonstWennAnweisungen]] [ElseIf Bedingung 3 Then [SonstWennAnweisungen]] ... [Else [SonstAnweisungen]] End If
Bei dieser Schreibweise werden die Teile in eckige Klammern geschrieben, die nicht unbedingt notwendig, also optional sind. So kann eine solche Anweisung nur aus If Bedingung Then Anweisungen End If
aber auch nur aus If Bedingung Then Anweisungen Else SonstAnweisungen End If
bestehen, da die Else- und ElseIf-Abschnitte beide optional sind. Sie können in einem If-Block beliebig viele ElseIf-Abschnitte
176
Kapitel 12: VBA Grundlagenwissen
verwenden. Allerdings darf sich hinter einer Else-Zeile keine ElseIf-Anweisung mehr befinden. Bei der Programmausführung wird ein If-Block von oben nach unten abgearbeitet. Zunächst wird die Bedingung hinter dem If überprüft. Ist sie erfüllt, ergibt sie also den Wert True, werden die nachfolgenden Anweisungen ausgeführt. Danach wird das Programm mit der Anweisung End If fortgeführt. Falls das nicht der Fall ist, werden nacheinander alle ElseIf-Bedingungen – sofern es welche gibt – geprüft. Ist keine der Bedingungen True gewesen, wird zum Schluss die Else-Anweisung ausgeführt.
Einrückungen Bei If-Anweisungen ist es sehr hilfreich, mit Einrückungen zu arbeiten. So lässt sich beispielsweise ein vergessenes End If relativ schnell finden.
Bei If-Anweisungen besteht auch die Möglichkeit, mehrere If-Abfragen ineinander zu schachteln.
Beispiel: Rabatt bei langer Buchungsdauer Je nachdem, wie lange die Casa-Maria-Appartements gebucht werden, soll ein unterschiedlich großer Rabatt angeboten werden. Ab 29 Tagen werden 8%, zwischen 15 und 28 Tagen 4% und zwischen 10 und 14 Tagen nur noch 2% Rabatt angeboten. Dazu habe ich das Formular frmRabattrechner erstellt. Hier werden Anreise- und Abreisedatum eingetragen sowie der Tagespreis des Appartements. Nach Klick auf die Schaltfläche CMDBERECHNEN werden dann im unteren Teil der Gesamtbetrag, der Rabattbetrag und der ermäßigte Betrag ausgegeben.
12.6 Bedingte Abfragen und Verzweigungen
177
Bild 12.9: Berechnen, was unterm Strich rauskommt
In der zugehörigen Prozedur gibt es eine Reihe von If-Abfragen. Die Gültigkeitsabfragen am Anfang werden jeweils mit einer Meldung und Exit sub beendet, wodurch der Programmablauf unterbrochen wird. Sind die Angaben im oberen Teil des Formulars richtig gemacht, folgt im Programmablauf nach der Berechnung der Anzahl der Tage die eigentliche Definition der Rabattstaffel. Am Ende werden dann die berechneten Werte in die Textfelder TXTBETRAG, TXTRABATT bzw. TXTBETRAGERMÄSSIGT geschrieben. Außerdem wird die Höhe des Rabatts in das Bezeichnungsfeld LBLRABATT eingetragen. Option Compare Database Option Explicit Private Sub cmbBerechnen_Click() Dim dblAnzahl As Double Dim dblRabatt As Double, dblBetrag As Double ' Keine Null-Werte zulassen - Einträge erzwingen If IsNull(txtTagespreis) Then MsgBox ("Bitte Tagespreis eintragen") Exit Sub ' Prozedur verlassen End If If IsNull(txtAbreise) Or IsNull(txtAnreise) Then MsgBox ("Bitte Anreise und Abreise eintragen") Exit Sub End If ' Anreise vor Abreise überprüfen, ' da dblAnzahl sonst negativ werden würde If txtAbreise < txtAnreise Then MsgBox ("Anreise muss vor Abreise liegen")
178
Kapitel 12: VBA Grundlagenwissen
Exit Sub End If ' Anzahl der Tage berechnen dblAnzahl = txtAbreise - txtAnreise + 1 ' Rabattstaffel definieren If dblAnzahl >= 29 Then dblRabatt = 0.08 ElseIf dblAnzahl >= 15 Then dblRabatt = 0.04 ElseIf dblAnzahl >= 10 Then dblRabatt = 0.02 End If ' Betrag ohne Rabatt dblBetrag = dblAnzahl * txtTagespreis txtBetrag = dblBetrag ' Rabatt in Bezeichnungsfeld schreiben lblRabatt.Caption = Format(dblRabatt, "#0% Rabatt:") ' Rabattbetrag dblBetrag = dblBetrag * dblRabatt txtRabatt = dblBetrag ' Ermäßigter Betrag dblBetrag = txtBetrag - txtRabatt ' Ermäßigten Betrag ausgeben txtBetragErmässigt = dblBetrag End Sub
12.6.2
Select Case-Anweisungen
Verzweigungen sind außer mithilfe einer If-Struktur auch mit einer Select Case-Anweisung möglich. Gerade bei If-Strukturen mit mehreren ElseIfs ist eine Select Case-Struktur oft übersichtlicher. Allgemein lässt sich eine Select Case-Anweisung durch Select Case Variable [Case Ausdruck 1 [Anweisungen 1]
12.6 Bedingte Abfragen und Verzweigungen
179
[Case Ausdruck 2 [Anweisungen 2] ... [Case Ausdruck n [Anweisungen n]]]] [Case Else [SonstAnweisungen]] End Select
ausdrücken. Eine solche Anweisung wird durch die Schlüsselwörter Select Case und End Select eingeschlossen. In der ersten Zeile wird eine Variable angegeben, deren Wert in den späteren Case-Zeilen überprüft wird. Ist der Ausdruck, der nach Case folgt, für die Variable erfüllt, werden die folgenden Anweisungen abgearbeitet. Ist der Ausdruck nicht erfüllt, wird der nächste Case-Ausdruck geprüft. Trifft keine der hinter Case ausgeführten Bedingungen zu, werden – falls vorhanden – die SonstAnweisungen nach Case Else ausgeführt.
Beispiel: Rabattstaffel mit Select Case Die Rabattstaffel soll nun folgendermaßen erweitert werden:
Tabelle 12.11: Neue Rabattstaffel
Anzahl Tage
Rabatt
0–7
0%
8 – 14
2%
15 – 21
4%
22 – 28
6%
29 – 35
8%
ab 36
10%
Um die Programmierung mit Select Case zu testen, müssen Sie einfach nur den Rabattstaffel-If-Block des letzten Beispiels durch die folgende Select Case-Struktur ersetzen. Select Case dblAnzahl Case Is >= 36 dblRabatt = 0.1 Case Is >= 29
180
Kapitel 12: VBA Grundlagenwissen
dblRabatt Case Is >= 22 dblRabatt Case Is >= 15 dblRabatt Case Is >= 8 dblRabatt End select
= 0.08 = 0.06 = 0.04 = 0.02
Prozentzahlen Achten Sie darauf, wenn Sie mit Prozentzahlen rechnen möchten, eine solche Zahl durch 100 zu teilen, so dass 100% der Zahl 1 entsprechen, 4% hingegen der Zahl 0,04 (bzw. 0.04 in amerikanischer Schreibweise).
12.7 Wiederholte Anweisungen: Schleifen Schleifen sind Programmieranweisungen, die es Ihnen erlauben, Teile Ihres Programms mehrfach hintereinander auszuführen. Die drei wichtigsten Möglichkeiten, Schleifen zu programmieren, sollen Ihnen in den folgenden Abschnitten vorgestellt werden.
12.7.1
For...Next
Die For...Next-Schleife verwendet einen Zähler, der mitzählt, wie häufig der in die Schleife eingeschlossene Programmteil bereits durchlaufen wurde. Ist die angegebene Anzahl von Durchläufen erreicht, wird die Prozedur hinter der Anweisung Next weitergeführt. Allgemein kann man eine For..Next-Schleife durch For Zähler = Anfang To Ende [Step Schrittweite] [Anweisungen] [Exit For] [Anweisungen] Next [Zähler]
12.7 Wiederholte Anweisungen: Schleifen
181
ausdrücken. Dabei ist Zähler eine Variable, die als ganze Zahl (beispielsweise als Integer) deklariert wurde. Anfang und Ende geben den Anfang- bzw. Endwert für den Zähler an, wie For intZähler = 0 To 10. Die folgenden Anweisungen würden elf Mal durchlaufen werden, nämlich für die Werte intZähler = 0,1,..10. Der in Klammern geschriebene Teil Step Schrittweite wird nur benötigt, wenn der Zähler nicht – was er standardmäßig tut – um eins weitergezählt werden soll, sondern beispielsweise um 2 oder um -1, wie in den folgenden beiden Zeilen: For intGeradeZahlen = 2 To 20 Step 2 For intRückwärts = 10 To 0 Step -1
In der ersten Zeile nimmt der Zähler intGeradeZahlen die Werte 2,4,6...20 an, in der zweiten Zeile durchläuft intRückwärts die Werte 10,9,8...0. Die Anweisungen, die zwischen den Schlüsselwörtern For und Next liegen, werden nun solange durchlaufen, bis der Zähler den Wert Ende erreicht hat, es sei denn, es befindet sich eine Bedingung in den Anweisungen, die einen vorzeitigen Abbruch erzwingt. Ein solcher Abbruch erfolgt durch die Zeile Exit For. Die Prozedur wird dann bei der ersten Anweisung fortgesetzt, die der Zeile Next folgt.
Beispiel: Bericht mehrmals drucken mit For...Next Nach Klick auf die Schaltfläche ADRESSETIKETTEN im Formular frmStart wird in diesem Beispiel in einer Inputbox abgefragt, wie oft der Bericht gedruckt werden soll. Diese Angabe wird dann in einer For...Next-Schleife verarbeitet. Mit der IsNumeric-Funktion wird dabei festgestellt, ob die Eingabe eine Zahl ist und mit DoCmd.OpenReport wird der Bericht gedruckt. Private Sub cmdAdressetiketten_Click() Dim varAnzahl Dim intZähler As Integer varAnzahl = InputBox _ ("Wie oft soll die Adressenliste gedruckt werden?") ' Abbrechen, nichts oder 0 eingeben führt zu Abbruch If varAnzahl = "" Then Exit Sub If varAnzahl < 1 Then Exit Sub
182
Kapitel 12: VBA Grundlagenwissen
If IsNumeric(varAnzahl) Then ' Ggf. vorhandene Kommastellen abschneiden varAnzahl = varAnzahl \ 1 For intZähler = 1 To varAnzahl DoCmd.OpenReport _ ("rptEtikettenAdressenDeutschland") Next Else ' Meldung, wenn keine Zahl eingegeben wurde MsgBox ("Bitte ganze Zahl eingeben!") End If End Sub
12.7.2
Do...Loop
Für eine Do...Loop-Schleife gibt es verschiedene Varianten. Eine solche Schleife läuft solange (While) oder bis (Until) eine Bedingung erfüllt ist. Allgemein lässt sich eine Do...Loop-Schleife in zwei unterschiedlichen Formen schreiben, entweder die Bedingung wird gleich zu Anfang abgefragt, wie in Do {While | Until} Bedingung [Anweisungen] [Exit Do] [Anweisungen] Loop
oder die Bedingung wird nach der eigentlichen Schleife kontrolliert, wie in Do [Anweisungen] [Exit Do] [Anweisungen] Loop {While | Until} Bedingung
Die zweite Form gewährleistet, dass die Do...Loop-Schleife mindestens einmal ausgeführt wird, wohingegen die erste Form keinmal, einmal oder mehrmals ausgeführt werden kann.
12.7 Wiederholte Anweisungen: Schleifen
183
Beispiel: Bericht mehrmals drucken mit Do...Loop Um das letzte Beispiel mit Do...Loop zu lösen, müssen Sie den For...Next-Programmteil ersetzen durch eine der beiden folgenden Do...Loop-Lösungen. Da bei dieser Art von Schleife nicht automatisch weitergezählt wird, geschieht das hier mit der Zeile intZähler = intZähler + 1. intZähler = 0 Do While intZähler <= varAnzahl DoCmd.OpenReport ("rptEtikettenAdressenDeutschland") intZähler = intZähler + 1 Loop
Im folgenden Ausschnitt aus einer Prozedur läuft die Schleife so lange, bis der Wert von intZähler größer ist als varAnzahl: intZähler = 0 Do Until intZähler > varAnzahl DoCmd.OpenReport ("rptEtikettenAdressenDeutschland") intZähler = intZähler + 1 Loop
Bericht am besten ohne Do...Loop und ohne For...Next drucken Beim Ausdrucken eines Berichtes in einer Schleife muss der Bericht jedes Mal neu generiert werden. Besser ist es, hierfür die Anzahl der Kopien anzugeben, wie in folgendem Programmfragment: ' Bericht öffnen DoCmd.OpenReport "rptEtikettenAdressenDeutschland", acViewPreview ' Ausdruck der gewählten Anzahl von Kopien DoCmd.PrintOut PrintRange:=acPages, PageFrom:=1, PageTo:=1, Copies:=varAnzahl ' Bericht schließen DoCmd.Close ObjectType:=acReport, ObjectName:="rptEtikettenAdressenDeutschland"
184
Kapitel 12: VBA Grundlagenwissen
12.8 Springen mit GoTo Manchmal ist es erforderlich, dass man innerhalb der Prozedur eine bestimmte Zeile anspringt und von dort die Prozedur fortsetzt. Dabei sind GoTo's hilfreich. Zu viele GoTo's sollten Sie innerhalb Ihrer Programme vermeiden, da sonst der Programmcode schwer lesbar wird. Um ein GoTo verwenden zu können, müssen Sie angeben, wohin gesprungen werden soll. Dazu verwendet man so genannte Sprungmarken. Das sind einfach Bezeichnungen vor derjenigen Zeile, die angesprungen werden soll. Eine solche Sprungmarke erhält zur Erkennung einen »:«. Im folgenden Ausschnitt einer Prozedur soll dann zur Sprungmarke Ende gesprungen werden, wenn die Bedingung intNummer > 10000 erfüllt ist. ... If intNummer > 10000 GoTo Ende ... Ende: End Sub
12.8 Springen mit GoTo
185
13 Unterprogramme erstellen »Non prendere il lavoro come un nemico, e non farne nemmeno l'unica ragione della tua vita. – Betrachte die Arbeit nicht als Feind und mache sie auch nicht zum einzigen Grund deines Lebens.« Nehmen Sie sich das zu Herzen und erleichtern Sie sich die Arbeit mit VBA, indem Sie Ihre Programme in kleine logische Einheiten unterteilen! Solche Einheiten werden als Unterprogramme bezeichnet.
Wie die Arbeit mit Unterprogrammen funktioniert, möchte ich Ihnen in diesem Kapitel zeigen. Unterprogramme sind vor allem dann sehr nützlich, wenn es Anweisungen in einem Programm gibt, die mehrmals aufgerufen werden, oder wenn Sie dieselben Anweisungen in verschiedenen Prozeduren benötigen. Dann kann man diese Anweisungen in ein Unterprogramm »auslagern«. Ein solches Unterprogramm kann dann entweder mehrfach in einer Prozedur aufgerufen werden oder im zweiten Fall können verschiedene Prozeduren dasselbe Unterprogramm aufrufen. Grundsätzlich unterscheidet man zwei Arten von Unterprogrammen: Function- und Sub-Prozeduren. Function-Prozeduren (oder kurz Funktionen genannt) werden meist für Berechnungen eingesetzt und haben einen Ergebniswert. Sub-Prozeduren führen häufig eine Reihe von Anweisungen aus, ohne dabei einen Wert zu berechnen und zurückzugeben.
Globale Function- und Sub-Prozeduren Benötigen Sie die gleichen Function- und Sub-Prozeduren in verschiedenen Formularen, so erfassen Sie die Unterprogramme in einem eigenen Modul und machen sie so allgemein zugänglich. Legen Sie dazu mit EINFÜGEN MODUL ein entsprechendes Modul an.
186
Kapitel 13: Unterprogramme erstellen
13.1 Function-Prozeduren Eine Function-Prozedur besteht aus einer Reihe von Anweisungen, die zwischen einer Function- und einer End Function-Anweisung stehen. Sie rufen eine solche Function-Anweisung aus einer Prozedur heraus auf, indem Sie den Namen der Function-Prozedur angeben und gegebenenfalls zusätzlich – in Klammern – einige Parameter, die die Function-Prozedur steuern.
13.1.1
Sie kennen bereits Function-Prozeduren!
Im Prinzip haben Sie Function-Prozeduren bereits kennen gelernt, sie wurden von mir bisher immer kurz als Funktionen bezeichnet. So kennen Sie bereits die Funktion Now (die Systemdatum und -zeit Ihres PCs zurückgibt) oder die Funktion Format (die eine Zahl nach bestimmten Angaben formatiert als Zeichenkette zurückgibt). Die Funktion Now wird ohne Parameter verwendet, mit der Zeile datZeit = Now
wird die Funktion Now aufgerufen, die Systemdatum und -zeit bestimmt und diese an die Variable datZeit übergibt. Wie die Funktion Now im Einzelnen aussieht, wissen wir nicht. Da sie in VBA integriert ist, haben wir darauf auch keinen Einfluss. Die Funktion Format verwendet im Gegensatz zur Now-Funktion zwei Argumente. Mit der Zeile strDM = Format(txtEuro * dblKurs, "#,##0.00")
wird die Funktion Format aufgerufen und es werden ihr beim Aufruf gleichzeitig zwei Argumente mit übergeben: Zum einen ein Wert (hier in Form einer Multiplikation), der formatiert werden soll, zum anderen die Formatierungsvorschrift. Die Funktion gibt dann die berechnete und formatierte Zeichenkette an die Variable strDM zurück.
13.1.2
So sieht eine Function-Prozedur aus
Ganz allgemein können Sie eine Function-Prozedur durch die folgenden Zeilen beschreiben:
13.1 Function-Prozeduren
187
[Public | Private] Function Name [(Argumentenliste)] [As Typ] [Anweisungen] [Name = Ausdruck] [Exit Function] [Anweisungen] [Name = Ausdruck] End Function
Werden mehrere Argumente in der Argumentenliste genannt, werden sie durch Kommata voneinander getrennt. Zudem sollten Sie jedem Argument der Argumentenliste einen Datentyp zuweisen, sonst werden die Argumente als Datentyp Variant übergeben. Beispielsweise kann die folgende erste Zeile einer Function-Prozedur für ein zu übergebendes Argument so: Private Function MwSt(dblBetrag As Double) As String
oder für zwei Argumente so: Private Function MwSt(dblBetrag As Double, _ intSatz As Integer) As String
aussehen. Neben den Argumenten, die an die Funktion übergeben werden, wird auch der Rückgabewert der Funktion deklariert. In obigem Beispiel wird der Wert für MwSt als String deklariert.
Funktion zum Errechnen der Mehrwertsteuer Stellen Sie sich vor, Sie arbeiten in einer Prozedur mit Nettobeträgen und möchten dazu in einer Funktion die Mehrwertsteuer berechnen. Sie erstellen dazu eine Function-Prozedur, der zwei Argumente übergeben werden, nämlich der Nettobetrag, für den die Mehrwertsteuer errechnet werden soll, und der Mehrwertsteuersatz, der 0, 7 oder 16 Prozent betragen kann. Private Function MwSt(dblBetrag As Double, _ intSatz As Integer) As String MwSt = Format(dblBetrag * intSatz / 100, "#,##0.00") End Function
188
Kapitel 13: Unterprogramme erstellen
13.1.3
So rufen Sie eine Function-Prozedur auf
Soll die Funktion MwSt in einer Prozedur aufgerufen werden, so könnte der Aufruf beispielsweise strSteuer = MwSt(2345, 16)
lauten oder strSteuer = MwSt(dblNetto, intSteuerschlüssel)
oder auch MsgBox "Die Mehrwertsteuer beträgt " & _ MwSt(dblNetto, intSteuersatz) & " DM."
13.1.4
Beispiel: Eigene Funktion definieren
Sie haben die Möglichkeit, beliebige eigene Funktionen zu definieren. Für die Casa Maria habe ich eine Funktion ausgedacht, die angibt, wieviel ein Appartement pro Quadratmeter pro Person pro Tag kostet. Dazu teile ich den Preis pro Tag durch die Quadratmeter und durch die maximale Anzahl der Personen, wobei ich die Personenzahl um 0,5 erhöhe, wenn ein Kleinkind zusätzlich erlaubt ist. Diese Spezialfunktion für das Formular frmAppartements sieht dann so aus: Option Compare Database Option Explicit Private Function AppKennzahl(dblPreis As Double, _ dblFläche As Double, dblPers As Double, _ fKind As Boolean) As Double If fKind = True Then dblPers = dblPers + 0.5 End If AppKennzahl = Format(dblPreis / (dblFläche * dblPers),"0.00") End Function
13.1 Function-Prozeduren
189
Aufgerufen wird die Funktion über das Klicken auf die Schaltfläche CMDAPPKENNZAHL, die ich neu zum Formular frmAppartements hinzugefügt habe: Private Sub cmdAppKennzahl_Click() Dim dblDEM As Double, dblEUR As Double dblDEM = AppKennzahl(Me.PreisDEM, Me.Größe, _ Me.MaximaleBelegung, Me.KleinkindZusätzlichErlaubt) dblEUR = AppKennzahl(Me.PreisEUR, Me.Größe, _ Me.MaximaleBelegung, Me.KleinkindZusätzlichErlaubt) MsgBox dblDEM & " DM/Tag/Pers/qm oder dblEUR & " `/Tag/Pers/qm "
" & _
End Sub
Mit Me Felder des aktuellen Formulars ansprechen Mit Me können Sie schnell und bequem die Felder des aktuellen Formulars ansprechen. Wenn Sie den Punkt nach Me eingegeben haben, bekommen Sie automatisch eine Liste mit Auswahlmöglichkeiten angezeigt.
Damit das Ganze in der beschriebenen Form funktioniert, habe ich für das Formular frmAppartements als neue Datensatzherkunft die Abfrage qryAppartementsMitPreis festgelegt. Darin habe ich aus der Tabelle tblPreisgruppen das Feld PREISPROTAG als PreisDEM eingebunden und das Feld PreisEUR berechnet. Dabei habe ich auf den schon aus Kapitel 3 bekannten Ausdruck Runden(PreisProTag/1,95583,0) zurückgegriffen. Beide Felder habe ich als Zusatzinformation in das Formular frmAppartements mit eingebunden.
190
Kapitel 13: Unterprogramme erstellen
Bild 13.1: Die selbst definierte Function-Prozedur wurde aufgerufen
13.2 Sub-Prozeduren Der Hauptunterschied von Sub-Prozeduren zu Function-Prozeduren besteht darin, dass eine Sub-Prozedur keinen Wert zurückgibt. Ansonsten wird sie ebenso wie eine Funktion über ihren Namen aufgerufen und Sie können einer Sub-Prozedur beim Aufruf ebenso Argumente übergeben. Allgemein lässt sich eine Sub-Prozedur durch [Private | Public] Sub Name [(Argumentenliste)] [Anweisungen] [Exit Sub] [Anweisungen] End Sub
beschreiben. Sollen mehrere Argumente übergeben werden, werden sie durch Komma voneinander getrennt. Geben Sie – wie in Funktionen auch – für die einzelnen Argumente deren Datentyp an, sonst werden sie als Argumente vom Datentyp Variant behandelt.
13.2 Sub-Prozeduren
191
Der Aufruf einer Sub-Prozedur erfolgt über ihren Namen: Sollen Argumente verwendet werden, werden sie (ohne Klammern) hinter dem Namen aufgeführt, wie Prozedurname txtEingabe
Es gibt eine zweite Möglichkeit, eine Sub-Prozedur aufzurufen, die aber nicht so häufig verwendet wird: Call Prozedurname(txtEingabe)
Sie verwendet dabei das Schlüsselwort Call. Jetzt werden die Argumente – wie in einer Funktion – mit Klammern übergeben.
Beispiel: Motto des Tages für alle Das Motto des Tages soll in den Titelleisten aller Formulare erscheinen. Dazu wird die Variable gstrMotto in einem eigenen Modul als globale Variable deklariert. Erstellen Sie dazu mit EINFÜGEN MODUL das Modul mdlMotto. Das Abfragen des Tagesmottos wird in diesem Modul als Sub-Prozedur angelegt. Bild 13.2: Sub-Prozedur im Modul mdlMotto
Mit Chr(13) wird im Text der InputBox ein Zeilenumbruch eingefügt. Vom eingegebenen Text werden mit Left (gstrMotto,40) die
192
Kapitel 13: Unterprogramme erstellen
ersten 40 Zeichen abgeschnitten, da für viel mehr im Startformular gar kein Platz wäre. Die Sub-Prozedur soll jetzt nicht mehr direkt im Startformular ausgeführt werden, sondern wird von dort aus aufgerufen. Die Ereignisprozedur, die beim Öffnen des Formulars frmStart ausgeführt wird, ändert sich wie folgt: Private Sub Form_Open(Cancel As Integer) Motto ' Ruft die Sub-Prozedur auf ' Motto in Titelleiste des Formulars schreiben Me.Form.Caption = gstrMotto End Sub
Mit Me.Form.Caption = gstrMotto wird das in der Variablen gespeicherte Motto in die Titelleiste des gerade geöffneten Formulars geschrieben. Fügen Sie die Ereignisprozedur ohne Aufruf der Sub-Prozedur in den Code der anderen Formulare ein. Private Sub Form_Open(Cancel As Integer) ' Motto in Titelleiste des Formulars schreiben Me.Form.Caption = gstrMotto End Sub
Damit wird beim Öffnen des jeweiligen Formulars das Motto in die Titelleiste übernommen. Wenn Sie möchten, können Sie zusätzlich ein kleines Kürzel an den Anfang stellen, also z.B. Me.Form.Caption = "App. "& gstrMotto für das Formular frmAppartements. Damit lassen sich mehrere geöffnete Formulare in der Taskleiste besser unterscheiden.
13.3 Variablenübergabe Zwei Verfahren der Übergabe von Argumenten an Function- und Sub-Prozeduren werden von VBA unterstützt: per Referenz und per Wert. Was verbirgt sich dahinter?
13.3 Variablenübergabe
193
13.3.1
Übergabe per Referenz
Wenn es nicht anders angegeben ist, wird ein Argument »per Referenz« übergeben. Das folgende Beispiel zeigt die Auswirkungen einer Übergabe per Referenz. Fügen Sie die folgenden Prozeduren in ein neues Modul namens mdlÜbergabeTest ein. Sub PerReferenz(dblBetrag As Double) '16% Mwst dblBetrag = dblBetrag * 1.16 MsgBox "Brutto: " & dblBetrag End Sub Sub PerReferenzTest() Dim dblSumme As Double dblSumme = 1000 MsgBox "Summe 1 = " & dblSumme PerReferenz dblSumme MsgBox "Summe 2 = " & dblSumme End Sub
Zum Testen der Prozedur Sub PerReferenzTest klicken Sie irgendwo in die Prozedur und dann auf die 団-Taste. Wird die Funktion PerReferenzTest ausgeführt, wird der Wert 1000 der Variablen dblSumme zugewiesen. Der Wert wird vom Programm in einer MessageBox mit dem Text Summe 1 = 1000 eingeblendet. Im Programm wird anschließend die Prozedur PerReferenz mit dem Argument dblSumme ausgeführt. Die Prozedur rechnet das übergebene Argument zu einem Bruttowert inklusive Mehrwertsteuer um, der in einer MessageBox als Brutto: 1160 angezeigt wird. Der letzte Befehl der Prozedur Test gibt die Variable dblSumme erneut in einer MessageBox aus. Sie zeigt den Text Summe 2 = 1160. Der Aufruf der Prozedur PerReferenz hat also den Inhalt der Variable dblSumme der Prozedur Test verändert. Der Grund dafür ist, dass bei der standardmäßigen Übergabe per Referenz der Prozedur PerReferenz die Adresse im Speicher übergeben wird, an der sich die Variable dblSumme befindet. PerReferenz verwendet diese Speicheradresse, benennt diese aber dblBetrag. dblSumme und dblBetrag sind damit zwei verschiedene Namen für den gleichen Speicherplatz, allerdings nur während des Aufrufs von PerReferenz. Jede Änderung an dblBetrag verändert also auch dblSumme.
194
Kapitel 13: Unterprogramme erstellen
13.3.2
Übergabe per Wert
Bei der Übergabe »per Wert«, die durch das Befehlswort ByVal bei der Definition eines Arguments einer Prozedur definiert wird, wird nicht die Speicheradresse, sondern der Inhalt der Variable übergeben. Im nächsten Listing wurde das Beispiel von oben umgearbeitet. Sub PerWert(ByVal dblBetrag As Double) '16% Mwst dblBetrag = dblBetrag * 1.16 MsgBox "Brutto: " & dblBetrag End Sub Sub PerWertTestVal() Dim dblSumme As Double dblSumme = 1000 MsgBox "Summe 1 = " & dblSumme PerWert dblSumme MsgBox "Summe 2 = " & dblSumme End Sub
Durch die Übergabe per Wert wird der Inhalt der Variablen dblSumme in der Prozedur PerWertTest nicht durch den Aufruf der Prozedur PerWert verändert.
Übergeben Sie Ihre Variablen mit ByVal Der Einsatz von ByVal kann Fehler vermeiden helfen, die durch unerwünschte und unbeabsichtigte Veränderungen in Prozeduren entstehen können.
13.3 Variablenübergabe
195
14 Vordefinierte Funktionen Sie müssen nicht alles neu erfinden. Es gibt eine große Anzahl vordefinierter Funktionen, auf die Sie bei der Arbeit mit VBA zurückgreifen können. Wie heißt es so schön: »La migliore maestra di vita è l'esperienza; ma arriva quando ormai è troppo tardi. – Die beste Lehrerin ist die Erfahrung; aber sie kommt, wenn es bereits zu spät ist.« Damit Sie von der Erfahrung anderer profitieren können, habe ich für Sie in diesem Kapitel die wichtigsten Funktionen nach Anwendungsgebieten gruppiert aufgelistet.
14.1 MsgBox-Funktion als einführendes Beispiel Am Beispiel der MsgBox-Funktion, die ich im Folgenden genauer erläutere, zeige ich Ihnen, was in den aufgeführten Funktionen stecken kann. Die MessageBox ist eine von Access zur Verfügung gestellte Funktion, die eine Nachricht auf dem Bildschirm anzeigt. Zur Fehlersuche kann sie im Programmcode eingefügt werden und den Wert einer kritischen Variablen MsgBox intTest1
oder einer Rechnung MsgBox (intTest1+intTest2)*12
anzeigen. Sollen Werte zusammen mit Texten ausgegeben werden, sind sie mit einem »&«-Zeichen miteinander zu verknüpfen. MsgBox "Das Ergebnis lautet " & intTest1+intTest2
Für die darzustellende Nachricht können bis zu 1000 Zeichen verwendet werden. Soll die Nachricht in mehreren Zeilen angezeigt werden, kann ein Zeilenumbruch mit Chr(13) erzeugt werden: MsgBox "Das Ergebnis lautet:" & Chr(13) & intTest1+intTest2
196
Kapitel 14: Vordefinierte Funktionen
14.1.1
Schaltflächen für eine MessageBox
Allerdings erlaubt eine MessageBox noch mehr. Es besteht die Möglichkeit, neben dem Mitteilungstext (der in der Funktion als prompt bezeichnet wird) und der standardmäßigen OK-Schaltfläche weitere Schaltflächen wie ABBRECHEN, JA, NEIN, WIEDERHOLEN u.ä. anzeigen zu lassen. Zudem können verschiedene Icons wie ein Stop, Achtungs- und Info-Symbol eingestellt werden. Nach prompt sehen Sie in der Beschreibung der Funktion [, buttons] aufgeführt, wobei die eckigen Klammern den Eintrag als optional kennzeichnen. Die folgende Tabelle gibt einen Überblick über die wichtigsten Zeichen und Schaltflächen, die an dieser Stelle eingefügt werden können.
Konstante
Wert
Bedeutung
vbOKOnly
0
Zeigt nur Schaltfläche OK an
vbOKCancel
1
Zeigt OK und ABBRECHEN an
vbAbortRetryIgnore
2
Zeigt ABBRECHEN, WIEDERHOLEN und IGNORIEREN
vbYesNoRetry
3
Zeigt JA, NEIN und ABBRECHEN an
vbYesNo
4
Zeigt JA, NEIN an
vbRetryCancel
5
WIEDERHOLEN und ABBRECHEN
cbCritical
16
Zeigt ein Stopzeichen
vbQuestion
32
Zeigt ein Fragezeichen
vbExclamation
48
Zeigt ein Ausrufezeichen
cbInformation
64
Zeigt ein Infozeichen
vbDefaultButton1
0
1. Taste ist voreingestellt
vbDefaultButton2
256
2. Taste ist voreingestellt
vbDefaultButton3
512
3. Taste ist voreingestellt
vbMsgBoxRight
524288
Text rechtsbündig setzen
Tabelle 14.1: Argumente für Schaltflächen und Symbolen auf einer MessageBox
Für eine MessageBox können die in der Tabelle aufgeführten Argumente von der Meldung, die angezeigt werden soll, mit Komma abgetrennt dargestellt werden. Es ist dabei unerheblich, ob die genannte Konstante oder der Wert als Parameter verwendet werden. So aktivieren beispielsweise sowohl
14.1 MsgBox-Funktion als einführendes Beispiel
197
MsgBox "Der eingetragene Wert ist zu groß!", vbExclamation
als auch MsgBox "Der eingetragene Wert ist zu groß!", 48
die im folgenden Bild dargestellte MessageBox. Bild 14.1: MessageBox mit Ausrufezeichen
Es besteht zudem wie im folgenden Beispiel die Möglichkeit, aus jeder Gruppe eine Konstante zu wählen und alle mit einem »+«Zeichen zu verbinden. MsgBox "Soll der Bericht wirklich ausgedruckt werden?", _ vbYesNo + vbQuestion + vbDefaultButton2, _ "Zahl der Ausdrucke überprüfen"
Der Text nach dem zweiten Komma kann für die Titelleiste der MessageBox vorgegeben werden. In der Funktion steht hier [, title]. Die MessageBox könnte ebenso wie MsgBox "Soll der Bericht wirklich ausgedruckt werden?", _ 4 + 32 + 256, "Zahl der Ausdrucke überprüfen"
oder wie MsgBox "Soll der Bericht wirklich ausgedruckt werden?", _ 292, "Zahl der Ausdrucke überprüfen"
geschrieben werden und die folgende MessageBox erzeugen. Bild 14.2: MessageBox mit JA/NEIN-Schaltflächen
Zwar ist die Schreibweise mit den Zahlencodes bestechend kurz, allerdings wissen Sie in zwei Wochen nicht mehr, für was 292 stand. vbYesNo + vbQuestion + vbDefaultButton2 hingegen werden Sie auch dann noch interpretieren können.
198
Kapitel 14: Vordefinierte Funktionen
14.1.2
Die MessageBox abfragen
Eine solche MessageBox mit unterschiedlichen Schaltflächen macht nur Sinn, wenn man auch herausfinden kann, welche Schaltflächen betätigt wurden. Man kann einer Variablen die MsgBox-Funktion zuweisen varTest=MsgBox("Möchten Sie fortfahren?",vbOKCancel)
und danach die Variable abfragen, um herauszufinden, welche Taste gedrückt wurde. If varTest=vbOK Then ... ' Weiter im Programm Else ... ' Stoppe hier End If
Die folgende Tabelle gibt alle möglichen Rückgabewerte der Schaltflächen an.
Konstante
Wert
Gedrückte Schaltfläche
vbOK
1
Ok
vbCancel
2
Abbrechen
vbAbort
3
Abbruch
vbRetry
4
Wiederholen
vbIgnore
5
Ignorieren
VbYes
6
Ja
VbNo
7
Nein
Tabelle 14.2: Rückgabewerte der MessageBox
Beispiel: Wollen Sie wirklich drucken? In Kapitel 12 hatte ich Ihnen gezeigt, wie Sie in einer InputBox die Anzahl der Ausdrucke für den Bericht rptEtikettenAdressenDeutschland abfragen. Die Prozedur wurde nach Klick auf die Schaltfläche ADRESSETIKETTEN im Formular frmStart ausgelöst. Dieses Beispiel soll jetzt ergänzt werden durch eine Sicherheitsabfrage, ob denn der Bericht wirklich für die gewählte Anzahl ausge-
14.1 MsgBox-Funktion als einführendes Beispiel
199
druckt werden soll. Das geänderte Listing sieht dann folgendermaßen aus: Private Sub cmdAdressetiketten_Click() Dim varAnzahl, varMsgbox Dim intZähler As Integer varAnzahl = InputBox _ ("Wie oft soll die Adressenliste gedruckt werden?", _ "Anzahl der Ausdrucke", "1") ' Abbrechen, nichts oder 0 eingeben führt zu Abbruch If varAnzahl = "" Then Exit Sub If varAnzahl < 1 Then Exit Sub If IsNumeric(varAnzahl) Then ' Ggf. vorhanden Kommastellen abschneiden varAnzahl = varAnzahl \ 1 ' --------- Neu eingefügt -------------' Anzahl wird in MessageBoxtext eingebunden varMsgbox = _ MsgBox(("Soll die Adressenliste wirklich " _ & varAnzahl & " mal ausgedruckt werden?"), _ vbYesNo + vbQuestion + vbDefaultButton2, _ "Zahl der Ausdrucke überprüfen") ' Wenn Schaltfläche Nein dann abbrechen If varMsgbox = vbNo Then Exit Sub End If ' -------------------------------------' Alternative zur For...Next-Schleife ' Bericht öffnen DoCmd.OpenReport "rptEtikettenAdressenDeutschland", _ acViewPreview ' Ausdruck der gewählten Anzahl von Kopien DoCmd.PrintOut PrintRange:=acPages, PageFrom:=1, _ PageTo:=1, Copies:=varAnzahl ' Bericht schließen DoCmd.Close ObjectType:=acReport, _ ObjectName:="rptEtikettenAdressenDeutschland" Else ' Meldung, wenn keine Zahl eingegeben wurde MsgBox ("Bitte ganze Zahl eingeben!") End If End Sub
200
Kapitel 14: Vordefinierte Funktionen
Bild 14.3: Sicherheitsabfrage vor dem Ausdruck
Im obigen Listing wurde auch der Eintrag für die InputBox geändert. Dazu wurde nach dem ersten Komma der Titel und nach dem zweiten Komma der voreingestellte Wert eingegeben. Wie Sie an diesen Beispielen sehen, haben es die vordefinierten VBA-Funktionen in sich. Nehmen Sie die folgende Übersicht als Anregung und probieren Sie einzelne Funktionen aus. Schlagen Sie dabei zur Unterstützung in der VBA-Hilfe unter dem Namen der einzelnen Funktionen nach.
14.2 Funktionen für Zeichenketten Funktion
Beschreibung
Asc(string)
gibt den Zeichencode des ersten Buchstabens der Zeichenfolge zurück. string ist ein benanntes Argument, das eine gültige Zeichenfolge beschreibt.
Chr(Zeichencode)
gibt ein Zeichen abhängig vom eingegebenen Code zurück. Zeichencode ist eine Zahl, die ein bestimmtes Zeichen kennzeichnet, Chr(13) beispielsweise steht für einen Zeilenumbruch, Chr(65) für den Buchstaben »A«.
Format(Ausdruck[, Formatanweisung[, ErsterWochentag[, ErsteWocheImJahr]]])
formatiert einen Ausdruck nach den unter Formatanweisung angegebenen Vorgaben.
InStr([start, ]string1, string2[, compare])
sucht das Vorkommen einer Zeichenfolge in einer anderen.
LCase(Zeichenfolge)
wandelt die angegebenen Zeichen in kleine Buchstaben um.
Left(string, length)
gibt die Zahl length von Zeichen links vom Ende von string zurück.
Len(string)
liefert die Länge einer Zeichenfolge zurück.
14.2 Funktionen für Zeichenketten
201
Funktion
Beschreibung
LTrim(Zeichenfolge)
entfernt führende Leerzeichen.
Mid(ZnFVariable, Anfang [,Länge])
liefert Länge Zeichen, gezählt am Anfang, aus der Zeichenfolge zurück. Ist Länge nicht angegeben, werden alle Zeichen bis zum Ende des Strings zurückgegeben.
Right(string, length)
gibt die Zahl length von Zeichen rechts vom Ende von string zurück.
RTrim(Zeichenfolge)
entfernt nachgestellte Leerzeichen.
Space(Zahl)
gibt einen String mit Zahl Leerzeichen zurück.
Str(Zahl)
wandelt Zahl in eine Zeichenfolge um.
StrComp(string1, string2[, compare])
vergleicht zwei Zeichenketten.
Trim(Zeichenfolge)
entfernt führende und nachgestellte Leerzeichen.
UCase(Zeichenfolge)
wandelt die angegebenen Zeichen in Großbuchstaben um.
Val(string)
gibt die Zahlen aus einem String zurück.
14.3 Funktionen für Dateioperationen
202
Funktion
Beschreibung
Close [Dateinummerliste]
schließt eine Datei. Dateinummerliste kann eine oder mehrere Nummern enthalten. Ohne Nummer werden alle geöffneten Dateien geschlossen.
EOF(Dateinummer)
überprüft, ob das Ende einer Datei erreicht ist. Die Dateinummer wird durch den Befehl Open vergeben.
FileCopy source, destination
kopiert eine Datei.
FileDateTime(Pfadname)
gibt Datum und Uhrzeit der Erstellung bzw. letzten Änderung der angegebenen Datei zurück.
FileLen(Pfadname)
gibt die Größe einer Datei in Byte an.
Kapitel 14: Vordefinierte Funktionen
Funktion
Beschreibung
GetAttr(Pfadname)
gibt einen Wert zurück, der Aufschluss über die Dateiattribute gibt.
Input# Dateinummer, VarListe
liest die unter VarListe angegebenen Variablen aus der Datei ein.
Kill(Pfadname)
löscht die angegebene Datei. Es besteht die Möglichkeit, die Platzhalter »*« und »?« für mehrere oder einzelne Zeichen einzusetzen.
Line Input# Dateinummer, Stringvariable
liest eine Zeile aus einer Textdatei und weist sie der angegebenen String-Variablen zu.
Name AlterPfad As NeuerPfad
ändert den Namen einer Datei oder eines Verzeichnisses.
Open Pfad [For Modus] [Access Zugriff] [Sperre] As [#]Dateinummer [Len=Satzlänge]
ermöglicht die Eingabe in bzw. Ausgabe aus einer Datei. Modus kann als Append, Binary, Input, Output oder Random gesetzt werden. Sperre wird als Shared, Lock Read, Lock Write, oder Write bestimmt.
Print# Dateinummer, [Ausgabeliste]
gibt Daten nach den Angaben der Ausgabeliste in eine Datei aus.
SetAttr pathname, attributes
setzt Attribute für eine Datei.
14.4 Funktionen für Verzeichnisoperationen Funktion
Beschreibung
ChDir Pfad
wechselt den Ordner.
ChDrive Laufwerk
wechselt das Laufwerk.
CurDir [(Laufwerk)]
gibt den aktuellen Pfad zurück. Laufwerk ist eine Zeichenfolge, die angibt, auf welchem Laufwerk der aktuelle Pfad zurückgegeben werden soll.
Dir[(Pfadname[, Attribute])]
gibt den Namen einer Datei oder eines Verzeichnisses zurück.
MkDir Pfad
erstellt ein neues Verzeichnis.
RmDir Pfad
löscht ein Verzeichnis. Pfad gibt das zu löschende leere Verzeichnis mit Pfad an.
14.4 Funktionen für Verzeichnisoperationen
203
14.5 Konvertierung
204
Funktion
Beschreibung
CBool(Ausdruck)
wandelt einen Ausdruck in den Datentyp Boolean um. Ausdruck kann eine beliebige numerische Zahl oder eine Zeichenfolge sein. Ist der Wert ungleich Null, so gibt CBool True zurück, andernfalls False.
CByte(Ausdruck)
wandelt einen Ausdruck in den Datentyp Byte um. Ausdruck kann eine beliebige numerische Zahl oder eine Zeichenfolge sein.
CCur(Ausdruck)
wandelt einen Ausdruck in den Datentyp Currency um; Ausdruck kann eine beliebige numerische Zahl oder eine Zeichenfolge sein
CDate(Ausdruck)
wandelt einen Ausdruck in den Datentyp Date um. Ausdruck kann ein beliebiger als Datum erkennbarer Ausdruck, wie ein Datum als Zeichenfolge sein.
CDbl(Ausdruck)
wandelt einen Ausdruck in den Datentyp Double um. Ausdruck kann eine beliebige numerische Zahl oder eine Zeichenfolge sein.
CInt(Ausdruck)
wandelt einen Ausdruck in den Datentyp Integer um. Ausdruck kann eine beliebige numerische Zahl oder eine Zeichenfolge sein.
CLng(Ausdruck)
wandelt einen Ausdruck in den Datentyp Long um. Ausdruck kann eine beliebige numerische Zahl oder eine Zeichenfolge sein.
CSng(Ausdruck)
wandelt einen Ausdruck in den Datentyp Single um. Ausdruck kann eine beliebige numerische Zahl oder eine Zeichenfolge sein.
CStr(Ausdruck)
wandelt einen Ausdruck abhängig vom angegebenen Argument in den Datentyp String um.
CVar(Ausdruck)
wandelt einen Ausdruck in den Datentyp Variant um. Ausdruck kann eine beliebige numerische Zahl oder eine Zeichenfolge sein.
Kapitel 14: Vordefinierte Funktionen
14.6 Datums- und Zeitfunktionen Funktion
Beschreibung
Date
gibt das aktuelle Systemdatum zurück.
DateAdd (interval, gibt einen Wert des Datentyps Variant zurück. number, date) Dieser Wert enthält ein Datum, das um einen vorgegebenen Zeitraum in der Zukunft liegt. Interval ist
eine Zeichenfolge, die das zu addierende Intervall festlegt, number ist ein numerischer Ausdruck, der die Anzahl der Intervalle definiert, date ist ein Datum, zu dem das Intervall addiert werden soll. Als Zeichenfolge für das Intervall werden folgende Ausdrücke verwendet: yyyy (Jahr), q (Quartal), m (Monat), y (Tag des Jahres), d (Tag), w (Wochentag), ww (Woche), h (Stunde), n (Minute) und s (Sekunde) DateDiff interval, date1, date2, firstdayofweek[, firstweekofyear]])
gibt die Anzahl von Intervallen zwischen zwei definierten Terminen an. Interval ist eine Zeichenfolge, die das zu addierende Intervall festlegt (s. DateAdd()). Date1, date2 sind zwei Termine zur Berechnung; firstdayofweek ist eine Konstante, die den ersten Tag der Woche festlegt, standardmäßig ist der Sonntag der erste Tag der Woche; firstweekofyear ist eine Konstante, die die erste Woche des Jahres festlegt; standardmäßig wird die Woche zur ersten, in der der 1. Januar liegt.
DatePart(interval, date [, firstdayofweek[, firstweekofyear]])
gibt einen bestimmten Teil eines vorgegebenen Datums zurück. Interval ist eine Zeichenfolge, die das zu addierende Intervall festlegt (s. DateAdd()); Date ist ein Datum zum Auswerten; firstdayofweek ist eine Konstante, die den ersten Tag der Woche festlegt, standardmäßig ist der Sonntag der erste Tag der Woche; firstweekofyear ist eine Konstante, die die erste Woche des Jahres festlegt; standardmäßig wird die Woche zur ersten, in der der 1. Januar liegt.
DateSerial(year, month, day)
gibt einen Datumswert mit dem angegebenen Tag, Monat und Jahr zurück.
DateValue(Datum)
wandelt eine Zeichenfolge in einen Datumswert um.
Day(Datum)
gibt einen Wert vom Datentyp Variant zurück, der den Tag des Monats angibt, also eine Zahl zwischen 1 und 31.
14.6 Datums- und Zeitfunktionen
205
Funktion
Beschreibung
Hour(Uhrzeit)
gibt einen Wert vom Typ Variant zurück, der die Stunde als Zahl zwischen 0 und 23 angibt.
Minute(Uhrzeit)
gibt einen Wert vom Typ Variant zurück, der die Minute als Zahl zwischen 0 und 59 angibt.
Month(Datum)
gibt eine Zahl zwischen 1 und 12 zurück.
Now
gibt das aktuelle Systemdatum sowie die aktuelle Systemuhrzeit zurück.
Second(Uhrzeit)
gibt einen Wert vom Typ Variant (Integer) zurück, der die Sekunde als Zahl zwischen 0 und 59 angibt.
Time
gibt die aktuelle Uhrzeit des Systems zurück.
TimeSerial(hour, minute, second)
gibt einen Wert vom Typ Variant mit der angegebenen Sekunde, Minute und Stunde zurück.
TimeValue(Zeichenfolge)
gibt einen Wert vom Typ Date zurück. Zeichenfolge ist ein Datum, das aus dem Bereich 1. Januar 100 bis 31. Dezember 9999 gewählt werden kann.
Weekday (date, [firstdayofweek])
gibt den Wochentag als ganze Zahl zurück; gezählt wird ab Sonntag, als der Tag 1.
Year(Datum)
Gibt eine ganze Zahl als Jahreszahl zurück.
14.7 Informationsfunktionen
206
Funktion
Beschreibung
IsArray(VarName)
gibt True zurück, falls die Variable ein Datenfeld ist, sonst False. VarName kann beliebige Variable sein.
IsDate(VarName)
gibt True zurück, falls die Variable VarName ein Datumswert ist.
IsEmpty(VarName)
gibt True zurück, falls die Variable VarName ein leerer Variant ist.
IsNull(VarName)
gibt True zurück, falls die Variable VarName den Wert Null hat.
IsNumeric(VarName)
gibt True zurück, falls die Variable VarName einen numerischen Wert enthält.
IsObject(VarName)
gibt True zurück, falls die Variable VarName ein Objekt ist.
Kapitel 14: Vordefinierte Funktionen
14.8 Finanzfunktionen Funktion
Beschreibung
DDB(AnschWert, Restwert, Nutzungsdauer, Periode)
liefert als Ergebnis den Abschreibungswert eines Anlageobjektes nach der degressiven DoppelratenAbschreibung für einen bestimmten Zeitabschnitt.
FV(Zins, Zzr, Rmz, Bw, F)
liefert den Endwert einer Annuität bei regelmäßigen Zahlungsausgängen bei konstantem Zinssatz.
IPmt(Zins, Periode, Zzr, Bw, Zw, F)
gibt den Zinssatz einer Annuität pro Zeitraum bei regelmäßigen, konstanten Zahlungen zurück.
NPer(Zins, Rmz, Bw, Zw, F)
liefert als Ergebnis die Anzahl der Zahlungen einer Investition bei vorgegebenen Werten für den Jahreszins (Zins), Ratenmonatszahlungen (Rmz), Barwert (Bw), zukünftigem Wert (Zw) und Fälligkeit (F).
Pmt(Zins, Zzr, Bw, Zw, F)
liefert als Ergebnis den Betrag der Ratenmonatszahlungen für eine Investition bei vorgegebenen Werten für den Jahreszins (Zins), Zahlungszeiträume (Zzr), Barwert (Bw), zukünftigem Wert (Zw) und Fälligkeit (F).
PPmt(Zins, Periode, Zzr, Bw, Zw, F)
liefert als Ergebnis den Betrag der Zahlung auf das Kapital für eine Investition in einem gegebenen Zeitraum bei vorgegebenen Werten für den Jahreszins (Zins), Zahlungszeiträume (Zzr), Barwert (Bw), zukünftigem Wert (Zw) und die Fälligkeit (F).
PV(Zins, Zzr, Rmz, Zw, F)
liefert als Ergebnis den Barwert einer Investition bei vorgegebenen Werten für den Jahreszins (Zins), die Zahlungszeiträume (Zzr), Ratenmonatszahlungen (Rmz), zukünftigem Wert (Zw) und Fälligkeit (F).
Rate(Zzr, Rmz, Bw, Zw, F, Schätzwert)
gibt den Zinssatz einer Annuität pro Zeitraum zurück.
SYD(AnschWert,Restwert,Periode)
liefert als Ergebnis den Wert der arithmetisch-degressiven Abschreibung für ein Anlageobjekt in einem bestimmten Zeitraum.
SLN(AnschWert, Restwert, Nutzungsdauer)
liefert als Ergebnis den Wert der linearen Abschreibung für ein Anlageprojekt.
14.8 Finanzfunktionen
207
15 Fehler finden und behandeln »A chi ha fortuna il bue gli porta un vitello.– Wer Glück hat, dem macht der Ochse ein Kalb.« Und wer Pech hat, macht einen Fehler! Damit Sie durch kleine Fehler nicht in's große Unglück gestürzt werden, gibt es für die VBA-Programmierung eine ganze Reihe von Möglichkeiten zur Fehlersuche und -behandlung.
Ich möchte Ihnen in diesem Kapitel Programmkomponenten, Verfahren und Programmiertechniken beschreiben, die Ihnen bei der Vermeidung von Programmfehlern helfen sollen.
15.1 Fehlerarten Grundsätzlich lassen sich drei Arten von Fehlern unterscheiden:
Fehler beim Kompilieren Fehler in Programmen, die durch falsch geschriebene oder angewendete Befehle entstehen, werden bei der Ausführung der Programme entdeckt. Mit dem Befehl DEBUGGEN/KOMPILIEREN VON CASA MARIA können Sie auch eine Überprüfung von Hand starten. Zudem werden Sie durch die automatische Syntaxüberprüfung während der Programmeingabe auf offensichtliche Schreibfehler sofort hingewiesen.
Laufzeitfehler Treten während des Ablaufs eines Programms Fehler oder ungültige Operationen auf, die zum Abbruch des Programms führen, wird ein Laufzeitfehler (run-time error) ausgelöst. Haben Sie in Ihrem Programm keine eigene Fehlerbehandlung programmiert, so wie ich es am Ende des Kapitels beschreibe, wird das Programm mit einer Fehlermeldung angehalten.
208
Kapitel 15: Fehler finden und behandeln
Laufzeitfehler treten beispielsweise auf, wenn im Programm der Wertebereich einer Variablen überschritten wird. Wird einer Variablen vom Typ Integer der Wert 100.000 zugewiesen, tritt ein Laufzeitfehler auf, denn Integer-Variablen können nur Werte zwischen -32768 und 32767 enthalten. Ein weiterer, häufig auftretender Fehler ist die Division durch Null. Sie erhalten einen solchen Fehler, wenn im Befehl dblErgebnis = dblZahl1 / dblZahl2
die Variable dblZahl2 den Wert 0 aufweist.
Logische Programmfehler Die unangenehmsten und am schwierigsten auffindbaren Fehler sind logische Programmfehler. Bei solchen Fehlern ist das Programm äußerlich, also syntaktisch, korrekt, aber Fehler in der Programmlogik führen zu falschen Ergebnissen. Nur durch ausführliches Testen können Sie Ihr Programm von logischen Programmfehlern befreien.
15.2 Der Debugger zur Fehlersuche Für die Fehlersuche bietet Ihnen Access einen Debugger an. Ein Debugger ermöglicht die schrittweise Abarbeitung eines Programms und die Kontrolle von Zwischenständen, um Ihren Fehlern auf die Spur zu kommen. Für die Vorstellung der Debugging-Möglichkeiten verwende ich eine Routine, die die Summe der Werte eines Feldes (Array) ermittelt. Dazu habe ich das folgende einfache Formular frmFehlersuche erstellt. Bild 15.1: Testformular
15.2 Der Debugger zur Fehlersuche
209
Damit Sie meine Fehlersuchbemühungen besser nachvollziehen können, habe ich das Listing der Ereignisprozedur Sub cmdTest_Click abgedruckt. Option Compare Database Option Explicit Private Sub cmdTest_Click() Dim varWerte As Variant, intZähler As Integer Dim strText As String intZähler = 0 Do varWerte = Array("Stadt ", "Land ", "Fluss ", _ "Name ", "Tier ", "Beruf ") strText = strText & varWerte(intZähler) intZähler = intZähler + 1 Loop Until intZähler > 6 MsgBox strText End Sub
Die Prozedur cmdTest_Click erzeugt einen Laufzeitfehler, da die Do...Loop-Schleife nicht rechtzeitig abbricht. Der Index eines Arrays beginnt mit 0. Die Prozedur versucht in der Schleife auf varWerte(6) zuzugreifen, da die Abbruchbedingung erst gültig wird, wenn intZähler den Wert 7 hat. Das führt zur folgenden Fehlermeldung, da bei sechs Werten im Array nur die Elemente 0 bis 5 existieren und angesprochen werden können. Bild 15.2: Fehlermeldung eines Laufzeitfehlers
Klicken Sie im Dialogfeld, das den Laufzeitfehler anzeigt, auf die Schaltfläche DEBUGGEN, wird es geschlossen und die Zeile, die den Fehler ausgelöst hat, wird im Code-Fenster farbig dargestellt.
210
Kapitel 15: Fehler finden und behandeln
Bild 15.3: Unterlegte aktuelle Programmzeile
Übrigens können Sie den obigen Fehler leicht umgehen, indem Sie als Abbruchbedingung Loop Until intZähler > UBound(varWerte)
angeben. Die Funktion UBound() (Upper Bound) ermittelt die obere Grenze eines Feldes. Mit LBound() (Lower Bound) beziehen Sie sich auf die untere Grenze, die im Normalfall 0 ist. Verwenden Sie UBound(), so arbeitet Ihr Programm auch dann richtig, wenn Sie Elemente zum varWerte-Feld hinzufügen oder wegnehmen.
In der DEBUGGEN-Symbolleiste stehen Ihnen eine Reihe von Schaltflächen zur Verfügung, mit denen Sie den Debugger zur Fehlersuche bedienen können. Sie aktivieren die Symbolleiste mit ANSICHT SYMBOLLEISTEN DEBUGGEN.
15.2 Der Debugger zur Fehlersuche
211
Die DEBUGGEN-Symbolleiste bietet Ihnen neben dem bekannten Entwurfsmodus-Symbol die folgenden Schaltflächen:
Tabelle 15.1: Die Schaltflächen der Symbolleiste DEBUGGEN
Schaltfläche
Name
Bedeutung
Sub/UserForm ausführen (Fortsetzen)
Programm weiter fortführen
Unterbrechen
Programm anhalten
Zurücksetzen
Programm abbrechen
Haltepunkt ein/aus
Haltepunkt setzen bzw. entfernen
Einzelschritt
Nächsten Befehl abarbeiten
Prozedurschritt
Nächste Prozedur abarbeiten
Prozedur abschließen
Nächsten Befehl in vorhergehender Prozedur abarbeiten
Lokal-Fenster
Lokal-Fenster einblenden
Direktfenster
Direktfenster einblenden
Überwachungsfenster
Überwachungsfenster einblenden
Aktuellen Wert anzeigen
Aktuellen Wert der markierten Variablen zeigen
Aufrufeliste
Liste der durchlaufenen Unterprogramme zeigen
Programmänderungen im Debug-Modus Es ist möglich, dass Sie Ihr Programm ändern, während es im Debug-Modus abläuft. So kann beispielsweise eine fehlerhafte Programmzeile direkt berichtigt werden und das Programm danach weiterlaufen.
212
Kapitel 15: Fehler finden und behandeln
Endlosschleife Manchmal passiert es, dass das Programm in einer Endlosschleife kreist. Wenn Sie beispielsweise aus dem Programm den Befehl intZähler = intZähler + 1 entfernen, entsteht eine Endlosschleife. Mithilfe der Tastenkombination 圳+垂 können Sie Ihr VBA-Programm unterbrechen. Damit wechseln Sie in den DebugModus.
15.2.2
Anzeige von aktuellen Werten
Der Inhalt einer Variablen lässt sich abfragen, indem Sie den Cursor auf eine Variable positionieren. Nach einer kurzen Verzögerung wird der aktuelle Wert der Variablen in einem gelben Rechteck angezeigt. Bild 15.4: Automatischer Datentipp
Werden keine Werte angezeigt, überprüfen Sie die Einstellung für AUTOMATISCHE DATEN-TIPS im Dialogfeld unter EXTRAS OPTIONEN auf dem Registerblatt EDITOR. Für die Anzeige der Werte muss die Option aktiviert sein. Alternativ können Sie auch, um den in Bild 15.3 gezeigten Fehler in der betroffenen Zeile zu lokalisieren, den Inhalt der Variablen intZähler mit der Schaltfläche AKTUELLEN WERT ANZEIGEN ermitteln.
15.2 Der Debugger zur Fehlersuche
213
Markieren Sie dazu die Variable intZähler und betätigen Sie die Schaltfläche, um das folgende Dialogfeld zu erhalten. Bild 15.5: Aktuellen Wert anzeigen
Mit ABBRECHEN schließen Sie das Dialogfeld, mit HINZUFÜGEN wird die Variable intZähler in die Überwachungsliste aufgenommen, die ich Ihnen weiter unten im Abschnitt 15.2.6 beschreibe.
15.2.3
Das Direktfenster
Die Inhalte von Variablen und viele weitere Operationen können im Direktfenster abgefragt und aufgerufen werden. Sollte es nicht zu sehen sein, aktivieren Sie das Direktfenster mit der gleichnamigen Schaltfläche. Im Direktfenster dient ein Fragezeichen als Druckbefehl. Möchten Sie den Wert einer Variablen oder das Ergebnis einer Funktion im Direktfenster anzeigen lassen, so setzen Sie ein Fragezeichen davor, wie beispielsweise im nächsten Bild dargestellt. Bild 15.6: Ausgabe im Direktfenster
Aufruf im Direktfenster Sie rufen eine Funktion im Direktfenster auf, indem Sie ein Fragezeichen voranstellen. Damit wird das Ergebnis der Funktion im Direktfenster ausgegeben. Prozeduren werden im Direktfenster mithilfe ihres Namens gestartet, ohne dass ein Fragezeichen verwendet wird.
214
Kapitel 15: Fehler finden und behandeln
Der Befehl Debug.Print Verwenden Sie in Ihrem Programm den Befehl Debug.Print, so können Sie sofort in das Direktfenster schreiben. Um dem Fehler auf die Spur zu kommen, ergänzen Sie die Beispielprozedur durch einen Debug.Print-Befehl: Debug.Print "Zähler= "; intZähler ; strTest
Klicken Sie erneut auf die Schaltfläche TEST im Formular frmFehlersuche, nachdem Sie den Debugger mit dem Menübefehl AUSFÜHREN ZURÜCKSETZEN verlassen haben. Nun wird für jeden Schleifendurchlauf der Inhalt der Variablen intZähler mit Debug.Print im Direktfenster ausgegeben, bevor das Programm erneut mit der Fehlermeldung beendet wird. Bild 15.7: Ausgabe im Direktfenster
Im Direktfenster lässt sich deutlich erkennen, dass beim Zählerstand von 6 schon alle Werte im Array ausgegeben sind. Der nächste Durchlauf führt damit zum Fehler. Für die Aufbereitung der Ausgabedaten mit Debug.Print stehen Ihnen eine Reihe von Formatierungsmöglichkeiten zur Verfügung, die ich Ihnen kurz vorstellen möchte. Mehrere Ausdrücke können entweder mit einem Leerzeichen oder mit einem Semikolon getrennt werden. Ein Leerzeichen hat dabei
15.2 Der Debugger zur Fehlersuche
215
dieselbe Wirkung wie ein Semikolon. Setzen Sie hinter einen Ausdruck ein Komma, wird die nächste Ausgabe um eine Tabulatorposition verschoben. Ist das letzte Zeichen einer Debug.Print-Anweisung ein Semikolon oder ein Komma, wird die nächste Debug.Print-Ausgabe nicht in einer neuen Zeile begonnen, sondern direkt bzw. einen Tabulatorabstand hinter die aktuelle Ausgabe gesetzt. Daten vom Typ Boolean werden entweder als Wahr oder als Falsch ausgegeben. Für Werte vom Typ Date wird das Standardformat für kurze Datumsangaben verwendet.
15.2.4
Schrittweise Abarbeitung
Sie können ein VBA-Programm schrittweise durchlaufen lassen und dabei Haltepunkte setzen, an denen das Programm stoppt. Zusätzlich können Sie die Inhalte Ihrer Variablen permanent überwachen und Abbruchkriterien definieren.
Haltepunkt Mithilfe der Schaltfläche HALTEPUNKT legen Sie die Zeile fest, an der die Ausführung unterbrochen werden soll. Alternativ können Sie einen Haltepunkt mit der Maus definieren. Klicken Sie dazu einfach links von der Zeile, für die der Haltepunkt definiert werden soll, auf den grauen Balken im Code-Fenster. Es besteht auch die Möglichkeit, mehrere Haltepunkte in einem Programm zu definieren. Sie werden jeweils durch einen dunkelroten Balken dargestellt. Hat Ihr Programm einen Haltepunkt erreicht, lassen sich mithilfe des Direktfensters oder über die Schaltfläche AKTUELLEN WERT ANZEIGEN die Inhalte Ihrer Variablen ausgeben, die bis dahin verwendet wurden.
216
Kapitel 15: Fehler finden und behandeln
Bild 15.8: Definierter Haltepunkt
Anhalten, Weiterlaufen und das Ganze von vorne Soll das Programm beendet werden, betätigen Sie zu einem beliebigen Zeitpunkt die Schaltfläche ZURÜCKSETZEN. Mit der Schaltfläche FORTSETZEN wird das Programm ab dem Haltepunkt gestartet, es läuft dann bis zum nächsten Haltepunkt bzw. bis zum Programmende. Die Schaltfläche UNTERBRECHEN wird aktiv, sobald Sie Ihr Programm gestartet haben. Mit ihr können Sie ein laufendes Programm unterbrechen und gegebenenfalls direkt Änderungen vornehmen. Ein unterbrochenes Programm kann mit der Schaltfläche FORTSETZEN fortgeführt werden.
Einzelschritte Mithilfe der Schaltfläche EINZELSCHRITT wird ein Programm Zeile für Zeile abgearbeitet. Sie können so den Ablauf Ihres Programms genau verfolgen. Wird im Programm eine Prozedur oder eine Funktion aufgerufen, wird beim schrittweisen Durchlauf des Programms in die entsprechende Prozedur oder Funktion verzweigt. Alternativ können Sie Einzelschritte mit der Taste 囦 oder über DEBUGGEN EINZELSCHRITT durchführen.
Prozedurschritte Möchten Sie beim schrittweisen Durchlaufen eines Programms nicht jede Prozedur oder Funktion einzeln durchlaufen, sondern überspringen, so verwenden Sie die Schaltfläche PROZEDURSCHRITT (oder 圶+囦 bzw. DEBUGGEN PROZEDURSCHRITT).
15.2 Der Debugger zur Fehlersuche
217
Prozedur abschließen Hilfreich insbesondere beim schrittweisen Durchlaufen großer und tief verschachtelter Programme ist die Schaltfläche PROZEDUR ABSCHLIEßEN (圳+圶+囦 oder DEBUGGEN PROZEDUR ABSCHLIEßEN). Die Schaltfläche führt das Programm mit dem nächsten Befehl der Prozedur fort, die die aktuell aktive Prozedur aufgerufen hat.
Ausführen bis zur Cursor-Position Klicken Sie mit dem Mauszeiger in eine Zeile Ihres Programms und rufen dann DEBUGGEN AUSFÜHREN BIS CURSOR (oder 圳+囦) auf. Es werden dann alle Programmzeilen bis zu der angeklickten Zeile durchlaufen.
Nächste Anweisung festlegen Sollten Sie mit den Debugging-Möglichkeiten einige Erfahrung gesammelt haben, so kann Ihnen der Befehl DEBUGGEN NÄCHSTE ANWEISUNG FESTLEGEN oder 圳+囧 weitere Unterstützung bieten. Sie bestimmen damit die Programmzeile, ab der ein Programm weiter ausgeführt werden soll. Selektieren Sie dazu die gewünschte Programmzeile und wählen Sie dann den Befehl an. Alternativ können Sie auch mit der Maus den kleinen gelben Zeiger, der links von der gelb markierten aktuellen Programmzeile gezeigt wird, auf die gewünschte Zeile verschieben.
15.2.5
Das Lokal-Fenster
Im Lokal-Fenster werden alle Variablen und ihre Werte angezeigt, die im aktuell ablaufenden Programm für eine bestimmte Prozedur existieren. Insbesondere beim schrittweisen Durchlaufen eines Programms lassen sich hier leicht Inhalte von Variablen ermitteln. Komplexe interne und benutzerdefinierte Variablen werden in einer Baumstruktur abgebildet. Durch einen Klick auf das Pluszeichen vor der Variablen öffnen Sie die nächste Ebene der Datenstruktur der Variablen.
218
Kapitel 15: Fehler finden und behandeln
Bild 15.9: Baumstruktur für Variablen
15.2.6
Überwachung von Variablen
Die dauernde Kontrolle von Variablen oder Ausdrücken kann mit der Überwachungsfunktion eingerichtet werden. Die überwachten Ausdrücke werden im Überwachungsfenster dargestellt. Mit der Schaltfläche ÜBERWACHUNGSFENSTER bzw. ANSICHT ÜBERWACHUNGSFENSTER schalten Sie das Fenster ein. Um eine Variable zu überwachen, rufen Sie mit DEBUGGEN ÜBERWACHUNG HINZUFÜGEN das folgende Dialogfeld auf. Haben Sie vorher eine Variable oder einen Ausdruck markiert, wird er automatisch in das Feld AUSDRUCK übernommen. Bild 15.10: Überwachung hinzufügen
15.2 Der Debugger zur Fehlersuche
219
Für überwachte Ausdrücke sind drei Einstellungen möglich: Mit ÜBERWACHUNGAUSDRUCK wird der Inhalt einer Variablen bzw.
das Ergebnis eines Ausdrucks im Überwachungsfenster angezeigt. Vereinbaren Sie UNTERBRECHEN, WENN DER WERT TRUE IST, dann stoppt Ihr Programm in dem Moment und an der Zeile, bei der der überwachte Ausdruck als Ergebnis den Wert Wahr (True) ergibt. Möchten Sie das Programm bei einer Änderung des Inhalts einer Variablen oder eines Ausdrucksergebnisses anhalten, so selektieren Sie die Option UNTERBRECHEN, WENN WERT GEÄNDERT WURDE. Im Überwachungsfenster werden die drei Einstellungsmöglichkeiten durch verschiedene Symbole im Überwachungsbereich dargestellt. Bild 15.11: Überwachungsfenster
15.2.7
Aufrufeliste
Mithilfe der Schaltfläche AUFRUFELISTE öffnen Sie ein Dialogfeld, das die Prozeduren und Funktionen anzeigt, die bis zur aktuellen Zeile im Programm durchlaufen wurden.
15.3 Vermeidung von Fehlern Da kaum jemand auf Anhieb fehlerfrei programmiert, möchte ich Ihnen in diesem Abschnitt die wichtigsten Strategien zur Fehlervermeidung zusammenfassen.
220
Kapitel 15: Fehler finden und behandeln
Deklaration von Variablen Verwenden Sie eine neue Variable, ohne sie vorher mit einem DimBefehl deklariert zu haben, wird als Typ automatisch Variant zugewiesen. Dies wird als implizite Deklaration bezeichnet. Die implizite Deklaration von Variablen ist bequem, denn eine neue Variable steht zur Verfügung, wann immer sie benötigt wird. Allerdings ist dies auch fehlerträchtig: Angenommen, Sie verwenden in Ihrem Programm die Variable intZähler und möchten nun mit dem nächsten Befehl zum Inhalt der Variable den Wert Eins hinzuzählen und das Ergebnis in das Steuerelement txtErgebnis übergeben. txtErgebnis.Text = intZaehler + 1
Haben Sie den Fehler gefunden? Das in txtErgebnis.Text übertragene Ergebnis ist nämlich immer Eins, denn implizit wurde eine neue Variable intZaehler erzeugt anstatt intZähler zu verwenden. Sie können Fehler aufgrund von implizit deklarierten Variablen umgehen, indem Sie am Anfang Ihres Programms durch den Befehl Option Explicit
nur noch explizit vereinbarte Variablen zulassen. Der Befehl wird in den Deklarationsteil eines Moduls oder Formulars aufgenommen. Sie können Option Explicit automatisch in jedes Programm einfügen lassen, indem Sie über EXTRAS OPTIONEN das Registerblatt EDITOR aufrufen. Selektieren Sie die Option VARIABLENDEKLARATION ERFORDERLICH, damit die Option Explicit automatisch bereitgestellt wird.
Kleine Einheiten Zerlegen Sie Ihre Programme in überschaubare, kleine Einheiten, in Funktionen und Sub-Prozeduren. Fehler lassen sich oft besser eingrenzen, wenn kleine Programmteile mit lokalen Variablen verwendet werden.
15.3 Vermeidung von Fehlern
221
Möglichst keine globalen Variablen verwenden Setzen Sie keine oder möglichst wenige globale Variablen ein. Oft ist es nur sehr schwer nachzuvollziehen, welche Routine oder Funktion eine globale Variable zu welchem Zeitpunkt geändert hat. Globale Variablen sollten sehr sorgfältig dokumentiert sein, damit ihr Zustand und Inhalt zu jedem Zeitpunkt eindeutig ist.
Übergabe von Parametern als Wert (ByVal) Übergeben Sie Parameter an Sub-Prozeduren und Funktionen nach Möglichkeit immer als Wert, also mit ByVal. Standardmäßig werden in Access Parameter als Referenz, ByRef, übergeben. Dabei wird dem Unterprogramm die Adresse der Variablen im Speicher mitgeteilt. Das Unterprogramm verwendet die Adresse, um den Inhalt der Variablen zu bestimmen (die verschiedenen Möglichkeiten der Parameterübergabe haben Sie in Kapitel 13 kennen gelernt).
Namenskonventionen Hilfreich beim Vermeiden, aber auch beim Suchen von Fehlern ist die Verwendung der Namenskonvention für Variablen, Konstanten, Funktionen und Prozeduren, auf die ich schon öfter eingegangen bin.
Kommentare Schreiben Sie ausführliche Kommentare! Kommentieren Sie Ihren Code, auch wenn es Ihnen zu trivial vorkommt, mit Worten zu erklären, was im Programm passiert. Spätestens in einem halben Jahr wissen auch Sie nicht mehr, welche Bedeutung bestimmte Abläufe in Ihrem Programm haben. Muss Ihr Programm von anderen Personen gepflegt und gewartet werden, sind Kommentare oft die einzige Chance, den Ablauf eines Programms zu verstehen.
15.4 Fehlerbehandlung Tritt zur Laufzeit eines VBA-Programms ein Fehler auf, wird eine entsprechende Fehlermeldung angezeigt, und das Programm wird
222
Kapitel 15: Fehler finden und behandeln
beendet. Solche Programmabbrüche sind unangenehm, weil in vielen Fällen Daten verloren gehen können, da das Programm komplett verlassen wird. Ich rate Ihnen deshalb, eigene Fehlerbehandlungsroutinen zu implementieren, um auf Laufzeitfehler zu reagieren. In den folgenden Abschnitten möchte ich Ihnen einen Überblick über die Behandlung von Fehlern und die zur Verfügung stehenden Befehle geben.
Bei allen Fehlern anhalten Im Registerdialogfeld zu EXTRAS OPTIONEN kann auf dem Registerblatt ALLGEMEIN die Option BEI JEDEM FEHLER eingeschaltet sein. Damit wird jegliche, von Ihnen in Ihren Programmen definierte Fehlerbehandlung ausgeschaltet, d.h., Access behandelt jeden Fehler selbst. Diese Option ist während des Testens einer Applikation sinnvoll. Später sollte sie jedoch auf jeden Fall deaktiviert werden.
Sie können die Fehlerbehandlung so einstellen, dass beim Auftreten eines Fehlers ein bestimmter, für die Fehlerbehandlung definierter Bereich in Ihrem Programm angesprungen wird. Mit On Error Goto Label wird die eigene Fehlerbehandlung aktiviert, wobei Label eine Zeilennummer oder Sprungmarke angibt. Tritt ein Fehler auf, wird das Programm zum Label verzweigt und die dort aufgeführten Befehle werden abgearbeitet. Jeder Fehler wird automatisch in einem Err-Objekt abgelegt, dessen Eigenschaften Sie in Ihrem Programm abrufen bzw. dessen Methoden Sie verwenden können. Das Fehlerobjekt Err besitzt die in folgender Tabelle aufgeführten Eigenschaften und Methoden.
Tabelle 15.2: Eigenschaften und Methoden des ErrObjekts
Eigenschaft/Methode Beschreibung Number
gibt Nummer des Fehlers zurück.
Description
fügt Beschreibungstext für den Fehler ein.
Source
gibt den Namen der Anwendung zurück, die den Fehler ausgelöst hat.
15.4 Fehlerbehandlung
223
Tabelle 15.2 (Forts.): Eigenschaften und Methoden des ErrObjekts
Eigenschaft/Methode Beschreibung LastDLLError
enthält die Beschreibung eines Fehlers, der in einer DLL-Bibliothek aufgetreten ist.
HelpFile
gibt die Hilfedatei an, aus der der Hilfetext zum Fehler entnommen wird.
HelpContext
gibt die Kontextkennung in der Hilfedatei an.
Raise
erzeugt einen Fehler.
Clear
setzt das Err-Objekt zurück.
15.5 Fehlerbehandlungsbefehle In den folgenden Abschnitten erläutere ich Ihnen die verschiedenen Fehlerbehandlungsbefehle.
15.5.1
Fehlerbehandlung setzen: On Error Goto
Die Fehlerbehandlung wird in einem Programm mit dem Befehl On Error Goto Sprungmarke eingeleitet. Sprungmarke steht für eine benannte Sprungmarke oder Zeilennummer. Eine ganz einfache Fehlerbehandlung zeigt das folgende Programm. Sub MinimalFehlerbehandlung() On Error Goto Err_Fehlerbehandlung ' Hier kommt der Fehler: Division durch 0 Debug.Print 1/0 Exit Sub Err_Fehlerbehandlung: Msgbox "Fehler " & Err.Description & " aufgetreten!" End Sub
Ab der Sprungmarke, hier Err_Fehlerbehandlung, wird der aufgetretene Fehler behandelt. Sie müssen dabei sicherstellen, dass die Befehle der Fehlerbehandlung nicht abgearbeitet werden, wenn kein Fehler ausgelöst wurde. Normalerweise wird direkt vor der Sprungmarke der Fehlerbehandlung der Befehl Exit Sub bzw. Exit Function eingefügt.
224
Kapitel 15: Fehler finden und behandeln
Beim Verlassen einer Sub- oder einer Function-Prozedur wird eine dort gesetzte Fehlerbehandlung zurückgesetzt; damit hat die Fehlerbehandlung die gleiche Gültigkeit und Lebensdauer wie die Prozedur, in der sie definiert ist.
15.5.2
Fehler übergehen: On Error Resume Next
Möchten Sie beim Auftreten eines Fehlers direkt mit der Programmzeile weitermachen, die auf die Zeile folgt, die den Fehler ausgelöst hat, verwenden Sie den Befehl On Error Resume Next. Der Befehl hat die gleiche Gültigkeit und Lebensdauer wie die Prozedur oder Funktion, in der er verwendet wird. Den Einsatz des Befehls möchte ich Ihnen anhand des folgenden kleinen Programms erläutern: Sub UmrechnungMitFehler() Dim dblWert As Double dblWert = InputBox("Betrag in DM") MsgBox "Betrag in EURO = " & dblWert / 1.95583 End Sub
Rufen Sie die Sub-Prozedur auf, wird in einer InputBox ein Wert abgefragt. Anschließend wird in der MessageBox das umgerechnete Ergebnis gezeigt. Das funktioniert so lange, wie Sie Zahlen in der InputBox eingeben. Tippen Sie Buchstaben ein, so erhalten Sie den Laufzeitfehler 13, »Typen unverträglich«, denn Sie versuchen nun, eine Zeichenkette einer Variablen vom Typ Double zuzuweisen. Im folgenden Listing finden Sie eine Variante der Prozedur, in der durch On Error Resume Next vermieden wird, dass die Laufzeitfehlermeldung eingeblendet wird. Anschließend wird die Nummer des Fehlers ausgewertet: ist sie 0, ist kein Fehler ausgelöst worden, d.h., die Eingabe war korrekt. Sub Umrechnung() Dim dblWert As Double On Error Resume Next dblWert = InputBox("Betrag in DM") If Err.Number = 0 Then MsgBox "Betrag in EURO = " & dblWert / 1.95583
15.5 Fehlerbehandlungsbefehle
225
Else MsgBox "Eingabe muss eine Zahl sein! End If End Sub
Zurücksetzen der Fehlerbehandlung: On Error Goto 0 Um die eigene Fehlerbehandlung innerhalb einer Prozedur oder Funktion wieder abzuschalten, wird der Befehl On Error Goto 0 eingesetzt. Die Sprungmarke 0 ist eine Access-interne Adresse. Das Programm verzweigt zu dieser internen Adresse, selbst wenn Sie in Ihr Programm eine gleichnamige Sprungmarke einfügen. Das bedeutet für die Programmausführung, dass Access die Kontrolle über die Fehlerbehandlung zurück erhält.
Und weiter im Programm: Die Resume-Befehle
Bild 15.12: Resume-Befehle Programmzeile, die Fehler ausgelöst hat
Nächste Programmzeile
Fehlerbehandlung
Die Resume-Befehle Resume, Resume Next und Resume Sprungmarke werden eingesetzt, um nach einem Fehler das Programm weiter abzuarbeiten.
Resume Resume Sprungmarke
Resume Next
Sprungmarke: Programmzeile
Ist es möglich, innerhalb Ihrer Fehlerbehandlung den aufgetretenen Fehler zu beheben, kann durch Resume die Abarbeitung Ihres Programms mit der Programmzeile fortgesetzt werden, die den Fehler ausgelöst hat, während Resume Next das Programm an der Zeile fortführt, die der Zeile mit dem Fehler folgt. Durch Resume Sprungmarke können Sie gezielt eine Stelle im Programm anspringen, an der Ihr Programm fehlerfrei fortgeführt werden kann.
226
Kapitel 15: Fehler finden und behandeln
15.5.3
Die On Error-Aufrufkette
Tritt in der On Error-Fehlerbehandlung selbst der nächste Fehler auf, kann er nicht von der gerade aktiven Fehlerbehandlung, also von sich selbst, abgefangen werden. Access durchläuft die Kette der eingerichteten Fehlerbehandlungen, bis eine nicht aktive Fehlerbehandlung gefunden wird, der der Fehler übergeben wird. Sind alle Fehlerbehandlungen eines Programms aktiv und es tritt ein weiterer Fehler auf, wird die Standardfehlermeldung zum Fehler gezeigt und das Programm abgebrochen.
15.6 Beispielhafte Fehlerbehandlung Innerhalb der Fehlerbehandlung einer Sub oder Function ist es möglich, auf den aufgetretenen Fehler spezifisch zu reagieren. Im folgenden Beispiel-Code ist innerhalb des Fehlerbehandlungsblocks eine Select Case-Anweisung programmiert. Sub Fehlerbehandlung() On Error GoTo err_Fehlerbehandlung '... hier steht Ihr Programm Exit Sub err_Fehlerbehandlung: Select Case Err.Number Case 11: ' Division durch Null '...hier die entsprechenden Befehle Case 13: ' Typen unverträglich '...hier die entsprechenden Befehle Case Else MsgBox "Fehler <" & Err.Description & _ "> (" & Err.Number & _ ") in Sub " & _ " aufgetreten!" End Select End Sub
Für jeden Fehler, den Sie speziell behandeln möchten, fügen Sie ein weiteres Case und die entsprechenden Befehle ein, so wie es exemplarisch für die Fehler 11 und 13 gezeigt ist.
15.6 Beispielhafte Fehlerbehandlung
227
16 DAO und andere Objekte »A buon intenditore poche parole bastano. – Dem Kenner reichen wenige Worte.« Wenn Sie sich mit Objekten auskennen, kommen Sie im Umgang mit Access schneller zum Ziel. Darum jetzt dies Kapitel zum Thema.
16.1 Was ist ein Objekt? VBA ist eine teilweise objektorientierte Programmiersprache. Ich möchte Ihnen eine kurze Einführung in diese Programmiertechnik geben und zunächst einmal klären, was hier unter Objekten verstanden wird. Bei der Arbeit mit Access haben Sie immer mit Objekten zu tun. Beispielsweise ist Ihr Programm selbst, jedes Formular und jedes Steuerelement ein Objekt.
16.1.1
Objekthierarchien
Man kann hier eine so genannte Objekthierarchie bilden. Das oberste Objekt, welches alle anderen beinhaltet, ist das Programm selbst. Im Programm können Formularobjekte enthalten sein. Und jedes der Formulare, also der Formularobjekte, kann Steuerelemente enthalten, die selbst Objekte sind.
Ein Haus als Objekt vorstellen Zum besseren Verständnis sollten Sie sich einmal ein Objekt aus dem täglichen Leben vorstellen – nehmen wir das Objekt »Haus«. In dem Haus gibt es drei Ferienappartements, die ihrerseits auch wieder als Objekte betrachtet werden können. Diese Ferienappartement-Objekte enthalten weitere Objekte wie Zimmer, Fenster, Lichtschalter usw. Viele Objekte eines Hauses, wie beispielsweise Türen, gibt es an mehreren Stellen. Um vor lauter Objekten nicht den Überblick zu verlieren, bietet es sich an, eine Liste aller Türen zu führen. In der Programmierung werden solche Listen als Auflistung (engl. collection) bezeichnet.
228
Kapitel 16: DAO und andere Objekte
Über die Objekthierarchie ist es also möglich, gezielt ein einzelnes Objekt auszuwählen – also z.B. die Tür zwischen Wohnzimmer und Esszimmer im Appartement im Obergeschoss. Diese Tür hat bestimmte Eigenschaften: Sie ist geöffnet oder geschlossen und hat eine bestimmte Farbe und Größe. Nun gibt es Methoden, diese Eigenschaften zu verändern: Sie können die Tür schließen oder mit einer anderen Farbe anstreichen. Übertragen auf Access funktioniert das genauso.
16.1.2
Objekte in Access
Auch in Access gibt es Objekte, Eigenschaften und Methoden: Steuerelemente und Formulare sind Objekte, die von verschiedenen Eigenschaften beschrieben werden und die mit Methoden verändert werden können. Im Laufe dieses Buches haben Sie schon viele Erfahrungen gesammelt im Aufrufen von Objekten und im Einsatz von Methoden zum Ändern von Objekteigenschaften. Sie haben beispielsweise die Titelzeile des Formulars frmAppartements mithilfe der Eigenschaft Caption bestimmt, indem Sie frmAdressen.Caption = gstrMotto
programmiert haben (wobei gstrMotto das Motto des Tages als String enthält). Wie Sie hier sehen, werden die Eigenschaften und Methoden eines Objekts durch einen Punkt mit dem Objektnamen verbunden. Bei der Arbeit mit Objekten werden Sie in der Form unterstützt, dass sobald Sie einen Punkt hinter einen Objektnamen setzen, sofort in einer Auswahlliste die zur Verfügung stehenden Eigenschaften und Methoden des Objekts gezeigt werden (vorausgesetzt, die Option ELEMENTE AUTOMATISCH AUFLISTEN ist unter EXTRAS OPTIONEN auf dem Registerblatt EDITOR ausgewählt).
16.1.3
Der Objektkatalog
Im Visual Basic-Editor steht Ihnen ein Objektkatalog zur Verfügung. Hier finden Sie eine Übersicht über alle Objekte mit ihren Eigenschaften und Methoden.
16.1 Was ist ein Objekt?
229
Den Objektkatalog können Sie über die gleichnamige Schaltfläche, über ANSICHT OBJEKTKATALOG oder 因 aufrufen. Bild 16.1: Der Objektkatalog
Die in Access zur Verfügung stehenden Objekte sind in Bibliotheken aufgeteilt. Normalerweise sind angewählt. Sie können die Liste aufklappen und gezielt einzelne Bibliotheken anschauen. ACCESS ist die allgemeine Access-Programmbibliothek, CASA MARIA steht für die aktuell geladene Datenbank und VBA ist die allgemeine VBA-Bibliothek. Im unteren Teil des Bildes ist hier als Beispiel im mittleren Fenster das Objekt APPLICATION selektiert, rechts die Eigenschaft FORMS, die selbst wieder ein Objekt oder genauer: eine Auflistung ist, in der sich alle geöffneten Formulare als Objekt ansprechen lassen. Damit Ihnen nicht vor lauter Objekten in Objekten in Objekten der Kopf schwirrt, noch einmal eine kurze Orientierung.
16.2 Wozu sind Objekte gut? Sie können sich nicht vorstellen, wozu die ganzen Objekte gut sein sollen? Dann betrachten Sie das Ganze doch einmal von der praktischen Seite her:
230
Kapitel 16: DAO und andere Objekte
Sie möchten das Textfeld TXTTEXT im Formular frmFormular
ändern? Mit Forms!frmFromular!txtText.value="Neuer Eintrag" greifen Sie darauf zu, d.h., Sie nutzen das FORMS-Objekt! Sie möchten den Bericht rptBericht ausdrucken? Dazu geben Sie die Zeile DoCmd.OpenReport "rptBericht" in Ihr Programm ein. Damit nutzen Sie das DoCmd-Objekt!
16.3 Der With-Befehl Ich möchte Ihnen nun das Befehlswort With beschreiben, das die Arbeit mit Objekten vereinfachen, zumindest aber etwas Schreibarbeit ersparen kann. Für das Formular frmObjektTest habe ich folgendes Programm geschrieben, das beim Klick auf die Schaltfläche CMDTEXTFELDERÄNDERN ausgelöst wird: Private Sub cmdTextfelderÄndern_Click() txtEintrag1.BackColor = 65535 txtEintrag1.ForeColor = 8421440 txtEintrag1.FontBold = True txtEintrag1.Value = "Casa Maria" txtEintrag1.TextAlign = 2 ' Zentriert End Sub
In jeder Zeile muss wieder der Name des Textfeldes erwähnt werden. Mit With geht es kürzer: Private Sub cmdTextfelderÄndern_Click() With txtEintrag1 .BackColor = 65535 .ForeColor = 8421440 .FontBold = True .Value = "Casa Maria" .TextAlign = 2 ' Zentriert End With End Sub
Wichtig ist, dass jede der Eigenschaften mit einem Punkt eingeleitet wird. So ist eindeutig, dass es sich um eine Objekteigenschaft oder -methode handelt.
16.3 Der With-Befehl
231
16.4 Auflistungen Eine Auflistung ist ein Spezialfall eines Feldes mit Objekten. Am einfachsten kann ich das an einem Beispiel erläutern: Alle Steuerelemente eines Formulars gehören automatisch zu der Auflistung Controls, die wiederum eine Eigenschaft des Formulars ist. Mit MsgBox frmForm.Controls(0).Name
würde der Name des ersten Steuerelements des geöffneten Formulars frmForm in einer MessageBox ausgegeben werden. Sie könnten aber auch durch frmForm.Controls("txtEintrag1").Value = "Dies ist ein Text"
den Text des Textfelds mit dem Namen Eintrag1 setzen. Das geht ebenso, nur kürzer, mit frmForm.Controls!txtEintrag1.Value = "Dies ist ein Text"
Oder Sie schreiben für das gerade aktive Formular Me.Controls("txtEintrag1").Value = "Dies ist ein Text"
Mehrere Textfelder unsichtbar machen Hier ein kleiner Zaubertrick, wie Sie mehrere Textfelder eines Formulars unsichtbar machen können. Zum Ausprobieren binden Sie folgende For...Next-Schleife in die oben für das Formular frmObjektTest erstellte Prozedur. Dim strSpeicher As String Dim intZähler As Integer For intZähler = 1 To 3 ' Feldname aus Text und Ziffer bilden strSpeicher = "txtEintrag" & intZähler Forms("frmObjektTest").Controls(strSpeicher).Visible _ = False Next
Die Textfelder des Formulars frmObjektTest haben die Namen TXTTXTEINTRAG2 und TXTEINTRAG3. Deshalb lassen sie sich mit der obigen For...Next-Schleife nacheinander unsichtbar machen.
EINTRAG1,
232
Kapitel 16: DAO und andere Objekte
16.5 Makroaktionen über DoCmd-Objekt nutzen Mithilfe des DoCmd-Objekts können Sie bis auf wenige Ausnahmen alle Access-Aktionen ausführen, die sich mit Makros auslösen lassen. Um den Bericht rptAppartements in der Seitenansicht zu öffnen, schreiben Sie: DoCmd.OpenReport "rptAppartements", acViewPreview
Wie gewohnt werden Sie im Visual Basic-Editor durch die Eingabehilfen unterstützt. Neben der Seitenansicht erhalten Sie zur Auswahl angeboten: ACVIEWNORMAL (Ausdruck), ACVIEWDESIGN (Entwurf). Außerdem stehen die Pivot-Ansichten zur Verfügung. Bild 16.2: Konstanten anzeigen als Eingabeunterstützung
Eine Auflistung aller DoCmd-Methoden finden Sie im Objektkatalog. Tippen Sie einfach DoCmd in das Suchfeld des Objektkatalogs und starten Sie die Suche mit Klick auf das SUCHEN-Symbol. Bild 16.3: Elemente des DoCmdObjekts anzeigen lassen
16.5 Makroaktionen über DoCmd-Objekt nutzen
233
Wenn Sie ein Element der Liste markieren, können Sie mit Klick auf das Fragezeichen einen Hilfetext zur jeweiligen DoCmd-Methode anzeigen lassen.
Manchmal gibt es Alternativen zu DoCmd Zu einer Reihe von DoCmd-Methoden gibt es VBA-Befehle, die Sie als Alternative einsetzen können. Achten Sie in den Hilfetexten auf entsprechende Hinweise. So nutzen Sie z.B. statt DoCmd.GoToControl "txtAnreise" besser txtAnreise.SetFocus.
16.6 Datenbankzugriff mit DAO Manchmal kann es praktisch sein, die Daten einer Datenbank direkt zu ändern oder zu ergänzen.
16.6.1
Unterschiedliche Wege zu den Daten
Microsoft hat für den Zugriff auf die Daten einer Datenbank im Laufe der Zeit mehrere Zugriffsprogrammmodule entwickelt. Die beiden wichtigsten sind DAO und ADO.
DAO DAO, Data Access Objects, ist eine Sammlung von Objekten, die Methoden und Eigenschaften bereitstellen, um auf Access- und andere Datenbanken zuzugreifen. DAO wurde für Access entwickelt, beim Zugriff auf andere Datenbanken kann es zu Einschränkungen kommen. Mit DAO können alle Möglichkeiten des Access-Datenbankkerns, der so genannten Jet-Engine, genutzt werden.
ADO Seit Access 2000 liefert Microsoft die Datenbankzugriffsschnittstelle ADO, Active Data Objects. Ebenso wie DAO stellt ADO Ob-
234
Kapitel 16: DAO und andere Objekte
jekte, Methoden und Eigenschaften zum Zugriff auf Datenbanken bereit, allerdings nicht mehr auf Access spezialisiert. ADO ist die neuere und leistungsfähigere Zugriffsvariante, deren Verwendung von Microsoft empfohlen wird.
DAO oder ADO? Nun stellt sich die Frage: DAO oder ADO? Formulieren wir es einmal so: die Zukunft gehört (zumindest bis Microsoft etwas Neues einfällt) ADO, aber wenn Sie nicht komplexe Programmsysteme erstellen möchten, ist DAO für den Einstieg besser geeignet.
Einsatz von DAO ermöglichen Sie können DAO nur verwenden, wenn Sie einen Verweis auf die entsprechende Objektbibliothek aktiviert haben. Rufen Sie über EXTRAS VERWEISE das Dialogfeld VERWEISE im VISUAL BASIC-EDITOR auf und wählen Sie den Eintrag MICROSOFT DAO 3.6 OBJECT LIBRARY.
16.6.2
Recordset-Objekte
Bei dem Einsatz von DAO wird mit so genannten Recordsets gearbeitet. Was ist ein Recordset? In einem Recordset-Objekt wird die Ergebnismenge eines Zugriffs auf Daten der Datenbank zurückgegeben. Mithilfe der Methoden des Objekts kann die Sortierung der Daten geändert werden, es kann nach bestimmten Werten gesucht und Daten können geändert werden. Ein Recordset kann man sich als eine Tabelle von Daten vorstellen, die mithilfe eines SQL-Befehls zusammengestellt wurden. Der SQL-Befehl bestimmt die Spalten der Tabelle. Ein Datensatzzeiger zeigt intern auf den aktuellen Datensatz. Sollen die Inhalte eines Datensatzes bearbeitet werden, muss der Datensatzzeiger mithilfe der Move-Methoden des Recordsets zum entsprechenden Datensatz verschoben werden.
16.6 Datenbankzugriff mit DAO
235
Die Eigenschaften BOF und EOF ermöglichen die Kontrolle des Datensatzzeigers. Hat BOF den Wert True, steht der Datensatzzeiger vor dem ersten Datensatz. Ist die Position des Datensatzzeigers hinter dem letzten Datensatz des Recordsets, ist EOF wahr. Die Methode AddNew fügt dem Recordset einen neuen, leeren Datensatz hinzu. Mit Edit bearbeiten Sie den aktuellen Datensatz. Die Methode Delete löscht den aktuellen Datensatz. Voraussetzung dafür ist allerdings, dass die Ergebnismenge bearbeitbar ist, d.h. die Eigenschaft Updatable wahr ist.
Tabelle 16.1: Eigenschaften eines Recordsets
Tabelle 16.2: Methoden eines Recordsets
236
Eigenschaften
Bemerkung
BOF
(Begin Of File) ist dann wahr, wenn der Datensatzzeiger vor dem ersten Datensatz steht.
EOF
(End Of File) ist dann wahr, wenn der Datensatzzeiger hinter dem letzten Datensatz steht.
NoMatch
ist wahr, wenn eine Suche mit den Find-Methoden ohne Ergebnis war.
RecordCount
gibt die Anzahl der Datensätze im Recordset zurück; bei Recordsets vom Dynaset ist der Wert erst aktuell, wenn zuvor die Methode MoveLast ausgeführt wurde.
Updatable
Die Daten des Recordsets können geändert werden bzw. Datensätze können gelöscht und hinzugefügt werden, wenn die Eigenschaft Updatable wahr ist.
Methode
Bemerkung
MoveNext
bewegt den Datensatzzeiger zum nächsten Datensatz.
MovePrevious
bewegt den Datensatzzeiger zum vorhergehenden Datensatz.
MoveFirst
bewegt den Datensatzzeiger zum ersten Datensatz.
MoveLast
bewegt den Datensatzzeiger zum letzten Datensatz.
FindFirst Kriterien
sucht den ersten Datensatz, der den Kriterien entspricht.
FindNext Kriterien
sucht den nächsten Datensatz, der den Kriterien entspricht.
FindLast Kriterien
sucht den letzten Datensatz, der den Kriterien entspricht.
Kapitel 16: DAO und andere Objekte
Tabelle 16.2 (Forts.): Methoden eines Recordsets
Methode
Bemerkung
FindPrevious Kriterien
sucht den vorhergehenden Datensatz, der den Kriterien entspricht.
Edit
schaltet einen Datensatz in den Bearbeitungsmodus.
AddNew
hängt einen neuen, leeren Datensatz an das Recordset.
Update
schreibt einen neuen oder aktualisierten Datensatz in die Datenbank.
Um auf die Werte in den Tabellenspalten des Recordsets zuzugreifen, verwenden Sie die Feldnamen in der Form DAO.Recordset("Feldname")
oder besser DAO.Recordset!Feldname.
Mit Recordsets arbeiten Jetzt möchte ich Ihnen zeigen, wie Sie mit Recordsets in Ihrer Datenbank Daten verändern, hinzufügen oder löschen können. Wenn Sie auf die Tabelle tblAdressenDeutschland zugreifen möchten, schreiben Sie am Anfang Ihrer Prozedur: Dim rst As DAO.Recordset Set rst = CurrentDb.OpenRecordset("tblAdressenDeutschland")
Damit deklarieren Sie die Variable rst als Recordset, das Sie dann mit Set öffnen, wobei CurrentDb für die aktuelle Datenbank steht. Um auf die Werte in den Tabellenspalten des Recordsets zuzugreifen, verwenden Sie die Feldnamen in der Form DAO.Recordset("Feldname")
oder besser DAO.Recordset!Feldname
Mit der Variablen rst brauchen Sie dann einfach nur rst.Nachname
zu schreiben, um das zugehörige Feld anzusprechen.
16.6 Datenbankzugriff mit DAO
237
Daten verändern Um den aktuellen Datensatz zu ändern, kopieren Sie mit Edit die Daten in einen internen Puffer. Sind die Daten bearbeitet, wird die Änderung mit Update geschrieben. Erst danach sind die Bearbeitungen dauerhaft gespeichert. Public Sub DatensatzÄndern_DAO() Dim rst As DAO.Recordset Set rst = CurrentDb.OpenRecordset("tblAdressenDeutschland") ' Alle Datensätze durchlaufen (bis EOF -End of File) Do Until rst.EOF ' Recordset bearbeiten rst.Edit ' Allen Nachnamen 'von' voranstellen rst!Nachname = "von " & rst!Nachname ' Datensatzänderungen speichern rst.Update ' Zum nächsten Datensatz gehen rst.MoveNext Loop rst.Close End Sub
Mit dieser Prozedur machen Sie alle Casa-Maria-Gäste zu Adeligen. Wenn Sie das von vor den Namen wieder entfernen wollen, ändern Sie die Programmzeile für den nächsten Durchlauf einfach wie folgt: rst!Nachname = Right(rst!Nachname, Len(rst!Nachname) - 4)
Neue Datensätze hinzufügen Mithilfe von AddNew wird dem Recordset ein neuer Datensatz hinzugefügt. Dem zunächst leeren Datensatz können dann Felder zugeordnet werden. Nach Update werden die Daten in die zugrunde liegende Tabelle geschrieben. Private Sub DatensatzHinzufügen_DAO() Dim rst As dao.Recordset Set rst = CurrentDb.OpenRecordset("tblBuchungen") With rst ' Neuen Datensatz anlegen .AddNew
238
Kapitel 16: DAO und andere Objekte
' Mit Daten füllen !Appartementnummer = 12 !Buchungsnummer = 200300301 ' Datum in englischer Schreibweise !Anreise = #3/13/2003# !Abreise = #3/21/2003# ' Neuen Datensatz speichern .Update End With rst.Close End Sub
Datensätze löschen Sie können den aktuellen Datensatz mit Delete löschen. Es bietet sich an, dafür ein Recordset für eine Abfrage zu erstellen. Dazu wird bei der Definition des Recordsets einfach der Name der Abfrage eingetragen. Public Sub DatensatzLöschen_DAO() Dim rst As dao.Recordset Set rst = CurrentDb.OpenRecordset("qryAlteBuchungen") ' qryAlteBuchungen zeigt Buchungen, ' deren Abreisedatum mehr als 400 Tage zurück liegt. ' Ist das Recordset bearbeitbar? If rst.Updatable = False Then MsgBox "Recordset kann nicht aktualisiert werden" Exit Sub End If ' Alle Datensätze durchlaufen Do Until rst.EOF ' Datensatz löschen rst.Delete ' Zum nächsten Datensatz gehen rst.MoveNext Loop rst.Close End Sub
Schluss mit dem DAOismus Genug der Theorie. Im nächsten Kapitel geht es um die praktische Umsetzung des neu gewonnenen Wissens um VBA, DAO und Co.
16.6 Datenbankzugriff mit DAO
239
17 VBA-Praxisbeispiel Nicht nur in unserer Ferienappartementsiedlung Casa Maria, auch im Rest der Toskana hält man sich an das alte Sprichwort »Di giove e di marte non si sposa e non si parte. – Donnerstags und dienstags heiratet man nicht und reist nicht ab.« Viele unserer Gäste scheinen davon noch nichts gehört zu haben, denn sie heiraten, reisen ab und an, wie es ihnen gerade in den Kram passt, ohne sich darum zu kümmern, welcher Wochentag gerade ist!
Damit es bei der Aufnahme der Buchungen trotzdem kein Kuddelmuddel gibt, habe ich dafür ein neues Access-Formular entworfen, das die Sache vereinfachen soll. Dabei habe ich auf das zurückgegriffen, was Thema des VBA-Teils dieses Buches war.
17.1 Wie sollen Buchungen aufgenommen werden? Das Telefon klingelt, jemand ruft an und möchte ein Casa-MariaFerienappartement buchen. In dieser Situation muss sich das neue Formular bewähren. Die Frage »Wer möchte welches Appartement wann buchen?« soll möglichst einfach geklärt werden, so dass am Ende die Buchung aufgenommen ist und der Gast eine Buchungsbestätigung bekommt. Genau genommen müssen ja drei Fragen geklärt werden: die nach dem Gast, nach dem Buchungszeitraum und nach dem Appartement. Für alle drei findet sich ein Bereich auf dem Formular.
240
Kapitel 17: VBA-Praxisbeispiel
Bild 17.1: Wer möchte wann welches Appartement buchen?
Im Formular soll es möglich sein, den gewünschten An- und Abreisetermin aufzunehmen und dann aus der Liste der zu diesem Zeitraum freien Appartements eines auszuwählen. Für das Appartement sollen zusätzlich eine obere Preisgrenze und die mindestens erforderliche Personenanzahl angegeben werden können. Über die Angabe des Namens soll schnell herausgefunden werden, ob der Gast bereits im Adressverzeichnis enthalten ist oder neu aufgenommen werden muss. Sind alle Fragen geklärt, soll die Buchung per Klick aufgenommen und automatisch eine Buchungsbestätigung ausgedruckt werden.
17.2 Was steckt hinter dem Formular? VBA-Code! Aber nicht nur – zum Teil spielen auch Abfragen für das Funktionieren des Formulars eine wichtige Rolle. Ich möchte Ihnen kurz die grundsätzlichen Überlegungen und Lösungsansätze vorstellen. Damit (und mit dem Wissen aus den letzten Kapiteln) sollte es Ihnen leicht möglich sein, den Code zu knacken und zu verstehen, was sich hinter dieser Liste von Programmzeilen verbirgt!
17.2 Was steckt hinter dem Formular?
241
17.2.1
Gast wählen
Der im Formular frmWunschTermin im Feld TXTSUCHFELD eingetragene Name dient als Filterkriterium, das beim Öffnen von frmAdressenWählen mit DOCMD.APPLYFILTER gesetzt wird. Nach Klick auf die SUCHEN-Schaltfläche CMDSUCHEN wird frmWunschTermin geöffnet und die herausgefilterten Datensätze werden angezeigt. Der gewünschte Datensatz wird dann nach Klick auf die Schaltfläche CMDGASTÜBERNEHMEN mit folgender Prozedur in frmWunschTermin übernommen, wobei die Gästenummer in die globale Variable glngGast geschrieben wird: Private Sub cmdGastÜbernehmen_Click() ' Ausgewählte Gästenummer in globaler Variable speichern glngGast = [Gästenummer] ' Name des Gastes in frmWunschTermin übernehmen Forms![frmWunschTermin]![txtVollerName] = [VollerName] ' Dies Formular schließen DoCmd.Close ' Zu Formular frmWunschTermin wechseln DoCmd.OpenForm "frmWunschTermin" ' Öffentliche Sub-Prozedur zum Aktualisieren der ' Angaben in der Buchungsspalte aufrufen BuchungAnzeigen End Sub
Die öffentliche Sub-Prozedur BuchungAnzeigen liegt im Modul mdlWunschTerminBuchung. Sie aktualisiert die Buchungsspalte und hat folgenden Aufbau: Option Option Public Public Public
Compare Database Explicit glngAppartement As Long gstrTermin As String glngGast As Long
Public Sub BuchungAnzeigen() ' Buchungsspalte aktualisieren, Bezeichnungsfeld ändern, ' je nachdem, ob ein Eintrag vorhanden ist oder nicht. If glngGast <> 0 Then Forms!frmWunschTermin.lblGast.Caption = _ "Rechnung geht an: " Else
242
Kapitel 17: VBA-Praxisbeispiel
Forms!frmWunschTermin.lblGast.Caption = _ "Gast wählen!" End If If gstrTermin <> "" Then Forms!frmWunschTermin.lblZeitraum.Caption = _ "Zeitraum: " & gstrTermin Else Forms!frmWunschTermin.lblZeitraum.Caption = _ "Zeitraum wählen!" End If If glngAppartement <> 0 Then Forms!frmWunschTermin.lblAppartement.Caption = _ "App.Nr.: " & glngAppartement Else Forms!frmWunschTermin.lblAppartement.Caption = _ "Appartement wählen!" End If ' Schaltfläche cmdBuchungAufnehmen aktivieren, ' wenn alles eingetragen ist If glngAppartement <> 0 And gstrTermin <> "" _ And glngGast <> 0 Then Forms!frmWunschTermin.cmdBuchungAufnehmen.Enabled = True Else ' Fokus irgendwo hin setzen, damit die Schaltfläche ' gleich deaktiviert werden kann Forms!frmWunschTermin.cboMaximaleBelegung.SetFocus Forms!frmWunschTermin.cmdBuchungAufnehmen.Enabled = False End If End Sub
17.2.2
Wunsch-Termin auswählen
Wird ein Anreisedatum eingetragen, erscheint standardmäßig automatisch ein zwei Wochen später liegendes Abreisedatum. Dieser Eintrag kann per Klick auf die Optionsfelder auf eine oder drei Wochen geändert werden. Wird das Abreisedatum so geändert, dass es keiner geraden Wochenanzahl entspricht, wird automatisch FREIER EINTRAG angezeigt. Diese gegenseitige Abhängigkeit von Optionsfeldgruppe und Einträgen in An- und Abreise wurde mit If Then und Select Case-Strukturen programmiert.
17.2 Was steckt hinter dem Formular?
243
17.2.3
Appartement wählen
Das Listenfeld, das die zum gewählten Zeitraum freien Appartements anzeigt, basiert auf der Abfrage qryWunschTerminFrei, die wiederum die Abfrage qryBelegteAppartements abfragt. Der Trick dabei ist, dass in qryBelegteAppartements zuerst die belegten Appartements herausgefiltert werden. In Abfrage qryWunschTerminFrei werden dann alle Appartements angezeigt, nur nicht die aus qryBelegteAppartements. Übrig bleiben also nur die freien! Ein Appartement ist belegt, wenn entweder die WUNSCHABREISE, die WUNSCHANREISE oder beide in einem Buchungszeitraum liegen. Für alle drei Fälle wird in qryBelegteAppartements ein entsprechendes Kriterium eingefügt. Bild 17.2: Ausschnitt aus qryBelegteApartements
Das in der Liste angeklickte Appartement wird zum Buchen übernommen.
Auswahl einschränken Die beiden Kombinationsfelder zum Angeben von Preisgrenze und Personenanzahl basieren auf Abfragen, die nur die in den zugehörigen Tabellen eingetragenen Werte als Auswahl zulassen.
17.2.4
Buchen, wenn alles gewählt ist
Wenn Gast, Zeitraum und Appartement gewählt sind, wird die Schaltfläche BUCHUNG AUFNEHMEN aktiviert und es kann gebucht werden. Die Buchungsdaten werden per DAO.RECORDSET eingetragen. Nach einer Bestätigungsmeldung kann automatisch der Bericht rptBuchungsbestätigung mit der Buchungsbestätigung ausgedruckt werden. Der Bericht beruht auf der Abfrage qryBuchungsbestätigung, die nur den Datensatz mit der gerade erstellten Buchungsnummer anzeigt.
244
Kapitel 17: VBA-Praxisbeispiel
17.3 Listing Option Compare Database Option Explicit ' Als Long, da Gästenummer und Appartementnummer AutoWerte Dim lngGast As Long, Dim lngAppartement As Long Dim strTermin As String ' zum Anzeigen des Zeitraums Private Sub Form_Load() 'Globale Variablen zurücksetzen gstrTermin = "" glngAppartement = 0 glngGast = 0 End Sub Private Sub cmdSuchen_Click() ' Formular frmAdressenWählen öffnen DoCmd.OpenForm "frmAdressenWählen" ' Dabei nur Adressen anzeigen, bei denen die in ' frmWunschTermin im txtSuchfeld eingetragene ' Zeichenfolge im Feld VollerName enthalten ist DoCmd.ApplyFilter , "VollerName like ""*"" & forms![frmWunschTermin]!txtSuchfeld &""*"" " ' Gästenummer wird dabei in txtGast und VollerName in ' txtVollerName geschrieben End Sub Private Sub txtWunschAnreise_AfterUpdate() ' Abreisedatum in Abhängigkeit von in Optionsfeld fraWoche ' gewählter Wochenanzahl eintragen [txtWunschAbreise] = [txtWunschAnreise]+(7*fraWoche.Value) ZeitraumÜbernehmen 'in rechte Spalte ' Neuberechnung: kein Listeneintrag markiert lstAppartements = "" ' Appartementliste und Buchungsspalte aktualisieren ListenEintrag End Sub Private Sub txtWunschAbreise_AfterUpdate() Dim dblDauerOption As Double Dim dblWunschWochen As Double dblDauerOption = fraWoche ' Wenn Anreise und Abreise eingetragen sind, überprüfen, ' ob geänderte Abreise 1, 2 oder 3 Wochenabstand entspricht ' und ggf. Opt. markieren If IsNull(Me.txtWunschAnreise) = False _ And IsNull(Me.txtWunschAbreise) = False Then
17.3 Listing
245
' Lässt sich Dauer durch 7 Tage teilen? dblWunschWochen =( _ [txtWunschAbreise]-[txtWunschAnreise]) / 7 fraWoche = Cint(dblWunschWochen) ' Zu int konvertieren ' Wenn noch keine Anreise eingetragen wurde, ' um unter Dauer angegebener Wochenzahl zurückrechnen Else Me.txtWunschAnreise= _ Me.txtWunschAbreise-(dblDauerOption * 7) End If ' Anreise muss vor Abreise liegen If [txtWunschAbreise] < [txtWunschAnreise] Then [txtWunschAbreise] = [txtWunschAnreise] MsgBox "Abreise muß nach Anreise liegen" End If ZeitraumÜbernehmen 'in rechte Spalte ' Wegen Neuberechnung soll kein Listeneintrag markiert sein lstAppartements = "" ' Appartementliste und Buchungsspalte aktualisieren ListenEintrag End Sub Public Sub ZeitraumÜbernehmen() ' Eintrag in Buchungsspalte generieren ' Wenn nichts eingetragen wird nichts übernommen If (IsNull(Me.txtWunschAbreise) = True _ And IsNull(Me.txtWunschAnreise) = True) Then strTermin = "" ' Sonst Eintrag aus An- und Abreise zusammensetzen Else strTermin = [txtWunschAnreise] & "-" & _ [txtWunschAbreise] End If End Sub Private Sub fraWoche_AfterUpdate() ' Neue Wochenauswahl im Optionsfeld führt zu Neuberechnung ' von WunschAbreise txtWunschAnreise_AfterUpdate End Sub Private Sub cboMaximaleBelegung_AfterUpdate() ' Wegen Neuberechnung soll kein Listeneintrag markiert sein lstAppartements = "" ' Appartementliste und Buchungsspalte aktualisieren ListenEintrag End Sub
246
Kapitel 17: VBA-Praxisbeispiel
Private Sub cboPreisProTag_AfterUpdate() ' Wegen Neuberechnung soll kein Listeneintrag markiert sein lstAppartements = "" ' Appartementliste und Buchungsspalte aktualisieren ListenEintrag End Sub Private Sub lstAppartements_Click() ' Appartementliste und Buchungsspalte aktualisieren ListenEintrag End Sub Public Sub ListenEintrag() ' Appartementliste aktualisieren DoCmd.Requery "lstAppartements" ' Wenn kein Appartement vorhanden lngAppartement leeren If Me.lstAppartements = "" Then lngAppartement = 0 ' sonst Listeneintrag übernehmen Else lngAppartement = Me.lstAppartements End If 'Anzahl der freien Appart. in Bezeichnungsfeld ausgeben If Me.lstAppartements.ListCount = 0 Then Me.lblListeAppartements.Caption = _ "Zum angegebenen Zeitraum sind keine " & _ "Appartements " & _frei! " & _ "(Bitte oben neue Auswahl)" ElseIf Me.lstAppartements.ListCount = 2 Then Me.lblListeAppartements.Caption = _ "Zum angegebenen Zeitraum ist ein " & _ "Appartement frei! " & _ "(Zum Auswählen auf Eintrag klicken):" Else Me.lblListeAppartements.Caption = _ "Zum angegebenen Zeitraum sind " _ & Me.lstAppartements.ListCount - 1 & _ "Appartements frei!" & _ "(Zum Auswählen auf Eintrag klicken):" End If ' Eintrag in Buchungsspalte aktualisieren ' ist als globale Sub-Procedur abgelegt, damit man auch ' von frmAdresseWählen darauf zugreifen kann. ' Wert für globale Variablen setzen gstrTermin = strTermin glngAppartement = lngAppartement BuchungAnzeigen End Sub
17.3 Listing
247
Private Sub cmdBuchungAufnehmen_Click() Dim rst As DAO.Recordset ' zuerst Buchungsnummer berechnen mit angepasstem ' Buchungsnummernmakro mcrBuchungsnummerVBA, das sich auf ' qryBuchungsnummerVBA bezieht. ' Buchungsnummer wird in txtBuchungsnummer geschrieben DoCmd.RunMacro "mcrBuchungsnummerVBA" Dim rst As dao.Recordset 'Buchungsdaten in Tabelle tblBuchungen eintragen Set rst = CurrentDb.OpenRecordset("tblBuchungen") With rst .AddNew !Appartementnummer = lngAppartement !Buchungsnummer = txtBuchungsnummer ' DateValue wandelt Datum in richtige Schreibweise um !Anreise = DateValue(txtWunschAnreise) !Abreise = DateValue(txtWunschAbreise) .Update .Close End With rst.Close 'Buchungsdaten in Tabelle tblBelegung eintragen Set rst = CurrentDb.OpenRecordset("tblBelegung") With rst .AddNew !Gästenummer = lngGast !Buchungsnummer = txtBuchungsnummer !Rechnung = -1 'als Rechnungsadresse markieren .Update .Close
End With rst.Close ' Wegen Neuberechnung soll kein Listeneintr. markiert sein lstAppartements = "" ' Appartementliste und Buchungsspalte aktualisieren ' ListenEintrag ' Buchungsdaten in MessageBox anzeigen MsgBox "Folgende Buchung wurde aufgenommen:" & Chr(13) & _ "Rechnung an:" & txtVollerName & Chr(13) & _ "Zeitraum: " & strTermin & Chr(13) & _ "Appartementnummer: " & lngAppartement & Chr(13) & _ "Buchungsnummer: " & txtBuchungsnummer
248
Kapitel 17: VBA-Praxisbeispiel
' Auf Wunsch Buchungsbestätigung ausdrucken If MsgBox("Soll eine Bestätigung ausgedruckt werden?", _ vbYesNo + vbQuestion, "Buchungsbestätigung") = vbYes _ Then DoCmd.OpenReport "rptBuchungsbestätigung" End If ' wieder zu Formular wechseln DoCmd.OpenForm "frmWunschTermin" ' Wegen Neuberechnung soll kein Listeneintrag markiert sein lstAppartements = "" ' Appartementliste und Buchungsspalte aktualisieren ListenEintrag End Sub Private Sub Form_Open(Cancel As Integer) 'Motto des Tages übernehmen Me.Form.Caption = "Aufnehmen einer Buchung: " & gstrMotto End Sub
17.3 Listing
249
Index A Active Data Objects............................... 234 AddNew (Methode)................................ 237 ADO .................................................... 234 Anwendungstitel ................................... 129 Argumente ........................................... 193 Asc ..................................................... 201 Auflistung ............................................ 232 Aufrufreihenfolge .................................. 212 Ausdrücke finden.................................. 113 Ausdrucks-Generator......................... 40, 79 AutoExec-Makro .................................... 126
Chr ..................................................... 201 CInt .................................................... 204 Clear (Methode) ................................... 224 CLng ................................................... 204 Close .................................................. 202 Code behind forms ............................... 152 Code-Fenster ....................................... 151 Code-Generator ...................................... 20 Const (Anweisung)................................ 167 CSng................................................... 204 CurDir ................................................. 203 Currency.............................................. 158 CVar ................................................... 204
B Bedingte Abfragen ................................ 176 Bedingte Formatierung ............................ 24 Beispieldatenbank ............................ 12, 16 BOF (Eigenschaft) ................................. 236 Boolean....................................... 158, 162 By Reference (ByRef)............................. 222 By Value (ByVal) ................................... 222 Byte .................................................... 158 ByVal (Anweisung)................................. 195
C Call (Anweisung) ................................... 192 Case (Anweisung) ................................. 180 Case Else (Anweisung) .......................... 180 CBool .................................................. 204 CByte .................................................. 204 CCur.................................................... 204 CDate.................................................. 204 CDbl.................................................... 204 CD-ROM................................................. 14 ChDir................................................... 203 ChDrive ............................................... 203
250
Index
D DAO ............................................ 234, 244 Data Access Objects............................. 234 Date ....................................158, 164, 205 DateAdd .............................................. 205 DateDiff .............................................. 205 Datenbank ADO ................................................ 234 DAO ................................................ 234 Grundeinstellungen........................... 126 Datenbankfenster ausblenden ............... 129 Datensatz mit Recordset hinzufügen ....................................... 238 löschen ........................................... 239 verändern ........................................ 238 Datentyp Boolean................................... 158, 162 Byte ................................................ 158 Currency .......................................... 158 Date........................................ 158, 164 Double ............................................ 158 Integer............................................. 158 Long................................................ 158 Single.............................................. 158
(Datentyp) String ...................................... 158, 166 Variant............................................. 158 DatePart .............................................. 205 DateSerial............................................ 205 DateValue............................................ 205 Datum ................................................... 29 Datumswerte........................................ 164 Day ..................................................... 205 DDB .................................................... 207 Debug.Print .......................................... 215 Debugger ............................................. 209 Deklaration explizit ............................................. 156 implizit............................................. 156 Description (Eigenschaft)....................... 223 Dim (Anweisung)................................... 156 Dir ...................................................... 203 Direktfenster ................................ 212, 214 Do (Anweisung) .................................... 183 DoCmd ................................................ 242 DoCmd-Objekt ...................................... 233 DomWert ............................................. 116 Double ................................................ 158
E Edit (Methode)...................................... 237 Eigenschaften ...................................... 229 Eigenständige Module ........................... 152 Einzelschritt ............................. 60, 99, 217 Else (Anweisung) .................................. 177 ElseIf (Anweisung) ................................ 176 End If (Anweisung) ................................ 177 End Select (Anweisung) ......................... 180 End Sub (Anweisung) ............................ 154 EOF (Eigenschaft) ................................. 236 EOF (Funktion) ...................................... 202 Ereignis ................................................. 60 bei eingefügter Grafik ........................ 133 beim Öffnen ....................................... 66 für Formular........................................ 66 im Bericht ........................................ 120 im Unterbericht ................................. 122 nach Aktualisierung ............................. 64
Exit Exit Exit Exit
Do (Anweisung) .............................. 183 For (Anweisung).............................. 182 Function (Anweisung) ...................... 188 Sub (Anweisung) ............................ 191
F False .................................................. 162 Fehler übergehen ................................. 225 Fehlerbehandlung Err-Objekt Clear (Methode) ............................ 224 Description (Eigenschaft)................ 223 HelpContext (Eigenschaft) .............. 224 HelpFile (Eigenschaft) .................... 224 LastDLLError (Eigenschaft) ............. 224 Number (Eigenschaft)..................... 223 Raise (Methode)............................ 224 Source (Eigenschaft)...................... 223 Fehler übergehen.............................. 225 Fehlerobjekt ..................................... 223 On Error Goto ................................... 224 On Error Goto 0 ................................ 226 On Error Resume Next....................... 225 Resume........................................... 226 Resume Next ................................... 226 Zurücksetzen ................................... 226 Fehlerobjekt......................................... 223 Fehlersuche......................................... 208 Debug.Print...................................... 215 Direktfenster .................................... 214 Einzelschritt ..................................... 217 Haltepunkte ..................................... 212 Prozedurschritt ................................. 217 Strg+Unterbr .................................... 213 Überwachung ................................... 219 Feld aktivieren........................................... 32 Eigenschaften ändern ......................... 82 Eigenschaften per Makro ändern .......... 97 unsichtbar ......................................... 97 Felder ................................................. 168 Feldwert ................................................ 27 FileCopy .............................................. 202 FileDateTime........................................ 202
Index
251
FileLen ................................................ 202 Filtern per Makro .................................. 100 FindFirst (Methode) ............................... 236 FindLast (Methode) ............................... 236 FindNext (Methode)............................... 236 FindPrevious (Methode) ......................... 237 Fokussierung.......................................... 25 For (Anweisung) .................................... 182 Format......................................... 162, 201 Format-Funktion.................................... 114 Formular automatisch zentrieren ...................... 131 beim Starten öffnen .......................... 129 Uhrzeit einbinden .............................. 144 Formularsynchronisation........................ 104 Function (Anweisung) .................... 186, 188 Funktionen Dateien u. Verzeichnisse ChDir............................................ 203 ChDrive......................................... 203 CurDir........................................... 203 Dir................................................ 203 FileCopy........................................ 202 FileDateTime ................................. 202 FileLen.......................................... 202 GetAttr.......................................... 203 MkDir ........................................... 203 Name ........................................... 203 RmDir........................................... 203 SetAttr.......................................... 203 Dateioperationen Close............................................ 202 EOF .............................................. 202 Input# .......................................... 203 Kill ............................................... 203 Line Input#.................................... 203 Open ............................................ 203 Print# ........................................... 203 Datenfelder IsArray............................ 206 Datum u. Uhrzeit Date............................................. 205 DateAdd ....................................... 205 DateDiff ........................................ 205 DatePart ....................................... 205 DateSerial..................................... 205 DateValue ..................................... 205
252
Index
(Funktionen: Datum u. Uhrzeit) Day .............................................. 205 Hour ............................................ 206 Minute ......................................... 206 Month .......................................... 206 Now ............................................. 206 Second......................................... 206 Time ............................................ 206 TimeSerial .................................... 206 TimeValue .................................... 206 Weekday ...................................... 206 Year............................................. 206 Finanzen DDB............................................. 207 IPmt............................................. 207 NPer ............................................ 207 Pmt.............................................. 207 PV................................................ 207 Rate............................................. 207 SLN ............................................. 207 SYD ............................................. 207 Typkonvertierung Asc .............................................. 201 CBool........................................... 204 CByte ........................................... 204 CCur ............................................ 204 CDate .......................................... 204 CDbl ............................................ 204 Chr .............................................. 201 CInt ............................................. 204 CLng ............................................ 204 CSng............................................ 204 CVar............................................. 204 Format ......................................... 201 LCase .......................................... 201 Str ............................................... 202 UCase.......................................... 202 Val............................................... 202 Verschiedenes IsDate .......................................... 206 IsEmpty ........................................ 206 IsNull ........................................... 206 IsNumeric..................................... 206 IsObject........................................ 206 Zeichenfolgen InStr ............................................ 201
(Funktionen: Zeichenfolgen) Left .............................................. 201 Len .............................................. 201 LTrim............................................ 202 Mid .............................................. 202 Right ............................................ 202 RTrim ........................................... 202 Space........................................... 202 Str ............................................... 202 StrComp ....................................... 202 Trim ............................................. 202
G GetAttr................................................. 203 Gruppenmakro........................................ 77 Gültigkeitsprüfung................................... 68
H Haltepunkte ......................................... 212 HelpContext (Eigenschaft)...................... 224 HelpFile (Eigenschaft)............................ 224 Hour.................................................... 206
I If Then................................................ 243 If (Anweisung)....................................... 176 Input# ................................................. 203 InputBox ...................................... 140, 201 InStr.................................................... 201 Integer................................................. 158 IPmt () ................................................. 207 IsArray................................................. 206 IsDate ................................................. 206 IsEmpty ............................................... 206 IsNull .................................................. 206 IsNumeric ............................................ 206 IsObject............................................... 206
K Kill ...................................................... 203 Kombinationsfeld.................................... 84
(Kombinationsfeld) zum Nachschlagen............................ 107 Kommentare........................................ 155 Kompilierfehler..................................... 208 Konstanten.......................................... 167
L LastDLLError (Eigenschaft) .................... 224 Laufzeitfehler....................................... 208 LBound ............................................... 211 LCase ................................................. 201 Left..................................................... 201 Len..................................................... 201 Line Input# .......................................... 203 Logische Operatoren............................. 173 Lokal-Fenster ............................... 212, 218 Long ................................................... 158 Loop (Anweisung) ................................. 183 LTrim .................................................. 202
M Makro ......................................16, 44, 233 Aktionen ............................................ 55 Aktionsargumente............................... 55 an Ereignis binden .............................. 60 ausführen .......................................... 59 AutoExec ......................................... 126 bearbeiten ......................................... 57 bedingte Ausführung ........................... 68 Einzelschritt ....................................... 60 Einzelschrittmodus.............................. 99 Feldeigenschaften ändern.................... 97 gebunden .................................... 62, 66 Grundlagen ........................................ 54 im Bericht ........................................ 120 in VBA-Code umwandeln .................... 146 Meldung .......................................... 124 mit Maus erstellen.............................. 52 mit Suchfunktion ................................ 88 per Klick ausführen............................. 47 zum Filtern....................................... 100 Makroentwurfsfenster ............................. 17 Makro-Generator .................................... 64
Index
253
Me (Anweisung) .................................... 190 Meldung ................................................ 17 MessageBox ................................ 141, 196 Methoden ............................................ 229 Mid ..................................................... 202 Minute................................................. 206 MkDir .................................................. 203 Modulweite Variablen ............................ 170 Month ................................................. 206 MoveFirst (Methode) ............................. 236 MoveLast (Methode) ............................. 236 MoveNext (Methode) ............................. 236 MovePrevious (Methode) ....................... 236 MsgBox ............................................... 196
N Namenskonvention ............... 159, 160, 222 Namenskürzel für Variablen ................... 158 Next (Anweisung) .................................. 182 NoMatch (Eigenschaft) .......................... 236 Now .................................................... 206 NPer().................................................. 207 Number (Eigenschaft)............................ 223
O Objekthierarchie ................................... 228 Objektkatalog ............................... 230, 233 Objektleiste............................................ 16 ÖffnenBericht ......................................... 46 On Error Goto ....................................... 224 On Error Goto 0 .................................... 226 On Error Resume Next........................... 225 Open ................................................... 203 Operatoren........................................... 172 Option Explicit (Anweisung) ............ 157, 221
P Pmt() ................................................... 207 Print# .................................................. 203 Private (Anweisung)............................... 188 Prozedurschritt ..................................... 217 PV()..................................................... 207
254
Index
R Raise (Methode)................................... 224 Rate() ................................................. 207 Ratenmonatszahlungen......................... 207 Rechnen in Berichten ....................................... 39 in Formularen ..................................... 34 RecordCount (Eigenschaft) .................... 236 Recordset............................................ 244 Recordset-Objekt.................................. 235 AddNew (Methode).................... 237, 238 BOF (Eigenschaft) ............................. 236 Edit (Methode).......................... 237, 238 EOF (Eigenschaft) ..................... 236, 238 FindFirst (Methode) ........................... 236 FindLast (Methode) ........................... 236 FindNext (Methode)........................... 236 FindPrevious (Methode) ..................... 237 MoveFirst (Methode) ......................... 236 MoveLast (Methode) ......................... 236 MoveNext (Methode) ......................... 236 MovePrevious (Methode) ................... 236 NoMatch (Eigenschaft) ...................... 236 RecordCount (Eigenschaft)................. 236 Updatable (Eigenschaft) .................... 236 Update (Methode)..............237, 238, 239 Referenz.............................................. 194 Resume .............................................. 226 Resume Next ....................................... 226 Right................................................... 202 RmDir ................................................. 203 RTrim .................................................. 202 run-time error....................................... 208
S Schleifen............................................. 181 Schlüsselwörter ................................... 154 Second ............................................... 206 Select Case......................................... 243 Select Case (Anweisung)....................... 180 SetAttr ................................................ 203 Single ................................................. 158 SLN() .................................................. 207 Source (Eigenschaft)............................. 223
Space.................................................. 202 Start-Einstellungen................................ 128 Startformular........................................ 129 Step (Anweisung).................................. 182 Steuerelement Tip-Text.......................... 132 Str() .................................................... 202 StrComp .............................................. 202 Strg+Unterbr ........................................ 213 String .......................................... 158, 166 Sub (Anweisung)........................... 186, 191 Suchen in zwei Feldern.................................... 94 mit Kombinationsfeld .......................... 84 mit Makro .......................................... 88 SYD() .................................................. 207 Symbolleisten ...................................... 134 Synchronisieren.............................. 49, 104
T Time.................................................... 206 TimeSerial ........................................... 206 TimeValue............................................ 206 Titelleisteneintrag ändern ...................... 143 Trim .................................................... 202 True .................................................... 162
U Übergabe per Referenz .......................... 194 Übergabe per Wert................................ 195 Überwachung ....................................... 219 Überwachungsfenster............................ 212 UBound ............................................... 211 UCase ................................................. 202 Uhrzeit................................................. 165 Umbenennen........................................ 203 Umschaltfäche ..................................... 100 Unterformular ....................................... 109 Unterprogramm .................................... 186 Until (Anweisung) .................................. 183
Updatable (Eigenschaft) ........................ 236 Update (Methode) ................................ 237
V Val...................................................... 202 Variable............................................... 156 deklarieren............................... 142, 156 globale ............................................ 192 Gültigkeit ......................................... 170 Variablenübergabe................................ 193 Variant ................................................ 158 VBA .............................................. 19, 136 VBA-Code ändern............................................. 136 aus Makro erstellen .......................... 146 neu erstellen.................................... 139 VBA-Entwicklungsumgebung................... 150 Vergleichsoperatoren ............................ 172 Verkettungsoperatoren.......................... 174 Vermeidung von Fehlern ........................ 220 Verzweigungen ..................................... 176 Visual Basic-Editor.......................... 20, 150
W Wahrheitswerte ............................ 158, 162 Weekday ............................................. 206 While (Anweisung) ................................ 183 With (Anweisung).................................. 231 Wochentagszählung................................ 30
Y Year.................................................... 206
Z Zeilenfortführung .................................. 156 Zurücksetzen ....................................... 226 ZW().................................................... 207
Index
255