Flexible Modulprogrammierung mit ADIMENS Talk, Teil 5: Ausgabemöglichkeiten der gefundenen Datensätze

Wie findet man die Daten, die man in der Datenbank sucht? Das war das Thema im Teil 4. Ich hoffe, daß Sie das vorgestellte Suchmodul für Ihren Anwendungsfall gebrauchen können.

Das naive Bild einer Datenbank reicht im allgemeinen bei einer zunehmenden Komplexität der Darstellung von Datenbeziehungen nicht aus. Deshalb möchte ich Ihnen in diesem Teil zuerst einige Grundlagen der verschiedenen Techniken der Datei-Adressierung aufzeigen. Anschließend wird anhand der Funktionsbeschreibung der folgenden vier Grundmoduln eine der vielfältigen Ausgabemöglichkeiten von gefundenen Datensätzen gezeigt werden. Die Vorstellung des Modulkonzeptes und die Beschreibung der Moduln mit Hilfe von Struktogrammen und von Hierachiediagrammen wird es Ihnen dann ermöglichen, Ihre Daten flexibel zu gebrauchen. Somit werden Sie zum Schluß die Möglichkeit haben, sämtliche verfügbaren Daten in überschaubarer und relativ einfacher Weise auszuwerten.

Techniken zur Lokalisierung eines Datensatzes

a) Das sukzessive Durchsuchen der Datei

Dies ist wohl die einfachste, aber auch grobschlächtigste Methode, einen Datensatz innerhalb einer Datei zu lokalisieren. Der Datensatzzeiger wird auf den Anfang der Datei gesetzt. Der Zeiger rückt dann jedesmal nur um einen Datensatz weiter und vergleicht dabei die Merkmalsausprägung des zu suchenden Datensatzes.

Abb. 1: Darstellung des schrittweisen Suchens von Daten
Abb. 2: Darstellung des binären Suchens von Datensätzen
Abb. 3: Differenzierte Suche nach DS im Bereich der L.-Nr. von 3 bis 10

Diese Methode ist für die meisten Zwecke viel zu langsam und kann wahrscheinlich nur bei kleinen Satzmengen benutzt werden. Im letzten Teil wurde deshalb bei der Suche nach einem Lieferantennamen in einem bestimmten Bereich von Lieferantennummern eine Sicherheitsabfrage bei der sukzessiven Suche von mehr als 100 Datensätzen implementiert.

b) Das schrittweise Suchen von Datensätzen

Wenn die Datensätze sequentiell geordnet, also nach einem Schlüssel organisiert sind, braucht nicht jeder Satz gelesen zu werden, um die Datei zu durchsuchen. Der Rechner kann z.B. jeden hundertsten Satz in aufsteigender Folge des Schlüssels untersuchen (siehe Abb. 1). Wenn ein Satz gefunden wird, dessen Schlüssel wert größer als der gesuchte Schlüsselwert ist, werden die 99 zuletzt übersprungenen Sätze sequentiell durchsucht.

Diese Technik wird “das schrittweise Suchen” genannt, wobei die Schrittweite zwar konstant aber wählbar sein muß. Dies könnte eine Optimierungsmethode bei der Suche nach zwei Bedingungen sein. Angenommen die Anzahl der Sätze in Ihrer Datei, die durchsucht werden soll, wird mit DS bezeichnet, dann beträgt die optimale Schrittweite OS = SQR(DS). In jedem Schritt über OS Datensätze hinweg wird nur einmal ein Schlüsselvergleich durchgeführt, bis die zutreffende Gruppe von Sätzen erreicht ist.

Das schrittweise Suchen ist für das Durchsuchen sehr großer Dateien ungeeignet. Es ist aber eine wichtige Technik zum Suchen in einem relativ kleinen Ausschnitt aus einer Datei.

c) Das binäre Suchen

Das binäre Suchen kann angewendet werden, wenn die Sätze nach ihrem Schlüssel sortiert sind. Das binäre Suchen beginnt am Mittelpunkt des zu durchsuchenden Bereiches und vergleicht den Schlüssel des dortigen Satzes mit dem gesuchten, womit einer der beiden Halbbereiche als zutreffend erkannt wird. Dann wird dieser Bereich halbiert und der gleiche Prozeß wiederholt (s. Abb. 2). Die Halbierung des Bereiches wifd so fortgesetzt, bis der gewünschte Satz gefunden oder als nicht in der Datei enthalten erkannt ist. Wie das schrittweise Suchen ist auch das binäre Suchen eher für das Suchen in kleineren Ausschnitten von Dateien geeignet.

d) Die Suche nach einem Index

Indizieren gibt ihrer Datei den Anschein, als wäre sie sortiert, ohne die Reihenfolge der Datensätze wirklich zu verändern. ADIMENS erstellt eine Indexdatei mit dem Befehl INDEX > Merkmalsname <. In der Indexdatei, die als Binärbaum organisiert ist, befinden sich nur die Inhalte des Feldes, nach dem indiziert worden ist, der sogenannte Schlüssel. Die Bayer-Bäume sind dabei eine spezielle Art dieser Binärbäume. In jedem Knoten sind mehrere Verweise (ca. 20 - 50) auf weitere Knoten oder auf Blätter. Verweise auf echte Blätter und die dort gespeicherten Datensätze findet man nur in den untersten Knoten. Alle Knoten haben die gleiche Größe (z.B. 1 KByte) und lassen sich daher gut an die Sektorgröße einer Diskette oder Festplatte anpassen. Datenbanken mit Bayer-Baum-Struktur zeichnen sich durch besonders kurze Zugriffszeiten aus. ADIMENS verdankt seine hohe Arbeitsgeschwindigkeit derartigen Algorithmen, die optimal auf Bayer-Bäume zugeschnitten sind. So erreicht man kurze Zugriffszeiten auf alle Datensätze. Die Suchzeiten hängen im wesentlichen von der Höhe des Datenbaumes ab. Auch bei mehreren tausend Datensätzen sind die Bayer-Bäume von ADIMENS zum Suchen eines beliebigen Datensatzes nur unwesentlich länger als zum Zugriff auf den ersten. Die Reihenfolge der Schlüsselbegriffe in der Indexdatei bestimmt die Reihenfolge, in der auf die Daten in Ihrer Datei zugegriffen wird. Diese Methode ermöglicht einen wesentlich schnelleren Zugriff auf die Daten, als es bei einer nichtindizierten Datei möglich wäre.

