Arrays sind indizierte Datenfelder. Aditalk kennt keine Arrays. Anwender müssen dennoch nicht darauf verzichten: TOS zeigt drei Methoden, diese Felder nachzubilden.
Indizierte Datenfelder bieten über Schlüsselnummern Zugriff auf jeden einzelnen Feldinhalt. Um diese Arrays in Aditalk nachzubilden, stehen drei Wege offen:
Betrachten wir zunächst die Strings. Die Aditalk-Dokumentation gibt die erlaubte Länge eines Strings mit 80 Zeichen an. Tatsächlich beträgt die maximale Länge eines solchen Strings jedoch 256 Zeichen. Addieren Sie hintereinander gleichlange Strings in einen neuen String, erhalten Sie ein Array, das sich leicht mit dem SUB-STR-Befehl abfragen läßt.
Sie wollen z. B. zehn Dateinamen in ein Array überführen. Das Directory befindet sich in einer Datei [dir.dat], die Sie vorher mit RUN angelegt haben. Bestimmen Sie jetzt einen Leerstring [dir] und lesen in ihn die einzelnen Zeilen von [dir.dat] so ein, daß jeder Dateiname genau zwölf Zeichen lang ist.
STORE "" TO dir
SET INPUT TO "dir.dat”
SET CONSOLE OFF
SET INPUT ON
DO WHTLE(not eof)
ACCEPT TO t
STORE t+SPACE (12-LEN (t)) TO t
STORE dir+t TO dir
ENDDO
SET INPUT OFF
SET INPUT TO ""
SET CONSOLE ON
Verwenden Sie nun den SUBSTR-Befehl und eine einfache Zähl variable [i], um aus dem Array-String [dir] einzelne Dateinamen zu eliminieren.
STORE SUBSTR( dir, i*12+1, 12) TO dat
STORE TRIM dat TO dat
In der Variablen [dat] befindet sich jetzt der i-te Name des Array-Strings [dir].
Eine weitere Anwendung für einen String als Array bietet sich, wenn Sie Suchergebnisse für später festhalten wollen. Nehmen wir an, daß Sie im Postleitzahlengebiet 8xxx alle Kunden suchen, deren Umsatz 3000 Mark übersteigt und die zur Branche X gehören. Die passenden Datensätze wollen Sie aber nicht sofort, sondern erst später weiterverarbeiten. Als Lösung bietet sich an, die SKIP-Abstände der passenden Datensätze in ein Stringarray zu speichern.
INDEX Plz
STORE "" TO wahl
STORE 0 TO x
STORE 1 TO n
STORE FIND 8000 TO ok
DO WHILE(Plz<=8999)
IF(Branche="X" AND Umsatz>3000)
STORE wahl+STR(X,2,0) TO wahl
STORE n+1 TO n
STORE 1 TO x
ELSE
STORE x+1 TO x
ENDIF
SKIP +1
ENDDO
Nach Beendigung der Suche stehen in »wahl« die einzelnen Blätter-SKIPs. Wo wir schon dabei sind, gleich noch etwas Komfort in die Bedienung: Wollen Sie mit den Pfeiltasten
STORE 1 TO i
STORE FIND 8000 TO ok
SKIP INT(SUBSTR(wahl,i 2 1,2))
DISPLAY
DO WHILE(true)
WAIT TO msg
DO CASE
CASE(LASTKEY()="right" AND i<n)
STORE i+1 TO i
CASE(LASTKEY()="left" AND i>1)
STORE i-1 TO i
CASE (LASTKEY () ="cr")
EXIT
OTHERWISE
BELL
ENDCASE
SKIP INT(SUBSTR(wahl,i*2-1,2))
DISPLAY NONAMES
ENDDO
Als Array läßt sich auch eine logische Datei (ein Karteikasten) verwenden, wenn Sie diese vorher mit INIT.PRG angelegt haben. Diese Variante bietet sich z. B. für Menüs an. Als Menü verstehe ich hier auch die Auswahl vorgegebener Textzeilen, etwa für Anreden, Konditionen usw. Die logische Datei heißt dann z. B. »TABU«. Als Schlüsselmerkmal bietet sich ein 1-bis 2-stelliges Nummernfeld an. Als Menü legen Sie ein Mehrfach-Stringfeld von entsprechender Zeichenlänge an. Nehmen wir an, daß das Menüfeld **m« heißt. Es soll acht Zeilen enthalten, die schon beschriftet sind. Das Menü geben Sie folgendermaßen aus:
STORE 1 TO i
STORE(JUMP 1 TO tabu.nr) TO ok
DO WHILE(i<9)
@ i+5,20 ?? m(i)
STORE i+1 TO i
ENDDO
Das Menü soll so reagieren, daß es die jeweils aktuelle Menüzeile invertiert anzeigt. Dazu ist es notwendig, dem Ausgabestring ein CHR(27)+'p' voranzustellen. Die Steuerung der Auswahl in den Menüeinträgen erfolgt durch die Pfeiltasten auf und ab. Ein auf in der ersten Zeile soll zur letzten springen, ein ab in der letzten wieder zur ersten Zeile. Return bestätigt den aktiven Menüpunkt. Die Sequenz zur Zeilenschwärzung weisen wir der Variablen [p] zu. Das Auswahllisting lautet:
STORE CHR(27)+'p' TO p
STORE 1 TO i
DO WHILE(true)
WAIT TO msg
DO CASE
CASE(LASTKEY() ="down" AND i<8)
STORE i+1 TO i
CASE(LASTKEY()="down" AND i=8)
STORE 1 TO i
CASE(LASTKEY()="up" AND i> 1)
STORE i-1 TO i
CASE(LASTKEY()="up" AND i=1)
STORE 8 TO i
CASE (LASTKEY() ="cr")
EXIT
OTHERWISE
BELL
ENDCASE
ENDDO
BACK
Die getroffene Auswahl steht jetzt als Ziffer in [i] und läßt sich entsprechend weiterverarbeiten. Vergessen Sie nicht, mit BACK in die aktuelle Datei zurückzuspringen.
Benötigen Sie das Menü für das Auswählen einer Anrede oder Kondition, müssen die zugehörigen Textzeilen in entsprechender Länge angelegt und beschriftet sein. Ausgewählt wird mit der oben gezeigten Routine oder über Eingabe einer Zifferntaste. Für diesen Fall sollten Sie die Wahlpunkte mit der dazugehörigen Nummer als Info anzeigen. Im Ausgabelisting ändert sich dann die Zeile:
@ i+5,20 ?? m(i)
in die folgende Anweisung:
@ i+5,20 ?? STR(i,1,0)+" - "+m(i)
Das Auswahllisting verkürzt sich dabei wesentlich. Nehmen wir an, der Anwender soll eine von fünf Anreden auswählen, z. B.: 1-An, 2-Firma, 3-Herrn, 4-Frau, 5-Fräulein. Das Listing sieht folgendermaßen aus:
DO WHILE(true)
WAIT TO msg
STORE INT(msg) TO msg
IF(msg>=1 AND msg<=5)
EXIT
ELSE
BELL
ENDIF
ENDDO
Mit [i] ist jetzt die ausgewählte Anrede aus dem Anredemenü an entsprechender Stelle einsetzbar. Vergessen Sie auch hier nicht den Rücksprung mit BACK.
Ergibt eine Suche viele Datensätze, ist eine Listenausgabe übersichtlicher als die Anzeige einzelner Datensätze in der Maske. Der Bildschirm gibt aber je Zeile nur maximal 80 Zeichen aus. Abhilfe schafft ein horizontales Scrollen mit Tab und Backtab. Diese Hilfe ist leicht zu verwirklichen: Legen Sie gleichzeitig zur Bildschirmausgabe eine Datei an, in der je Datensatz in einer Zeile alle Feldinhalte nacheinander aufgelistet sind. Beim Horizontalscrollen lesen Sie diese Datei mit INPUT ein und bringen ihren Inhalt als SUB-STR auf den Bildschirm.
Bezeichnen wir die Fensterdatei als [datei.txt], die Seitenlange mit [z] und die Zeilenlänge mit [s]. Dabei ergibt sich [s] als Addition aller, jeweils um 1 erhöhten, Feldlängen.
s = LEN (Merkmal -1)+1 +
LEN(Merkmal-2)+1 +
usw. +
LEN(Merkmal-n)
Beginnt die Zeilenausgabe nicht in Spalte 0, müssen Sie zu [s] die führenden Leerspalten addieren. Fängt die Ausgabe nicht in Zeile 0 an, sind zu [z] die führenden Leerzeilen zu addieren. Achten Sie in diesem Fall auch darauf, solche Leerzeilen ebenfalls in die Fensterdatei einzufügen. Beim Lesen der Fensterdatei sind sie zu überspringen.
STORE 3 TO i
SET PRINTER TO "datei.txt,z,s"
SET PRINTER ON
DO WHILE (i<z+1)
@ i,2 ?? Merkmal-1,Merkmal-2, usw., Merkmal-n
> hier steht die Suchroutine, z.B. SKIP +1 <
STORE i+1 TO i
ENDDO
SET PRINTER OFF
SET PRINTER TO "prn:,72,80"
Die folgende Routine sorgt für ein Horizontalscrollen. Dabei entsprechen [x-1], [x-2] usw. der Spaltenanzahl bis Merkmal-1, Merkmal-2 usw., je Merkmal um 1 erhöht:
STORE 0 TO i
SET INPUT TO "datei.txt"
SET CONSOLE OFF
SET INPUT ON
DO WHILE(i<3)
ACCEPT TO t
STORE i+1 TO i
ENDDO
SET INPUT OFF
SET CONSOLE ON
Durch die obigen Befehle werden die ersten drei Leerzeilen überlesen.
DO WHILE(i<18)
SET CONSOLE OFF
SET INPUT ON
ACCEPT TO t
SET INPUT OFF
SET CONSOLE ON
@ i,2 ?? SUBSTR(t,x-? 2,76)
STORE i+1 TO i
ENDDO
SET INPUT TO ""
Je nach x-? beginnt der ausgegebene 76 Zeichen lange String bei Merkmal-1 bis Merkmal-n. Beide Routinen müssen in einer Schleife eingebunden sein, wobei nach Ausgabe der ersten Seite eine Abfrage zum weiteren Vorgehen erforderlich ist: Scrollen oder nächste Seite ausgeben und in Fensterdatei speichern? Sind mehrere Seiten ausgegeben, müssen die vorhergehenden vor dem Horizontalscrollen überlesen werden. Das spielt aber zeitlich praktisch keine Rolle, weil ein sichtbarer Zeitaufwand nur für die Bildschirmausgabe vorhanden ist.
Um ausgegebene Datensätze auszuwählen, programmiert man einen Zeiger in Spalte 0, den die Pfeiltasten auf- oder abbewegen. Die Auswahl erfolgt mit Return. Nach Return enthält i die Zeilennummer, über die der Datensatz beim Einlesen der Fensterdatei manipulierbar ist.
STORE 3 TO i
DO WHILE(true)
@ 1,0 ?? ">"
WAIT TO msg
DO CASE
CASE(LASTKEY()="down" AND i<18)
STORE i+1 TO i
CASE(LASTKEY()="up" AND i>3)
STORE i-1 TO i
CASE (LASTKEY () ="cr ")
EXIT
OTHERWISE
BELL
ENDCASE
ENDDO
Die Einzelroutinen müssen in eine Schleife eingebunden sein. Wie sie aussehen, sehen sie auf der Diskette.
Um festzustellen, ob ein neues Fenster auszugeben ist, verwenden Sie z. B. eine Zählvariable »wi« sowie eine Kontrollvariable »wx« . Ähnliches gilt auch beim Horizontalscrollen für das Feststellen von [w-?]. (wk)