[Allegro] Trick 78 : Variable Variablen
Bernhard Eversberg
ev at biblio.tu-bs.de
Do Jun 4 13:11:54 CEST 2015
Dieser Beitrag hätte schon am 21.4. versandt werden sollen, war dann
aber in der Hitze des Tagesgeschäfts unter den Tisch gefallen. Er
beschreibt die allgemeine Methodik, die hinter dem FLEX o-besta.flx
steckt.
Trick 78 : Variable Variablen
----------------------------- 2015-04-21
Manchmal braucht man eine unbestimmte Anzahl von Variablen, deren Namen
man nicht im Vorhinein festlegen kann, sondern die Namen selber stehen
wiederum in anderen Variablen. Dann sprechen wir von "variablen
Variablen", kurz "var.Var."
Beispiel 1: Man will ORDER-Bestellsätze durcharbeiten und dabei
zu einem bestimmten Auftraggeber die Summen errechnen, die er
von den einzelnen Kontingenten ausgegeben hat. Man weiß nicht,
welche und wieviele Kontingente es sind, auch das soll die Auswertung
dann erst ergeben, und eine Liste nach Kontingenten geordnet
soll entstehen. [Realisiert in dem FLEX o-besta.flx des ORDER-Systems.]
Beispiel 2: Die momentan ausgeliehenen Exemplare sollen nach Signatur-
gruppen geordnet und gezaehlt werden. (Die Signaturgruppe ergibt sich
beim Standard aus dem Unterfeld #9DG$s.)
Dabei sind insgesamt vier Probleme zu loesen.
1. Eine var.Var. erzeugen
Sagen wir, in #una steht jeweils ein Variablenname, z.B. eine
Signaturgruppe, ein Lieferanten- oder Kontingentcode o.a.
Wenn nun in #una z.B. xy steht, und in #uwe der Wert 101,
dann soll $QVxy den Inhalt 101 kriegen. Wie macht man das? So:
var "$QV" #una "=" #uwe
ins
ACHTUNG: Es ist hier $QVxy gewaehlt statt $xy, weil es damit moeglich
wird, diese Variablen aus allen anderen $-Variablen herauszufischen.
Statt QV ein anderes Praefix nehmen, wenn man QV schon anderweitig
braucht! (Vielleicht VV?)
Mehr als zwei Buchstaben sind auch moeglich. Statt grossen Buchstaben
gehen auch kleine, wenn die Auswertung im selben FLEX passiert.
2. Mit einer var.Var. rechnen
In $QVxy sei irgendein Wert, und auf den wollen wir die Zahl
in #uza addieren, die Summe dann wieder in $QVxy speichern:
Der Name "xy" soll jetzt mal in $v stehen.
(Wenn $QVxy noch nicht belegt ist, hat sie den Wert 0)
var "$QV" $v " +#uza"
// in iV steht jetzt $QVxy +#uza, das wird so ausgerechnet:
eval
// und in $summe kopiert
ins $summe
// diese Summe dann wieder der Variablen $QVxy zugewiesen
var "$QV" $v "=" $summe
ins
Wenn man nur zaehlen will (Problem 2), wie oft der Wert "xy"
vorkommt, der in $v steht, dann die erste Zeile so:
var "$QV" $v " +1"
3. Die erzeugten var.Var. herausfischen, ordnen und anzeigen
Am Ende kommt der Moment, wo man alle so entstandenen $QVxy sortieren
und ausgeben will.
Zuerst muessen wir aus dem "großen" Variablenspeicher alle extrahieren,
deren Namen mit $QV anfangen. Schwierig, denn die stehen im Variablen-
speicher leider nicht schoen geordnet! Aber so geht's:
// In $X soll die Liste der Werte landen, also erst leermachen:
var ""
ins $X
// die erste der grossen Var. nehmen (koennte z.B. $A abc sein)
first $1
ins $X
// In $X steht jetzt z.B. $A abc
// Schleife zur Sammlung der $QV-Variablen
:floop
// naechste Var.
next $1
// Ende?
if no jump flend
ins $v
// Nur wenn Name mit $QV beginnt, dann an $X anhaengen
if "$QV" var $X n $v;ins $X
// In $x stehen also die Var. mit Zeilentrennungszeichen
// denn n = Codes 13 10 = ^M^J
jump floop
// $X enthaelt jetzt die komplette Liste
:flend
// Erste Zeile von $X wegnehmen, wenn sie NICHT mit $QV beginnt
var $X
if not "$QV" var $X (b"^M^J");ins $X
// Jetzt stehen in $X genau alle $QV-Variablen: jeweils $QVxy wert
var $X
// Das Praefix $QV wegnehmen
ins _$QV__
// und aufsteigend nach Namen ordnen
sort a0
ins $X
// Liste ist fertig, anzeigen
sho IV
Nun stehen in $X die Variablen samt Namen, also $QVxy wert, getrennt
durch "^M^J" - das ist bequem fuer die Anzeige mit show IV.
Mit "sho IV" sieht man die Liste in der Anzeige und kann sie da
herauskopieren. Oder man macht sonstwas anderes aus $X.
4. Die erzeugten var.Var. alle loeschen
FLEXperten werden sofort fragen: Wenn wir dann also eine Anzahl von
Variablen haben, deren Namen mit $QV anfangen, aber wir wissen die
genauen Namen nicht und auch nicht die Anzahl, wie können wir sie
alle zusammen loswerden? Damit sie bei einem weiteren Durchlauf mit
anderen Daten nicht stoeren!
[Hinweis: Falls man die $QV-Var. nach Ablauf des FLEXes nicht mehr
braucht, $qV statt $QV nehmen, dann verschwinden sie automatisch.]
So geht's:
// UP zum Loeschen aller mit $QV beginnenden Variablen
:$QVdel
var ""
ins $qall
first $1
var (e" ")
ins $qall
// Schleife zur Sammlung der $QV-Variablen in $qall
:qloop
// naechste Var.
next $1
// Ende?
if no jump qlend
var (e" ")
ins $vq
// Nur wenn Name mit $QV beginnt, dann an $qall anhaengen
if "$QV" var $qall "//" $vq;ins $qall
// In $qall stehen also die Var., mit // getrennt
jump qloop
:qlend
var $qall
sho IV
// Erste Zeile von $qall wegnehmen, wenn sie NICHT mit $QV beginnt
var $qall
if not "$QV" var $qall (b"//");if "" jump QVend;ins $qall
if not $qall jump QVend
// Jetzt stehen in $qall genau alle $QV-Variablen: jeweils $QVxy wert
// Eine leere Zuweisung uf jede Variable ausfuehren, z.B. $QVabc=\ins
var $qall (e"//")
var +"="
ins
var $qall (b"//")
if "" jump QVend
ins $qall
jump qlend
:QVend
return
Mehr Informationen über die Mailingliste Allegro