Kombination von Techniken

Zusammenfassend möchte ich hier noch einmal betonen, daß die Datensuche vom Datenbanksystem ADIMENS sehr gut unterstützt wird. Leider tauchen aber in der Praxis Probleme auf, die man mit Hilfe der Kenntnis dieser Suchtechniken besser, schneller und effizienter lösen kann.

Bei manchen Problemen können Sie Kombinationen der oben genannten Techniken benutzen, um die Sätze zu adressieren. Ein Index z.B. kann einen Bereich der Datei lokalisieren, und dieser wird dann sequentiell oder nach der Binär-Suchmethode durchsucht. Die Suche nach einem Lieferantennamen in einem bestimmten Bereich der Lieferantennummern können Sie sehr elegant mit Hilfe dieser Methode lösen.

Abb. 4: Anzeige einer Adresse auf dem Bildschirm
Abb. 5: Anzeige einer Telefonliste auf dem Bildschirm
Abb. 6: Kopieren der DS in eine temporäre Datei

Funktionsbeschreibung der Module

Das Suchen nach Datensätzen mit speziellen Merkmalsausprägungen sollte genau auf den Anwendungsfall hin geplant werden. Außerdem sollte die Möglichkeit der differenzierten Selektion von Datensätzen gegeben sein.

Im letzten Teil wurden deshalb zwei Module vorgestellt, die die benutzerfreundliche Suche von Datensätzen in einem Anwendungsprogramm unterstützen. Man hatte dort die Möglichkeit, nach einem numerischen und einem alphanumerischen Merkmal zu suchen.

In Abb.3 sehen Sie den Bildschirmausdruck bei einer differenzierten Suche in einem Bereich von Lieferantennummern. Da die Anzahl der Datensätze mit der letzten Lieferantennummer übereinstimmt, sind keine Datensätze im gewählten Bereich gelöscht worden. Deshalb wurden auch 8 davon gefunden.

Nun haben Sie die Möglichkeit, verschiedene Optionen auszuwählen. Für diese Auswahloptionen sollen, in diesem Teil der Serie, flexible, universell einsetzbare Module aufgezeigt werden.

Zuerst möchte ich Ihnen aber die einzelnen Module vorstellen. Der Anwender hat die Möglichkeit, verschiedene Fälle mit den Funktionstasten anzuwählen, nachdem die Datensätze gefunden wurden. Mit der Tastenbetätigung F10 wird eine Adresse auf dem Bildschirm angezeigt (siehe Abb. 4). Dabei wurde nach der Lieferantennummer aufsteigend sortiert. Die Sortierrichtung kann vom ADI-Talk-Menü oder im Quelltext mit dem SET-Befehl umgestellt werden.

Wenn mit der Funktionstaste Fl der gefundene Datensatz angezeigt wurde, kann mit “E” wieder ins Menü >Suchen nach Datensätzen< gesprungen werden. Ansonsten können Sie mit einer beliebigen Taste “weiterblättern“. Der Datensatzzeiger wird dabei um Eins erhöht und der nächste Datensatz, der den Bedingungen genügt, angezeigt. Diese Möglichkeit haben Sie natürlich nur solange, bis das Ende Ihrer Datei erreicht ist, oder bis alle gefundenen Datensätze auf dem Bildschirm angezeigt wurden.

Mit der Funktionstaste F2 können Sie sich von diesem Datensatz die Telefonliste anzeigen lassen (Abb. 5). Diese Unterscheidungen werden von Fall zu Fall unterschiedlich sein. Trotzdem sollten Sie bedenken, daß man auch hier eine Möglichkeit hat, bestimmte Informationen vom Zugangsberechtigungscode des jeweiligen Benutzers abhängig zu machen.

Abb. 7: Sortiermerkmale auswählen
Abb. 8: Auswahl einer Adressen- oder Telefonliste
Abb. 9: Druckstart mit "D" oder Abbrechen mit "A"

Sie haben mit dem Anwendungsprogramm immer ein Ziel. Zur Erfüllung der erforderlichen Aufgaben (vgl. Teil 2 - konzeptionelle Schritte bei der Einführung einer Datenbank) müssen vom Datenbanksystem ADIMENS Informationen von außen aufgenommen, verarbeitet und entsprechende Informationen nach außen wieder abgegeben werden. Durch die Integration aller Ihrer Daten können Sie sie nach anderen Gesichtspunkten als bisher vorgesehen auswerten.

Deshalb werden die nachfolgenden Module es Ihnen erlauben, spezielle Sichten von Benutzergruppen auf die Daten abzuändern. Damit können Sie neue Sichten für Personengruppen einführen.

Für die meisten Anwendungen genügt es allerdings nicht, nur die Daten auf dem Bildschirm auszugeben, sondern man möchte auch Datensätze auf dem Drucker ausgeben lassen, beispielsweise, um eine sortierte Telefonliste oder eine nach bestimmten Merkmalen ausgewählte Adressenliste zu erstellen.

Für diese Zwecke benötigen Sie ein Modul, welches die Datensätze in eine temporäre Datei kopiert. Diese Datei hat die gleichen Merkmalsnamen wie die aktuelle Datei. Wollen Sie eine Adressenliste ausdrucken lassen, werden zunächst alle gefundenen Datensätze in eine temporäre Datei kopiert. Diese kann dann nach den verschiedensten Merkmalen indiziert werden. Außerdem können Sie die Datei mehrmals hintereinander ausdrucken lassen.

In der Zeit, in der die Datensätze kopiert werden, können Sie Ihren Drucker einschalten und das Papier einlegen. Abb. 6 zeigt diese Phase. Nachdem das Kopierende erreicht ist, erscheint die Meldung, daß man eine beliebige Taste drücken soll, um weiterzumachen.

In den nachfolgenden beiden Menüs (s. Abb. 7 und Abb. 8) können Sie verschiedene Sortiermerkmale auswählen und zwischen einer Adreßliste oder einer Telefonliste wählen. In unserem Beispiel sollte nach dem Lieferantennamen sortiert und eine Adressenliste erstellt werden.

