.so /z/ing_src/macdoc .pn 320 .NH 1 .NH 1 .NH 1 .ds RH \f3AMX/ZIP\f1 .ds RF \f3\*(xx\f1 .ds LH Beispiele .ds LF \*(vv .ds CH - % - .bp .NH 2 .ft B Terminkontrolle ** .ft R .LP .sp 10 .NH 3 .ft B Vorbemerkung .ft R .LP Um sich sinnvoll in ein \*(xx-System einzuordnen, sollte das Prinzip des "Werkzeugkastens" auch in der Anwenderebene durch\%ge\%standen werden - n\o'a"'mlich kleine Programme mit exakt abgegrenzten Leistungen zu schaffen und diese zu einem Paket verbinden. Nachfolgend wird auszugsweise ein Projekt vorgestellt, das die Nutzung von AMX und ZIP veranschaulicht. .LP Als Bedingungen seien gestellt: .br Die Terminkontrolle ist schirmorientiert zu l\o'o"'sen. Bei Bedarf k\o'o"'nnen Protokolle gedruckt werden. Die zu kontrollierende Einheit besteht aus einer Basis-Massnahme und keiner oder beliebig vielen Festlegungen. W\o'a"'hrend des Kontrollvorganges sollen die Basis-Massnahmen gezeigt (entsprechend vorzugebender Eingrenzungen), ge\o'a"'ndert oder als realisiert markiert werden - Festlegungen sollen gezeigt, korrigiert, als realisiert markiert oder neu hinzugef\o'u"'gt werden. Neben der M\o'o"'glichkeit \o'u"'ber Zieltermine zu recherchieren, kann nach dem Kreis der, f\o'u"'r die Reali\%sierung der Massnahme Verantwortlichen (Gruppe oder Einzelperson) oder nach dem Kreis, der eine Massnahme ausgel\o'o"'st hat (Gruppe oder Einzelperson) - gegen\o'u"'ber dem der recherchierende Leiter also rechenschaftspflichtig ist - eingegrenzt werden. Es existiert eine Nomenklatur, die Struktureinheiten ordnet bzw. gruppiert. .NH 3 .ft B Relationen .ft R .LP Innerhalb der Datenbank .ft B terkon .ft R werden folgende Relationen verwendet: .br .ft B basis .ft R enth\o'a"'lt die Basis-Massnahmen. \o'U"'ber die Massnahme-Nummer .ft B mnr .ft R werden die dazugeh\o'o"'rigen Festlegungen identifiziert. .ft B vongrup .ft R gibt Auskunft, durch welche Struktureinheit (auch \o'u"'bergeordnete Organe) die Massnahme veranlasst wurde (Gruppe), .ft B vonpart .ft R grenzt innerhalb der Gruppe auf einen konkreten Partner ein. .ft B angrup .ft R bzw. .ft B anpart .ft R geben an, wer die Massnahme verantwortlich zu realisieren hat (Gruppe bzw. Partner). .ft B edat .ft R ist das Rechnerdatum, zu dem die Massnahme erfasst wurde und .ft B termin .ft R der vorgegebene Zieltermin. Die Angabe .ft B festanz .ft R gilt als Hinweis auf die aktuelle Anzahl von Festlegungen, ist der Wert -1 sind alle Festlegungen realisiert (Hinweis zum Austragen). Der eigentliche Text wird vierzeilig in .ft B tx1..tx4 .ft R abgelegt. .DS L Relation: basis --------- P8000 / EVK Olbernhau Besitzer: kodir Tupellaenge: 218 Verfallsdatum: Tue Jan 1 00:00:00 1991 Tupelanzahl: 131 Speicherstruktur: HEAP Pages: 1 + 46 Relationentyp: Nutzerrelation Domaenname Typ Laenge Schluessel -------------------------------------------- mnr i 4 edat i 4 vongrup i 2 vonpart i 2 angrup i 2 anpart i 2 tx1 c 49 tx2 c 49 tx3 c 49 tx4 c 49 termin i 4 festanz i 2 -------------------------------------------- .DE .ft B festl .ft R enth\o'a"'lt die zur Basis-Massnahme geh\o'o"'rigen Festlegungen. .ft B fnr .ft R nummeriert innerhalb der Massnahme-Nummer, .ft B vgrup .ft R und .ft B vpart .ft R geben die Verantwortlichkeit und .ft B kgrup .ft R bzw. .ft B kpart .ft R die Kontrollpflicht an. Mit .ft B realis .ft R wird ein Kennzeichen f\o'u"'r gegebene Realisierung (=1) gesetzt. .DS L Relation: festl --------- P8000 / EVK Olbernhau Besitzer: kodir Tupellaenge: 216 Verfallsdatum: Tue Jan 1 00:00:00 1991 Tupelanzahl: 26 Speicherstruktur: HEAP Pages: 1 + 11 Relationentyp: Nutzerrelation Domaenname Typ Laenge Schluessel -------------------------------------------- mnr i 4 fnr i 2 tx1 c 49 tx2 c 49 tx3 c 49 tx4 c 49 termin i 4 vgrup i 2 vpart i 2 kgrup i 2 kpart i 2 realis i 2 -------------------------------------------- .DE .ft B partn .ft R enth\o'a"'lt die Nomenklatur und Bezeichnungen der Struktureinheiten, die an der Terminkontrolle teilhaben. Mit .ft B grup .ft R wird eine Gruppe, mit .ft B fein .ft R ein Partner bestimmt. .DS L Relation: partn --------- P8000 / EVK Olbernhau Besitzer: kodir Tupellaenge: 28 Verfallsdatum: Tue Jan 1 00:00:00 1991 Tupelanzahl: 56 Speicherstruktur: HEAP Pages: 1 + 1 Relationentyp: Nutzerrelation Domaenname Typ Laenge Schluessel -------------------------------------------- grup i 2 fein i 2 bez c 24 -------------------------------------------- .DE .ft B mafenr .ft R ist eine tempor\o'a"'re Relation, die jeweils alle Massnahme-Nummern, sich qualifizierender Tupel der Relation .ft B basis .ft R bzw. die dazugeh\o'o"'rigen Festlegungs-Nummern der Relation .ft B festl .ft R enth\o'a"'lt. .DS L Relation: mafenr --------- P8000 / EVK Olbernhau Besitzer: kodir Tupellaenge: 6 Verfallsdatum: Tue Jan 1 00:00:00 1991 Tupelanzahl: 0 Speicherstruktur: HEAP Pages: 1 + 0 Relationentyp: Nutzerrelation Domaenname Typ Laenge Schluessel -------------------------------------------- mnr i 4 fnr i 2 -------------------------------------------- .DE .NH 3 .ft B Steuerprogramm .ft R .LP Um die relativ langen Zeilen der Quellprogramme noch einigermassen \o'u"'bersichtlich darstellen zu k\o'o"'nnen, wurden nachfolgend \et durch drei Leerzeichen ersetzt. .LP Das Hauptmenue steht in der Prozedur .ft B hauptm.c. .ft R Hier das Hauptprogramm: .sp 2 .nf /* Hauptmenue zur Terminkontrolle in hauptm.c */ /* Pfadname in cmd.c definiert */ # include # include # include "/z/zip/inkeys.h" char command[65]; main() { char *cmd(); initzip(); if (!system(cmd("part"))) goto fehler; for (;;) { switch(hauptm()) { case 1: while (system(cmd("kontr"))) { system(cmd("teko")); system(cmd("delmaf")); } system(cmd("fanze")); break; case 2: system(cmd("eiko")); system(cmd("fanze")); break; case 3: while (system(cmd("druw"))) { system("modifyr terkon mafenr heapsort mnr fnr"); system("nq -nb newpg"); if (!system(cmd("druk"))) { perror("Systemfehler"); sleep(5); break; } clear(); refresh(); } system(cmd("delmaf")); break; case 4: system(cmd("nomenkl")); if (!system(cmd("part"))) goto fehler; break; case 5: crmode(); noecho(); clear(); refresh(); nocrmode(); echo(); endwin(); exit(0); default: goto fehler; } } fehler: crmode(); noecho(); clear(); refresh(); nocrmode(); echo(); endwin(); printf("*** System-Fehler ***\en"); exit(-1); } .fi .LP .ft B initzip() .ft R ist eine Prozedur aus libzip.a, die die Initia\%lisierung des Paketes .ft B curses .ft R und des Paketes .ft B zip .ft R veranlasst. Die Auswahl erfolgt \o'u"'ber die Prozedur hauptm(), indem die gew\o'u"'nschte Zeile mit der Kursortaste (\o'|v') angefahren und mit -> angeklickt wird. Um einen \o'U"'berblick bez\o'u"'glich der Lei\%stung der einzelnen Programme zu verschaffen wird nachfolgend die Menue-Prozedur .ft B hauptm.c .ft R gezeigt: .sp 2 .nf /* Hauptmenue zur Terminkontrolle */ # include # include "/z/zip/inkeys.h" # define Fragen 5 # define Beginn 5 extern char *SO, *SE; hauptm() { static char *men[] = { "? Kontrolle von Faelligkeiten mit Aenderungsmoeglichkeit.. ", "? Erfassung neuer Basis-Massnahmen (auch mit Festlegungen) ", "? Druck von Protokollen (auch mit Eingrenzungen).......... ", "? Aenderung und Ergaenzung der Nomenklatur (Partner)...... ", "? Beendigung der Arbeit................................... " }; int inp; int aus; int zl, sp, spa; char buf[80]; crmode(); clear(); datum(12, 5); move(2, 5); addstr("TERMINKONTROLLE Hauptmenue"); zl = Beginn; sp = 5; for (inp = 0; inp < Fragen; inp++) { move(zl+inp, sp); strcpy(buf, SO); strcat(buf, men[inp]); strcat(buf, SE); addstr(buf); } move(zl, sp-1); refresh(); noecho(); for (;;) { aus = 0; switch(inp = ZZgetchx()) { case CCdo: getyx(stdscr, zl, spa); if (zl < (Fragen+Beginn-1)) move(++zl, spa); break; case CCup: getyx(stdscr, zl, spa); if (zl > Beginn) move(--zl, spa); break; case CCri: nocrmode(); echo(); aus = zl - Beginn + 1; move(zl, sp+1); addstr(men[aus-1]); refresh(); return(aus); default : continue; } refresh(); } } .fi .LP Mit der Prozedur hauptm() wird eine Leistung beschrieben, die in der Regel die ZIP-Prozedur menzip() ausf\o'u"'hrt - der einzige Unterschied besteht darin, dass das f\o'u"'hrende Fragezeichen nach dem Anklicken durch die nachfolgende Zeichenkette (normale Darstellung) \o'u"'berschrieben wird. Die Pointer *SO und *SE stammen aus der termcap und realisieren das Ein- und Ausschalten einer inversen Darstellung der Terminal\%ausgabe. .ft B ZZgetchx() .ft R bietet die M\o'o"'glichkeit, in der termcap definierte Steuerfolgen auszuwerten - hier CCdo (Cursor down), CCup (Cursor up) usw. - und entsprechende Reaktionen des Programms zu gestalten. Die Prozedur steht in libzip.a, die entsprechenden Definitionen zu CCdo, CCup usw. in inkeys.h. Mit getyx() aus curses l\o'a"'sst sich die aktuelle Kursorposition auf dem Standard-Screen (stdscr) erfragen und auf die nachfolgenden beiden Parameter zur\o'u"'ck\%schreiben. .NH 3 .ft B Kontroll-Menue .ft R .LP Das Programm .ft B teko .ft R wird nach dem Programm .ft B kontr .ft R gerufen. Mittels kontr wird eine Abfrage zur Qualifikation (Eingrenzung) der Massnahmen bzw. Festlegungen realisiert. Es entsteht die Relation .ft B mafenr, .ft R die eingangs alle eingegrenzten Massnahmen anbietet. Wird teko durch einen Abbruch vorzeitig verlassen, ist diese Relation mit delmaf wieder zu l\o'o"'schen. .ft B teko .ft R wird nachfolgend komplett gezeigt, Bezugspunkte f\o'u"'r Erl\o'a"'uterungen werden laufend nummeriert (n) und als Kommentar gekennzeichnet. .sp 2 .ft B teko.x: .ft R .nf ## shared terkon /* Menue 1 - Kontr.-Menue: Eingangsrelation mafenr aus kontr */ /* Kontrolle von Festlegungen und Basis-Massnahmen; */ /* Basis-Massnahmen koennen geaendert, Festlegungen geaendert*/ /* und neue hinzugefuegt werden; */ # include ## long MNR; ## int GRUP; ## int FEIN; ## int FNR; ## char BEZ[24]; ## char TX1[49]; ## char TX2[49]; ## char TX3[49]; ## char TX4[49]; ## long EDAT; ## long TERMIN; ## int VGRUP; ## int VPART; ## int AGRUP; ## int APART; ## int FESTL; ## int REALIS; char DATUM[9]; char SLE[15]; char ANTW[2]; char mess[25]; int VON; int clr; int zl, sp; int anzfest; amx() { /* (1) */ static char *bas[] = { "Weiter.............. ", "Realisiert.......... ", "Aendern............. ", "Festl. zeigen/aend.. ", "Festlegungen zufueg. ", "Abbruch............. " }; static char *fest[] = { "Weiter.............. ", "Realisiert.......... ", "Aendern............. ", "Festlegungen zufueg. " }; static char *festzu[] = { "Festlegungen zufueg. ", "Abbruch............. " }; int c; int d; int flag; int flagm; int flagf; int end_fl; int bas_fl; int maxfnr; int t_count; long old_mnr; initzip(); ## open basis ## open partn ## open festl ## open mafenr ## use (+basis,partn,+festl,+mafenr) zyk: end_fl = 0; ## scan mafenr (MNR=$mnr, FNR=$fnr) ## { ++end_fl; ## } if (!end_fl) { /* (2) */ melde(); goto end; } if (MNR == old_mnr) goto zyfest; clr = 0; flag = 0; ## scan basis $mnr=MNR (TX1=$tx1,TX2=$tx2,TX3=$tx3,TX4=$tx4, ## TERMIN=$termin,VGRUP=$vongrup, ## VPART=$vonpart,AGRUP=$angrup,APART=$anpart,FESTL=$festanz) ## { ++flag; anzfest = FESTL; /* (3) */ abas(); getyx(stdscr, zl, sp); move(2, 52); if (anzfest == -1) sprintf(mess, "Festlegungen realisiert"); else sprintf(mess, "%2d Festlegung(en) ! ", anzfest); addstr(mess); refresh(); move(zl, sp); c = menzip(bas, 6, 3, 52); switch(c) { case 2: /* B.-M. loeschen vorbereiten */ ZZbeep(); okay(1,0); if (ANTW[0] == 'j' || ANTW[0] == 'J') { ZZbeep(); FESTL = -1; } break; case 3: /* B.-M. korrigieren */ dbas(); /* Bereich fuer B.-M. loeschen */ /* (5) */ if (!ebas()) c = 1; break; default: break; } if (c == 2 || c == 3) { ## replace ($mnr=MNR,$tx1=TX1,$tx2=TX2,$tx3=TX3,$tx4=TX4, ## $termin=TERMIN,$vongrup=VGRUP,$edat=EDAT, ## $vonpart=VPART,$angrup=AGRUP,$anpart=APART,$festanz=FESTL) } ## } switch(c) { case 6: goto end; case 1: case 2: case 3: ## scan mafenr $mnr=MNR ## { ## delete ## } goto zyk; default : break; } d = 0; flagf = 0; zyfest: switch(c) { case 4: if (FNR) /* Ueber Festl. recherchiert */ { ## scan mafenr $mnr=MNR (FNR=$fnr) ## { ## scan festl $mnr=MNR, $fnr=FNR (TX1=$tx1,TX2=$tx2,TX3=$tx3, ## TX4=$tx4,TERMIN=$termin,VGRUP=$vgrup, ## VPART=$vpart,AGRUP=$kgrup,APART=$kpart,REALIS=$realis) ## { dfest(); afest(); d = menzip(fest, 4, 13, 52); switch(d) { case 1: break; case 2: ZZbeep(); okay(1,0); if (ANTW[0] == 'j' || ANTW[0] == 'J') { ZZbeep(); REALIS = 1; } case 3: if (!REALIS) kfest(); ## replace ($mnr=MNR,$fnr=FNR,$tx1=TX1,$tx2=TX2,$tx3=TX3, ## $tx4=TX4,$termin=TERMIN,$vgrup=VGRUP, ## $vpart=VPART,$kgrup=AGRUP,$kpart=APART,$realis=REALIS) break; case 4: c = 5; goto zyfest; } ## } ## delete ## } } else /* Keine Festl.-Nr.: Recherche BMn. */ { ++flagf; ## scan festl $mnr=MNR (FNR=$fnr,TX1=$tx1,TX2=$tx2,TX3=$tx3, ## TX4=$tx4,TERMIN=$termin,VGRUP=$vgrup, ## VPART=$vpart,AGRUP=$kgrup,APART=$kpart,REALIS=$realis) ## { dfest(); afest(); d = menzip(fest, 4, 13, 52); switch(d) { case 1: break; case 2: REALIS = 1; case 3: if (!REALIS) kfest(); ## replace ($mnr=MNR,$fnr=FNR,$tx1=TX1,$tx2=TX2,$tx3=TX3, ## $tx4=TX4,$termin=TERMIN,$vgrup=VGRUP, ## $vpart=VPART,$kgrup=AGRUP,$kpart=APART,$realis=REALIS) break; case 4: c = 5; goto zyfest; } ## } } break; case 5: ++flagf; zyzuf: if (d == 4) { maxfnr = 1; ## scan festl $mnr=MNR (FESTL=$fnr) ## { if (FESTL > maxfnr) maxfnr = FESTL; ## } } TX1[0] = '\e0'; TX2[0] = '\e0'; TX3[0] = '\e0'; TX4[0] = '\e0'; FNR = maxfnr + 1; kfest(); ## append festl ($mnr=MNR,$fnr=FNR,$tx1=TX1,$tx2=TX2,$tx3=TX3, ## $tx4=TX4,$termin=TERMIN,$vgrup=VGRUP, ## $vpart=VPART,$kgrup=AGRUP,$kpart=APART,$realis=REALIS) if ((d = menzip(festzu, 2, 13, 52)) == 1) { d = 4; goto zyzuf; } break; default: break; } if (flagf) { ## scan mafenr $mnr=MNR ## { ## delete ## } flagf = 0; } goto zyk; end: ## commit ## close partn ## close basis ## close festl ## close mafenr } /* (4) */ ks_part() { ## scan partn $grup=GRUP, $fein=FEIN (BEZ=$bez) ## { ## } } .fi .LP Die Datenbank wird f\o'u"'r mehrere Nutzer gleichzeitig ge\o'o"'ffnet (shared). Dabei sind die Relationen .ft B basis, festl .ft R und .ft B mafenr .ft R zum Lesen und Schreiben sowie .ft B partn .ft R nur zum Lesen verf\o'u"'gbar (use). Die lokalen Vereinbarungen .ft B (1) .ft R repr\o'a"'sentieren jeweils ein Menue, das mit menzip() zur Anzeige kommt. .LP Die Prozedur .ft B melde() .ft R bei .ft B (2) .ft R teilt bei den Phasen, die mehrere Sekunden keine Ver\o'a"'nderungen am Bildschirm veranlassen, mit, dass der Rechner arbeitet. Die Prozedur beinhaltet lediglich eine Positionierung mit move(), nachdem vorher mit getyx() die aktuelle Kursor-Position gesichert wurde und gibt die Zeichenkette .ft B Ich arbeite! .ft R mit addstr() aus - die Prozeduren entstammen curses. .sp 2 .nf /* Ausschrift einer Meldung am Bildschirm */ # include melde() { int zl, sp; getyx(stdscr, zl, sp); move(15, 1); addstr(" Ich arbeite ! "); refresh(); move(zl, sp); } .fi .LP Die Prozedur .ft B abas() .ft R bei .ft B (3) .ft R fasst einige Positionierungen und ZIP-Prozeduren zusammen. .sp 2 .nf /* Anzeige Basis-Massnahmen */ # include extern int GRUP, VGRUP, FEIN, VPART, AGRUP, APART; extern long TERMIN; extern char DATUM[9]; extern char SLE[15]; extern int clr; extern int anzfest; extern char mess[25]; abas() { emnr(clr++, 0); tocdat(&TERMIN, DATUM); dfest(); strcpy(SLE, "Basis-Massn."); bas(clr, -1); tobdat(DATUM, &TERMIN); move(8, 0); refresh(); strcpy(SLE, "Aufgst. durch"); GRUP = VGRUP; FEIN = VPART; ks_part(); kvekop(clr, 0); strcpy(SLE, "Realis. durch"); GRUP = AGRUP; FEIN = APART; ks_part(); kvekop(clr, 0); APART = FEIN; refresh(); } .fi .LP abas() soll die Basis-Massnahmen entsprechend der, in der Relation mafenr vorgegebenen Reihenfolge anzeigen. Um dies etwas zu verdeutlichen, sehen wir uns den Aufbau der oberen H\o'a"'lfte des Bildschirms an: .sp 2 .DS L +-----------------------------------------------------------+ Massnahme-Nr.: 9999999999 >>>> TERMINKONTROLLE <<<< Text Basis-Massn. : 1 Festlegung(en) ! >aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..aa< +--------------------+ >aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..aa< |Weiter..............| >aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..aa< |Realisiert..........| >aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..aa< |Aendern.............| Termin(tt.mm.jj) : 28.02.89< |Festl. zeigen/aend..| \&.Aufgst. durch > Partner: Kombinatsd.. |Festlegungen zufueg.| \&.Realis. durch > Partner: Direktor T.. |Abbruch.............| +--------------------+ +-----------------------------------------------------------+ .DE .LP Die Abbildung wurde nicht v\o'o"'llig korrekt wiedergegeben, weil eine Breite von 80 Zeichen den rechten Rand beim Druck zu weit \o'u"'berschreitet. Das invers zu zeigende Menue aus der Zeichenkettenvariablen .ft B *bas .ft R wurde gerahmt dargestellt. In der Regel wird der untere Teil des Bildschirms - sofern Festlegungen vorhanden sind - beim Anklicken der 4. Zeile des Menues mit der analogen Darstellung zur Festlegung gef\o'u"'llt. Das Menue 'Weiter' zeigt die n\o'a"'chste Massnahme. Das Anklicken von 'Realisiert' ist mit einer R\o'u"'ckversicherung verbunden - die Frage .ft B Okay (j/n)? .ft R muss mit 'j' beantwortet werden, bevor die Massnahme tats\o'a"'chlich zum L\o'o"'schen markiert wird. Ein Piepton (ZZbeep()) best\o'a"'tigt die L\o'o"'schvormerkung. .LP Zur\o'u"'ck zu abas(). .ft B curses.h .ft R wurde eingezogen, um die Makros aus curses .ft B move() .ft R und .ft B refresh() .ft R verf\o'u"'gbar zu haben. Die Prozedur .ft B emnr() .ft R ist aus ZIP entstanden und zeigt die Massnahme-Nr. an. Der Erarbeitungsweg wird gezeigt. .br Mit dem Editor ist folgendes File .ft B emnr_m .ft R zu erstellen: .sp 1 .DS L Massnahme-Nr.: #999999999 >>>> TERMINKONTROLLE <<<< .DE Die Erzeugung des Quell- und Objektcodes erfolgt mit dem Aufruf: zip -l ../LIBTERM emnr Die Maskenidentifikation '_m' darf nicht im Aufruf angegeben sein, sonst wird der gesamte Name als Basisname interpretiert. Im Dialog antworten sie in dieser Reihenfolge: .nf l MNR n .fi .LP Zur Verdeutlichung wird das entstehende _i-File gezeigt, das f\o'u"'r eventuelle Modifikationen genutzt werden kann und \o'u"'ber den stattgefundenen Dialog informiert. .DS L emnr -l ../LIBTERM long MNR n n .DE .LP .ft B tocdat() .ft R wandelt die intern \o'u"'bliche long-Darstellung (Zeit, Datum) in die normale Darstellung des Datums (tt.mm.jj). .ft B dfest() .ft R l\o'o"'scht auf dem Bildschirm den Bereich, auf dem Festlegungen dargestellt werden, um zu vermeiden, dass eine m\o'o"'glicherweise von der vorausgegangenen Massnahme abgebildete Festlegung stehen bleibt. Die ZIP-Prozedur .ft B bas() .ft R rea\%lisiert die Anzeige der n\o'a"'chsten 6 Zeilen, wobei das 2. Argument '-1' die Prozedur veranlasst, unabh\o'a"'ngig von einer gew\o'u"'nschten Korrekturart, die Variablen nur auszuschreiben. Die Maske .ft B bas_m .ft R sieht so aus: .DS L Text #aaaaaaaaaaaa: >#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa< >#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa< >#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa< >#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa< Termin(tt.mm.jj) : #aaaaaaa< .DE Aus dem _i-File wird ersichtlich, welche Variablen verwendet und wie sie behandelt werden sollen: .DS L bas -a 2 -pl ../LIBTERM char SLE[15] n n char TX1[49] j n char TX2[49] j n char TX3[49] j n char TX4[49] j n char DATUM[9] j testdat() w .DE Die Maske wird auf dem Bildschirm nach der 2. Zeile angeh\o'a"'ngt (-a 2) und die Variable DATUM[9] einer Pr\o'u"'fung mit .ft B testdat() .ft R unterzogen (g\o'u"'ltiges Datum) - diese Pr\o'u"'fung wird nur bei einer Korrektur des alten Wertes angestossen. .ft B tobdat() .ft R ist die Umkehrung von tocdat(). .LP Mit .ft B refresh() .ft R werden die, auf der Speicherfl\o'a"'che stdscr vorgenommenen \o'A"'nderungen sichtbar gemacht - dieser Algorithmus hilft, insgesamt ein ruhiges Abbilden auf dem Schirm zu realisieren und die Kursorbewegungen zu optimieren. Die Prozedur .ft B ks_part() .ft R - es geht noch um abas() - stammt aus teko.x (4). AMX-Statements k\o'o"'nnen nicht in separat zu \o'u"'bersetzenden Prozeduren verwendet werden, der AMX-Compiler generiert ein main(). Das gezeigte Beispiel weist auf eine sehr effiziente Anwendung von AMX hin, mit der differenzierte und relativ komplizierte Einsatzf\o'a"'lle l\o'o"'sbar sind. ks_part() sucht zum angegebenen Schl\o'u"'ssel f\o'u"'r GRUP und FEIN die Bezeichnung aus der Relation partn. Die Ausgabe der Bezeichnung erfolgt mit .ft B kvekop(). .ft R Im Gegensatz zu bas() kann kvekop() nicht durch eine fest eingestellte Zeilennummer zur Positionierung \o'u"'bersetzt werden, da es zweimal bei Basis-Massnahmen und zweimal bei Festlegungen benutzt wird. F\o'u"'r solche Anwendungsf\o'a"'lle ist die Option -z von ZIP gedacht, wie am Beispiel nocheinmal gezeigt werden soll: .DS L \&.#aaaaaaaaaaaaa >Partner: #aaaaaaaaaaaaaaaaaaaaaaa .DE Aus kvekop_i wird der Aufruf deutlich: .DS L kvekop -zl ../LIBTERM char SLE[15] n n char BEZ[24] n n .DE .LP Nachdem abas() abgearbeitet ist, wird \o'u"'ber die Anzahl der Festlegungen informiert. Die Verwendung von curses schliesst direkte Ausgaben auf den Schirm (printf()) aus, deshalb erfolgt erst der Aufbau der Zeichenkette mit sprintf() und anschliessend die Ausgabe mittels addstr(). .LP .ft B menzip() .ft R ist in das Paket ZIP eingegliedert und gestattet eine freie Postionierung eines Menues - das seitliche Ausrutschen der Zeichenketten bei \o'U"'berschreitung der Spalte 80 wird nicht kontrolliert, ebenso sollte die Spalte 80 selbst nicht benutzt werden, weil einige Terminaldriver dort eigenwillig reagieren. Die Argumente f\o'u"'r menzip() haben folgende Bedeutung: .IP 1.Argument: Variable, in der die auszugebende Zeichenkette definiert ist. .IP 2.Argument: Zeilenzahl des Menues; .IP 3.Argument: Zeilennummer des Bildschirms, ab der das Menue geschrieben werden soll, zusammen mit der Spaltennummer ergibt das die linke obere Ecke des Menues. .IP 4.Argument: Spaltennummer des Bildschirms, mit 1 beginnend. .LP Sofern das benutzte Terminal invers schreiben kann, wird das Menue so ausgegeben und die angeklickte Zeile auf normal gewandelt. .LP Mit der Prozedur .ft B ebas() .ft R (5) k\o'o"'nnen Basismassnahmen korrigiert werden, insoweit unterscheidet sie sich von abas(). Durch die Korrektur ist ausserdem denkbar, dass w\o'a"'hrend einer Eingabe mit zweimal Interrupt (bspw. DEL) abgebrochen wird und der R\o'u"'ckkehrcode der ZIP-Prozedur im Hauptprogramm behandelt werden muss. Nachfolgend die Prozedur: .nf /* Erfassung oder Korrektur von Basis-Massnahmen */ # include extern int GRUP, VGRUP, FEIN, VPART, APART, VON, AGRUP; extern long TERMIN; extern char DATUM[9]; extern char SLE[15]; extern char ANTW[2]; extern int clr, anzfest; extern char mess[25]; ebas() { tocdat(&TERMIN, DATUM); move(1, 0); emnr(clr, 0); wdh: strcpy(SLE, "Basis-Massn."); if (!bas(clr, 1)) return(0); tobdat(DATUM, &TERMIN); move(2, 52); sprintf(mess, "%2d Festlegung(en)!", anzfest); addstr(mess); move(8, 0); refresh(); strcpy(SLE, "Aufgst. durch"); GRUP = VGRUP; VON = 0; if (!verkog(clr, 0)) return(0); VGRUP = GRUP; VON = 1; FEIN = VPART; if (!verkop(clr, 0)) return(0); VPART = FEIN; strcpy(SLE, "Realis. durch"); GRUP = AGRUP; VON = 0; move(10, 0); refresh(); if (!verkog(clr, 0)) return(0); AGRUP = GRUP; FEIN = APART; VON = 1; if (!verkop(clr, 0)) return(0); APART = FEIN; okay(1, 0); if (ANTW[0] == 'n' || ANTW[0] == 'N') goto wdh; else ZZbeep(); return(1); } .fi .LP Innerhalb von ebas() sind die ZIP-Prozeduren .ft B verkog() .ft R f\o'u"'r die Eingabe des Gruppenschl\o'u"'ssels und .ft B verkop() .ft R f\o'u"'r die Eingabe des Partnerschl\o'u"'ssels interessant, weil hier \o'u"'ber eine Hilfe (Eingabe von ?) aus der Relation partn die Schl\o'u"'sseltabelle f\o'u"'r Gruppen bzw. Partner innerhalb der gew\o'a"'hlten Gruppe angezeigt werden k\o'o"'nnen. Als Beispiel wird verkog() vorgestellt: .DS L Maske: #aaaaaaaaaaaaaa > Gruppe: #9 verkog_i: -zhl ../LIBTERM verkog char SLE[15] n n int GRUP j n s_part() p .DE .LP Die Hilfe wird in diesem Fall \o'u"'ber .ft B s_part() .ft R realisiert. .nf /* Nutzt das File 'partner' aus 'part.x', zeigt fuer Hilfe ** die Gruppenuebersicht bzw. die Partner zur Gruppe an ! */ # include extern int GRUP; extern int VON; s_part() { FILE *fp, *fopen(); int zl = 8; int count = 14; int fein, grup; char bez[24]; char buf[29]; if ((fp = fopen("/z/ing_db/work/termin/partner", "r")) == NULL) { echo(); nocrmode(); perror("partner not found"); exit(0); } while (fscanf(fp, "%d %d ", &grup, &fein) != EOF) { if (fgets(bez, 24, fp) == NULL) break; if (!VON) { if (!fein) { move(zl, 50); addstr(" "); sprintf(buf,"%2d %s", grup, bez); move(zl, 51); addstr(buf); } else continue; } else { if (GRUP == grup) { move(zl, 50); addstr(" "); sprintf(buf, "%2d %s", fein, bez); move(zl, 51); addstr(buf); } else continue; } ++zl; if (!(--count)) { refresh(); getchar(zl); zl = 8; count = 14; } } refresh(); fclose(fp); } .fi .LP Der scan() aus ks_part() k\o'o"'nnte auf den ersten Blick eigentlich auch hier genutzt werden, analog m\o'u"'sste anstelle des fscanf() die Prozedur ks_part() stehen und die in der Qualifikation geforderten Werte in einer Schleife aktua\%li\%siert werden. Allerdings w\o'a"'re die Formulierung der Qualifikation '$grup=GRUP, $fein=FEIN' zu differenzieren und damit drei scan() erforderlich. Die Kopie der Relation partn in ein \*(xx -File ist in diesem Fall doch der geringere Aufwand. Da maximal 14 Zeilen, beginnend ab 6, geschrieben werden k\o'o"'nnen, wird mit getchar(zl) die Ausgabe gestoppt und nach Eingabe eines beliebigen Zeichens fortgesetzt. .LP Einige wesentliche Dinge sind damit erkl\o'a"'rt. Da der Rahmen des Anwenderhandbuches durch weitergehende Beschreibungen gesprengt w\o'u"'rde, muss hier das Kapitel abgebrochen werden.