Hier die Lösung:
DOLL.FLX : Dollarzeichen ueberall durch das Dreieck ersetzen
2009-11-26
first #
falls der erste Satz gelöscht ist: nächster Satz
if del jump weiter
Jeder Satz wird in dieser Schleife verarbeitet:
:schleife
Kommt $ im Satz vor? Wenn nicht, -> :weiter
if not _$_ jump weiter
*************
var k_1
:loop
Kombination ^ und _ steht fuer das Dreieck:
ins ,$,^_,
ins
var k_2
if not "" jump loop
**************
put speichern
Nächsten Satz holen (interne Nummernfolge)
:weiter
next #
kein Satz mehr, Ende erreicht
if cancel jump exit
der Satz ist gelöscht
if del jump weiter
es gab noch einen Satz? dann -> :schleife
if yes jump schleife
:exit
end
Statt des Abschnitts zwischen ***** geht auch, kürzer:
var kn
ins ,$,^_,
ins
put
Das wäre der fünfte Trick: mit var kn wird der gesamte Satz in die iV kopiert
die Ersetzung darin durchgeführt und das Ganze wieder in den Arbeitsspeicher
zurückkopiert.
(2009-11-26)
---------------------------------------------------------------------------------------------------
Trick 75: Index ändern on-the-fly
Bestimmte Einträge im laufenden Betrieb ändern
Aufgabe: Schnell mal eben für eine Anzahl von Sätzen einen bestimmten
Registereintrag ändern.
Warum das?
Wer kennt es nicht: Man macht an den Indexparametern eine ganz kleine
Änderung, aber a99 ist zu dumm, dann schnell mal eben die nicht mehr
korrekten Schlüssel automatisch rauszusuchen und -zuwerfen und die
nunmehr korrekten einzusortieren.
Warum das so ist? Nun, a99 kriegt einfach gar nicht mit, daß man was
geändert hat - es prüft nicht ständig, ob die Datei noch so ist wie
vorher - und falls nicht, dann genau das Richtige zu tun. Das wäre
leider zuviel verlangt, man muß also selber dran denken, daß man den
Index dann erneuert.
Ha! Index erneuern, das ist bei Kleinbanken kein Problem, aber bei
sehr großen braucht's massig Zeit und ist im Netz auch nur dann
möglich, wenn gerade keiner an der Datenbank arbeitet, und das kann
schon ein arges Ärgernis sein; in einem 24/7-Betrieb geht das gar
nicht!
Aber FLEX birgt das Potential für einen pfiffigen Trick, und der geht so:
Zuerst die Ergebnismenge aller Sätze bilden, bei denen die
Änderung sich auswirken würde.
Dann einen FLEX schreiben, der
a) aus einem Satz den nicht mehr gültigen Schlüssel bildet und
diesen löscht (mit ixdel ...)
b) aus demselben Satz den nunmehr gültigen Schlüssel bildet und
diesen einfügt (mit ixadd ...)
Es folgt das Kochrezept, an das man sich in jedem Fall halten kann.
(Doku zu den zwei Befehlen: h xixadd. Darin auch Hinweis auf einen
aufwendigeren FLEX umindex.flx, der sich empfiehlt, wenn besonders
viele Schlüssel zu ändern sind; darauf wurde auch in der Vb.202
schon kurz aufmerksam gemacht. Er löscht zunächst *alle* Schlüssel
eines Satzes nach Maßgabe der alten Parameter und speist dann alle
nach Vorschrift der neuen neu ein. Je nach Menge dauert das viel
länger. umindex.flx ist im Gesamtpaket mit drin.)
// Ergebnismenge der relevanten Sätze vorher bilden
first
:loop
// den alten, nicht mehr korrekten Schl. bilden
// und zwar mit Index-Präfix, z.B |7, ohne Spatium dahinter
var "|..." ...
ins #uzA
var i " " #uzA
ixdel
// den neuen, jetzt korrekten Schl. bilden
var "|..." ...
ins #uzN
var i " " #uzN
ixadd
:nxt
next
if yes jump loop
mes ERLEDIGT!
Statt var "..." ... ist natürlich jeweils ein geeigneter Algorithmus
für den betr. Schlüssel einzusetzen. Dazu sind evtl. mehrere Befehle
nötig. Insbes. kann man mit xcode ip oder xcode iq die Umcodierung
der Indexparameter mit heranziehen.
Auch umgekehrt, zuerst neu dann alt, ist es möglich. Oder wahlweise nur
den alten, nicht mehr benötigten Schlüssel löschen oder nur den neuen,
den es bisher noch nicht gab, erzeugen.
Ferner ist es natürlich auch möglich, statt nur eines Schlüssels gleich
mehrere zu löschen und/oder neu einzuspeisen; dann erweitert man eben
die Sache um entsprechende Abschnitte. Ratsam ist natürlich immer, es
erst mit einer kleinen Erg.Menge zu testen...
Aber was, wenn man auf keine Weise die Ergebnismenge aller betroffenen
Sätze bilden kann? Dann erweitert man die Schleife mit first # und
next # eben auf die Gesamtbank und startet es vor der Mittagspause.
Aber Achtung: Statt einfach nur next # muß es dann so lauten:
:nxt
next #
if deleted jump nxt
if not cancel jump loop
denn es könnte sich bei dem mit next # geladen Satz um einen
gelöschten handeln ("deleted"), so einer ist zu überspringen.
---------------------------------------------------------------------------------------------------