Aus Abb. 9 wird ersichtlich, daß man zu diesem Zeitpunkt noch die Möglichkeit hat, den Druckmodus zu verlassen. Das Modul zum Drucken von Datensätzen ist eingestellt auf eine Zeilenanzahl von 64 pro Seite. Nachdem 64 Zeilen (= Datensätze) ausgedruckt wurden, soll jedesmal eine Abfrage ausgegeben werden, ob man den Druck abbrechen möchte. Außerdem soll auf jeder neuen Seite die aktuelle Seitenanzahl stehen und die Kopfzeile jedesmal am Anfang ausgedruckt werden. Bei einer großen Adressenliste ist es immer ärgerlich, wenn die Kopfzeile der Liste nur einmal am Anfang steht.

Zudem kann der Fall auftreten, daß während des Drückens Ihr Papier zu Ende geht. Deshalb ist es sinnvoll, das Ausdrucken Ihrer Liste zum Beginn einer neuen Seite zu unterbrechen.

Abb. 10: Beispielausdruck einer Adressenliste
Abb. 12: Struktogramm von LISUBI.TLK
Abb. 11: Die temporäre Datei wird wieder gelöscht

Einen Beispielausdruck einer kleinen Liste zeigt Abb. 10.

Nachdem die gewünschte Liste ordnungsgemäß ausgedruckt wurde, kann das Programm mit “A” (Abbruch) abgebrochen werden. Mit der Eingabe “D” (Druckstart) wird die Liste dupliziert. Beim Programmabbruch wird die vorher erstellte temporäre Datei wieder gelöscht (s. Abb. 11). Nun befindet man sich erneut im Menü Suchen von Datensätzen.

Vorstellung der Modulkonzeption

Ich werde Ihnen zwei Ausgabemöglichkeiten - die Bildschirmausgabe und die Ausgabe auf einem Drucker - mit ADIMENS Talk aufzeigen. Das Modulstruktur-Diagramm zeigt dabei die Zusammenhänge der Module vom Teil 4 und von diesem Teil. Kurz zur Wiederholung: Das Modul LSUCHE.TLK stellt die Suchmaske und die Verzweigungsmöglichkeiten zur Verfügung. Mit dem Modul LNR-BER.TLK wird die Eingabe einer Nummer iterativ überarbeitet. In diesem Teil sind die vier Module LISUBI.TLK, LISUDR.TLK, LCOPY.TLK und LDRUCKAD.TLK. neu hinzugekommen. Die Module LCOPY und LDRUCKAD werden wiederholt vom Modul LISUDR aufgerufen und abgearbeitet. LCOPY kopiert die spezifischen Lieferantendatensätze in die temporäre Datei (s. auch Teil 2: Abb. 5 - Allgemeiner Aufbau eines Modulstruktur-Diagrammes). LDRUCKAD stellt sozusagen das Ausgabeformat der auszudruckenden Datensätze zur Verfügung und regelt die Druckausgabe mit der Sicherheitsabfrage vor jeder neuen Seite.

Damit die temporäre Datei gelöscht wird, mußte ich dem Modul LSUCHE noch einen Anweisungsblock hinzufügen. Das Listing 1 zeigt diesen zusätzlichen Anweisungsblock. Sie können Block 11 direkt hinter den Block 10 einfügen, der im Teil 4 (Modul LSUCHE) vorgestellt wurde.

Zusammenfassung

Mit den Teilen 4 und 5 wurde eine der Möglichkeiten aufgezeigt, Moduln für das Suchen von Daten auf systematische Art und Weise zu gestalten. Neben diesen Hauptaufgaben - Maskenaufbau, Datensicherung, Erfassen und Suchen von Datensätzen, die immer bei der Erstellung einer Datenbank-Anwendungsprogrammierung auftreten, fehlt noch ein weiteres wichtiges Modul, das das Ändern und das Löschen von Datensätzen aus einer bestimmten Datei gewährleistet.

Von diesem voraussichtlich letzten universell einsetzbaren Modul wird Teil 6 in der nächsten Ausgabe berichten.

/**** 11 ****/
/* Die temporäre Kopierdatei wird wieder gelö.    */ 
/* Es gibt bei ADIMENS keinen Befehl, bei dem die */ 
/* ganze Datei gelöscht wird. Deshalb muß man     */ 
/* sukzessive jeden einzelnen Datensatz löschen.  */ 
IF TEMP
    § 18,00 CLEAR
    §18,00 SAY BILD1 + BILD1
    § 19,20 SAY "Die temporäre Datei wird gelöscht"
    § 20,00 SAY BILD1 + BILD1
    STORE 0 TO ZAEHL
    USE ADRESSENCOPY
    INDEX LNUMMER

/*************************************************/
/*SOLANGE die Zählvariable ungleich der Zahl der */ 
/*gefundenen Datensätze ist. Die Datens. werden  */ 
/*einzeln gelöscht.                              */
DO WHILE NOT (ZAEHL = GD)
/*************************************************/

        /* Der erste Datensatz muß immer fest bleiben, */
        /* da die Datei indiziert wurde.               */
        SKIP 1 
        DELETE
        STORE ZAEHL + 1 TO ZAEHL 
        /* BEENDEN der DO-WHILE-Schleife               */
    ENDDO

    USE ADRESSEN 
ELSE
    /* NICHTS TUN                                      */
ENDIF
/**** 11 ****/

Listing 1: Zusätzlicher Anweisungsblock zum Löschen einer temporären Datei

/*   PROGRAMM LISUBI.TLK                         */
/*************************************************/ 
/* Dies ist ein Beispiel für ein Programmodul    */ 
/* zum Ausdrucken von Datensätzen innerhalb der  */ 
/* Datenbank Das Programm greift auf die Datenb. */ 
/* BEISPIEL zu.                                  */
/* Copyright by Hans-Ülrich Mayer                */
/*************************************************/

/**** 1 ****/
/* FESTLEGUNG DER SCHALTERSTELLUNGEN             */
/* Löschen des Bildschirmes                      */
CLEAR
/* Unterdrücken der automatischen Maskenanzeige  */ 
SET AUTOSC OFF 
/* Die Sonderregelungen für die Funktion FIND sind abgeschaltet */
SET DBASE OFF 
/* Die Datenbank und die Datei wurde schon geöf. */

/**** 1 ****/

/*************************************************/

