[Allegro] Trick 76: Erweiterte Ausgabe von Ergebnismengen

Bernhard Eversberg ev at biblio.tu-bs.de
Do Sep 11 10:20:41 CEST 2014


Trick 76 : Erweiterter Aktionsradius
------------------------------------                         2014-09-11

Aufgabe: Schnell mal eben eine Ergebnismenge durcharbeiten, wobei aber
zu jedem Satz auch die mit ihm in bestimmter Weise verknüpften Sätze
mit verarbeitet werden sollen, aber nicht unbedingt in derselben Weise
wie der Hauptsatz. Beispiele sind nicht nur die verknüpften Bandsätze,
sondern auch Exemplar- oder Bestellsätze oder die Ausleihen von
Nutzern etc., d.h. alles kommt in Betracht, was durch die Indexierung
miteinander zusammenhängt.
Ferner: Es soll ein reines FLEX-Verfahren sein, also ohne Export-
parameter, bis auf Umcodierung.
Und: Das Verfahren soll mit a99 und mit acon funktionieren.

Option: Vielleicht will man auch gelegentlich schnell mal eben die
Gesamtbank entsprechend abarbeiten ...

Beisp.1: Erg.Menge exportieren, aber unter jedem Satz die Exemplardaten
          auflisten.

Beisp.2: In jedem Satz der Erg.Menge bestimmte Änderungen vornehmen,
          zusätzlich aber auch in den verknüpften Untersätzen.

Gesucht ist eine allgemeine Lösung, die in allen vergleichbaren
Fällen zum Einsatz kommen kann! Ein FLEX-Unterprogramm also, aber mit
Variationsmöglichkeiten.

Man konnte solche Produktionen seit langem mittels der "Nachladung"
in den Exportparametern bewerkstelligen. Nun aber soll eine Methode
gefunden werden, die allein mit FLEX arbeitet, denn die Export-
Parametrierung ist eine wegen ihrer Abstraktheit und Kryptik doch recht
schwierig anzuwendende Sache.

    --------------
    Der Lösungsweg
    --------------

Folgende Kurzbezeichnungen sind sinnvoll:
    HM = Hauptergebnismenge
    ZM = Zusatz-Erg.Menge, jeweils zu einem Satz der HM zu bilden
         (Manchmal ist sie leer!)

Zwei Probleme stellen sich in den Weg:

Problem 1:
Wir können nicht die übliche Methode  first / next  verwenden, denn zu
jedem Satz ist eine Zusatz-Erg.Menge (ZM) zu bilden - dadurch wird
dann die HM geschlossen. Nach Verarb. der ZM ist zur HM zurückzukehren
und in dieser dann zum nächsten Satz zu gehen. Das ginge in a99, in
acon aber nicht!  [Evtl. wird das noch geändert!]
Lösung: Aus der HM wird mittels des Befehls
            var i,
         eine Nummernliste erstellt, in der die internen Satznummern
         durch ',' getrennt vorliegen
         Aber ACHTUNG: Die Liste wird in einer $-Var. gespeichert, das
         beschränkt die Größe der Erg.Menge auf etwa 8-10000. Will man
         größere erschlagen können, muß man die Methodik umstellen
         auf Speicherung in einer Datei und dann zeilenweises Einlesen.

Problem 2: Die folgenden drei je spezifischen Aktionen können
nicht Teil des erwünschten, allgemeingültigen Unterprogramms sein:

ZMget : Bildung der zu einem HM-Satz gehörigen ZM
HMact : Ausführung der gewünschten Aktion am HM-Satz
ZMact : ... am verknüpften ZM-Satz

Lösung: Unser Unterprogramm soll  EXTACT  heißen, d.h. es beginnt mit
der Zeile  :EXTACT  und endet mit  return. (Der Name leitet sich ab
von "extended action", wie man die Sache auch bezeichnen könnte.)
Das Unterprogramm enthält nicht selber die drei Aktionen, sondern
die liegen als Unterprogramme "weiter oben" im Haupt-FLEX, unter den
o.g. Namen, denn sie müssen spezifisch für die jeweilige konkrete
Aufgabe sein.
Weil aber verschachtelte Unterprogramme nicht möglich sind, müssen
die drei Unterprogramme mit "jump ..." aufgerufen werden, d.h. sie
sind keine echten Unterprogramme, sondern werden jeweils mit einem
"jump ..." beendet, der zurück in das Unterprogramm  EXTACT hinter den
jeweiligen Aufruf führt: :HMact endet mit  jump HMactRet  und führt
damit zu  :HMactRet  unter  jump HMact, usw.


     ===============
     Was ist zu tun?
     ===============

Im Haupt-FLEX sieht der Ablauf so aus:
und hier muß man die "AKTIONen" selber geeignet programmieren!,
d.h. NUR das hier, zwischen ANFANG und ENDE, ist der variable Teil,
den man in den eigenen FLEX bzw. Job einbauen muss:

(Also das folgende Muster kopieren und geeignet modifizieren!)

// *** ANFANG des eigenen .flx oder .job ************************
// ... Vorbereitende AKTIONen ...

