← TOS 07 / 1990

Dreifelderwirtschaft: Benutzung von Arrays, die Aditalk nicht kennt

Anwendung

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:

  • Strings
  • logische Dateien
  • normale Dateien

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 , blättern und mit «Return* die Ausgabe abbrechen, lautet die Routine folgendermaßen:

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

Logische Datei als Array - Ersatz

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.

Übersichtliche Listenausgabe

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 ""

Die Pfeiltasten bewegen den Zeiger

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)

Hans Körner