/**** 2 ****/
/* MENÜAUSGABE - Aufbau der Kopfzeile            */
CLEAR
/* aktuelle Datumsanzeige und der Uhrzeit        */
@ 02     ,00  SAY " Datum "
@ 03     ,00  SAY DATE()
@ 02     ,72  SAY "Uhrzeit"
@ 03     ,72  SAY TIME()
@ 01     ,00  SAY BILD1 + BILD1
@ ROW()  ,TAB SAY "          DATEN - SUCHE       *** V 1.01 ***"
@ ROW()+1,TAB SAY "flexible Anwendungsprogrammierung mit ADIMENS Talk" 
@ ROW()+1,00  SAY BILD2 + BILD2
@ ROW()  ,00  SAY BILD2 + BILD2
@ ROW()+1,00  SAY " "
IF ( MSG = "F01" )
    @ ROW(),TAB SAY " Anzeige von Datensätzen - ADRESSENLISTE "
ELSE
    @ ROW(),TAB SAY " Anzeige von Datensätzen - TELEFONLISTE  "
ENDIF
@ ROW()+1, TAB SAY " "
@ ROW()+1,00 SAY BILD1 + BILD1
/**** 2 ****/

/************************************************/

/**** 3 ****/
/* LÖSCHEN des mittleren Bildschirmbereiches    */
/* Durchlaufe die Schleife SOLANGE die Eingabe richtig ist. */
@ 10,00 CLEAR
/* Lokale Variablendeklaration                  */
STORE FALSE TO OK
STORE SPACE(1) TO EINGABE
STORE 0 TO ZAEHL
/**** 3 ****/

/************************************************/

/* UNTERSCHEIDUNG zwischen einer Adressenliste und einer Telefonliste */
IF ( MSG ="F01" )

/* FALL, für das Anzeigen einer Adressenliste auf dem Bildschirm  */
/* Wenn keine L.-Nummer eingegeben wurde, Suche nachdem L.- Namen */
    IF ( DSZUST = "0" )

        /**** 4 ****/

/* Es wird der Datensatz geladen, welcher die Bed. erfüllt. */
        STORE ( JUMP VLNAME TO LNAME ) TO OK

/************************************************/ 
/* SOLANGE DURCHBLÄTTERN bis die Suche beendet  */ 
/* wird oder bis alle Datensätze mit der        */
/* angegebenen Bedingung gezeigt wurden.        */
        DO WHILE NOT ( (ZAEHL = GD) OR (EINGABE = "E"))
/************************************************/

/* Es werden hier nur zwei verschiedene Fälle unterschieden */
            STORE 0 TO LAUF 
            @ 12,00 CLEAR 
/* ANZEIGEN des Datensatzes                                 */
            @ 12,23 SAY "Lieferanten Nr. " + TRIM (STR(LNUMMER,6,0))
            @ 14,23 SAY "Firma : "         + TRIM(LFIRMA)
            @ 15,23 SAY "Name  : "         + TRIM(LNAME)
            @ 16,23 SAY LSTRASSE
            @ 17,23 SAY STR(LPLZ,4,0)      + " " + LORT
            @ 19,00 SAY BILD1 + BILD1 
            STORE 1 TO LAUF 
            IF ( LAUF = 1 )
                @ 21,13 SAY " E = BEENDEN " )
                @ 22,25 WAIT "WEITERMACHEN BELIEBIGE TASTE DRÜCKEN" TO EINGABE
            ENDIF
            STORE ZAEHL + 1 TO ZAEHL 
            SKIP 1
/* BEENDEN der Do-While SCHLEIFE                            */
        ENDDO

/* ZEIGER auf den ersten Datensatz zurücksetzen und Entfernen des */
/* Suchschlüssels.                                                */
        BACK
        /**** 4 ****/

    ELSE

/***********************************************/
/* Fall, bei dem unter Umständen mehrere       */
/* Datensätze gezeigt werden. Solange bis alle */ 
/* gefunden Datensätze angezeigt wurden oder   */
/* durch eine Eingabe bestätigt wird, daß keine*/
/* Datensätze mehr angezeigtwerden sollen.     */
DO WHILE NOT ( (ZAEHL = GD) OR (EINGABE = "E") )
/***********************************************/
        STORE STR(DSZU,6,0) TO DSZUST
        STORE 0 TO LAUF 
/* FALL, bei dem kein Namen angegeben wurde    */
/* und bei dem nur nach der Lieferanten        */
/* Nummer gesucht werden soll.                 */
        IF ( VLNAME = "" )

            /**** 5 ****/
            INDEX LNUMMER
            STORE ( FIND INT(DSZUST) ) TO OK
            IF (OK)
/* ANZEIGEN DES DATENSATZES                    */
                @ 12,00 CLEAR
                @ 12,23 SAY "Lieferanten Nr. " + TRIM(STR(LNUMMER,6,0))
                @ 14,23 SAY "Firma : "         + TRIM(LFIRMA)
                @ 15,23 SAY "Name : "          + TRIM(LNAME)
                @ 16,23 SAY LSTRASSE
                @ 17,23 SAY STR(LPLZ,4,0)      + " " +LORT
                @ 19,00 SAY BILD1 + BILD1 
                STORE 1 TO LAUF 
                STORE ZAEHL+1 TO ZAEHL 
            ENDIF
            /**** 5 ****/

        ELSE

            /**** 6 ****/
/* Fall, bei dem nach der Lieferanten          */
/* Nummer und nach dem Namen des               */
/* Lieferanten gesucht werden soll             */
                INDEX LNUMMER
                STORE ( FIND INT(DSZUST) ) TO OK 
                IF (OK)
                    IF ( LNAME = VLNAME )
/*ANZEIGEN des aktuellen Datensatz             */
                        @ 12,00 CLEAR
                        @ 12,23 SAY "Lieferanten Nr.:"+ TRIM(STR(LNUMMER, 6,0))
                        @ 14,23 SAY "Firma : "        + TRIM (LFIRMA)
                        @ 15,23 SAY "Name : "         + TRIM(LNAME)
                        @ 16,23 SAY LSTRASSE
                        @ 17,23 SAY STR(LPLZ,4,0)     + LORT
                        @ 19,00 SAY BILD1 + BILD1 
                        STORE 1 TO LAUF
                        STORE ZAEHL + 1 TO ZAEHL 
                    ENDIF 
                ENDIF
                /**** 6 ****/

            ENDIF
            IF ( LAUF = 1 )
                @ 21,13 SAY  " E = BEENDEN "
                @ 22,25 WAIT "WEITERMACHEN, BELIEBIGE TASTE DRÜCKEN" TO EINGABE
            ENDIF