// Fuer acon:
var m
if %ac-% echo off

//  Wenn Gesamtbank gewuenscht, dann Flag $gF setzen:
// $gF=1

// Sonst muss jetzt eine Erg.Menge vorliegen, evtl. geordnet.

exp f <dateiname>   // Ausgabedatei oeffnen
exp p utf   // diese 2 Zeilen nur für Wandlung von ASCII nach UTF-8
exp wA      // Bei #-A in utf.apr wird der zu schreibende Text umcodiert

// der Aufruf des Unterprogramms:
perform EXTACT
mes Erledigt!

// ... nachbereitende Aktionen des Hauptteils ...

end

// An das Ende des eigenen Jobs kommt noch dieser Teil,
// ebenfalls selbst zu schreiben, weil spezifisch.

// ###############
//  Diese drei Abschnitte sind aufgabenspezifisch auszufuellen:

//  1. Bildung der Sub-Erg.Menge  ZM
:ZMfind
// *** hier AKTION zur Bildung der ZM-Erg.Menge, evtl. mit Ordnung ***
// i.d.R. mit "var ..." einen Suchbefehl machen und dann "find"
//  zurueck in das UP
jump ZMfindRet

//  2. Verarb. d. Satzes aus der HM (ist jetzt der aktive Satz)
:HMact
// *** hier AKTIONen mit dem HM-Satz ***
// evtl. bestimmte Sätze ausschließen, z.B. mit
// if not #20 jump HMnext
// i.d.R. mit "write ..." die Ausgabe erzeugen
jump HMactRet

//  3. Export des aktuellen Satzes der ZM (ist jetzt aktiver Satz)
:ZMact
// *** hier AKTIONen mit dem ZM-Satz  ***
// i.d.R. mit "write ..." die Ausgabe erzeugen
jump ZMactRet

// ################

//  jetzt noch die Datei hinzunehmen, in der :EXTACT ist:
include extact.inc

// *** ENDE des eigenen FLEXjobs *********************************


  ================ extact.inc =====================================

==>Mit  X getfile extact.inc  können Sie sich die Datei holen!
   oder von hier kopieren:

// *** Beginn extact.inc *****************************************
//  Label fuer den Aufruf mit  perform EXTACT  zur Anwendung auf die
//  aktuelle Erg.Menge, die in der vorliegenden Reihenfolge
//  abgearbeitet werden soll

:EXTACT
//  Die internen Nummern der HM in $hm ablegen, mit , getrennt
var i,
ins $hm
//  Diese Liste wird dann abgearbeitet von vorn nach hinten
//  ACHTUNG: die Erg.Menge kann fuer diese Methode nicht groesser als
//  8-10.000 Saetze sein.

// Wenn $gF besetzt, dann Gesamtbank abarb.

if $gF first #;if del jump HMgesamt

:HMloop
//  die erste (bzw. naechste) Nummer nehmen, # davorsetzen
//  ($hm beginnt mit dieser Nr.)
//  und den HM-Satz mit dieser Nr. laden
//  - falls nicht $gF gesetzt, dann ist jetzt naechste Satz schon da
if not $gF var "#" $hm (e",");f1nd

//  Die HM-Aktion ausfuehren
jump HMact

:HMactRet
//  Zu dem Satz nun die zusaetzliche Menge (ZM) bilden
// Vorher  Objekt 2 einschalten - damit dann  next #  klappt
// aber 1 nach 2 kopieren, damit unter :ZMfind zugaenglich
copy obj 1 2
set obj 2
// d.h. die ZM-Saetze werden in Obj.2 geladen
jump ZMfind
//  (von dort Ruecksprung mit  jump ZMfindRet)
:ZMfindRet
// "less than 1"?  d.h. ZM ist leer
if l1 set obj 1;jump HMnext

//  Die ZM ist nicht leer, also abarbeiten

first
:ZMloop
// die ZM-Aktion  :ZMact  ausfuehren (im HauptFLEX)
jump ZMact
// von dort zurueck mit  jump ZMactRet
:ZMactRet
// naechsten Satz der ZM
next
if yes jump ZMloop
// keiner mehr da - Die ZM schliessen und loeschen
close res
// ZM Ende, jetzt wieder Objekt 1
set obj 1

//  Hauptschleife geht weiter, momentan erste Nr. der HM wegnehmen
:HMnext
// Wenn Gesamtbank:
if $gF jump HMgesamt

// Naechsten Satz der Erg.Menge
var $hm (b",")
//  verkuerzte Liste wieder in $hm
ins $hm
//  Ist noch was da? Dann weiter in Hauptschleife mit dem naechsten Satz
if $hm jump HMloop
jump HMend

// naechsten Satz der Gesamtbank, etwas schwierig wg. unbesetzter 
Nummern etc.
:HMgesamt
next #
// Ende? (a99: cancel, acon: no)
if no jump HMend
if cancel jump HMend

if del jump HMgesamt
jump HMloop

:HMend
return
end
// **** ENDE  extact.inc  *****************************************




Mehr Informationen über die Mailingliste Allegro