ADAT Das Datenbanksystem ADAT-Skriptum Preißl 2 Inhaltsverzeichnis Dies ist eine nur teilweise aktualisierte Version des alten auf Access 2.0 basierenden Files. Alle Screenshots stammen noch aus Access 2.0, was aber nur optische und kaum inhaltliche Nachteile hat. Die zu den Beispielen passende Datenbank ist schschul-form.mdb Als zusätzliche Literatur zu diesem Skriptum eignet sich natürlich verschiedene Access Bücher, aber auch diverse Webseiten Das bestes Access Tutorial findet sich bei Michael Brydon mis.bus.sfu.ca/tutorials/MSAccess/tutorials.html Access Profi Seiten (unvollständig) : www.donkarl.com Karl Donaubauers sehr gehaltvolle Page incl. Linksammlung www.freeaccess.de hier gibt es vor allem die knowhow.mdb - umfangreichste Sammlung diverser Beispiele in einer DB www.mvps.org/access/ umfangreichste amerikanische Page www.trigeminal.com wahrscheinlich die besten Profis Wie alle Schriftwerke unterliegt diese Skriptum dem Urheberrechtsschutz (beim Vertrieb in den USA ist dafür ein Copyright Vermerk notwendig). Sie können daher für den privaten Gebrauch einige wenige Kopien anfertigen, Sie dürfen diese aber keinesfalls verkaufen und es ist ebenfalls nicht zulässig wenn Sie Teile des Skriptums oder gar das ganze Konvolut als eigene Schöpfung ausgeben. ADAT-Skriptum Preißl 3 1. MS-ACCESS 1.1. Allgemeines MS-Access ist eine relationale Datenbank der Firma Microsoft und läuft unter Windows. Es ist kein Client - Server System, als Datenbank stellt Access somit keine Konkurrenz zu den großen Datenbankherstellern wie Oracle oder Informix dar. Obwohl es schon seit langer Zeit Windows Datenbanken gab (Superbase, Omnis, ...) brachte die Vorstellung von Access Bewegung in den Markt, die Ablöse der MS-DOS Datenbanken (dBase, ...) durch Windows Datenbanken hatte begonnen. Heute haben praktisch alle PC-Datenbankanbieter die Windows Version Ihres Produkts im Programm. Access ist ein völlig neues System und mußte zu keinerlei Vorgängerversion kompatibel sein. Es bietet den höchsten Bedienungskomfort aller Windows-Datenbanken. Unterstützt durch Ratgeber und Assistenten (das sind Programme, die beim Erstellen von Applikationen helfen) können Anfänger simple Datenbankanwendungen entwickeln ohne sich in Handbücher bzw. Helptexte vertiefen zu müssen. Die Gestaltung komplexerer Anwendungen ist wohl möglich, die Programmierfähigkeiten von Access sind aber noch verbesserungswürdig. Ähnlich wie z.B. die Tools von Oracle (Forms, Report) bietet Access ein Rahmenprogramm, mit dem die Bearbeitung bzw. der Ausdruck von Daten möglich ist. Mit Triggern kann man an verschiedener Stelle in den Ablauf eingreifen. Wer aber seine Benutzeroberfläche abweichend von den Access Vorgaben gestalten möchte verliert jegliche Vorteile und muß selbst in Access-Basic programmieren. Access bietet ausreichende Performance, benötigt dazu aber auch leistungsfähige Rechner. Ein 486er mit mindestens 8 MB Hauptspeicher sollte für komplexe Anwendungen angeschafft werden. Access war das erste System, das mit der ODBC Schnittstelle arbeiten konnte. ODBC (Open Database Connectivity) ist eine Windows Datenbankschnittstelle, die von mehreren renommierten Datenbankherstellern gemeinsam mit Microsoft entwickelt wurde. Es handelt sich dabei um eine in Syntax und Umfang exakt festgelegte SQL Schnittstelle, die in Form von C-Funktionen angeboten wird. Das Client-Programm (in unserem Fall ACCESS) schickt SQL - Befehle (die im ODBC Treiber vom ODBC-Dialekt in den serverspezifischen Dialekt übersetzt werden) an einen beliebigen Datenbankserver, oder übernimmt selbst Zugriffsaktivitäten (z.B. bei Xbase Dateien) . Client-Programm (z.B. ACCESS Anwendung) ODBC ODBC -Treiber xBase Datei ODBC -Treiber Datenbankserver (z.B. Oracle, Informix) Client-Programm (z.B. eigenes C-Programm) Schnittstelle Client-Programm (.....) Netzwerkverbindung mit den notwendigen Protokollen ADAT-Skriptum Preißl 4 Access kann folglich mit seinem eigenen Datenbanksystem arbeiten, was im Einplatz- oder auch Mehrplatzbetrieb (mehrere Anwender arbeiten auf der gleichen Datenbankdatei) möglich ist. Ebenso kann über die ODBC Schnittstelle auf andere Datenbanken zugegriffen werden, wenn dafür ein ODBC - Treiber installiert ist. Zusätzlich gibt es noch die Möglichkeit Datenbanktabellen aus anderen gängigen DBSystemen (z.B. dBase, Paradox) zu importieren (dabei wird eine Access Datenbanktabelle angelegt und die Daten werden transferiert) oder auch einzubinden (dabei bearbeitet Access die Tabelle im Originalzustand, die Tabelle kann auch weiterhin in ihrem eigenen DBSystem verwendet werden). Auch Daten aus Ascii Dateien, die mittels Feldtrennzeichen oder mit fixen Feldlängen gegliedert sind, können mit den vorbildlichen Importfunktionen importiert werden. Access beinhaltet keinen Compiler, der exe-Files erzeugen könnte, es gibt aber eine lizenzfrei weitergebbare Runtime Version (Access Development Toolkit), mit dem man Access Anwendungen an Kunden weitergeben kann. Die Anwendung kann dann beim Kunden nur mehr ausgeführt werden, es ist kein Einblick in die Sourcen möglich. Wenn man Access startet, dann erscheint ein leerer Schirm mit dem Dateimenü, wo man Datenbanken neu anlegen, reparieren, komprimieren (ist eigentlich nur ein reorganisieren, wobei gelöschter Platz frei wird), verschlüsseln (die DB wird ab dann auch verschlüsselt bearbeitet) oder öffnen kann. Wenn man beispielsweise eine vorhandene Datenbank öffnet (und ein allfällig vorhandenes Makro namens Autoexec bestimmt nichts anderes), dann erscheint nebenstehendes Fenster. Man sieht dabei links jene Buttons, welche die sechs sogenannten Access Objekte darstellen. Wie man sieht sind hier bereits einige Tabellen angelegt. Abfragen stellen normalerweise einen beliebigen SQL-Selectbefehl dar, dessen Ausgabe auch einigermassen gestaltet werden kann. Die Select Befehle stehen aber auch als Views zur Verfügung und es gibt darüber hinaus auch die Möglichkeit Insert, Update und Delete Befehle unterzubringen. Eine Abfrage ist aber nur jeweils ein SQL Befehl (kein Script mehrerer Befehle). Formulare stellen den Tool für die Bildschirmmaskenprogrammierung dar, den Feldern des Bildschirmformulars werden dabei Felder aus der Datenbank zugeordnet. Das Formular zeigt (wenn nicht durch Filter eingeschränkt) alle Daten der zugrundeliegenden Datenbanktabelle an, die Daten können beliebig geändert, gelöscht bzw. erweitert werden. Berichte sind flexible Möglichkeiten der Listenerstellung. Beispielsweise ist es sehr einfach möglich eine Listausgabe für beliebige Klebeetiketten zu erhalten. Um eine einfache Oberfläche zu gestalten braucht man nur simple Ablauflogik, die man mit Makros definieren kann, welche beispielsweise durch das Drücken eines Buttons oder auch beim Ändern eines Formularfelds aktiviert werden können. Muß die Logik komplexer gestaltet werden, dann greift man zu Modulen, die in Access Basic (eine vollwertige 3. Generations - Programmiersprache mit speziellen Erweiterungen) geschrieben werden. Wenn man mit dem normalen Ablauf der Formulare und Berichte nicht zufrieden ist oder auch spezielle Sonderwünsche hat, die in Access nicht vorgesehen sind, dann kann die Programmierung auch sehr aufwendig werden - eine Eigenheit aller Programmiertools. ADAT-Skriptum Preißl 5 1.2. Tabellen in MS-Access Die Daten einer Access Datenbank werden, wie bei relationalen DBs üblich, in Tabellen gespeichert. Jede Tabelle verfügt über Felder in den Access Datentypen und sollte auch immer einen Primärschlüssel haben. Auch ist es möglich verschiedene Indizes zu definieren. Als mögliche Datentypen gibt es : Text Memo Zahl Datum/Zeit Währung Zähler Ja/Nein OLE-Objekt normale Texte lange Texte Fix- und Gleitkommazahlen bis 255 Zeichen bis 32000 Byte Integers mit 1,2,4 Byte Gleitkomnma 4, 8 Byte Datum und Zeit speicherbar 4+4 Byte ist ein 8 Byte Integer mit 15 Vor-, 4 Nachkommastellen nummeriert automatisch von 1 aufwärts, ist ein 4 Byte Integer ist ein logischer Datentyp einfügen von Bildern, etc. Zum Datentyp gehören noch die sogenannten Feldeigenschaften, welche erst die Feldgröße (wieviele Stellen), eventuell vorhandene Kommastellen, ein Not NULL (Eingabe erforderlich) und einen Defaultwert festlegen. Beim Anzeigen bzw. in Formularen wo das Datenbankfeld vorkommt werden Ein- und Ausgabeformat und die Beschriftung genutzt. Die Formatierung kann mehrfach angegeben werden (bei Zahlen beispielsweise für positive, negative, Wert 0 und NULLwert); näheres im Helptext unter "Format". Ähnlich einer Check-Klausel funktionieren Gültigkeitsregeln samt zugehörigem Fehlertext. Wenn Datenänderungen in der Tabelle stattfinden werden sie geprüft (erst ab V 2.0), die Prüfbedingungen können sich aber nur auf den gerade bearbeiteten Satz beziehen. Indizes können wie gewohnt (ein oder mehrere Felder, unique oder nicht) angelegt werden. Das Anlegen der Tabellen mußte bis Version 1.1 ausschließlich mit dem dafür vorgesehenen Formular erfolgen, erst ab V 2.0 gibt es die Möglichkeit mit Create Table Tabellen anzulegen. In der Folge sehen Sie ein Beispiel für das Tabellenanlegeformular. Die Feldeigenschaften (hier angezeigt für das Feld lergehalt) beinhalten bei Texten noch die Möglichkeit leere Felder (blank) zu verhindern. Die feldübergreifenden Gültigkeitsbedingungen stehen in einem eigenen Fenster. Auch besteht die Möglichkeit nachträglich den Aufbau einer Tabelle zu ändern, die bestehenden Daten werden dann (soweit wie möglich) konvertiert. ADAT-Skriptum Preißl 6 Zusätzlich gibt es noch die Möglichkeit Tabellen aus anderen Datenbanken (auch anderer Hersteller) zu importieren. Importiert man aus einer anderen Access DB, dann kann man die Tabelle und wahlweise auch die Daten importieren, bei dBase wird nur die Tabelle mitsamt den Daten importiert, bei normalen Ascii Dateien muß man die Tabelle vorher anlegen um dann die Daten zu importieren. Es ist auch möglicht Tabellen anderer Datenbanken einzubinden. Access kennt dann den Tabellenaufbau, die Tabellen bleiben aber in der ursprünglichen Datenbank und werden dort bearbeitet. Mit dieser Methode funktioniert auch der Zugriff über die ODBC Schnittstelle. Hat man die Tabellen definiert, dann besteht auch die Möglichkeit Beziehungen einzutragen. Bis zur Version 1.1 war die Beziehungsdefinition noch mühsam, es konnte zwischen zwei Tabellen immer nur eine einzige Beziehung geben. Ab Version 2.0 kann man aber die Beziehungen beliebig und sehr komfortabel (siehe grafische Darstellung) setzen. Access kann die referntielle Integrität nicht nur prüfen, sondern auch den Fremdschlüssel mitändern bzw. mitlöschen. 1.3. Abfragen Unter der Bezeichnung Abfragen findet sich nicht nur eine komfortable und mächtige Möglichkeit Daten nach verschiedenen Kriterien zu lesen und anzuzeigen, das Ergebnis der Abfrage kann in weiterer Folge wie eine Tabelle verwendet werden. Auch kann man Datensätze neu anlegen, ändern und löschen. Seit V 2.0 sind fast alle in der SQL üblichen Möglichkeiten gegeben. Probleme zeigten sich nur bei komplexeren Update Befehlen und bei der Count - Aggregatsfunktion. Für SQL Kundige ist die Abfrage eine Benutzeroberfläche, mit der man bequem einen Select Befehl erstellen kann. Der Befehl kann gespeichert und jederzeit ausgeführt werden, das Ergebnis wird in Tabellenform präsentiert. Jeder gespeicherte Select Befehl steht auch automatisch als View zur Verfügung und kann bei jeder folgenden Applikationsentwicklung wie eine Tabelle verwendet werden (auch Update auf die Abfrage ist möglich !). Alternativ zur weiter unten dargestellten Benutzeroberfläche kann man die Befehle auch als SQL Code schreiben bzw. zwischen Oberfläche und SQL Code wechseln. ADAT-Skriptum Preißl 7 Beim Erstellen einer Abfrage wählt man zuerst die benötigten Tabellen (oder Views) aus und gibt die für den JOIN notwendigen Beziehungen an (bei den Tabellen spezifizierte Beziehungen werden automatisch übernommen). Dies wird im oberen Teil der Abfrage grafisch dargestellt, ein Doppelklick auf den Beziehungspfeil ermöglicht nähere Angaben (Outer Join). Dadurch ist der FROM Zweig erledigt. Felder aus den Tabellen werden mittels Drag and Drop in die darunterliegende Ausgabeleiste übernommen, Ausdrücke formuliert man dort direkt und stellt so den SELECT Zweig fertig. In der Kriterien-Zeile kann man den WHERE Zweig formulieren (kompliziertere Teile wie geschachtelte Selects müssen getippt werden). Die Zeile >Sortierung< legt offensichtlich die ORDER Klausel fest. Mit der Anzeigen-Zeile kann man beispielsweise nach Feldern sortieren, aber diese Felder dann nicht anzeigen. Weil man auch die umfangreichen Access-Basic Funktionen im Select befehl einsetzen kann sind die Möglichkeiten beachtlich. Mit dem Summenzeichenbutton im Toolbar kann man noch eine weitere Zeile einblenden, in der man Gruppierungen einträgt (GROUP BY, HAVING, Gruppenfunktionen). Als besondere Ausgabegestaltung existiert die Kreuztabellenabfrage, wobei ein Gruppierungselement (Group By Feld) als Spaltenüberschrift definiert wird. Die anderen Gruppierungselemente ergeben die Zeilenüberschrift. Man kann aber pro Kreuztabellenelement nur einen Ausdruck ausgeben und die Anzahl der Spaltenwerte darf nicht zu groß werden. Zusätzlich gibt es noch Sonderformen, wobei das Abfrageergebnis eine neue Tabelle bildet (SELECT INTO) oder sogar einen INSERT, UPDATE bzw. DELETE Befehl darstellt. Beim Start einer Abfrage kann man auch Parametereingaben anfordern, die dann im WHERE Zweig oder sonstwo verwendet werden können. Wenn man in der SQL-Ansicht das Aussehen eines Befehls betrachtet, der mit der Benutzeroberfläche gebaut wurde, dann fällt der neuartige FROM Zweig auf. Hat man wie oben die Tabellen klasse und lehrer, dann sieht der SQL Befehl in etwa so aus : SELECT DISTINCTROW klasse.klanr, klasse.klabezeichnung, klasse.klavstand, lehrer.lername, lehrer.lervorname AS Überschrift FROM lehrer INNER JOIN klasse ON lehrer.lernr = klasse.klavstand WHERE klasse.klanr = ‘03TA’; Die Abgabe DISTINCTROW ist ähnlich dem DISTINCT und wird immer automatisch erstellt. Der restliche Select-Zweig sieht ziemlich normal aus, lediglich die zahlreichen hier verwendbaren Access-Basic Funktionen könnten verwirren (z.B. Mid, Left, Right für Sub- ADAT-Skriptum Preißl 8 stringbildung; Now, DatAdd, DatDiff für Datumsausdrücke etc.). Der FROM-Zweig wird bereits gemäß Syntax der SQL-1992 Norm dargestellt. Es werden nicht nur die Tabellen aufgezählt, sondern auch pro Beziehung die Art des Join (normalerweise INNER JOIN, auch LEFT oder RIGHT JOIN als Varianten des Outer Join sind möglich). Zusätzlich gibt es eine ON Klausel, in der die eigentliche Beziehung mit Primärschlüssel = Fremdschlüssel (genau das was früher im WHERE-Zweig stand) geschrieben wird. Bei mehreren Tabellen könnte der FROM-Zweig so aussehen: FROM klasse INNER JOIN (gegenstand INNER JOIN (lehrsaal INNER JOIN (lehrer INNER JOIN stundenplan ON lehrer.lernr = stundenplan.untlernr) ON lehrsaal.lsaalnr = stundenplan.untlsaalnr) ON gegenstand.gegnr = stundenplan.untgegnr) ON klasse.klanr = stundenplan.untklanr Eine Access spezifische Erweiterung zeigt das folgende Beispiel : PARAMETERS [Für welche Klasse soll Stundenplan gezeigt werden:] Text; TRANSFORM Max([untlernr] & " " & [untlsaalnr]) AS Tabelement SELECT Mid([untstunde],3,1) AS Stunde, Max(klasse.klabezeichnung) AS Klasse FROM klasse INNER JOIN (gegenstand INNER JOIN (lehrsaal INNER JOIN (lehrer INNER JOIN stundenplan ON lehrer.lernr = stundenplan.untlernr) ON lehrsaal.lsaalnr = stundenplan.untlsaalnr) ON gegenstand.gegnr = stundenplan.untgegnr) ON klasse.klanr = stundenplan.untklanr WHERE ((stundenplan.untklanr Like [Für welche Klasse soll Stundenplan gezeigt werden:])) GROUP BY stundenplan.untklanr, Mid([untstunde],3,1) PIVOT Left([untstunde],2) PARAMETERS fordert den Benutzer auf eine Klasse einzugeben (im Datentyp Text), welche dann im WHERE-Zweig des Befehls verwendet wird. TRANSFORM und PIVOT sind zwei spezielle Kreuztabellenerweiterungen. Mid ist eine Substringfunktion, & verkettet Strings, Max(....) AS Klasse ist die Vergabe einer Spaltenüberschrift. 1.4. Formulare Einfache Formulare können in Access leicht erzeugt werden und bieten ein fixes Ablaufschema an, mit dem Daten angezeigt, eingefügt, geändert und gelöscht werden können. Jedem Formular steht eine Tabelle (oder Abfrage) gegenüber, deren Sätze bzw. Felder im Formular angezeigt werden. Beim Erzeugen eines Formulars (= eine Bildschirmanwendung) wird man bevorzugt einen Formularassistenten verwenden. Man hat die Wahl zwischen Einspaltig (nur ein Datensatz wird jeweils angezeigt), Tabelle (mehrere Datensätze untereinander), Haupt/Unterformular (einem einfachen Hauptformular wird ein weiteres Formular untergeordnet, dessen Daten jeweils passend angezeigt werden) und einem Diagramm (einer MS Draw Geschäftsgraphik). Auch das jetzt folgende Formular wurde mit einem Assistenten erzeugt. Die zweispaltige Darstellung und die größere Schrift sind das Ergebnis nachträglicher Bearbeitung. Im abgebildetem Formular beinhaltet das Hauptformular die Tabelle Klasse. Weil aber nicht nur die Nummer, sondern auch der Name des Klassenvorstands angezeigt werden soll wurde eine Abfrage (mit Klasse und Lehrer) verwendet. Es könnten alle Felder aus Klasse und Lehrer am Formular aufscheinen, es wurden aber nur einige dargestellt. Alle Felder aus der Tabelle Lehrer sind deaktiviert (Eingabe, Änderung ist nicht möglich). Man kann eigentlich nur den Datensatz aus Klasse bearbeiten; dem Formular die Abfrage mit Klasse und Lehrer zugrundezulegen ist aber die beste Möglichkeit wenn man zusätzliche (über einen Fremdschlüssel erreichbare) Daten anzeigen will. Ändert man jetzt in der Klasse den Fremdschlüssel klavorstand (Lehrernummer), dann wird automatisch der dazugehörige Lehrername aus der Tabelle Lehrer geholt und angezeigt. ADAT-Skriptum Preißl 9 Beim Starten des Formulars werden sofort alle Datensätze der Tabelle (eventuell eingeschränkt durch Filter) gelesen. Zu sehen ist zwar nur der erste, die Anzeige links unten im Formular (Datensatz: 1 - bezieht sich auf den angezeigten Satz „Klasse 03TA“) zeigt aber, daß bereits alle 3 Datensätze aus Klasse gelesen (und in einem sogenannten Dynaset zwischengespeichert) wurden. Mit den danebenliegenden Buttons und auch einigen Menübefehlen kann man die Sätze durchblättern. Wenn die Satzbearbeitung erlaubt ist, dann ist einfügen (nach dem letzten angezeigten Satz noch einmal weiterblätern), ändern (einfach in die Felder schreiben) und löschen (Satz markieren und löschen) möglich. Mangels einer sonstigen Suchmöglichkeit muß man Filter zur Einschränkung der angezeigten Satzmenge verwenden. Mit Hilfe der Filter/Sort Buttons (die mit dem Trichter) kann man ähnlich wie in Abfragen Such- und Sortierkriterien definieren (mit dem 1.Button), anwenden (drücke 2. Button) und wieder rücksetzen (mittels 3. Button). Diese Methode ist zwar sehr flexibel, aber einem Endanwender nur eingeschränkt zumutbar. Häufig wird daher eine zusätzliche Suchlogik mittels Programmierung selbst hergesetellt. Beim Öffnen eines Formulars sieht man bzw. liest also Access alle Sätze der zugrundeliegenden Tabelle (oder Abfrage). Bei einigen 1000 ist das kein Problem, aber bei 100 000 sehr wohl. Mit Filtern (können durch SQL Where-Zweige vom Programmierer oder mit den Trichterbuttons vom Anwender definiert werden) schränkt man die angezeigte Satzmenge ein. Jeder Anwender kann aber auf den rechtesten der 3 Filterbuttons drücken und hat wieder alle Sätze. Hat man beispielsweise eine ODBC-Verbindung zu sehr voluminösen Datenbanken ist dies performancemäßiger Selbstmord. Bei großen Datenmengen muß man als Programmierer Maßnahmen setzen, damit nicht zu viele Sätze gelesen werden. Beim Insert bewegt man sich zum letzten Satz und blättert dann noch einen weiter. Dort ist Platz für die Neueinfügung, was durch den Stern im Datensatzmarkierer kenntlich gemacht wird. Jeder Satz der angezeigt wird kann auch sofort durch überschreiben modifiziert werden. In Änderung befindliche Sätze erkennt man daran, daß der Datensatzmarkierer einen Bleistift zeigt. Wechselt man zum nächsten Datensatz, so wird die Änderung automatisch gespeichert und es erscheint wieder das Dreieck als normaler Datensatzmarkierer (aktueller Satz). Mit Mausklick auf den Datensatzmarkierer (oder über Menü) markiert man einen Datensatz; anschließend DEL Taste und er wird mit Rückfrage gelöscht. Das in diesem Beispiel enthaltene Unterformular (die Schüler der Klasse) ist ein eigenständiges (auch schon vor der Entwicklung des Hauptformulars getrennt abgespeichertes) Formular, in dem auch Daten geändert, gelöscht oder eingefügt werden können. Nur die Suche mit Filter ist nicht möglich, weil das Unterformular ohnehin nur die, zum im Haupt- ADAT-Skriptum Preißl 10 formular angezeigten Datensatz, passenden Daten zeigt. Dies wird über eine Feldverknüpfung (= Beziehung) zwischen Feldern des Haupt- und Unterformulars bewerkstelligt die intern als Filter gespeichert wird. Jedes Formular kann alternativ auch als Datenblatt dargestellt werden. Dies ist die Darstellung, in der Tabelleninhalte, Abfrageergebnisse und auch das Unterformular des obigen Formulars wiedergegeben werden. In Datenblättern kann man insbesondere nach Suchvorgängen wesentlich besser eine Satzmenge überblicken; weil man auch mehrere Sätze markieren kann lassen sich auch Satzmengen bearbeiten (z.B. löschen). Man kann dort auch einen einzelnen Satz aufsuchen (blättern bzw. positionieren mit dem Feldstecher Button). Steht die Einfügemarke am gewünschten Satz, so wechselt man wieder zurück in die normale Formulardarstellung um die Satzdetails besser darzustellen. Der Titel "Klassenliste" steht im Bereich Formularkopf, alle Felder im Detailbereich, zusätzlich könnte man noch Seitenköpfe und -füße angeben falls man die Formulardarstellung direkt drucken will. Die im Formular enthaltenen Felder nennt das Access Manual Steuerelemente. Unser Hauptformular verfügt über 4 Textfelder, die alle an ein Datenfeld aus der zugrundeliegenden Abfrage gebunden sind. Dadurch erhält man automatisch die Anzeige der Werte aus dem Abfrageergebnis. Berechnete Felder würden ihren Wert durch eine Berechnung, basierend auf den Ergebniswerten der Abfrage, erhalten. Ungebundene Felder können nur durch Makros oder Module sinnvoll eingesetzt werden. Es existieren weiters 2 Bezeichnungsfelder, die nur konstanten Text enthalten und jeweils an das nebenstehende Textfeld angehängt sind, womit sie gemeinsam mit dem Textfeld markiert und verschoben werden. Das letzte noch vorhandene Steuerelement ist ein Unterformular. Weitere Steuerelemente wären Optionsfelder, Umschaltflächen, Kontrollkästchen, etc. Die im Entwurfsmodus angezeigte Toolbox enthält alle möglichen Elemente. Kontrollkästchen eignen sich gut für die Darstellung von ja/nein Werten. Optionsgruppen mit mehreren Optionsfeldern eignen sich besonders um die Eingabe einiger fixer Werte zu ermöglichen (in einem Feld sind nur die Codes 1,2,3 möglich). Will man hingegen die möglichen Werte eine Felds dynamisch (durch die Inhalte anderer Datensätze) einschränken, dann sind Listfelder oder besser Kombinationsfelder einzusetzen. Linien, Rechtecke und Farben ermöglichen eine ansprechende Gestaltung des Formulars. Stellt man ein Formular im Entwurfsmodus dar, so kann man verschiedene Eigenschaftsfenster einsehen (zum Formular, den Bereichen und zu jedem Steuerelement), in dem alle Angaben zu diesem Element eingetragen bzw. geändert werden können. Die eigentliche Programmierung eines Formulars erfolgt über diese Eigenschaftsfenster. Hier finden sich alle Einstellungen, die der Formularassistent für sie vorgenommen hat, diese können bei Bedarf modifiziert und erweitert werden. Neben rein optischen Aufbesserungen kann in gewissem Rahmen auch das Verhalten der einzelnen Steuerelemente beeinflußt werden (aktivieren, sperren für Änderungen, Felder unsichtbar machen, etc.). Ebenfalls im Eigenschaftsfenster sind die jeweiligen Trigger positioniert, wo der Entwickler sich mit eigenem Code (Makro oder Access-Basic) in den Rahmenprogrammablauf einhängen kann. Grundsätzlich gibt es einen Standardprgrammrahmen, nach dem eine Formularbearbeitung abläuft. An verschiedensten Stelle in diesem Ablauf kann man als Anwendungsentwickler eigenen Programmcode einfügen, der genau dann abläuft, wenn der Standardablauf am Einfügepunkt vorbeikommt. Das Access Manual nennt diese Einfüge- bzw. Anhängepunkte Ereignisse (gemäß Windows Message-Konzept). Man kann auf ein solches Ereignis mit ADAT-Skriptum Preißl 11 eigenem Code reagieren oder auch nicht. Man sollte zu diesem Thema die Access Hilfe für „Liste der Ereignisse“ und „Reihenfolge der Ereignisse“ studieren. Als praktische Übung kann man das Formular Ereignistest der Skriptum-Beispieldatenbank starten. Dort werden die meisten einfallenden Ereignisse protokolliert. Im Anschluß sehen Sie das Eigenschaftsfenster des Formulars und für das Textfeld klanr. In den Eigenschaftsfenstern lassen sich für Formular, Bereiche und alle Felder (die Steuerelemente) diverse Angaben eintragen. Zu Beginn wird immer die Datenherkunft des Formulars/Felds festgelegt. Ebenfalls eingetragen wird wie der Zugriff auf die Daten möglich ADAT-Skriptum Preißl 12 ist (sichtbar, aktiviert, gesperrt). Einiger Raum ist dem Layout gewidmet, doch der größte Teil sind die einzelnen Ereignisse, bei denen man eigenen Code (Aufruf Makro oder BasicCode) eintragen kann, der dann ausgeführt wird wenn dieses Ereignis eintritt. Im Anschluß noch die Eigenschaftsfenster zweier spezieller Steuerelemente, nämlich das Unterformular aus der Sicht des Hauptformulars (bedenken sie, daß das Unterformular ein völlig eigenständiges Formular ist, welches über eigene Eigenschaftsfenster verfügt) und eine Combobox (ein ungebundenes Feld - keine Eintragung unter Steuerelementinhalt), die zusätzliche Angaben bezüglich der Daten im Listboxteil enthält. ADAT-Skriptum Preißl 13 1.4.1. Das Formular prüfeintrag Die Eintragung von Noten (in die Tabelle pruefung) wäre in einem echten Schulbetrieb wohl eine sehr häufige Tätigkeit. Folglich ist es sinnvoll, wenn man für das Noteneintragungsformular mehr Aufwand treibt, als bei anderen seltener verwendeten Eingabemasken. Würde man in einem simplen Formular Noten eingeben, so müßte man jeweils alle Felder des Datensatzes der Tabelle pruefung ausfüllen. Auch wären die hintereinanderliegenden Prüfungssätze kaum sinnvoll geordnet. Ein Lehrer ist es aber gewohnt, seine Noten in einer Art Klassenliste einzutragen, wo alle Schüler der Klasse als Zeilen aufscheinen. Wirklich eingetragen wird nur mehr die Notenspalte. Mit dem hier vorliegenden Formular wird versucht diese komfortable Noteneintragung als Formularoberfläche nachzubilden. Startet man das Formular, so sieht es so aus: Wenn man alle 4 Comboboxen in der obigen Zeile mit Werten belegt hat (auswählen aus Comboboxliste), dann erscheinen im mittleren Bereich die Schüler der angegebenen Klasse. Gibt es Noten die bereits eingetragen wurden, dann werden diese angezeigt, ansonsten ist die Notenspalte leer, kann aber jetzt befüllt (bearbeitet) werden. Erst wenn man auf den gleichnamigen Button drückt, dann werden Noten in der Tabelle pruefung gespeichert. ADAT-Skriptum Preißl 14 Als Datenherkunft dient dem Formular eine Hilfstabelle, die nur für dieses Formular angelegt und danach wieder gelöscht werden sollte. Leider kann sich das Formular seine eigene Tabelle weder createn noch droppen, daher muß dies in Makros geschehen. Das Makro hat zwei Teile (Makroname). „machehilftab“ ruft in der Bedingung eine BasicFunktion auf, die den Create Table durchführt. War dies erfolgreich, dann wird auch das Formular pruefeintrag geöffnet. „löschehilftab“ führt lediglich einen Drop Table für die Hilfstabelle aus. Function mache_hilf_prüf_tabelle() Rem Rem erzeugt eine Hilfstabelle zur Eintragung von Prüfungen nur sinnvoll verwendbar in Zusammenhang mit dem Formular prüfeintrag mache_hilf_prüf_tabelle = True ' Returnwert für erfolgreich On Error Resume Next DoCmd.RunSQL "drop table hilfprüfeintrag" ' Fehler abfangen wenn nicht da ' lösche Tabelle ' erzeuge die Tabelle On Error GoTo error_createtable DoCmd.RunSQL "create table hilfprüfeintrag (schnr long, schname text (15),schvorname text(10), schgebdat datetime, pruart char(3),prunote byte)" On Error GoTo 0 Exit Function error_createtable: MsgBox "Create Tabelle hilfprüfeintrag ist misslungen " mache_hilf_prüf_tabelle = False ' Returnwert verhindert weiteren Makroablauf Exit Function End Function Falls das Formular irrtümlich gestartet wird, wenn es die Hilfstabelle noch nicht gibt, dann kann man diesen Fehler abfangen, indem man eine Ereignisprocedur für das Ereignis „Bei Fehler“ im Eigenschaftsfenster des Formulars einträgt und dort speziell diesen Fehler abfängt (alle anderen Fehler könnten auch dort behandelt werden). Sub Form_Error (dataerr As Integer, Response As Integer) Const OBJEKTNICHTDA = 3011 Response = DATA_ERRDISPLAY ' Standardfehlermeldung anzeigen If dataerr = OBJEKTNICHTDA Then MsgBox "Starten Sie dieses Formular bitte nur über das Makro !" Response = DATA_ERRCONTINUE ' Standardfehlermeldung unterdrücken Exit Sub End If End Sub ADAT-Skriptum Preißl 15 Wenn das Formular startet, so wird auf jeden Fall der Inhalt der Hilfstabelle gelöscht indem beim Ereignis „Beim Öffnen“ eine Ereignisprocedur mit einem Delete Befehl existiert. Beim Schließen des Formulars passiert übrigens dasselbe. Es wird dann erwartet, daß der Benutzer die oberen 4 Felder befüllt. Weil dies ungebundene Felder sind, können sie auch nur durch Benutzereingabe oder Zuweisung in einem BasicModul zu Werten kommen. Jedesmal, wenn der Wert in einem der Felder aktualisiert wurde startet eine Ereignisprocedur, die dann den Modul „fülle_hilfprüf“ startet. Dort wird zuerst geprüft ob alle 4 Comboboxen über Werte verfügen, wenn das der Fall ist wird die zugrundelegende Hilfstabelle zuerst gelöscht und dann mit den Schülern der Klasse befüllt. Falls passende Prüfungen existieren (Datum, Lehrer, Gegenstand sind gleich), dann werden auch die Noten angezeigt. Auf jeden Fall können dann für alle Schüler der Klasse die Noten bearbeitet bzw. eingegeben werden. Function fülle_hilfprüfeintrag(woher As String) Rem Wenn sich im geöffneten Formular prüfeintrag eines der (ungebundenen) Rem Felder im Kopfbereich des Formulars ändert, so beeinflußt dies den Rem Inhalt des Formulars - die zugrundeliegende Tabelle neu befüllt !! Dim datvar Dim strvar As Variant As String ' Hilfsvariable für ein Datum im Format Datum ' Hilfsvariable für das Datum(als String) ' haben auch alle Felder des Formularkopfs einen Inhalt If Forms![prüfeintrag]![stprudatum] > " " And Forms![prüfeintrag]![stklanr] > " " And Forms![prüfeintrag]![stgegnr] > " " And Forms![prüfeintrag]![stlernr] > " " Then ' entleeren der Hilfstabelle DoCmd.RunSQL "delete from hilfprüfeintrag " If Not IsDate(Forms![prüfeintrag]!stprudatum) Then MsgBox (">> " & Forms![prüfeintrag]!stprudatum & " << kein Datum !") Forms![prüfeintrag]!stprudatum.SetFocus ' Positioniere auf das Feld Exit Function Else datvar = DateValue(Forms![prüfeintrag]!stprudatum) End If ' aufwendige Formatierung, damit in strvar ein Access-Basic ' tauglichen Datum entsteht das Format soll #mm/dd/jj# sein strvar = "#" & Format(datvar, "mm") & "/" & Format(datvar, "dd") & _ "/" & Format(datvar, "yyyy") & "#" ' Daten übertragen aus schüler, prüfung; der LEFT Join wird ' etwas mißbraucht um die gewünschte Info (aus der Tabelle ' Prüfung nur Daten mit vorgegebenen Datum, Lehrer, Gegenstand DoCmd.RunSQL "insert into hilfprüfeintrag (schnr,schname,schvorname,schgebdat,pruart,prunote) select S_schnr, s_name,s_vorname,s_gebdat,p_art,p_note from schueler left join pruefungnur on schueler.s_schnr = pruefungnur. p_S_Kandidat where s_k_klasse = Forms![prüfeintrag]!stklanr " ' Anzeige aktualisieren, damit neuer Inhalt auch zu sehen ist Forms![prüfeintrag].Requery End If End Function Der Benutzer kann daraufhin beliebig Noten eintragen. Sollen diese auch dauerhaft in der DB gespeichert werden, dann muß der große Button (unten) gedrückt werden. Dann werden die Daten in die Prüfungstabelle übertragen. Wenn er zwischendurch wieder in eine der Comboboxen geht und dort auch den Wert ändert, so führt dies zu einem Neuübertragen der Schüler in die Hilfstabelle, wobei die allenfalls eingetippten Noten (derzeit ohne Warnung) verloren gehen. Geht man nach der Eintragung einer Note direkt zum Button und drückt ADAT-Skriptum Preißl 16 diesen, dann ist die zuletzt getippte Note noch nicht gespeichert, weil sich dieser Satz noch in Bearbeitung befindet. Die Prozedur „speichere_aktuellen_Datensatz“, welche „Beim Hineingehen“ in den Button aufgerufen wird sorgt für sichere Speicherung. Function speichere_aktuellen_datensatz () If Forms!prüfeintrag.Dirty Then ' Bleistift sichtbar, Satz in Änderung ' alte Methode = simuliere einen Menüpunkt ' DoCmd.DoMenuItem A_FORMBAR, A_FILE, A_SAVERECORD, A_MENU_VER20 DoCmd.RunCommand acCmdSaveRecord End If End Function Dann kann die folgende Procedur „Beim Klicken“ des Button ausgeführt werden. Function speichere_prüfungen_inDB () Rem wenn der Button Speichern... gedrückt wird, dann läuft diese Proc Rem und befördert alle eingtragenen Prüfungen (Mit Note) in die Rem Prüfungstabelle Dim Dim Dim Dim strvar As String datvar As Variant datlergeg As String hilfstr As String ' Datum als String mit amerik. Formatierung ' aufbereiten Lernr, Gegenr in Konstantenform ' haben auch alle Felder einen Inhalt If Forms![prüfeintrag]![stprudatum] > " " And Forms![prüfeintrag]![stklanr] > " " And Forms![prüfeintrag]![stgegnr] > " " And Forms![prüfeintrag]![stlernr] > " " Then On Error GoTo speicher_datum_falsch datvar = DateValue(Forms![prüfeintrag]!stprudatum) On Error GoTo 0 ' aufwendige Formatierung des Datums in strvar strvar = "#" & Format(datvar, "mm") & "/" & _ Format(datvar, "dd") & "/" & Format(datvar, "yyyy") & "#" ' Formatierung Lehrernummer und gegenstandnummer (z.B. datlergeg = "'" & Forms![prüfeintrag]![stlernr] & "','" _ & Forms![prüfeintrag]![stgegnr] & "'" 'PS','PR' ) ' entferne die schon gespeicherten Prüfungen aus der tabelle prüfung ' diese stehen ja in hilfprüfeintrag und würden wiederholt eingefügt DoCmd.RunSQL "delete from pruefungen where p_datum = " & strvar & " And Forms![prüfeintrag]![stgegnr] = p_G_fach And Forms![prüfeintrag]![stlernr] = p_L_Pruefer and p_S_Kandidat in (select s_schnr from schueler where Forms![prüfeintrag]!stklanr = s_K_klasse)" ' aufbauen und ausführen des Insert Befehls, der die Prüfungen aus ' hildprüfeintrag nach pruefung überträgt hilfvar = "insert into pruefungen (p_datum,p_S_Kandidat,p_L_Pruefer, p_G_Fach,p_art,p_note) select " & strvar & ",schnr," & datlergeg & ",pruart ,prunote from hilfprüfeintrag where prunote > 1 " DoCmd.RunSQL hilfvar Else MsgBox (" Ohne vollständige Angaben kann nicht gespeichert werden !") Forms![prüfeintrag]!stklanr.SetFocus End If Exit Function speicher_datum_falsch: MsgBox (">> " & Forms![prüfeintrag]!stprudatum & " << ist kein Datum!") Forms![prüfeintrag]!stprudatum.SetFocus Exit Function End Function ADAT-Skriptum Preißl 17 Access Basic Access Basic als vollwertige 3-GL Nach der Vorstellung einiger Beispiele ist es nun notwendig einen genaueren Überblick über Access Basic zu erhalten. Aus heutiger Sicht kann festgestellt werden, daß alle jene Basic Dialekte, die den schlechten Ruf der Sprache begründet haben, nicht mehr existieren. In Access 2.0 ist zwar noch nicht Visual Basic for Applikations integriert, trotzdem existieren alle Möglichkeiten (Aufzählung folgt), über die eine typische Programmiersprache der 3. Generation verfügt Programm - logisch gesehen bildet sämtlicher Access-Basic Code, der in einer Datenbank existiert ein Programm. Die in Access vorgesehenen Standardabläufe (z.B. wie funktioniert ein Formular) sind quasi das Hauptprogramm, die selbstgeschriebenen Routinen nur Unterprogramme. Datei - ein Access Modul entspricht einer Datei. Der Code der meisten C-Programme wird üblicherweise auch in mehreren Dateien gespeichert. Eine Datei (hier also ein Modul) kann mehrere Unterprogramme (Sub) oder Funktionen enthalten, diese müssen aber ähnlich wie in C hintereinander im Modul stehen und dürfen nicht verschachtelt werden. Außerhalb von Funktionen können aber (wiederum ähnlich zu C) bestimmte Angaben stehen. Funktionen und Subs - Während natürlich nur die Funktion einen Rückgabewert hat können in jedem Fall Parameter vorkommen. Standardmäßig erfolt die Parameterübergabe mit Call by Reference, ändern Sie also Parameter im Unterprogramm oder auch in der Funktion, dann verändern sie damit direkt die Variable des rufenden Programms. Mit dem Zusatz ByVal kann eine Wertübergabe erzwungen werden. Variable - Wiederum vergleichbar zu C gibt es globale Variable (mit dem Schlüsselwort Global nur einmal in einem Modul definieren genügt für die datenbankweite Verfügbarkeit), modulglobale Variable (normale Definition mit Dim, aber außerhalb einer Funktion bzw. eines Unterprogramms führt zur Verfügbarkeit in allen Funktionen des Moduls) und lokale Variable, welche innerhalb einer Funktion (oder Upro) definiert werden und auch nur dort gültig sind. Lokale Variable haben auch nur eine kurze Lebensdauer (jeweils vom Funktionsstart bis zu dessen Ende), mit dem Schlüsselwort static kann man aber eine Lebensdauer für die ganze Access Sitzung erreichen. Datentypen - gibt es viele, wenn auch nicht dieselben wie in der Datenbank Ganzzahlig sind Gleitkomma Zeichenfolgen UniversalTyp integer, long, currency single und long string variant (dieser defaultmäßig vorhandene Datentyp kann jeden anderen Typ aufnehmen) zusätzlich gibt es noch Datentypen für die meisten Objekte (wie z.B. Database, Tabledef, Querydef, Recordset, Form, Control, … genauere Aufzählung folgt später) Kontrollstrukturen - Für jedes Element aus der strukturierten Programmierung existieren natürlich auch in Access Basic entsprechende Befehle. Unterprogramme und Funktionen sind vorhanden, Im Gegensatz zu C und den vielen Sprachen welche die C Syntax geerbt haben gibt es aber grundsätzliche Syntaxunterschiede ! Erläuterung und Beispiel aus C Erläuterung und Beispiel aus VB ADAT-Skriptum Preißl 18 C unterscheidet Groß- und Kleinschreibung (ursprünglich nur wegen der #defines in Verwendung ist dies heute leider auch bei Klassen und Variablennamen üblich). Übliche Programmierumgebungen färben zwar die Syntax ein prüfen aber nicht Gross- Kleinschreibung oder weitere Syntax. In VB können Sie schreiben wie sie wollen, wenn Sie eine Zeile verlassen wird diese aber interpretiert, es wird automatisch die richtige Gross- Kleinschreibung gesetzt. Es erfolgt auch eine teilweise Syntaxprüfung (die Zeile wird rot wenn fehlerhaft). Variablendefinitionen mit Variablendefinitionen mit Schlüsselwort typ name int x; double zahl; char text [80]; // Text in C leider als Array x = 2; zahl = 2.345; ' Kommentar nur so (wie C //) strcpy(text, "Hallo"); /* Dim x As Integer Dim zahl As float Dim text As String Dim var2 ' dies ist Typ Variant ' kann beliebige Inhalte haben x = 2 zahl = 2.345 text = "Hallo" C hat mehrere Kommentar Varianten (// ) */ In C ist bekannterweise jedes Statement mit einem ; abzuschliessen In VB wird ein Statement nicht mit einem speziellen Zeichen beendet sondern endet automatisch mit dem Zeilenende. Damit aus langen Statements nicht auch sehr lange Zeilen werden kann man am Ende der Zeile blank_ schreiben. Die nächste Zeile ist dann eine Folgezeile. int x, var1; float y, pi=3.14 ; Dim x As Integer, var1 As Integer Dim y As Double, pi As Double ' initialisiern geht nicht pi = 3.14 // pi wurde initialisiert x = 25 ; // sehr einfach y = pow(x,2) * pi ; // Kreisfläche // 2-zeilig x = 25 y = x ^ 2 _ * pi ' auch einfach ' Kreisfläche 2zeilig In C werden geschwungene Klammern { } eingesetzt um zusammenhängende Codeteile zu einer logischen Einheit zusammenzufassen (bei Funktion, if, while). Bedingungen müssen bei if und while in runde Klammern gesetzt werden um syntaktisch erkennbar zu sein. In VB gibt es keine vergleichbaren Zeichen, stattdessen haben alle jene Statements wo das zusammenfassen nötig ist ein dazupassendes Ende-Schlüsselwort. (if … end if, …) Bedingungen brauchen keine Klammern, weil entweder Zeilenwechsel oder das Schlüsselwort then für die syntaktische Erkennung sorgen. if (x == 2 || y < 4 ) if x = 2 or y > 4 Then x = 22 end if If (Sin(winkel) = 1) Then ... Else x = 2 y = 3 End If x = 22; If (sin(winkel) == 1) ... Else ADAT-Skriptum Preißl 19 { x = 2; y = 3; } x = 2 Do While x < 10 ' & ist Textverkettung MsgBox "x ist jetzt " & x x = x + 2 Loop x = 2; while (x < 10) { printf("x ist jetzt %d\n",x); x = x + 2; For i = 0 To 10 Step 1 ' ausgabe im Debugfenster Debug.Print i Next I } for (i=0;i<=10;i++) { printf("%d\n",i); } In VB werden Unterprogramme durch das eigene Schlüsselwort Sub definiert (und auch mit Call aufgerufen). Call by Reference ist üblich, Call by Value mittels Byval. Lokale Variable wie in C. In C sind auch Unterprogramme Funktio- Function fname(byval x) as Integer ' x hat Typ Variant nen, Call bei Value ist üblich, Call by Dim lokalx as integer Reference eine Sonderform. Lokale VariStatic erstesmal ' immer defaultinit auf 0 ablen haben die übliche kurze LebensIf (erstesmal = 0) Then dauer x = 25 erstesmal = 1 End If ... fname = 25.3 ' returnwert !! end function float fname (x float) { int lokalx; static int erstesmal = 1 ... Public Sub test(byval x, y) 'Parameter sind Variant Select Case (x) Case 2, 3: y = 5 Case 6: y = 25 Case Else: y = 100 End Select End Sub return 25.3; ' if (erstesmal) { x = 25; erstesmal = 0; } } es gibt ... void test (intx, int &y) x = fname(var2) call test (x,var2) { switch (x) { case 2: case 3: y=5; break; case 6: y=25; break; default : y = 100; } } void main () { ... x = fname(var2); test (x, var2); } KEINE main in Access ADAT-Skriptum Preißl 20 Aufrufe, Programmstartpunkt – In C, Java beginnen Programme immer mit ihrer main Funktion. Diese ruft andere Funktionen auf. In Ihren ersten Programmen haben Sie so den vollständigen Überblick gehabt, wo wann was aufgerufen wurde. Mit der Programmierung grafischer Oberflächen traten Eventsysteme auf den Plan, wo fremder Code (der des Betriebssystems) Events schickt, auf die sie mit dem Ausführen eigener Proceduren reagieren. Der zeitliche Ablauf Ihres selbstgeschriebenen Codes wird nicht mehr durch Ihre Aufrufe bestimmt sondern hängt davon ab, wann das Betriebssystem Events feuert. Ihre Programmlogik ist eine ganz andere, weil für das korrekte Funktionieren Ihres Codes das Wissen um die Events und deren zeitliche Abfolge notwendig ist. Bei Access ist es genauso. Die Funktionsweise eines Formulars oder Reports ist prinzipell eigenständig, schliesslich gibt es Access Datenbanken oder zumindest einzelne Formulare darin, die gänzlich ohne Benutzercode ablaufen. Will man aber eigenständiges (über das Standardverhalten hinausgehendes) Verhalten implementieren, dann geht das mit eigenem Code, den man an einen der zahllosen Events koppelt. Ereignisse gibt es auf Formular und auch auf Feldebene, alle Ereignisse sieht man unten in den Eigenschaftsfenstern. An jedes Ereignis kann man Code hängen, der zu einem genau definiertem Zeitpunkt abläuft. Das Formular Ereignistest hilft dabei einen Überblick über die zeitliche Abfolge der Events zu erlangen. Einige wichtige Events : Formular – beim Öffnen erstes Ereignis beim Öffnen eines Forms, nur einmal Formular – beim Laden zweites Ereignis beim Öffnen eines Forms (Daten werden erstmals gelesen) Formular – beim Anzeigen wenn der erstes datensatz gezeigt wird bzw. später wann immer man zu einem weiteren Datensatz blättert wird der Event ausgelöst. Dies ist auch der Zeitpunkt, wo intern berechnete Steuerelemente und verknüpfte Unterformulare neu angezeigt werden. Formular – vor Aktualisierung bevor ein Datensatz nach einer Änderung (oder Insert) wieder in die DB geschrieben wird. Eignet sich um Prüfungen vorzunehmen oder automatisch diverse Felder in der DB mit zu befüllen, setzt man den Parameter cancel=True, so wird die Speicherung abgebrochen und benutzerdefinierte Fehlermeldungen können angezeigt werden. Formular – bei Zeitgeber falls man einen Timerintervall eingestellt hat entspricht dies den Timerevents der grafischen Benutzeroberflächen Formular – beim Schliessen letztes Ereignis beim Schliessen eines Forms Steuerelement – beim Hineingehen Benutzer geht mit Maus oder Tastatur in ein Feld Steuerelement – vor Aktualisierung Feld wurde geändert und Feld wird gerade verlassen, man kann hier Werte prüfen und den Benutzer am Verlassen des Felds hindern, allerdings kann man keine Feldwerte setzen Steuerelement – beim Verlassen Benutzer geht wieder raus aus dem Formularfeld. ADAT-Skriptum Preißl 21 Kleiner Hinweis : Wenn Sie mittels Programmcode den Inhalt von Formularfeldern ändern, so lösen Sie dabei keine Steuerelementevents aus, der Datensatz ist aber trotzdem im geänderten Zustand, was Sie an der Bleistiftanzeige im Datensatzmarkierer auch sehen. ADAT-Skriptum Preißl 22 Objekte in Access Basic Die datenbankspezifischen Erweiterungen des Access Basic sind objektorientiert aufgebaut. Es gibt zwar keine Vererbung, dies ist aber nicht weiter tragisch, weil ohnehin schon alle relevanten Objekte existieren. Die meisten Objekte liegen in typischer hierarchischer Gliederung vor. Jedes Objekt verfügt über Auflistungen - stellen eine Zusammenfassung der existierenden untergeordneten Objekte eines bestimmten Typs dar. Damit kann man diese Objektmenge sequentiell durchsuchen und so beispielsweise feststellen ob bestimmte Objekte existieren. Jede Auflistung verfügt seinerseits über die Eigenschaft „Count“ (wieviele Objekte sind in der Aufzählung) und manchmal über die Methoden „Append, Refresh, Delete“. Methoden - stellen Funktionen dar, die auf oder mit dem Objekt ausgeführt werden können Eigenschaften - sind die Datenfelder eines Objekts; können teilweise auch verändert werden Access selbst ist in eine Komponente Benutzeroberfläche (das eigentliche Access) und in den Datenzugriffsteil (Jet Database Engine) geteilt. Die Jet-Engine wird auch verwendet um aus Visual-Basic oder Excel auf Datenbanken zuzugreifen. Die vorhandenen Objekte folgen dieser Gliederung: Access Objekte - sehen Sie in der Oberfläche - Formulare, Berichte, ... Objekt Auflistungen Methoden Eigenschaften Applikation Forms Reports Echo GetOption SetOption Quit CurrentObjectName CurrentObjectType MenuBar Debug - Print - Screen - - ActiveReport ActiveForm ActiveControl PreviousControl = MS Access selbst = Bildschirmbezug ADAT-Skriptum Preißl Form 23 keine Aufzählung, Controls sind aber erreichbar - viele, größtenteils im Eigenschaftsfenster - viele, größtenteils im Eigenschaftsfenster = ein offener Bericht keine Aufzählung, Controls sind aber erreichbar Control - - viele, größtenteils im Eigenschaftsfenster Module - Inserttext - Section - - ... = ein geöffnetes Bildschirmformular Report = Steuerelement in einem Form oder Report Datenzugriffsobjekte - sind in der Datenbank vorhanden - Tabellen, Beziehungen, ... sind in DAO oder ADO Libraries implementiert. ADAT-Skriptum Preißl Objekt Auflistungen Methoden Eigenschaften DBEngine Workspaces CompactDatabase RegisterDatabase CreateWorkspace RepairDatabase Idle LoginTimeout Version Databases Groups Users BeginTrans CreateGroup Close CreateUser CommitTrans OpenDatabase CreateDatabase Rollback Name Password Username Users CreateUser Name PID Groups CreateGroup NewPassword Name PassWord PID TableDefs Relations Recordsets QueryDefs Containers Close CreateTableDef CreateProperty Execute CreateQueryDef OpenRecordset CreateRelation CollatingOrder Transactions Connect Updatable Name Version QueryTimeout Fields Indexes CreateField CreateIndex CreateProperty OpenRecordset RefreshLink Attributes RecordCount Connect SourceTableName DateCreated Updatable LastUpdated ValidationRule Name ValidationText + Datenblattgestaltungseigenschaften Fields CreateField Attributes ForeignTable Name Table Fields AddNew Clone Close Delete Edit FillCache BOF Bookmark Bookmarkable CacheSize CacheStart DateCreated = der laufende Access-Datenbankzugriffsteil Workspace = eine Arbeitssitzung, beginnend mit der Benutzeridentifikation Group = Benutzergruppe User = Benutzeraccount Database = eine geöffnete DB TableDef = Tabelle in der DB Relation = Beziehung in DB RecordSet = eine Menge von Datensätze, die einzeln durchgelesen und auch bearbeitet 24 ADAT-Skriptum Preißl werden können. FindFirst FindLast FindNext FindPrevious Move MoveFirst MoveLast MoveNext MovePrevious OpenRecordset Requery Seek Update EOF Filter Index LastModified LastUpdated LockEdits Name NoMatch PercentPosition RecordCount Restartable Sort Transactions Type Updatable ValidationRule ValidationText Fields Parameters Close CreateProperty Execute OpenRecordset Connect Name SQL DateCreated ODBCTimeout Type LastUpdated ReturnsRecords Updatable + Datenblattgestaltungseigenschaften Documents - Name Owner Permissions UserName - - Container Owner DateCreated Permissions LastUpdated UserName Name - AppendChunk CreateProperty FieldSize GetChunk AllowZero Length Name Type Attributes OrdinalPosition ValidateOnSet CollatingOrder Required ValidationRule DataUpdatable Size ValidationText DefaultValue Sätze stammen aus ) Tabelle ) Dynaset (eine aktualisierbare Abfrage) ) SnapShot (eine nichtaktualisierbare Abfrage) QueryDef = eine Abfrage Container = Zusammenfassung von Objekten (das Datenbankfenster ist Containernbasierend) Document = Elemente eines Containers (sind von einem konkreten Objekttyp) Field = Felder aus der Datenbank 25 ADAT-Skriptum Preißl SourceField Value ForeignName SourceTable Parameter Index Name Value Type Fields CreateField Create Property Clustered Primary Foreign Unique IgnoreNulls Required Name 26