/*DATENSATZZEIGER um einen Datensatz erhöhen        */ 
            STORE DSZU+1 TO DSZU

/* BEENDEN der Schleife für die Anzeige v. Datens.  */ 
        ENDDO
/****************************************************/ 

    ENDIF
/* BEENDEN des Falles für die Bildschirm Anzeige v. Datensätzen */

ELSE

/* FALL, für die Anzeige einer Telefonliste auf */ 
/* dem Bildschirm. Wenn keine Lieferanten Nr. */ 
/* eingegeben wurde —>Suche nach dem Namen */
    IF ( DSZUST = "0" )
/* Es wird der Datensatz geladen, welcher die Bed. erfüllt. */
    STORE ( JUMP VLNAME TO LNAME ) TO OK

/************************************************/ 
/* SOLANGE die Bildschirmausgabe nicht beendet  */ 
/* werden soll, oder nicht alle gefundenen      */
/* Datensätze gefunden worden sind.             */
        DO WHILE NOT((ZAEHL = GD) OR (EINGABE = "E") )
/************************************************/

            /**** 7 ****/
/* Es werden hier zwei Fälle unterschieden      */
            STORE 0 TO LAUF 
            @ 12,00 CLEAR 
/* ANZEIGEN dieses Datensatzes                  */
            @ 12,23 SAY "Lieferanten Nr. : " + TRIM (STR(LNUMMER,6,0))
            @ 14,23 SAY "Firma : "           + TRIM(LFIRMA)
            @ 15,23 SAY "Name : "            + TRIM(LNAME)
            @ 16,23 SAY "TELEFON Nummer : "  + LTELEFON 
            @ 19,00 SAY BILD1 + BILD1 
/* Zuordnung einer Lieferanten Nummer           */
            STORE 1 TO LAUF 
            IF ( LAUF = 1 )
                @ 21,13 SAY "E = BEENDEN"
                @ 22,25 WAIT "WEITERMACHEN, BELIEBIGE TASTE DRÜCKEN" TO EINGABE
            ENDIF
            STORE ZAEHL+1 TO ZAEHL 
/* DATENSATZ ZEIGER um eins erhöhen             */
            SKIP 1
            /**** 7 ****/

/* BEENDEN der Schleife                         */
        ENDDO
/************************************************/

/* ZEIGER auf den ersten Datensatz zurücksetzen */ 
/* und Entfernen des Suchschlüssels.            */
        BACK

    ELSE

