Mit Select Case (engl. select a case: einen Fall auswählen) kann man sich so manche verschachtelte If-Konstruktion sparen. Wenn das Programm je nach dem Wert einer Variablen oder eines Ausdrucks verschiedene Dinge tun soll, setzt man diese Anweisung ein. Im folgenden Beispiel wird je nach Postleitzahl ein gar heiterer Spruch ausgegeben:
Select Case Postleitzahl Case 67271 MsgBox("Gruß an alle Obersülzener!") Case Meine_PLZ MsgBox("Hey, Du kommst aus meinem Dorf!") Case 11111,22222,33333,44444,55555,66666,77777,88888 MsgBox("Ey, dolle Postleite, ey!") Case 20000 To 29999 MsgBox("Moin moin!") Case Is > 80000 MsgBox("Himmeldonner, oa bajuvarischer Campi!") Case Else MsgBox("Wir grüßen Deutschland, Österreich, Hongkong...") End Case
Postleitzahl ist in diesem Beispiel der sogenannte Testausdruck. Hier darf entweder irgend etwas stehen, das eine Zahl ergibt (ein Zahlenausdruck) oder ein Zeichenkettenausdruck, also irgend etwas, das eine Zeichenkette ergibt. Dieser Testausdruck wird dann mit dem verglichen, was hinter den Case-Anweisungen steht (den Vergleichsausdrücken), und wenn er damit übereinstimmt, werden die Befehle ausgeführt, die nach der Case-Zeile stehen - bis zur nächsten Case-Zeile. Hinter Case können auch mehrere, durch Komma getrennte Vergleichsausdrücke stehen, von denen nur einer mit dem Testausdruck übereinstimmen muß. Mit To kann man auch einen ganzen Zahlenbereich angeben. Das Wörtchen Is muß man benutzen, wenn man <, >, <= oder >= verwenden will. Mit Case Else, das immer als letztes stehen muß, kann man bestimmen, was passieren soll, wenn keiner der vorher genannten Fälle zutrifft. Das Beispiel spricht wohl für sich selbst. Wichtig: wenn der Testausdruck mit zwei Vergleichsausdrücken übereinstimmt, wird nur der erste Fall berücksichtigt. Im Beispiel oben wird also auf jeden Fall immer nur eine Box ausgegeben, auch wenn zum Beispiel der Wert von Meine_PLZ mit 2 anfängt.
Die Variablen, die wir im ersten Kursteil besprochen haben, können Werte der unterschiedlichsten Art annehmen: sie können Zahlen enthalten, Zeichenketten, Datumsangaben oder Uhrzeiten. Meistens weiß man aber von Anfang an, daß eine Variable immer nur Zeichenketten oder immer nur Zahlen enthalten soll - man sagt auch, die Variable hat einen festen Datentyp. In diesem Fall kann man seine Programme schneller und speichersparender machen, indem man stattdessen Variablen benutzt, deren Typ von vornherein festgelegt ist. Den Typ eine Variablen legt man fest, indem man ihn in der Dim-Anweisung im Deklarationsteil mit angibt. Beispiel:
Dim Spielername As String
legt fest, daß die Variable Spielername eine Zeichenkettenvariable sein soll (engl. string). Wenn man versucht, dieser Variablen eine Zahl oder ein Datum zuzuweisen, gibt's eine Fehlermeldung. Eine andere Möglichkeit, einer Variable einen festen Typ zu geben, ist das Anhängen eines sogenannten Typkennzeichens (das Wort muß man sich nicht merken) an ihren Namen. So ist das Dollar-Zeichen $ das Typkennzeichen für Zeichenkettenvariablen. Das heißt, wenn man schreibt:
Dim Spielername$
dann ist die Variable Spielername$ ebenfalls eine Zeichenkettenvariable. In diesem Fall heißt diese Variable auch im ganzen Programm Spielername$ und nicht etwa Spielername. Die Typkennzeichen haben den Vorteil, daß man einer Variable ihren Typ jederzeit am Namen ansieht, ohne erst die Deklaration anschauen zu müssen.
Übersicht über die Datentypen:
Typ Typkennzeichen Beschreibung Integer % Ganze Zahlen (ohne Nachkommastellen) zwischen -32768 und +32767. Mit solchen Zahlen rechnet der Computer rasend schnell. Long & Ganze Zahlen zwischen -2147483648 und +2147483647. Fast genauso schnell wie Integer-Variablen. Single ! Kommazahlen. Double # Kommazahlen, bei denen doppelt so viele Stellen gespeichert werden wie bei Single-Zahlen. Sie sind deshalb genauer, verbrauchen aber mehr Speicherplatz, und das Rechnen geht langsamer. String $ Zeichenkette, darf bis zu 65336 Zeichen lang sein. Variant So heißt der "Datentyp", den wir bisher benutzt haben, und der eigentlich gar kein Datentyp ist, weil man in solchen Variablen eben Werte der unterschiedlichsten Typen speichern kann.
Für Datums- und Uhrzeitangaben gibt es leider keinen eigenen Typ, hier muß man immer Variant-Variablen benutzen.
Objekteigenschaften, die ja sowas ähnliches wie Variablen sind, haben übrigens auch immer einen Variablentyp: die Caption-Eigenschaft zum Beispiel hat logischerweise den Datentyp String, Farbeigenschaften haben den Datentyp Long, usw.
Manchmal darf an einer bestimmten Stelle im Programm nur ein Ausdruck mit einem ganz bestimmten Datentyp stehen. Wenn man hier andere Variablen oder Eigenschaften benutzen will, muß man sie erst in einen anderen Datentyp umwandeln. Dazu gibt es für jeden Datentyp eine Umwandlungsfunktion, deren Wert immer ihren ganz bestimmten Datentyp hat, egal, was hinter ihr in Klammern steht. So kann man mit CStr(zahl) eine Zahl in eine Zeichenkette «umwandeln». CInt(...), CLng(...), CSng(...), CDbl(...) und CVar(...) machen aus dem, was in den Klammern steht, einen Integer-, Long-, Single-, Double- bzw. Variant-Ausdruck.
Die Variablen, die wir bisher verwendet haben, waren überall im ganzen Programm benutzbar. Man kann Variablen aber auch so deklarieren, daß sie nur innerhalb einer einzigen Prozedur gültig sind. Variablen, die von allen Prozeduren benutzt werden können, nennt man globale Variablen, diejenigen, die nur in einer Prozedur gültig sind, heißen lokale Variablen.
Lokale Variablen deklariert man statt im Deklarationsteil einfach am Anfang der Prozedur, in der sie benutzt werden sollen.
Sub Form_Click () Dim i As Integer 'i ist eine lokale Variable ... End Sub
Vorsicht: eine so deklarierte lokale Variable verliert ihren Variablenwert, sobald die Prozedur verlassen wird. Beim nächsten Aufruf der Prozedur hat sie wieder den Wert Null! Wenn man will, daß die Variable ihren Wert behält, muß man sie statt mit Dim mit dem Befehl Static deklarieren.
Sub Form_Click () Static i As Integer ... End Sub
Wenn eine globale und eine lokale Variable den gleichen Namen haben, gibt es keine Fehlermeldung, sondern Visual Basic benutzt in der Prozedur die lokale Variable. (Lokale Variablen haben Vorrang vor globalen Variablen gleichen Namens)
Der Begriff Feld ist ziemlich mißverständlich: Variablenfelder haben rein gar nichts mit Textfeldern, Bildfeldern oder ähnlichem zu tun. Unter einem Variablenfeld versteht man eine Reihe von Variablen, die den gleichen Namen haben, und sich nur durch eine Nummer unterscheiden, den sogenannten Index (Mehrzahl: Indizes!). Die einzelnen Variablen nennt man dann Feldelemente. Wenn Du zum Beispiel ein Spiel schreibst, das eine Liste mit den besten Spielern enthalten soll, kannst Du diese ganze Liste in ein einziges Variablenfeld packen, und die Namen des besten, zweitbesten, drittbesten usw. Spielers haben jeweils den Index 1, 2, 3 usw. Mehr Beispiele gibt's im Kurs.
Deklarieren tut man so ein Feld, indem man im Deklarationsteil in Klammern hinter den Variablennamen schreibt, wie «groß» das Feld sein soll:
Dim HighScore$(10)
erzeugt ein Feld mit elf(!) Zeichenkettenvariablen: die erste heißt HighScore$(0) und die letzte HighScore$(10). Wenn man nur Feldelemente mit Indizes 1 bis 10 möchte, kann man auch schreiben:
Dim HighScore$(1 To 10)
(engl. to: bis) Noch raffinierter sind Felder, bei denen die einzelnen Feldelemente nicht mehr nur durch eine, sondern durch zwei (oder mehr) Zahlen beschrieben werden: wenn man zum Beispiel die Namen aller Teilnehmer eines Camps in ein Zeichenkettenfeld speichern will, kann man entweder ein großes Feld mit so vielen Elementen deklarieren, daß alle hineinpassen (jeder kriegt eine Nummer), oder man kann die Kids zusätzlich noch nach Kursen einteilen. Jeder Kurs kriegt eine Nummer, und die Kursteilnehmer darin bekommen eine Nummer innerhalb des Kurses. Deklarieren müßte man so ein Feld mit
Dim Teilnehmer$(12,10)
wenn es 12 Kurse gibt und die Teilnehmerhöchstzahl pro Kurs zehn Leute ist.
Print Teilnehmer$(3,4)
druckt dann den vierten Teilnehmer des dritten Kurses aus.
Richtig praktisch sind diese Variablenfelder vor allem dann, wenn man sie zusammen mit der For...Next-Schleife (nächster Abschnitt) benutzt.
Die For-Next-Schleife benutzt man, wenn eine Schleife nicht wie bei der Do-Loop-Schleife abhängig von irgendeiner Bedingung immer wieder durchlaufen werden soll, sondern wenn die Anzahl der Durchläufe schon vorher feststeht. Um diese Durchläufe zu zählen, benutzt man eine eigene Variable, die man Schleifenvariable oder auch Indexvariable nennt. Diese Schleifenvariable wird am Anfang auf eine bestimmte Zahl, den Anfangswert, gesetzt und dann nach jedem Schleifendurchlauf erhöht. Wenn sie eine andere Zahl, den Endwert, erreicht hat, wird die Schleife abgebrochen. Man kann jede For-Next-Schleife auch durch eine Konstruktion mit der Do-Loop-Schleife ersetzen. Die folgenden beiden Programme machen genau dasselbe:
Dim i Dim i For i = 1 to 10 i = 1 MsgBox i Do While i <= 10 Next i MsgBox i i = i + 1 Loop
Beide Programme geben auf genialste Weise die Zahlen von 1 bis 10 in je einer MsgBox aus (Graf Zahl läßt grüßen!). Das linke Programm mit der For-Next-Schleife ist zwei Zeilen kürzer und, wenn man diese Schleife erst einmal kennt, auch viel eleganter als das rechte.
Wie Du Dir sicher denken kannst, ist i in diesem Fall die Indexvariable, 1 der Anfangs- und 10 der Endwert.
Besonders praktisch ist die For-Nextmit Feldvariablen-Schleife im Zusammenhang mit Feldvariablen. Wenn man, wie oben beschrieben, die besten Spieler eines Spiels in einem Variablenfeld hat, dann kann man eine Highscore-Liste ganz einfach mit drei Zeilen ausgeben:
For i = 1 To 10 Print i;". Platz: ";HighScore$(i) Next i
Im Formular ergibt das:
1. Platz: Schorsch
2. Platz: Alois
3. Platz: Sepp
...
Na, warum nennt man die Schleifenvariable wohl auch Indexvariable?
Mit dem Anhängsel Step kann man auch in Zweier- oder größeren Schritten oder auch rückwärts zählen. Beispiele:
For j= 5 To 100 Step 5 'Zählt in Fünferschritten bis 100 For k = 30 To 15 Step -1 'Zählt rückwärts von 30 bis 15
Was Prozeduren sind, ist Dir ja sicher mittlerweile klar. Bisher haben wir allerdings immer nur Ereignisprozeduren geschrieben. Man kann aber auch «einfach so» Prozeduren schreiben, nämlich für Dinge, die in einem Programm an verschiedenen Stellen immer wieder vorkommen, oder die mit verschiedenen Ereignissen hervorgerufen werden sollen. Für solche Prozeduren muß man sich selbst einem Namen ausdenken, und man kann sie dann irgendwo im Programm selbst mit dem Befehl Call und diesem Namen aufrufen (engl. call: rufen). Wenn der Computer an diese Stelle im Programm kommt, führt er die Prozedur aus und macht danach einfach mit dem nächsten Befehl, der hinter dem Prozedurnamen steht, weiter.
Wenn man zum Beispiel ein Programm schreibt, in dem an mehreren Stellen auf immer wieder gleiche Weise ein besonderes Bild ins Formular gezeichnet werden soll, kann man dieses Bild innerhalb einer eigenen Prozedur aus Line- und Circle-Befehlen «zusammensetzen»:
Sub ZeichneBild () Line ... ... 'Hier stehen die einzelnen Befehle zum Zeichnen Circle ... End Sub
Man schreibt diese Prozedur im Codefenster irgendwo unter eine schon vorhandene (Ereignis-)Prozedur. Sobald man die Sub-Zeile geschrieben hat, wird das Codefenster geleert, und nur noch die neue Zeile ist darin zu sehen. Ändern kann man eine solche Prozedur später, indem man links oben im Codefenster «(allgemein)» wählt, und rechts oben dann den Prozedurnamen sucht und anklickt.
Zurück zu unserem Beispiel: Immer wenn das Bild jetzt tatsächlich ins Formular gezeichnet werden soll, braucht an der entsprechenden Stelle im Programm einfach nur
Call ZeichneBild
zu stehen. Dann wird die Prozedur ausgeführt und danach im Programm fortgefahren.
Und was tut man, wenn das Bild jedesmal an unterschiedliche Stellen im Formular gezeichnet werden soll? Man müßte eine Möglichkeit haben, der Prozedur auch noch die Koordinaten mitzuteilen, an denen das Bild stehen soll! Und, welche Überraschung, diese Möglichkeit gibt es tatsächlich:
Prozeduren mit Parametern
Man kann die Prozedur ZeichneBild auch so schreiben, daß beim Aufruf noch die x- und y-Koordinate des zu zeichnenden Bildes angegeben werden können. Der Aufruf würde dann zum Beispiel so aussehen:
Call ZeichneBild (1000 , 2000)
die beiden Angaben in Klammern nennt man Parameter oder Argumente der Prozedur. Die dazugehörige Prozedur muß natürlich auch anders aussehen als oben:
Sub ZeichneBild (XWert As Long, YWert As Long) Line (XWert,YWert)-(XWert+800,YWert+1600) ... 'und weitere Zeichenbefehle End Sub
Was hier in Klammern hinter ZeichneBild steht, sind die Deklarationen der Prozedurparameter. XWert und YWert sind für die Prozedur wie lokale Variablen, denen am Anfang, bevor die Prozedur ausgeführt wird, die Werte zugewiesen werden, die an der gleichen Stelle im Aufruf stehen. In diesem Fall bekommt XWert den Wert 1000 und YWert den Wert 2000. Innerhalb der Prozedur können diese Parameter wie ganz normale Variablen benutzt werden, man kann sogar ihren Wert ändern.
Noch komplizierter wird es, wenn im Aufruf nicht Zahlen, sondern wieder Variablen stehen. Dann ändert eine Änderung der lokalen Parametervariablen in der Prozedur nämlich auch den Wert der Variable, die im Aufruf benutzt wurde. Das kann man, wenn man es nicht will, dadurch verhindern, daß man beim Aufruf die Variable in Klammern setzt:
Call ZeichneBild((XWert),(YWert))
Es gibt noch eine andere Möglichkeit, solche Probleme zu verhindern: den By Val- Befehl, den ich hier aber nicht mehr erklären werde.
Funktionen
Funktionen haben wir schon im ersten Kursteil kennengelernt. Genauso wie man mit dem Schreiben von Prozeduren Basic sozusagen um eigene Befehle erweitern kann, kann man auch eigene Funktionen schreiben. Funktionen werden auf genau die gleiche Art wie Prozeduren geschrieben. Man kann sogar sagen, daß Funktionen nur eine bestimmte Art von Prozeduren sind. Der einzige Unterschied besteht darin, daß Funktionen einen Wert zurückgeben, sozusagen ein Ergebnis haben.
Als Beispiel nehmen wir eine Funktion, die Zentimeter in inch (englisches Zoll) umrechnet. Die Zentimeterlänge wird als Parameter übergeben:
Function Inch (Zenti as Integer) As Long Inch = Zenti / 2.54 End Function
Funktionen haben wie Variablen einen Datentyp, in diesem Falle Long, den man in der ersten Zeile angeben muß. Außerdem gibt es, wie man sieht, in der Funktion eine Art lokale Variable, die für das Ergebnis der Funktion steht und den gleichen Namen wie die Funktion selbst hat. Was am Ende der Funktionsausführung in dieser «Variablen» steht, wird zum Wert der Funktion.
Print Inch(35)
ergibt 13,77952756 im Formular.
Auch Buchstaben, Ziffern und Sonderzeichen wie Komma und Bindestrich werden vom Computer intern durch Zahlen dargestellt. So entspricht ein großes A der Zahl 65 und ein Punkt der Zahl 46. Die Zahl, die unter Windows zu einem Zeichen gehört, nennt man den ANSI-Code- des Zeichens (ANSI ist das amerikanische staatliche Institut für Normen, das diesen Code entwickelt hat). Eine Tabelle findest Du im Anhang dieses Skripts. Zur Umwandlung zwischen Zeichen und ANSI-Code gibt es zwei Funktionen:
Zeichen = Chr$( Ansicode )
wandelt eine Zahl in ein Zeichen um (engl. character: Zeichen). Wo Ansicode steht, muß man eine Zahl einsetzen, Zeichen steht hier für eine Zeichenketten- oder Variant-Variable. Beispiel:
Apfel$ = Chr$ ( 65 ) Print Apfel$
ergibt A im Formular. Umgekehrt gibt Asc( Zeichen ) den ANSI-Code des ersten Buchstabens der Zeichenkette Zeichen zurück.
Birne = Asc( Apfel$ ) Print Birne
ergibt mit dem oberen Beispiel wieder 65. Die Funktion heißt deswegen Asc, weil der Vorläufer des ANSI-Codes der ASCII-Code war, der allerdings keine internationalen Sonderzeichen wie Ä, Ö, Ü, ø, ç, ¿ oder ähnliches enthielt. Da Basic schon eine ältere Computersprache ist, tauchen hier solche «Altlasten» wieder auf.
Normalerweise braucht uns dieser ANSI-Code überhaupt nicht zu interessieren, aber manchmal will man in Zeichenketten besondere Zeichen einfügen, die man nicht anders als durch ihren ANSI-Code beschreiben kann.
Zum Beispiel gibt es einen ANSI-Code für das Zeilenende. Er hat die Nummer 13, und man braucht ihn in Visual Basic, wenn man Dialogboxen mit mehreren Zeilen Text auf den Bildschirm bringen will. Man fügt das Zeichen Nr. 13 dazu in seine Zeichenketten ein:
Frage$ = "Diese Frage mag Ihnen vielleicht" Frage$ = Frage$ & Chr$(13) & "überflüssig erscheinen, aber" Frage$ = Frage$ & Chr$(13) & "zur Sicherheit frage ich doch" Frage$ = Frage$ & Chr$(13) & "nochmal nach: Sind Sie sicher?" Entscheidung= MsgBox(Frage$, 4, "Frage bitte...")
ergibt eine Dialogbox mit mehreren Zeilen Text wie in der Abbildung.
Weitere Zeichenkettenfunktionen:
Len(string) ergibt die Länge einer Zeichenkette.
Left$(string, n) ergibt die ersten n Zeichen der Zeichenkette.
Right$(string, n) ergibt die letzten n Zeichen der Zeichenkette
Mid$ (string, n [, länge]) ergibt einen Teil der Zeichenkette, der bei der Position n beginnt und länge Zeichen lang ist. Die eckigen Klammern dürfen nicht eingegeben werden! Sie bedeuten nur, daß der Parameter länge auch weggelassen werden kann! Dann wird die gesamte restliche Zeichenkette zurückgegeben.
Instr$ ( [start,] string1, string2 ) sucht die Zeichenkette string2 in string1. Wenn string2 nicht in string1 vorkommt, wird 0 zurückgegeben, sonst die Stelle in string1, ab der string2 steht. Mit start kann man, wenn man will, noch angeben, ab dem wievielten Buchstaben in string1 mit dem Suchen angefangen werden soll.
Beispiele: Wenn Wort$="Kleinstaatengrenze" ist, dann ergibt:
Funktion Ergebnis Funktion Ergebnis Len(Wort$) 18 Instr(Wort$,"eng") 11 Left$(Wort$,7) "Kleinst" Instr(Wort$,"Tomate") 0 Right$(Wort$,6) "grenze" Instr(12,Wort$,"eng") 0 Mid$(Wort$,3,5) "einst" Instr(4,Wort$,"e") 11 Mid$(Wort$,6) "staatengrenze"
Chr$, Left$, Right$ und Mid$ kann man auch ohne das $-Zeichen am Schluß schreiben, dann sind sie vom Typ Variant anstatt vom Typ Zeichenkette.
Mit Variableninhalten ist es ähnlich wie mit Projekten: wenn man den Computer ausschaltet oder das Programm beendet, gehen sie für immer verloren. Und deshalb gibt es - wie bei Projekten - auch hier eine Möglichkeit, seine Daten auf die Festplatte oder Diskette zu sichern: die sequentiellen Dateien. Nur ist der Umgang mit ihnen etwas komplizierter als das Speichern von Projekten. Keine Panik, undurchschaubar ist es auch nicht!
Eine sequentielle Datei (lat. sequi: folgen) ist ungefähr wie eine Zeichenkette einfach eine Folge von Zeichen, die in diesem Fall hintereinander auf einen Datenträger geschrieben werden. Außerdem hat sie natürlich wie jede Datei einen Namen und einen Pfad.
Um so eine Datei benutzen zu können, muß man dem Computer zuerst einmal den Pfad und den Namen der Datei sagen, und ob man schreiben (output) oder lesen (input) will. Man nennt das: eine Datei öffnen. Dazu gibt es den Open-Befehl:
Open "C:\VB\DATEN.DAT" For Output As #1
Dieser Befehl sagt dem Computer, daß er im Verzeichnis VB auf der Festplatte C: eine Datei mit dem Namen DATEN.DAT anlegen soll, in die geschrieben werden und die die Nummer 1 bekommen soll. Jede offene Datei hat nämlich eine Nummer, mit der sie nachher identifiziert wird (siehe unten). Zwei gleichzeitig offene Dateien dürfen nicht die gleiche Nummer haben. Falls schon eine Datei mit diesem Pfad und Namen existiert, wird sie überschrieben! Wenn man das nicht will, sondern die Daten an schon vorhandene Daten in der Datei anhängen will, kann man statt Output das Wort Append (engl. append: anhängen) benutzen.
Um eine vorhandene Datei zu lesen, benutzt man das Wort Input:
Open "C:\VB\DATEN.DAT" For Input As #1
öffnet die Datei zum Lesen. Wenn die Datei nicht vorhanden ist, gibt's eine Fehlermeldung.
Wenn man eine Datei zum Schreiben geöffnet hat, kann man nun mit dem Print#- Befehl, einer Abwandlung des Print-Befehls, Daten hineinschreiben:
Print#1, Wort$
schreibt den Inhalt der Variablen Wort$ in die Datei mit der Dateinummer 1. Danach fügt er automatisch ein Zeilenendezeichen (Chr$(13)) und ein sog. Zeilenvorschubzeichen (Chr$(10)) in die Datei ein, rückt also sozusagen in der Datei «in die nächste Zeile vor». Das ist praktisch, weil dadurch die einzelnen Strings in der Datei getrennt werden. Man kann auch Zahlen in die Datei speichern, diese werden aber genau so Ziffer für Ziffer in die Zeichenkette geschrieben als wären es Zeichenketten.
Print#1, 4711 ist das gleiche wie Print#1, " 4711"
Man kann so viele Print#-Befehle hintereinander setzen, wie man möchte, vorausgesetzt, auf der Diskette oder Festplatte ist genug Platz. Wenn man mit Schreiben fertig ist, benutzt man den Befehl
Close 1
(engl. close: schließen, die eins ist die Dateinummer), um die Datei wieder «freizugeben». Wenn man das nicht tut, und der Computer stürzt aus irgendwelchen Gründen ab, bleibt auf dem Datenträger nur noch «Schrott» von der Datei übrig!
Lesen kann man eine Datei mit dem Line Input#-Befehl:
Line Input#1, Dateizeile$
Dieser Befehl liest eine «Zeile» aus der Datei Nr. 1, und legt sie in die Zeichenkettenvariable Dateizeile$ ab. Man kann auf diese Weise auch Zahlen einlesen, nur muß man aufpassen, daß an dieser Stelle in der Datei auch wirklich eine Zahl steht! Überhaupt muß man natürlich aufpassen, daß man die Daten in genau der gleichen Reihenfolge einliest, in der man sie auch ausgegeben hat. Sonst liest der Computer die falschen Daten in die falschen Variablen, und das gibt Verwirrung ohne Ende!
Auch hier muß man daran denken, die Datei nach dem Lesen mit dem Close-Befehl wieder zu schließen.
Noch eine nützliche Funktion im Zusammenhang mit Dateien: mit der EOF-Funktion (engl. end of file: Datei-Ende) kann man feststellen, ob die Datei, die man gerade liest, schon zu Ende ist. Man übergibt als Parameter die Dateinummer und erhält True, wenn man am Ende angekommen ist, sonst False. Mit einer Do...Until-Schleife kann man also so lange lesen, bis die Datei zu Ende ist.
In Visual Basic gibt es Befehle, die genau wie Eigenschaften zu bestimmten Objekten gehören. Diese Befehle nennt man Methoden des jeweiligen Objekts. Bisher haben sich für uns Befehle wie Print, Line, Circle usw. immer auf das Formular bezogen, in dem unser Programm ablief. Dabei habe ich bisher verschwiegen, daß diese Befehle genauso zum Formular gehören wie dessen Eigenschaften. Die genannten Grafikbefehle gibt es nämlich zum Beispiel auch als Methoden eines Bildfelds: Wenn man ein Bildfeld auf dem Formular plaziert und seine Name-Eigenschaft auf «MeinBildfeld» gesetzt hat, kann man mit
MeinBildfeld.Line (200,200) - (1800,1800)
eine Linie in das Bildfeld zeichnen. Die Koordinaten, die man hier angibt, beziehen sich entsprechend auch nicht mehr auf die obere linke Ecke des Formulars, sondern auf die des Bildfelds. Wenn man das Bildfeld im Programm bewegt, bewegt sich alles mit, was mit den Methoden des Bildfeldes hineingezeichnet wurde.
Um eine Methode eines Objektes zu benutzen, muß man also zuerst den Namen des Objektes und dann, durch einen Punkt getrennt, die Methode angeben. Noch ein Beispiel: jedes Objekt, außer dem Zeitgeber und Menüs (siehe unten), hat eine Move-Methode, mit der man es auf dem Bildschirm verschieben kann. Allgemein funktioniert diese Methode so:
Objekt.Move links, oben, Breite, Höhe
Objekt steht dabei für den Namen des Objekts, links, oben, Breite und Höhe stehen für die Werte, die seine Left-, Top-, Width- und Height-Eigenschaften nach der Verschiebung bekommen sollen. Dabei kann man oben, Breite und Höhe weglassen. Wenn man einen dieser Parameter angeben will, muß man allerdings auch alle, die davor stehen, angeben. Das gleiche erreicht man natürlich, wenn man stattdessen einfach den entsprechenden Eigenschaften neue Werte zuweist.
Wenn man das Objekt vor der Methode wegläßt, nimmt Visual Basic an, daß sie sich auf das Formular beziehen soll.
Welche Methoden ein Objekt zu Verfügung hat, kannst Du in der Online-Hilfe (siehe unten) nachschlagen.
Mit dem Menüpunkt «Neue Form» aus dem Datei-Menü kann man ein neues Formular auf den Bildschirm bringen, das man dann bearbeiten kann. Formulare sind in Visual Basic sehr selbständige Einheiten des Projektes: jedes Formular hat ein eigenes Codefenster, eigene Variablen und wird in einer eigenen Datei abgespeichert, wenn man sein Projekt speichert.
Wenn das Programm gestartet wird, wird zuerst einmal immer nur eine Form, die Startform, auf den Bildschirm gebracht. Von dieser Form aus kann man andere Formen auf den Bildschirm bringen, indem man den Befehl
Show AndereForm
gibt, wobei AndereForm für den Namen der anderen Form steht. Wenn man das zum ersten Mal seit Programmstart macht, wird vorher noch die Form_Load-Ereignisprozedur der neuen Form aufgerufen. Danach erscheint sie dann auf dem Bildschirm. Mit
Hide AndereForm
kann man eine sichtbare Form "verstecken", das heißt, sie verschwindet vom Bildschirm, aber alle ihre Eigenschaften bleiben erhalten, sie ist sozusagen nur "unsichtbar". Mit
Unload AndereForm
löscht man die Form komplett aus dem Speicher. Wenn man sie danach mit Show wieder auf den Schirm bringt, haben sie und ihre Objekte wieder die Eigenschaften, die man ihr im Entwurfsmodus gegeben hat, und die Form_Load-Prozedur wird wieder aufgerufen.
Die Gesamtheit des Codes, den man für eine Form geschrieben hat, also Deklarationsabschnitt und sämtliche Prozeduren und Funktionen, nennt man das Formmodul. Sämtliche Variablen, Konstanten, Prozeduren und Funktionen, die in einem Formmodul deklariert bzw. geschrieben wurden, können nur in diesem Formmodul benutzt werden.
Wenn man Variablen, Konstanten, Prozeduren oder Funktionen in mehreren Formmodulen benutzen will, muß man sie in einem eigenen Codemodul deklarieren bzw. schreiben. Das ist sozusagen ein Formmodul ohne Formular. Ein neues Codemodul legt man mit dem Menüpunkt «Datei/Neues Modul» oder mit dem zweiten Icon von links in der Visual-Basic-Titelleiste an (siehe Bildchen). Das Codefenster erscheint, und man kann nach Herzenslust Deklarationen, Prozeduren und Funktionen eingeben.
Um globale Variablen zu deklarieren, die in sämtlichen Form- und Codemodulen benutzt werden können, muß man außerdem statt des Dim-Befehls den Global-Befehl benutzen.
Global Anzahl As Integer, Dateiname As String
deklariert zwei globale Variablen: eine Ganzzahl- und eine Zeichenkettenvariable. Wenn man den Dim-Befehl benutzt, sind die Variablen nur im Codemodul gültig! Prozeduren oder Funktionen, die in einem Codemodul geschrieben wurden, sind in jedem Fall überall im Projekt aufrufbar.
Jetzt bekommt auch das Projektfenster einen Sinn: hier sind sämtliche Formen und Codemodule aufgelistet, und indem man eines von ihnen anklickt und dann «Code anzeigen» wählt, kann man das jeweilige Codefenster auf den Bildschirm bringen. Bei Formen kann man auch «Form anzeigen» wählen, um das Formfenster zu öffnen. Die Dateien, die auf «.VBX» enden, und die hier auch angezeigt werden, brauchen uns nicht zu kümmern.
Zu allen Befehlen, Steuerelementen, Eigenschaften, Methoden und zu vielem anderen gibt es Hilfstexte, die man auf einfache Weise am Bildschirm (online) abrufen kann. Die wichtigste Möglichkeit ist dabei die Taste <F1>. Beim Entwerfen von Steuerelementen kann man mit <F1> Hilfe zum aktuellen Steuerelement bekommen. Ist das Eigenschaftenfenster aktiv, bekommt man mit dieser Taste Hilfe zur markierten (aktuellen) Eigenschaft. Im Codefenster braucht man nur den Cursor auf einen Visual-Basic-Befehl, eine Eigenschaft oder Methode zu setzen und <F1> zu drücken, um einen Hilfstext darüber lesen zu können. Darüber hinaus gibt es auch noch das ?-Menü, um Hilfe anzufordern. Hier kann man sich das Inhaltsverzeichnis («Index») der Online-Hilfe anzeigen lassen oder, besonders praktisch, nach Themen in der Hilfe suchen.
Allerdings wird in vielen dieser Hilfstexte davon ausgegangen, daß man Visual Basic schon ziemlich gut kennt. Einige Absätze, die man nicht versteht, muß man halt einfach überlesen. Aber zum Nachschlagen von Befehlen ist die Online-Hilfe sehr gut geeignet. Für viele Befehle gibt es auch Beispiele, die man ins Codefenster kopieren und gleich ausführen lassen kann.
Fehler machen alle Programmierer. Bei professioneller Software wird meistens mehr als die Hälfte der Programmierzeit mit Fehlersuche und -berichtigung verbracht! Am ärgerlichsten und am schwersten zu finden sind dabei die Laufzeitfehler und die logischen Fehler: ein Laufzeitfehler ist ein Fehler, der von Visual Basic erst bemerkt werden kann, wenn das Programm läuft - zum Beispiel wenn man im Programm versucht, durch eine Variable zu teilen, deren Wert Null ist. Bei logischen Fehlern hingegen läuft das Programm zwar ohne jede Fehlermeldung, aber es macht nicht das, was es soll. Solche Fehler zu finden, kann eine größere Herausforderung sein als das Programmieren selbst! Erfahrung und Übung kann hier viel helfen: deshalb fang' schon im Kurs damit an, möglichst erst einmal selbst nach den Fehlern in Deinen Programmen zu suchen, und frag' dann erst den Kursleiter!
Ein paar Tips zur Fehlersuche:
Je früher man einen Fehler bemerkt, desto einfacher ist er zu finden! Deswegen sollte man, während man sein Programm schreibt, möglichst oft Probeläufe machen, um zu sehen, ob das, was man schon geschrieben hat, auch richtig funktioniert.
Wenn ein Fehler auftritt, versucht man zuerst, ihn möglichst genau einzugrenzen. Welche Variablen und Prozeduren können etwas damit zu tun haben, welche auf keinen Fall? An welcher Stelle tritt der Fehler zutage? Welche Werte haben die beteiligten Variablen und Eigenschaften zu diesem Zeitpunkt? Vorsicht: der Fehler selbst muß noch lange nicht an dieser Stelle liegen, es kann auch schon vorher etwas falsch gelaufen sein, das sich jetzt erst auswirkt!
Bei Endlosschleifen: ist die Abbruchbedingung richtig formuliert? Wann hätte sie erreicht werden sollen? Was ist stattdessen wohl passiert? Kann es sein, daß eine Ereignisprozedur sich selbst aufgerufen hat, indem sie ihr eigenes Ereignis ausgelöst hat?
Mit dem Befehl Debug.Print, der wie der Print-Befehl funktioniert, aber ins Debug-Fenster schreibt, kann man an interessanten Stellen im Programm Variablenwerte oder auch nur ein "Huhu!" ausgeben und überlegen, ob die Ausgabe dem entspricht, was man erwartet.
Debugging (sprich: Diebagging) ist Computerchinesisch und steht für Fehlersuche und -verbesserung. Ein bug ist ein Programmfehler. Visual Basic kann zwar natürlich nicht selbst die logischen Fehler in Programmen finden (dazu ist ein Computer zu blöde), aber es stellt eine Reihe von Hilfsmitteln für die Fehlersuche zur Verfügung.
Die zentrale Rolle spielt dabei der Unterbrechungsmodus: Die meisten Fehlersuchfunktionen kann man nur ausführen, wenn Visual Basic im Unterbrechungsmodus ist. Unterbrechen kann man ein Programm auf verschiedene Weise:
«von Hand» mit der Tastenkombination <Strg-Untbr> oder mit dem Pause-Icon in der Iconleiste, während das Programm läuft;
durch Einfügen des Stop-Befehls an die Stelle im Code, wo unterbrochen werden soll. Dieser Befehl bringt Visual Basic dazu, sofort in den Unterbrechungsmodus zu gehen.
durch Einfügen eines Haltepunkts irgendwo im Code. Einen Haltepunkt fügt man ein, indem man im Codefenster in die Zeile mit der Anweisung geht, vor der die Programmausführung angehalten werden soll, und dann das Icon mit der Hand in der Iconleiste anklickt (oder <F9> drückt oder den Menüpunkt «Test/Haltepunkt ein/ausschalten» wählt). Die Zeile wird daraufhin rot eingefärbt. Wenn das Programm auf diese Zeile trifft, geht Visual Basic in den Unterbrechungsmodus. Löschen kann man den Haltepunkt wieder, indem man mit dem Cursor in die Zeile geht und wieder das Hand-Icon wählt (oder ... oder ...).
Der einzige Unterschied zwischen Stop und dem Haltepunkt ist, daß der Stop-Befehl wirklich Teil des Codes ist und auch mit abgespeichert wird, während Haltepunkte beim Abspeichern verlorengehen.
Im Unterbrechungsmodus wird der aktuelle Befehl , der gerade ausgeführt werden sollte, als das Programm unterbrochen wurde, im Code-Fenster umrahmt. Wenn man an einer anderen Stelle im Programm weitermachen will, kann man den Cursor dorthin bewegen, und dann den Menüpunkt «Testen/Nächste Anweisung festlegen» wählen. Daraufhin wird der Befehl eingerahmt, und wenn man das Programm fortsetzt, wird an dieser Stelle weitergemacht.
Wenn das Programm unterbrochen wurde, kann man im Testfenster Befehle ausführen lassen, mit Print Variablen- oder Eigenschaftswerte anzeigen lassen und ändern, Prozeduren und Funktionen aufrufen und vieles mehr. Man darf allerdings hier keine Variablen deklarieren.
Mit dem Menüpunkt «Testen/Aufrufe.../...» oder dem mittleren Test-Icon kann man eine Liste der Prozeduren anfordern, die sich, als das Programm unterbrochen wurde, gerade in der Ausführung befanden. So kann man herausbekommen, welche Prozedur welche aufgerufen hat.
Mit dem Icon mit den beiden Pfotenabdrücken (Katze mit Holzbein?) kann man sein Programm Befehl für Befehl ausführen lassen (Einzelschritt). Bei einem Klick auf dieses Icon führt der Computer den nächsten Befehl im Programm aus und unterbricht dann wieder. Das Icon mit den vier Pfotenabdrücken macht genau dasselbe, nur wenn der nächste Befehl ein Prozeduraufruf ist, wird gleich die ganze Prozedur ausgeführt.
Das Icon mit der Brille schließlich ist der Schlüssel zur «Überwachung von Ausdrücken», einer Fehlersuchhilfe, die ich hier nicht mehr erklären werde.
Wenn man mit seinem Projekt zufrieden ist, den letzten Fehler ausgemerzt zu haben glaubt und am Programm nichts mehr ändern will, dann kann man Visual Basic eine sogenannte EXE-Datei erstellen lassen. Das bedeutet daß Visual Basic das Programm in eine Form übersetzt, die der Computer auch direkt, ohne Visual Basic, versteht. EXE-Datei heißt sie, weil ihr Dateiname auf .EXE endet. In dieser Form kann man ein Programm direkt im Programm-Manager von Windows erscheinen lassen, und Visual Basic muß nicht mehr gestartet werden, um das Programm laufen zu lassen. Man kann ein Programm, von dem man nur die EXE-Datei hat, aber auch nicht mehr ändern.
Um ein Programm übersetzen zu lassen, wählt man den Menüpunkt «Datei/EXE-Datei erstellen». Daraufhin erscheint ein Formular, in dem man den Dateinamen und den Pfad für die Datei sowie einen Programmnamen, der später im Programm-Manager erscheint, aussuchen kann. Das Programmsymbol wird, das sei nur kurz angedeutet, durch die Icon-Eigenschaft des Formulars bestimmt. Um die Datei in den Programm-Manager einzubinden, muß man dort zuerst die Programmgruppe anklicken, in die das Programm soll, danach den Menüpunkt «Datei/Neu», dann «Programm», «OK» und dann «Durchsuchen» wählen. Dann kommt man zu einem Formular, in dem man wieder Pfad und Namen der EXE-Datei angeben muß. Wenn man zweimal «OK» klickt, erscheint das Programmsymbol in der Gruppe.
Der Rahmen ist eine Art Formular im Formular. Er ist dazu gedacht, Steuerelemente, die zusammengehören, sowohl optisch als auch logisch zusammenzufassen. Wenn man einen Rahmen auf dem Formular angelegt hat, kann man darin andere Steuerelemente anordnen. Diese Steuerelemente gehören dann zum Rahmen: ihre Top- und Left-Eigenschaften (Koordinaten) beziehen sich nicht mehr auf das Formular, sondern auf die obere linke Ecke des Rahmens. Man kann diese Steuerelemente nicht aus dem Rahmen hinausbewegen. Wenn man den Rahmen im Formular verschiebt, werden alle Steuerelemente darin mitverschoben.
Mit der Caption-Eigenschaft wird die Überschrift, die oben im Rahmen steht, festgelegt.
Ähnlich wie man Variablen gleichen Typs zu Variablenfeldern «zusammenfassen» kann, kann man das auch mit Steuerelemente gleichen Typs tun. Die Steuerelemente erhalten dann alle den gleichen Namen, und benutzen die gleichen Ereignisprozeduren. Sie unterscheiden sich nur durch ihre Eigenschaften, und insbesondere durch ihre Index-Eigenschaft, eine Zahl, die nichts anderes ist als die Nummer des Steuerelements im Steuerelementfeld (- wie der Index eines Variablenfeldelements).
Wenn man zum Beispiel ein Programm schreibt, das einen «Taschenrechner» mit Buttons («Befehlsschaltflächen») als «Tasten» auf den Bildschirm bringt, ist es sinnvoll, die Buttons mit den Zahlen 0 bis 9 zu einem Feld zusammenzufassen. Dazu muß man allen Buttons den gleichen Namen (Name-Eigenschaft) geben, und die Eigenschaft Index je nach «Taste» mit den Werten 0 bis 9 belegen. Dann braucht man nur noch eine einzige Click-Prozedur für alle zehn Buttons zu schreiben. Welcher Button denn nun geklickt wurde, erfährt man aus der Variable Index, die bei Steuerelementfeldern an die Ereignisprozeduren als Parameter übergeben wird. Die Prozedur könnte nun so oder ähnlich aussehen:
Sub Zahltasten_Click (Index As Integer) ' Hier folgt irgend etwas, zum Beispiel: Textfeld.Text = Textfeld.Text & CStr(Index) End Sub
Das Kontrollkästchen ist ein Kästchen im Formular, das entweder leer oder «angekreuzt» sein kann. Diesen «Zustand» wechselt es immer, wenn man es anklickt. Man verwendet das Kästchen-Steuerelement dann, wenn der Benutzer irgendeine Ja/Nein-Entscheidung treffen soll. Zum Beispiel könnte es in einem Spiel dazu benutzt werden, den Zwei-Spieler-Modus ein- oder auszuschalten.
Das einzig wichtige Ereignis für dieses Steuerelement ist das Click-Ereignis, aber selbst das braucht man nicht sehr oft, denn meist genügt es, zu einem bestimmten Zeitpunkt den Zustand des Kontrollkästchens zu kennen. Dieser Zustand steht in der Value-Eigenschaft (engl. value: Wert): 0 bedeutet «nicht ausgewählt», 1 bedeutet «ausgewählt» und 2 bedeutet, daß das Kästchen gerade abgeblendet, also nicht anwählbar ist (Enable ist False). Mit der Caption-Eigenschaft legt man den Text fest, der neben dem Steuerelement erscheint.
Ein Optionsfeld (Option heißt Wahlmöglichkeit) ist fast das gleiche wie ein Kontrollkästchen: es wird ein Kreis dargestellt, der entweder gefüllt oder leer ist. Durch Anklicken kann man das Optionsfeld anschalten, was sich in der Value-Eigenschaft-Eigenschaft widerspiegelt. Der wesentliche Unterschied zum Kontrollkästchen: wenn in einer Form oder einem Rahmen mehrere Optionsfelder sind, kann nur eines von ihnen «angekreuzt» sein. Wenn man ein Optionsfeld anklickt, werden alle anderen Optionsfelder im gleichen Formular oder Rahmen ausgeschaltet. Man benutzt das Optionsfeld-Steuerelement deshalb dann, wenn der Benutzer aus mehreren Alternativen eine auswählen soll.
Menüs gelten auch als Steuerelemente, sie werden allerdings völlig anders entworfen: zum Entwerfen von Menüs gibt es ein eigenes Fenster, das man öffnet, indem man entweder den Menüpunkt «Fenster/Menüentwurf» wählt oder das Menüentwurf-Icon anklickt (das mit den Menüs drauf!).
Das Menüentwurfsfenster hat zwei Teile: im unteren Teil wird die Menüstruktur festgelegt: die Menütitel erscheinen in der ersten Spalte, die Menüpunkte selbst sind eingerückt, eventuelle Untermenüpunkte sind noch weiter eingerückt. Trennstriche, die Menüs unterteilen, werden hier durch einen einzelnen Bindestrich in einer eigenen Zeile dargestellt.
Der Benutzer soll Menüpunkte auch dadurch anwählen können, daß er die <Alt>-Taste zusammen mit einem Buchstaben, der im Menü unterstrichen ist, drückt. Dieser Buchstabe wird im Menüentwurfsfenster dadurch markiert, daß man vor ihn ein &-Zeichen (Kaufmanns-Und) schreibt. Dieses Zeichen wird nachher im Menü nicht ausgedruckt, stattdessen wird der Buchstabe dahinter unterstrichen dargestellt.
Im oberen Teil des Menüfensters können die Eigenschaften des unten markierten Menüpunkts bearbeitet werden. Name, Caption, Index (für Steuerelementfelder aus Menüpunkten), Visible und Enabled dürften klar sein. Mit Checked kann man bewirken, daß im Menü ein Häkchen () vor dem Menüpunkt erscheint (Wie in Visual Basic beim Menüpunkt «Ansicht/Werkzeugleiste»). Mit Abkürzungstaste kann man eine Tastenkombination auswählen, die den Menüpunkt aufrufen soll. Diese Tastenkombination erscheint auch im Menü hinter dem Menüpunkt (wie zum Beispiel bei «Bearbeiten/Ausschneiden» die Tastenkombination <Strg+X>). Die anderen Eigenschaften sind absolut uninteressant. Jeder Menüpunkt, selbst eine Trennlinie, muß übrigens einen Namen bekommen, auch wenn dieser Name bei Trennlinien nirgendwo sonst eine Rolle spielt.
Für jeden Menüpunkt muß man dann nur noch eine Click-Prozedur schreiben... (außer für Trennlinien und Menütitel). Wenn man das Menüentwurfsfenster verläßt und im Formfenster einen Menüpunkt anwählt, erscheint übrigens praktischerweise gleich das Codefenster mit der entsprechenden Click-Prozedur.
Das Listenfeld ist ein Feld auf dem Bildschirm mit einer Liste darin, aus der der Benutzer einen Punkt auswählen kann. Ein Kombinationsfeld heißt deshalb so, weil es eine Kombination aus einem Listenfeld und einem Textfeld ist. Es gibt drei verschiedene Arten von Kombinationsfeldern. Von welcher Art das K.-feld ist, wird durch seine Style-Eigenschaft festgelegt:
Style=0: Dropdown-Kombinationsfeld-. Man sieht hier zuerst nur ein Textfeld, in dem man Text eingeben kann, und daneben ein Icon mit einem Pfeil nach unten. Wenn man das Icon anklickt, öffnet sich darunter wie ein Menü eine Liste, aus der man ein Element auswählen kann, das daraufhin im Textfeld erscheint. Beispiel: Das Eingabefeld oben im Eigenschaftenfenster.
Style=1: Einfaches Kombinationsfeld. Genauso wie das Dropdown-K.-feld, nur daß die Liste die ganze Zeit zu sehen ist. Beispiel: Die Dateiauswahlliste in den Dialogfeldern für Laden und Speichern.
Style=2: Dropdown-Listenfeld-. Genauso wie das Dropdown-K.-feld, nur daß man im Textfeld nicht selber etwas eingeben, sondern nur etwas aus der Liste wählen kann. Es heißt zwar Dropdown-Listenfeld, ist aber auch nur eine spezielle Art des K.-feldes.
Die Listenelemente eines Listen- oder K.-feldes müssen Stück für Stück mit der AddItem-Methode in die Liste «geladen» werden. Oft macht man das in der Form_Load-Prozedur. Beispiel:
Musikliste.AddItem "BAP: Verdamp' lang her"
bringt einen Listeneintrag BAP: Verdamp' lang her in das Listen- oder Komb.-Feld Musikliste. Man kann jederzeit Einträge zu Listen hinzufügen. Löschen kann man sie wieder mit:
Musikliste.RemoveItem Index
wobei Index für die Nummer des Eintrags in der Liste steht. Die Nummer des ersten Eintrags ist 0. Mit Liste.Clear löscht man die ganze Liste.
Wichtige Eigenschaften von Listen- und Komb.-feld:
Die List( Index )-Eigenschaft ist in Wirklichkeit ein ganzes Feld von Eigenschaften! In den Elementen dieses Feldes befinden sich die Einträge der Liste. Mit Steuerelement.List(Index) kann man also auf die einzelnen Einträge zugreifen. In der Text-Eigenschaft steht das gerade ausgewählte Listenelement oder der im Textfeld eingegebene Text. Die ListIndex-Eigenschaft enthält die Nummer des ausgewählten Listenelements. Hat der Benutzer stattdessen etwas im Textfeld eingegeben, steht hier -1. Die ListCount-Eigenschaft gibt über die Anzahl der Listeneinträge Auskunft. Wenn die Sorted-Eigenschaft auf True gesetzt ist, wird die Liste automatisch alphabetisch sortiert.
Listen und Kombinationsfelder, bei denen mehrere Elemente ausgewählt werden können, oder die mehrspaltig sind, werde ich hier nicht mehr besprechen Hier hilft ein Blick in die Online-Hilfe weiter.
Mausereignisse:
Für besondere Anwendungen, zum Beispiel wenn man die rechte Maustaste abfragen oder gar Mausbewegungen verfolgen will, gibt es besondere Mausereignisse, die man statt Click und DblClick benutzen kann:
Das MouseDown- bzw. MouseUp-Ereignis trifft immer dann ein, wenn irgendein Mausknopf niedergedrückt bzw. losgelassen wurde, während sich der Mauszeiger über dem jeweiligen Objekt befand. An die MouseDown- und MouseUp-Ereignisprozeduren werden eine Reihe von Parametern übergeben:
Sub Objekt_MouseUp (Button As Integer, Shift As Integer, X As Single, Y As Single)
(Das steht natürlich alles in einer Zeile!) Button gibt die Maustaste an, die gedrückt wurde: Dabei steht 1 für die linke, 2 für die rechte und 4 für die mittlere Taste (wenn vorhanden). Den Shift-Parameter braucht man normalerweise nicht, er wird weiter unten bei den Tastenereignissen besprochen. In X und Y stehen die Koordinaten des Mauszeigers zu dem Zeitpunkt, als das Ereignis passierte - und zwar relativ zur linken oberen Ecke des Objektes, um dessen Ereignis es sich hier handelt! MouseDown- und MouseUp-Ereignisprozedur haben die gleichen Parameter.
Das MouseMove-Ereignis tritt immer dann auf, wenn die Maus über dem Objekt bewegt wurde. Dieses Ereignis trifft, wenn der Benutzer die Maus über den Bildschirm bewegt, in sehr kurzen Zeitabständen ein, deswegen darf die Ereignisprozedur nur sehr kurz sein, damit sie fertig ist, bevor das nächste Ereignis auftritt. Die Parameter der Ereignisprozedur sind die gleichen wie bei MouseDown und MouseUp. Der Button-Parameter hat aber eine etwas andere Bedeutung: hier gibt er an, welche Maustaste(n) gerade gedrückt war(en), während die Maus bewegt wurde. Auch hier entsprechen die verschiedenen Mausknöpfe den Zahlen 1, 2 und 4. Zusätzlich kann es aber sein, daß zwei oder alle Mausknöpfe gleichzeitig gedrückt waren, und dann werden die entsprechenden Zahlen addiert. Ein Button-Parameter von 3 bedeutet zum Beispiel, daß die rechte und die linke Maustaste gedrückt waren, denn 2 + 1 sind 3.
Tastaturereignisse:
Das KeyPress-Ereignis eines Objekts tritt dann auf, wenn der Benutzer eine Taste gedrückt hat, während das Objekt «aktiv», das heißt mit einem schwarzen Rahmen versehen war. (Man sagt auch, das Objekt «hat den Fokus»). Der Ereignisprozedur wird als Parameter der ANSI-Code der gedrückten Taste übergeben (ANSI-Tabelle siehe Anhang). Das KeyPress-Ereignis trifft nicht ein, wenn die Taste keinem ANSI-Zeichen entspricht, wie zum Beispiel bei Cursortasten, Funktionstasten oder Umschalttasten (<Strg>, <Alt> usw.). Dieses Ereignis ist mit dem Click-Ereignis für die Maus vergleichbar, während die folgenden Ereignisse eher dem MouseDown- und MouseUp-Ereignis entsprechen.
Die KeyDown- und KeyUp-Ereignisse treten ein, wenn eine Taste gedrückt (KeyDown) oder losgelassen (KeyUp) wurde, während ein Objekt den Fokus hatte. Im Gegensatz zum KeyPress-Ereignis wird an die Ereignisprozedur kein ANSI-Code, sondern ein eigener Tastencode als Parameter übergeben:
Sub Objekt_KeyDown (KeyCode As Integer, Shift As Integer)
Tastencodes Rücktaste 8 Bild ab 34 F2 113 Zahlblock-0 96 Tab 9 Ende 35 F3 114 Zahlblock-1 97 Entf 12 Pos1 36 F4 115 Zahlblock-2 98 Return 13 Nach links 37 F5 116 Zahlblock-3 99 Umschalt 16 Nach oben 38 F6 117 Zahlblock-4 100 Strg 17 Nach rechts 39 F7 118 Zahlblock-5 101 Pause 19 Nach unten 40 F8 119 Zahlblock-6 102 Rollen 20 Druck 42 F9 120 Zahlblock-7 103 Esc 27 Einfg 45 F10 121 Zahlblock-8 104 Leer 32 Entf 46 F11 122 Zahlblock-9 105 Bild auf 33 F1 112 F12 123 Zahlblock-, 108 Die Tasten A bis Z haben als Wert ihre ANSI-Codes (65 bis 90). Die Tasten 0 bis 9 oberhalb der Buchstabentasten haben als Wert ihre ANSI-Codes (48 bis 57).
Der KeyCode-Parameter ist der Code der gedrückten Taste. Jede Taste auf der Tastatur hat ihre eigene Nummer (siehe unten). Aus diesem Wert kann man aber auch wirklich nur die Taste entnehmen: «a» und «A» haben hier den gleichen Wert. Der Shift-Parameter gibt an, welche der drei Umschalttasten <Shift>,<Strg> und <Alt> gleichzeitig gedrückt war(en). Dieser Parameter funktioniert genauso wie der Button-Parameter in der MouseMove-Prozedur: die <Shift>-Taste entspricht dem Wert 1, die <Strg>-Taste 2 und die <Alt>-Taste 4. Wenn mehrere Umschalttasten gedrückt waren, werden diese Werte addiert. Wurden beispielsweise die Tasten <Strg> und <Alt> gedrückt, dann hat Shift den Wert 6. Der Parameter Shift wird übrigens auch bei den Mouse...-Ereignissen übergeben, damit man auf Mausereignisse anders reagieren kann, wenn gleichzeitig Umschalttasten gedrückt waren.
Obwohl KeyDown und KeyUp nahezu alle Tasten betreffen können, sollte man sie nur für Tastendrücke verwenden, die man mit dem KeyPress-Ereignis nicht behandeln kann.
0 n 32 Leer 64 @ 96 ` 128 n 160 Leer 192 À 224 à 1 n 33 ! 65 A 97 a 129 n 161 ¡ 193 Á 225 á 2 n 34 " 66 B 98 b 130 n 162 ¢ 194 Â 226 â 3 n 35 # 67 C 99 c 131 n 163 £ 195 Ã 227 ã 4 n 36 $ 68 D 100 d 132 n 164 ¤ 196 Ä 228 ä 5 n 37 % 69 E 101 e 133 n 165 ¥ 197 Å 229 å 6 n 38 & 70 F 102 f 134 n 166 ¦ 198 Æ 230 æ 7 n 39 ' 71 G 103 g 135 n 167 § 199 Ç 231 ç 8 BS** 40 ( 72 H 104 h 136 n 168 ¨ 200 È 232 è 9 TAB** 41 ) 73 I 105 i 137 n 169 © 201 É 233 é 10 LF** 42 * 74 J 106 j 138 n 170 ª 202 Ê 234 ê 11 n 43 + 75 K 107 k 139 n 171 « 203 Ë 235 ë 12 n 44 , 76 L 108 l 140 n 172 ¬ 204 Ì 236 ì 13 CR** 45 - 77 M 109 m 141 n 173 205 Í 237 í 14 n 46 . 78 N 110 n 142 n 174 ® 206 Î 238 î 15 n 47 / 79 O 111 o 143 n 175 ¯ 207 Ï 239 ï 16 n 48 0 80 P 112 p 144 n 176 ° 208 Ð 240 ð 17 n 49 1 81 Q 113 q 145 n 177 ± 209 Ñ 241 ñ 18 n 50 2 82 R 114 r 146 n 178 ² 210 Ò 242 ò 19 n 51 3 83 S 115 s 147 n 179 ³ 211 Ó 243 ó 20 n 52 4 84 T 116 t 148 n 180 ´ 212 Ô 244 ô 21 n 53 5 85 U 117 u 149 n 181 µ 213 Õ 245 õ 22 n 54 6 86 V 118 v 150 n 182 ¶ 214 Ö 246 ö 23 n 55 7 87 W 119 w 151 n 183 · 215 × 247 ÷ 24 n 56 8 88 X 120 x 152 n 184 ¸ 216 Ø 248 ø 25 n 57 9 89 Y 121 y 153 n 185 ¹ 217 Ù 249 ù 26 n 58 : 90 Z 122 z 154 n 186 º 218 Ú 250 ú 27 n 59 ; 91 [ 123 { 155 n 187 » 219 Û 251 û 28 n 60 < 92 \ 124 | 156 n 188 ¼ 220 Ü 252 ü 29 n 61 = 93 ] 125 } 157 n 189 ½ 221 Ý 253 ý 30 n 62 > 94 ^ 126 ~ 158 n 190 ¾ 222 Þ 254 þ 31 n 63 ? 95 _ 127 n 159 n 191 ¿ 223 ß 255 ÿ
** Die Werte 8 (BS), 9 (TAB), 10 (LF) und 13 (CR) stehen für Rückschritt-, Tabulator-, Zeilenvorschub- beziehungsweise Wagenrücklauf-Zeichen. Sie können nicht als Zeichen dargestellt werden, können aber die Textanzeige beeinflussen.
n Diese Zeichen werden nicht von Windows unterstützt.
E-Mail:
Marcus.Hermann@urz.uni-heidelberg.de
Letzte Änderung: 3.2.96