/************************************************/ 
/* FALL bei dem unter Umständen mehrere         */
/* Datensätze angezeigt werden SOLANGE alle     */
/* gefundenen Datensätze angezeigt werden oder  */ 
/* durch eine Eingabe bestätigt wird, daß keine */ 
/* Datensätze mehr angezeigt werden sollen.     */
        DO WHILE NOT ( (ZAEHL = GD) OR (EINGABE = "E") 
/************************************************/

            STORE STR(DSZU,6,0) TO DSZUST 
            STORE 0 TO LAUF 
/* FALL, bei dem kein Namen angegeben wurde     */
/* und nur nach der Lieferanten Nummer          */
/* gesucht werden soll.                         */
            IF (VLNAME = " ")

                /**** 8 ****/
                INDEX LNUMMER
                STORE FIND INT(DSZUST) TO OK 
                IF ( OK )
/* ANZEIGEN dieses Datensatzes                  */
                    @ 12,00 CLEAR
                    @ 12,23 SAY "Lieferanten Nr. : " + TRIM(STR(LNUMMER,6,0))
                    @ 14,23 SAY "Firma : " + TRIM(LFIRMA)
                    @ 15,23 SAY "Name : " + TRIM(LNAME)
                    @ 16,23 SAY "TELEFON NUMMER : " + LTELEFON 
                    @ 19,00 SAY BILD1 + BILD1 
                    STORE 1 TO LAUF 
                    STORE ZAEHL + 1 TO ZAEHL 
                ENDIF
                /**** 8 ****/

            ELSE

                /**** 9 ****/
/* FALL, bei dem nach der Lieferanten Nr.       */
/* und nach dem Namen des Lieferanten           */
/* gesucht werden soll.                         */
                INDEX LNUMMER
                STORE FIND INT(DSZUST) TO OK 
                IF ( OK )
                    IF ( LNAME = VLNAME )
/* ANZEIGEN dieses Datensatzes                  */
                        @ 12,00 CLEAR
                        @ 12,23 SAY "Lieferanten Nr. : " + TRIM(STR(LNUMMER,6,0))
                        @ 14,23 SAY "Firma : " +  TRIM(LFIRMA)
                        @ 15,23 SAY "Name : " + TRIM(LNAME)
                        @ 16,23 SAY "TELEFON NUMMER : " + LTELEFON 
                        @ 19,00 SAY BILD1 + BILD1 
                        STORE 1 TO LAUF 
                        STORE ZAEHL + 1 TO ZAEHL 
                    ENDIF 
                ENDIF
                /**** 9 ****/
            ENDIF
            IF ( LAUF = 1 )
                @ 21,13 SAY  " E = BEENDEN"
                @ 22,25 WAIT "WEITERMACHEN, BELIEBIGE TASTE DRÜCKEN" TO EINGABE
            ENDIF
/* DATENSATZ ZEIGER um eins erhöhen             */
            STORE DSZU + 1 TO DSZU

/*BEENDEN der Schleife für die Datensatz Anzeige*/ 
        ENDDO
/************************************************/
    ENDIF

/* FALL für die Anzeige der Listen am Bildschirm beenden. */
ENDIF
/* RÜCKKEHR zum Programm LSUCHE.TLK. */

@ 4,00 CLEAR 
@ 4,00 SAY BILD2 + BILD2
@ 6,12 SAY "        SUCHEN neuer Lieferanten ADRESSEN "
@ 7,00 SAY BILD1 + BILD1

Listing 2: Das Programm LISUBI.TLK.

/*                  LCOPY.TLK                   */
/************************************************/ 
/*  Progranmmodul zum Kopieren von              */
/*          Lieferanten Datensätzen.            */
/*Das Programm greift auf die Datenbank Beisp.zu*/
/*        copyright by Hans-Ulrich Mayer        */
/************************************************/

/**** 1 ****/

/* Abspeichern des gefundenen Datensatzes in  lokale temporäre Variablen */
/* Man befindet sich noch in der Datei ADRESSEN.*/ 
STORE LNAME     TO TVLNAME
STORE LNUMMER   TO TVLNR
STORE LFIRMA    TO TVLFIRMA 
STORE LSTRASSE  TO TVLSTRASSE 
STORE LPLZ      TO TVLPLZ
STORE LORT      TO TVLORT
STORE LTELEFON  TO TVLTELEFON
/**** 1 ****/

/*************************************************/ 

/**** 2 ****/
/* Es wird in die temporäre Datei verzweigt, ohne*/ 
/* daß die Datei ADRES.verlassen wird. Bei dem   */ 
/* Verzweigen in die andere Datei muP der Datei  */ 
/* Name dem Zielschlüssel vorangestellt werden.  */ 
/* Verbindung mit einem Punkt                    */
STORE (JUMP 0 TO ADRESSENCOPY.LNUMMER) TO TEMP 
/* Positionierung des ZEIGERS auf den letzten Datensatz. */
LAST
/* Löschen des Datensatzinhaltes ( nur die Kopie im Arbeitsspeicher ) */
NEW
/* EINTRAGEN der Merkmale in die Datei          */
/* Der Dateiname muß dabei dem Merkmalsnamen vorangestellt werden. */
REPLACE ADRESSENCOPY.LNUMMER  WITH TVLNR
REPLACE ADRESSENCOPY.LNAME    WITH TVLNAME
REPLACE ADRESSENCOPY.LFIRMA   WITH TVLFIRMA
REPLACE ADRESSENCOPY.LSTRASSE WITH TVLSTRASSE 
REPLACE ADRESSENCOPY.LPLZ     WITH TVLPLZ
REPLACE ADRESSENCOPY.LORT     WITH TVLORT
REPLACE ADRESSENCOPY.LTELEFON WITH TVLTELEFON
/**** 2 ****/ 

/************************************************/ 

/**** 3 ****/
/* Die Merkmale werden in der Datei abgespei. */
INSERT
/* Rückkehr zu dem v. dem JUMP - Befehl aktuellen Datensatz */
BACK
/**** 3 ****/ 

Listing 3: Das Programm LCOPY.TLK.

/*            PROGRAMM LISUDR.TLK                 */
/**************************************************/
/* Dies ist ein Beispiel für ein Programmodul zum */ 
/* Ausdrucken von Datens. auf dem Drucker. Sie    */ 
/* können vorher mit der Druckerinitial, die      */
/* spezifischen Steuercodes ihres Druckers,vorneh.*/
/* Das Programm greift auf die Datenbank BEISP.zu.*/ 
/*          copyright by Hans-Ulrich Mayer        */
/**************************************************/

/**** 1 ****/
/* FESTLEGUNG DER SCHALTERSTELLUNGEN              */
/* Löschen des Bildschirmes                       */
CLEAR
/* Unterdrücken der automatischen Maskenanzeige   */ 
SET AUTOSC OFF
/* Die Sonderregelungen für die Funktion FIND sind abgeschaltet */
SET DBASE OFF
/* Die Datenbank und die Datei wurde schon geöff */
/**** 1 ****/ 

/*************************************************/ 

/**** 2 ****/
/* MENÜAUSGABE - Aufbau der Kopfzeile            */
CLEAR
/* aktuelle Datumsanzeige und der Uhrzeit        */
@ 02     ,00  SAY " Datum "
@ 03     ,00  SAY DATE()
@ 02     ,72  SAY "Uhrzeit"
@ 03     ,72  SAY TIME()
@ 01     ,00  SAY BILD1 + BILD1
@ ROW()  ,TAB SAY " DATEN - SUCHE    *** V 1.01 *** "
@ ROW()+1,TAB SAY "flexible Anwendungsprogrammierung mit ADIMENS Talk"
@ ROW()+1,00 SAY BILD2 + BILD2 
@ ROW()  ,00 SAY BILD2 + BILD2
@ ROW()+1,00 SAY " "
@ ROW(),TAB SAY " DRUCKEN von Datensätzen "
@ ROW()+1, TAB SAY " "
@ ROW()+1,00 SAY BILD1 + BILD1
/**** 2 ****/

/*************************************************/ 

/**** 3 ****/
/* LÖSCHEN des mittleren Bildschirmbereiches     */
/* Durchlaufe die Schleife SOLANGE die Eingabe richtig ist. */
@ 10,00 CLEAR
/* Lokale Variablendeklaration                   */
STORE FALSE TO OK 
STORE SPACE(1) TO EINGABE 
STORE 0 TO ZAEHL 
STORE "F05" TO MSG 
/**** 3 ****/

/*************************************************/ 

/**** 4 ****/
/* Dieser Programmabschnitt kopiert die gefund.  */ 
/* Datensätze in eine TEMPORÄRE DATEI. Die temporäre */
/* Datei dient vor allem der Indizierung der Daten.  */
/* Somit hat man die Möglichkeit einer mehrmaligen   */
/* Ausgabe.                                      */
@ 10,02 SAY "Die gefundenen Datensätze werden alle in eine"
@ 11,02 SAY "         temporäre Datei kopiert. "
@ 13,02 SAY "Anzahl der zu kopierenden Datensätze: " +TRIM(STR(GD,6,0))
@ 14,02 SAY "schon kopierte Datensätze " +TRIM(STR(ZAEHL,6,0))
@ 18,02 SAY "Kopierstart BITTE WARTEN !!! "
@ 15,00 SAY BILD1 + BILD1
@ 17,00 SAY BILD1 + BILD1 
@ 19,00 SAY BILD1 + BILD1 
@ 10,54 SAY "      DRUCKEN "
@ 12,54 SAY "Bitte Papier einlegen und "
@ 13,54 SAY "Drucker eingeschalten ??? "
/**** 4 ****/

/************************************************/

IF ( DSZUST = "0" )

    /**** 5 ****/
    STORE ( JUMP VLNAME TO LNAME ) TO OK

    /**********************************************/ 
    /* SOLANGE die Zählvariable < Anzahl der gefundenen Datensätze GD */
    DO WHILE NOT (ZAEHL = GD)
    /**********************************************/

        @ 14,42 SAY TRIM(STR(ZAEHL+1,6,0)) 
        /******************************************/ 
        /* SPRUNG ins Untermodul LCOPY.TLK        */
        /* Die gefundenen Datensätze werden in die*/ 
        /* temporäre Datei kopiert                */
        DO "LCOPY"

/************************************************/ 
            STORE ZAEHL + 1 TO ZAEHL 
            SKIP 1 
        ENDDO

/* ZEIGER auf den Anfang der Datei zurücksetzen.*/ 
        BACK
        /**** 5 ****/

ELSE

    /**** 6 ****/ 
    /********************************************/
    /* SOLANGE die Zählvariable < gefundenen Datensätze GD */
    DO WHILE NOT ( ZAEHL = GD )
    /********************************************/

        @ 14,42 SAY TRIM(STR(ZAEHL+1,6,0))
        STORE STR(DSZU,6,0) TO DSZUST 
        IF ( VLNAME = "" )
            INDEX LNUMMER
            STORE FIND INT(DSZUST) TO OK
            IF ( OK )
    /********************************************/
    /* SPRUNG ins Untermodul LCOPY.TLK          */
    /* Die gefundenen Datensätze werden in      */
    /* die temporäre Datei kopiert.             */
                DO "LCOPY"
    /********************************************/
                STORE ZAEHL + 1 TO ZAEHL 
            ENDIF 
        ELSE
            INDEX LNUMMER
            STORE FIND INT(DSZUST) TO OK 
            IF (OK)
                IF (LNAME = VLNAME)
    /********************************************/
    /* SPRUNG ins Untermodul LCOPY.TLK          */
    /* Die gefundenen Datensätze werden in      */
    /* die temporäre Datei kopiert.             */
                    DO "LCOPY"
                    /****************************/
                    STORE ZAEHL + 1 TO ZAEHL 
                ENDIF 
            ENDIF 
        ENDIF
        STORE DSZU + 1 TO DSZU 
    ENDDO 
ENDIF
/**** 6 ****/ 

/************************************************/ 

/**** 7 ****/
@ 18,54 SAY "              Kopierende "
@ 22,20 SAY "Bitte eine beliebige Taste drücken " 
WAIT
/* Umschalten auf die temporäre Datei ADRESSENCOPY */
USE ADRESSENCOPY 
/**** 7 ****/

/************************************************/ 

/**** 8 ****/ 
/************************************************/ 
/* SOLANGE die Eingabe nicht richtig ist. Plausibilitätskontrolle */
DO WHILE NOT (UPPER (EINGABE) = "N" OR UPPER (EINGABE) ="L") 
/************************************************/ 

    STORE "N" TO EINGABE 
    @ 10,00 CLEAR
    /* ABFRAGE, ob nach dem Namen oder der L.-Nr. sortiert werden soll. */
    @ 10,14 SAY "Bitte entscheiden Sie sich für einen Sortierschlüssel"
    @ 13,14 SAY "sortieren nach dem LIEFERANTEN NAMEN : —> 'N' drücken"
    @ 14,14 SAY "sortieren nach der LIEFERANTEN NUMMER: -> 'L' drücken"
    @ 11,14 SAY "es wird dabei jeweils aufsteigend sortiert. "
    @ 15,33 SAY "EINGABE: " GET EINGABE
    @ 16,00 SAY BILD1 + BILD1 
    READ
    /* FALLUNTERSCHEIDUNG mit einer Plausibiltätskontrolle. */
    DO CASE
        CASE (UPPER (EINGABE) = "N" )
            STORE 1 TO SORT 
        CASE (UPPER (EINGABE) = "L" )
            STORE 2 TO SORT 
        OTHERWISE 
            BELL
            @ 19,00 SAY BILD1 + BILD1 
            @ 20,20 SAY "FALSCHE EINGABE !!! BITTE WIEDERHOLEN "
            @ 21,00 SAY BILD1 + BILD1
            @ 22,20 SAY " beliebige Taste drücken " 
            WAIT 
        ENDCASE 
    ENDDO
    
STORE " " TO EINGABE 
/**** 8 ****/

/************************************************/ 

/**** 9 ****/
/************************************************/ 
/* SOLANGE, die Eingabe nicht richtig ist.  Plausibiltätskontrolle. */
DO WHILE NOT(UPPER(EINGABE) = "A" ORUPPER(EINGABE)= "T")
/************************************************/ 

    STORE " " TO EINGABE
    @ 10,00 CLEAR
    /* ABFRAGE, ob eine Adressen- oder eine Telefon-Liste erstellt wird */
    @ 10,14 SAY "Bitte entscheiden Sie sich für eine Liste "
    @ 12,14 SAY "ADRESSEN Liste der Lieferanten : —> 'A' drücken "
    @ 13,14 SAY "TELEFON Liste der Lieferanten : —> ' T' drücken "
    @ 15,33 SAY "EINGABE: " GET EINGABE
    @ 16,00 SAY BILD1 + BILD1
    READ
    @ 17,27 SAY "Ist Ihr Drucker bereit ? " 
/* Fallunterscheidung mit Plausibilitätskontrolle */ 
    DO CASE
    /* Adressen Liste ausdrucken lassen             */
        CASE (UPPER (EINGABE) * "A")
            STORE " " TO EINGABE

/*********************************************************/ 
/* SOLANGE die Eingabe nicht richtig ist. Plausibiltät ! */
            DO WHILE NOT (UPPER (EINGABE) = "D" OR UPPER (EINGABE) = "A") 
/*********************************************************/ 

                STORE "D" TO EINGABE 
                @ 18,00 SAY BILD1 + BILD1 
                @ 19,10 SAY "DRUCK START -> 'D' drücken "
                @ 19,50 SAY "ABBRECHEN -> 'A' drücken "
                @ 20,00 SAY BILD1 + BILD1
                @ 21,33 SAY "EINGABE GET EINGABE
                READ
/**********************************************/ 
/* SPRUNG ins Untermodul LDRUCKAD.TLK.        */
/* Dort wurde das Format des Ausdruckes       */
/* der ADRESSENLISTE festgelegt.              */
DO "LDRUCKAD" 
/**********************************************/

            ENDDO

/* FALL : TELEFON LISTE auf dem Drucker  ausdrucken */
        CASE (UPPER (EINGABE) = "T" )
            STORE " " TO EINGABE

    /*******************************************/ 
    /* SOLANGE, die Eingabe nicht richtig ist. */
            DO WHILE NOT (UPPER(EINGABE )= "D" OR UPPER(EINGABE) = "A") 
    /*******************************************/

                STORE "D" TO EINGABE 6 18,00 SAY BILD1 + BILD1 
                @ 19,10 SAY " DRUCK START ->'D' drücken"
                @ 19,50 SAY " ABBRECHEN ->A' drücken"
                @ 20,00 SAY BILD1 + BILD1
                @ 21,33 SAY "EINGABE :" GET EINGABE
                READ
    /********************************************/
    /* SPRUNG ins Untermodul LDRUCKTE.TLK.      */
    /* Dort wurde das Format des Ausdruckes     */
    /* der TELEFON LISTE festgelegt.            */
                DO "LEER"
    /********************************************/

            ENDDO

    /* ANDERENFALLS Fehlermeldung und Warnton erzeugen. */
        OTHERWISE 
            BELL
            @ 18,00 CLEAR 
            @ 19,00 SAY BILD1 + BILD1 
            @ 20,20 SAY "FALSCHE EINGABE !!! BITTE WIEDERHOLEN "
            @ 21,00 SAY BILD1 + BILD1 
            @ 22,20 SAY " beliebige Taste drücken "
            WAIT
    ENDCASE

ENDDO
/**** 9 ****/

Listing 4: Das Programm LISUDR.TLK

/*                      LDRUCKAD.TLK            */
/************************************************/ 

/**** 1 ****/
/*  Datensatzzeiger auf den Anfang positionieren*/ 
USE ADRESSENCOPY 
IF (SORT = 1)
    INDEX LNAME 
ELSE
    INDEX LNUMMER 
ENDIF 
FIRST
/* LOKALE Variablendeklaration                  */
STORE 1 TO GDS
STORE 1 TO SEITE
COUNT ALL TO GDS
FIRST
CLEAR
/**** 1 ****/ 

/************************************************/ 

DO CASE
   CASE ( UPPER(EINGABE) = "D" )
        /**** 2 ****/
        SET CONSOLE OFF 
        SET PRINTER ON
        /* DRUCKEN der Kopfzeile                    */
        ? "            ADRESSEN LISTE vom : "
        ?? DATE ()
            /* Einzelblatt auswerfen */
            ? CHR(27)+CHR(25)+CHR(82)
            SET PRINTER OFF 
            SET CONSOLE ON 
            STORE SEITE+1 TO SEITE 
    /* Abfrage, ob eine neue Seite eingelegt wurde ?*/ 
            @ 0,0 CLEAR
            @ 10,20 SAY "NEUE SEITE WEITERDRUCKEN ?"
            @ 12,20 WAIT"           (J/N)          " TO EINGABE
            DO CASE
               CASE ( UPPER ( EINGABE) = "J" ) 
                    STORE " " TO EINGABE 
                    SET PRINTER ON 
                    SET CONSOLE OFF 
    /* DRUCKEN der Kopfzeile                        */
                    ? " ADRESSEN LISTE vom : "
                    ?? DATE()
                    ??"     SEITE: "
                    ?? TRIM(STR(SEITE,3,0))
                    ?  BILD1 + BILD1
                    ?  "NR     FIRMA       STRASSE"
                    ?? "            PLZ  WOHNORT "
                    ? BILD1 + BILD1 
                    STORE 6 TO Z 
               CASE ( UPPER(EINGABE)="N" )
                    STORE "E" TO EINGABE 
               OTHERWISE 
                    BELL
                    @ 18,00 CLEAR 
                    @ 19,00 SAY BILD1 + BILD1 
                    @ 20,20 SAY "FALSCHE EINGABE !!! BITTE WIEDERHOLEN"
                    @ 21,00 SAY BILD1 + BILD1 
            ENDCASE
            SET PRINTER ON 
            SET CONSOLE OFF 
        ENDIF

    ENDDO

/* Auswurf eines einzelnen Papierblattes.       */
        ? CHR(27)+CHR(25)+CHR(82)
        SET PRINTER OFF 
        SET CONSOLE ON
        /**** 2 ****/

    CASE (UPPER(EINGABE) = "A" )

        /**** 3 ****/
        /* NICHTS  TUN */
        /**** 3 ****/

    OTHERWISE

        /**** 4 ****/
        BELL
        @ 18,00 CLEAR 
        @ 19,00 SAY BILD1 + BILD1 
        @ 20,20 SAY "FALSCHE EINGABE !!! BITTE WIEDERHOLEN "
        @ 21,00 SAY BILD1 + BILD1 
        WAIT
        /**** 4 ****/

ENDCASE

/************************************************/ 

/**** 5 ****/
/* NEUER BILDSCHIRM AUFBAU                      */
/* MENÜAUSGABE - Aufbau der Kopfzeile           */
CLEAR
/* aktuelle Datumsanzeige und der Uhrzeit       */
@ 02     ,00   SAY " Datum "
@ 03     ,00   SAY DATE()
@ 02     ,72   SAY "Uhrzeit"
@ 03     ,72   SAY TIME()
@ 01     ,00   SAY BILD1 + BILD1
@ ROW()  ,TAB  SAY "          DATEN - SUCHE *** V 1.01 *** "
@ ROW()+1,TAB  SAY "flexible  Anwendungsprogrammierung mit ADIMENS Talk"
@ ROW()+1,00   SAY BILD2 + BILD2 
@ ROW()  ,00   SAY BILD2 + BILD2
@ ROW()+1,00   SAY " "
@ ROW(),TAB  SAY " DRUCKEN von Datensätzen "
@ ROW()+1, TAB SAY " "
@ ROW()+1,00 SAY BILD1 + BILD1
/**** 5 ****/

/************************************************/ 

Listing 5: Das Programm LDRUCKAD.TLK


Hans-Ulrich Mayer
Aus: ST-Computer 01 / 1989, Seite 113

Links

Copyright-Bestimmungen: siehe Über diese Seite