Workshops / Hintergrundberichte
|
1. ARexx-Kurs - Teil 5 (von Heiko Kuschel)
»ARexx-Kurs: Übersicht
1. Einführung in ARexx.
-
Wie funktionierts?
-
Was brauche ich?
-
Installation
-
ein erstes kleines Programm
-
Ein- und Ausgabe
-
do...end
2. Programmstruktur und Ansteuerung von anderen Programmen
-
if
-
do...end
-
address
-
Tracing
3. Ein- und Ausgabe; Funktionen
-
Ein- und Ausgabe
-
Stringfunktionen
-
mathematische Funktionen
-
Konvertierungsfunktionen
-
Bitmanipulation
4. komplexere Programmstrukturen
-
Operatoren
-
Procedure
-
Libraries
-
Systemfunktionen
5. Aufbau von Skripten
-
ein ARexx-Skript konzipieren
-
MUIRexx
-
Libraries
-
Beispiele für die Vernetzung von Programmen«
»
5. Beispiele für die Vernetzung von Programmen
5.0. Vorbemerkungen
Hier wiederhole ich für Quereinsteiger noch einmal einen Teil der
Vorbemerkungen, die ich zum ganzen Kurs gemacht habe.
Der Kurs wird als reine Text-Datei angefertigt, da auch Amiga Aktuell u.a.
in ASCII-Form verschickt wird. Um den Text etwas zu gliedern, habe ich
daher ein paar "Textmarker" eingefügt.
********** unterteilt einzelne Abschnitte
__________ bezeichnet Beginn und Ende eines ARexx-Programms. Die Striche
gehören nicht zum Programm!
(In der HTML-Version benutzen wir natürlich "schickere" Kennzeichnungen)
ARexx-Befehle werden in diesem Kurs immer GROSS geschrieben, obwohl das
eigentlich nicht nötig ist. Auf diese Weise kann man sie aber leichter
erkennen.
Ich hoffe, daß diese Regelung den Kurs etwas leserlicher macht.
Wenn ihr spezielle Fragen habt, etwas nicht verstanden habt oder Anregungen
und Ideen für weitere Kursteile habt, könnt ihr euch gerne an mich wenden.
Ich selbst benutze folgende ARexx-fähige Programme und kann daher auf deren
Programmierung kurz eingehen, wenn das gewünscht wird:
Wordworth, GoldEd, Database Professional, YAM, Miami, Voyager, TurboCalc.
Hier meine Kontaktadresse:
Heiko Kuschel
Lehmgrubenweg 13
97280 Remlingen
E-Mail: hk0006@wuerzburg.baynet.de
Und jetzt... viel Spaß mit ARexx!
5.1. Ein ARexx-Skript konzipieren
Mittlerweile haben wir so ziemlich alle ARexx-Befehle durchgemacht, die es
gibt. Aber - wie mache ich daraus nun ein sinnvolles ARexx-Skript? Bei
vielen Vorhaben ist das gar nicht so einfach, denn manche Programme, die
über ARexx anzusteuern sind, haben so ihre Eigenheiten. Ein paar
Grundprobleme möchte ich in diesem Kursteil ansprechen und dann noch
Skripte vorstellen, die ich selber für den "Hausgebrauch" geschrieben habe.
5.1.1. Wie finde ich die Adresse?
Fast alle ARexx-fähigen Programme bieten die Möglichkeit, ARexx-Skripte
über Menü oder sonstwie direkt aus dem Programm heraus zu starten. Dann ist
der Port des startenden Programms als ARexx-Port voreingestellt, an den die
Befehle geschickt werden sollen. Das sieht dann so aus:
OPTIONS RESULTS
PortName = ADDRESS()
|
Wenn später ein anderes Programm angesteuert wird und dadurch der Port mit
ADRRESS xxx verändert wird, kannst Du anschließend wieder auf das Programm
zurückkommen, das das Skript gestartet hat. Und zwar ganz einfach mit
ADDRESS VALUE PortName
PortName ist hier die Variable, in der der Portname des Programms abgelegt
wird, das das Skript gestartet hat. Z.B. Wordworth.1 oder YAM etc.
5.1.2. Eigenheiten der einzelnen Programme
Manche Programme haben nicht nur einen einzigen ARexx-Port. Stattdessen
öffnen sie für jedes Fenster einen eigenen, z.B. Wordworth und, soweit ich
weiß, auch Final Writer. Die werden dann durchnumeriert: Wordworth.1,
Wordworth.2 usw.
Dadurch kann man sich nie sicher sein, daß ein bestimmter Port tatsächlich
existiert! Es kann ja sein, daß das Fenster (und damit der Port), dem
Wordworth.1 zugeordnet wurde, geschlossen wurde. Vielleicht existieren
gerade nur Wordworth.3 und Wordworth.5. Wenn ich Wordworth also von außen
ansteuern will, ohne daß das Skript aus Wordworth heraus gestartet wurde,
ist es ziemlich schwierig, einen richtigen Port zu finden. Ich behelfe mir
immer mit der folgenden kleinen Schleife:
options results
DO Num = 1 to 20
WwPort = "WORDWORTH." || Num
IF SHOW(PORTS, WwPort) THEN DO
Address Value WwPort
leave Num
end
end
if num=21 then do
echo "Wordworth nicht gefunden! Programm endet."
quit
end
|
Übrigens gibt es auch andere Programme, die eine Zahl hintendran hängen,
bei der diese Zahl aber etwas anderes bedeutet. Der normale ARexx-Port von
GoldEd heißt z.B. GOLDED.1 Hier gibt es nur ein GOLDED.2, wenn GoldEd
tatsächlich nochmal neu gestartet wird. Alle Fenster mit unterschiedlichen
Texten innerhalb von GoldEd haben dagegen diesen einen ARexx-Port GOLDED.1.
Bei GoldEd gibt es noch eine weitere Besonderheit: Der Text muß für den
normalen Zugriff gesperrt werden. Dabei muß seit Version 4 von GoldEd auch
noch angegeben werden, für welche Version dieses Skript geschrieben wurde.
Sinnvoll, da sich der ARexx-Wortschatz von GoldEd beim Sprung von Version 3
auf 4 ziemlich geändert hat. Einzelheiten dazu stehen in der Online-Hilfe
zu GoldEd.
Ein Wort noch zu allgemeinen Problemen mit der Ausführung von Programmen:
Gerade bei Database Professional (DBPro) habe ich festgestellt, daß es oft
genau auf die Schreibweise (groß/klein etc.) ankommt. Oft ist es auch
nötig, daß Argumente in Anführungszeichen gesetzt werden. Beachte dabei
folgendes: Aus
FINDBASE "Adressen.db"
wird für Database:
FINDBASE Adressen.db
Du mußt stattdessen das Ganze nochmal in Anführungszeichen setzen, da immer
die äußersten durch ARexx entfernt werden:
'FINDBASE "Addressen.db"'
Alternativ müßte eigentlich auch gehen:
FINDBASE '"Addressen.db"'
An Database wird dann dieser Text übermittelt:
FINDBASE "Adressen.db"
Kapiert? Ich hoffe es. Das Kapitel mit den Anführungszeichen ist eines der
kompliziertesten in der ganzen ARexx-Programmiererei.
Übrigens: Mir ist es auch schon passiert, daß ich einen Befehl genau so
eingegeben habe, wie er im Handbuch steht, und es hat trotzdem nicht
funktioniert. Das war bei Beckertext III.
5.2. MUIRexx
5.2.1. Kurzeinführung
MUIRexx ist ein ausgesprochen gutes Hilfsmittel, um komplizierteste
Bedienoberflächen zu erstellen. Es ist gewissermaßen die Schnittstelle
zwischen ARexx und dem "Magic User Interface", kurz: MUI, mit dem
inzwischen viele Programme programmiert sind (z.B. YAM, Voyager, STFax,...)
MUIRexx ist anders als andere Libraries: Es ist ein eigenes Programm, das
über ARexx gesteuert wird und, je nach den Befehlen, die es erhält, ein
Fenster mit Schaltflächen, Listern, Texten oder was auch immer aufbaut. Es
ist im Aminet erhältlich unter dev/mui und kostet eine Shareware-Gebühr von
15 US-Dollar.
Nun wird das aber nicht einfach über ADDRESS MUIREXX gemacht, sondern jedes
erstellte Fenster bekommt einen eigenen ARexx-Port. Am einfachsten schaffst
Du das, indem Du mit MUIRexxBuild ein neues Fenster erstellst und dem einen
Namen gibst. Ich habe auf diese Weise ein Fenster mit dem Namen "Listen"
erstellt, das wird dann über ADDRESS Listen angesteuert.
Das Ganze funktioniert so ähnlich wie eine DO... END-Schleife: Erst wird
ein Fenster definiert, und darin einzelne Gruppen:
WINDOW
GROUP
GROUP
...
ENDGROUP
ENDGROUP
GROUP
....
ENDGROUP
ENDWINDOW
Das wäre eine typische Grundstruktur für eine Fensterdefinition. Die ganzen
Dinge mit diversen Variablen usw. kannst Du dabei weitgehend MUIRexxBuild
überlassen, das übrigens selbst eine MUIRexx-Anwendung ist!
5.2.2. Ein Beispiel
Bis jetzt habe ich es immerhin geschafft, ein Fenster aufzubauen, das
verschiedene Gruppen enthält. Nur das dazugehörige Programm fehlt noch, das
die damit verbundenen Aktionen auch ausführt... Da es hier aber um die
Arbeit mit MUIRexx geht, möchte ich das Ganze trotzdem einmal kurz
vorstellen. Weitere Beispiele finden sich ja auch im MUIRexx-Ordner.
Mein kleines Skript soll mir eigentlich die Verwaltung von Mailinglisten
vereinfachen. Das sind so eine Art EMail-Rundschreiben-Gruppen. Ich schicke
eine Mail an eine bestimmte Adresse, und diese Mail wird an alle verteilt,
die sich in der Mailingliste eingetragen haben.
Um in so eine Liste zu kommen, muß man an eine jeweils unterschiedliche
Adresse eine Mail schicken, etwa "subscribe PAmiga-list meine-Email-
Adresse". Ähnlich mit unsubscribe, wenn man wieder rauswill. Und daneben
gibt es noch manche Mailinglisten, bei denen man sich auch kurzzeitig
ausklinken kann, ohne sich vollständig zu verabschieden, indem man die
Optionen auf NOMAIL setzt, das heißt, ich kriege im Moment keine Mail. Für
jede Mailingliste existiert also:
-
eine Adresse, an die alle Befehle geschickt werden müssen
-
ein Befehl, um sich einzuschreiben
-
ein Befehl, um sich wieder auszuschreiben
-
evtl. ein Befehl, um die Listenoptionen auf NOMAIL zu setzen
-
evtl. ein Befehl, um NOMAIL wieder rückgängig zu machen.
Da ich immer wieder mal wechsle, dachte ich mir, es wäre sinnvoll, das über
ein Programm zu machen. Dabei wollte ich zunächst aus einer großen Liste
(wer die haben will, kann mich anmailen) ein paar Standard-Mailinglisten
auswählen können, die dann wiederum einzeln an- und abgeschaltet werden
können.
Das dazugehörige Fenster stelle ich mir so vor, daß ich eine Liste der
aktuellen (sprich: von mir vorausgewählten) Mailinglisten habe und über
"Prefs" weitere dazunehmen kann oder welche herausnehmen kann. In einer
Zeile untendrunter soll, sofern vorhanden, eine kurze Beschreibung der
Mailingliste stehen, die ich gerade angeklickt habe.
... und so sieht mein Programm dazu aus:
(da einige Programmzeilen sehr lang sind, habe ich die längeren unter ihnen
mit zwei Kommentarzeilen eingerahmt. Für viele von Euch ist sonst
vermutlich nicht zu erkennen, wo eine Programmzeile unterbrochen ist.
/*Das Folgende ist eine Zeile*/
hier dazwischen steht eine lange Programmzeile
/*bis hier*/
Das folgende Programm wird aus einer Shell heraus wie folgt gestartet:
muirexx:muirexx Listen.rexx PORT Listen
Listen.rexx ist dabei der Name des Skripts.
/* Application created by MUIBuild */
address Listen
MUIA_Listview_DragType = 0x80425cd3
MUIA_List_DragSortable = 0x80426099
MUIV_Listview_DragType_Immediate = 1
TRUE = 1
MUIA_Listview_MultiSelect = 0x80427e08
MUIA_Dropable = 0x8042fbce
MUIV_Listview_MultiSelect_Default = 1
MUIA_List_Quiet = 0x8042d8c7
MUIV_List_Insert_Sorted = -2
line = '%s';
/*Diese Variablen wurden von MUIRexxBuild selbstständig eingefügt*/
window COMMAND """quit""" PORT Listen TITLE """Mailinglisten-Verwaltung"""
group HORIZ REGISTER LABELS "Aktuelle,Prefs"
group ID Aktuell
group HORIZ
group FRAME
text LABEL "Liste der aktuellen Mailinglisten"
list ID List1
endgroup
group FRAME
text LABEL "Status"
space
radio LABELS "On,Off,Nomail"
space
endgroup
endgroup
view ID Help1 STRING "Hilfetext"
endgroup
group ID Prefs
group HORIZ
group FRAME
/*Das Folgende ist eine Zeile*/
text LABEL "Liste der bekannten Mailinglisten" list ID List2 ATTRS
MUIA_Listview_DragType MUIV_Listview_DragType_Immediate
MUIA_List_DragSortable TRUE
/*bis hier*/
endgroup
group FRAME
/*Das Folgende ist eine Zeile*/
text LABEL "Aktuelle Liste" list ID List3 ATTRS MUIA_Listview_DragType
MUIV_Listview_DragType_Immediate MUIA_List_DragSortable TRUE MUIA_Dropable
TRUE
/*bis hier*/
endgroup
endgroup
view ID Help2 STRING "Hilfetext2"
endgroup
endgroup
endwindow
/* bis hierher sollte es ziemlich verständlich sein. */
callhook ID List2 PORT INLINE INCLUDE List3 DROP,
COMMAND """options results;
address Listen;
line='%s';
/*Das Folgende ist eine Zeile*/
'list ID "List2" INSERT POS "MUIV_List_Insert_Sorted"
STRING' line;
/*bis hier*/
'list ID "List3" REMOVE STRING' line;
'list ID "List1" REMOVE STRING' line;"""
callhook ID List3 PORT INLINE INCLUDE List2 DROP,
COMMAND """options results;
address Listen;
line='%s';
/*Das Folgende ist eine Zeile*/
'list ID "List3" INSERT POS "MUIV_List_Insert_Sorted"
STRING' line;
/*bis hier*/
/*Das Folgende ist eine Zeile*/
'list ID "List1" INSERT POS "MUIV_List_Insert_Sorted"
STRING' line;
/*bis hier*/
'list ID "List2" REMOVE STRING' line;"""
callhook ID List1 INCLUDE List1
list ID List1 INSERT STRING "YAM"
list ID List1 INSERT STRING "PAmiga"
list ID List1 INSERT STRING "I-Amiga"
list ID List1 INSERT STRING "TeamAmiga"
list ID List1 INSERT STRING "STFax"
list ID List3 INSERT STRING "YAM"
list ID List3 INSERT STRING "PAmiga"
list ID List3 INSERT STRING "I-Amiga"
list ID List3 INSERT STRING "TeamAmiga"
list ID List2 INSERT STRING "CU-Amiga"
list ID List2 INSERT STRING "Voyager"
list ID List3 INSERT STRING "STFax"
|
Ich hoffe, daß der Aufbau des Fensters auch beim Lesen des Quelltextes
halbwegs verständlich wird. "REGISTER" sind die Karteikartenreiter am
oberen Ende des Fensters. Wenn ich eine Gruppe später nocheinmal
weiterverwenden muß, kann ich ihr mit ID einen Namen zuweisen, also z.B.
GROUP ID ErsteGruppe.
Schwieriger wird schon die Sache mit Callhook. Hier werden Ereignisse
definiert, nach denen irgendeine Aktion stattfinden soll. Also: Wenn ich in
"Prefs" einen Listennamen aus dem einen Lister in den anderen ziehe, muß
dieser Name natürlich im alten Lister verschwinden und im neuen auftauchen.
Da Computer, selbst Amigas, leider nicht intelligent genug sind, muß ich
ihm das extra sagen. Das sieht dann so aus:
callhook ID List2 PORT INLINE INCLUDE List3 DROP,
COMMAND """options results;
address Listen;
line='%s';
/*Das Folgende ist eine Zeile*/
'list ID "List2" INSERT POS "MUIV_List_Insert_Sorted"
STRING' line;
/*bis hier*/
'list ID "List3" REMOVE STRING' line;
'list ID "List1" REMOVE STRING' line;"""
|
Das heißt: Wenn in List2 etwas fallengelassen wird, und zwar aus List3,
dann starte ein ARexx-Skript, das den MUIRexx-Task Listen addressiert. In
List2 wird der Name der Mailingliste eingefügt (mit %s), in List3 entfernt
und ebenso in List1. (Das ist die erste, die man sieht, auf der Seite
"Aktuelle".)
Um das Programm zu vervollständigen, fehlen jetzt also nur noch weitere
solche Callhooks, die dann erst einmal den jeweils zur Liste gehörigen
Hilfetext anzeigen, auf der Seite "Aktuelle" den richtigen Radioknopf für
die jeweils angeklickte Liste aktivieren (also ob sie an, aus oder auf
NOMAIL gesetzt ist) - und außerdem noch eine Reihe von Knöpfen, um die
entsprechenden Befehls-mails loszuschicken, abzubrechen oder eine Übersicht
über den aktuellen Stand der Dinge auszugeben. Vielleicht hast Du ja Lust,
so etwas zu machen... :)
Anbei mein einfaches Programm, das vier verschiedene Mailinglisten
bestellt. So habe ich das bisher gehandhabt:
/* YAM und I-Amiga werden auf MAIL gesetzt, Pamiga und Team Amiga
bestellt*/
/* $VER: 1.0. 23.2.98 */
options results
if ~show("P",YAM) then address command "run Yam:Yam"
address command
'echo >t:Yamtext "SET YAM MAIL"'
'echo >t:Iamigatext "SET I-AMIGA MAIL"'
'echo >t:PAmigatext "SUBSCRIBE PAMIGA-LIST hk0006@wuerzburg.baynet.de"'
'echo >t:TAmigatext "SUBSCRIBE TeamAmiga hk0006@wuerzburg.baynet.de"'
"sys:rexxc/Waitforport YAM"
address YAM
mailwrite
writemailto "Listserv@tu-clausthal.de"
"writeletter t:Yamtext"
writequeue
mailwrite
writemailto "Majordomo@lists.netlink.co.uk"
"writeletter t:PAMIGATEXT"
writequeue
mailwrite
writemailto "listserv@listserv.acsu.buffalo.edu"
"writeletter t:Iamigatext"
writequeue
mailwrite
writemailto "majordomo@thule.no"
"writeletter t:TAMIGATEXT"
writequeue
address command
"delete >NIL: t:yamtext"
"delete >NIL: t:?amigatext"
|
Ich denke, dieses Skript solltest Du inzwischen mit Leichtigkeit verstehen.
5.3. andere Libraries
5.3.1. rexxreqtools.library
Die rexxreqtools.library findet sich, soweit ich weiß, im Aminet.
Sie enthält die Funktionen der reqtools.library, also alle Arten von
Requestern. Auch dafür gibt es im Lieferumfang schon ein paar Demos, mit
denen man ganz gut weiterarbeiten kann. Ich möchte nur eben vorstellen, wie
ich ein Skript beginne, das zuerst nachsieht, ob Wordworth läuft und dann
den Requester von Wordworth verwendet, ansonsten aber Rexxreqtools:
options results
DO Num = 1 to 20
WwPort = "WORDWORTH." || Num
IF SHOW(PORTS, WwPort) THEN DO
Address Value WwPort
leave Num
end
end
if num=21 then do
if ~show("L",rexxreqtools.library) then do
call addlib("rexxreqtools.library", 0, -30, 0)
end
gadtxt= "_Holen|E_nde|_To-Do-Liste|_Cancel"
Anf = upper(rtgetstring(" ","Bitte Textstelle eingeben:","Text
3.0.",gadtxt))
buttonresult=rtresult
end
else do
do i=0 to 5
viewwindow i
end /* wenn Makro nicht von WW aus aufgerufen wird, ist sonst die
Workbench vorne*/
/* keine Ahnung, wie man herausfinden kann, welches Fenster
existiert.*/
/*Das Folgende ist eine Zeile*/
WizardReq TITLE "Text 3.0." LABEL "Bitte Textstelle eingeben:" TEXTBOX 1
"_Stelle:" BUTTON 1 "_Holen" BUTTON 2 "E_nde" BUTTON 3 "_To-Do-Liste"
BUTTON "-1" "_Cancel"
/*bis hier*/
buttonresult = RESULT
Wizard_GetTextBox 1
Anf = UPPER(RESULT)
end
select
when buttonresult = 2 then do
when buttonresult = -1 then do
etc.
end
|
Hier hast Du nun also zwei verschieden definierte Requester drin: Einen mit
einem Wordworth-Befehl (WizardReq) und einen mit der Rexxreqtools.library
(rtgetstring).
Gleichzeitig natürlich auch die verschiedenen Möglichkeiten, das Ergebnis
des Requesters abzufragen: Bei reqtools wird der eingegebene Text sofort
als Variable übergeben. Welcher Knopf gedrückt wurde, kann über die
Variable rtresult abgefragt werden. Bei Wordworth steht die Nummer des
Knopfs in RESULT, und der eingegebene Text ebenfalls, nachdem der Befehl
Wizard_GetTextBox eingegeben wurde. Dabei die Nummer der Textbox nicht
vergessen! (hier 1) Es sind nämlich mehrere Textboxen in ein und demselben
Requester möglich.
Der "Abbruch"-Knopf hat die Nummer "-1" erhalten, da RESULT ebenfalls -1
enthält, wenn das Schließgadget in der linken oberen Ecke betätigt wird. So
haben wir zwei Fliegen mit einer Klappe geschlagen.
5.3.2. rexxtricks.library
Die Rexxtricks.library enthält eine Menge nützlicher Funktionen aus den
folgenden Bereichen:
AmigaDOS-Funktionen
SCSI-Funktionen
Clipboard-Funktionen
Listen-Funktionen
Publicscreen-Funktionen
Icon-Funktionen
Sonstige Funktionen
Diese im einzelnen zu erläutern, würde hier zu weit führen. Aber ich wollte
einmal auf diese Library aufmerksam machen, denn sie kann oft wirklich
nützlich sein. Lies mal die Anleitung, sie ist ziemlich gut!
5.4. Beispiele für die Vernetzung von Programmen
5.4.1. Beckertext und Wordworth
Das Schöne an ARexx ist ja gerade, daß es auch möglich ist, mehrere
Programme miteinander zu verknüpfen. Ein kleines Beispiel hatten wir
bereits in einem früheren Kursteil: Ein Skript, das Miami und YAM startet,
online geht, Post sendet und abholt und wieder offline geht. Das war
natürlich relativ simpel.
Beim folgenden Skript kommt immerhin dazu, daß ein bestimmter Text
irgendwie zwischen zwei Anwendungen ausgetauscht werden soll. Ich habe es
geschrieben, weil ich früher viel mit Beckertext gearbeitet habe, jetzt
inzwischen aber Wordworth verwende. Da BT und WW leider kein gemeinsames
Clipboard verwenden, Wordworth außerdem keinen "Dazuladen"-Befehl kennt,
war es gar nicht so einfach, das zu realisieren. Eigentlich tut dieses
Skript nichts anderes, als einen bereits markierten Text aus Beckertext in
das aktuelle Wordworth-Dokument an der aktuellen Stelle einzufügen. Und so
sieht das Ganze aus:
/* BT-Text (markierten Block) in WW5 einsetzen - MJ+HK 17.6.96 */
OPTIONS RESULTS
WwPortName = Address()
GetFont
OldFont = Result
GetFontSize
OldFontSize = Result
Address ('bt3')
kopiere
neudok
einsetzen
'asichern "T:BT"'
schliesse
Address Value WwPortName
New
Address Value Result
Open FILENAME "T:BT"
SelectAll
Font NAME OldFont SIZE OldFontSize
Copy
Close FORCE
Address Value WwPortName
Paste
Address Command delete "T:BT"
|
Also: Das Skript wird aus Wordworth aufgerufen, sonst ist es nicht möglich,
das aktuelle Fenster in Wordworth zu bestimmen.
Dann wird festgestellt, welche Schriftart an der aktuellen Stelle
eingestellt ist, damit auch der neue Text gleich in dieser Schriftart
erscheint.
Anschließend setze ich den aktuellen Port auf Beckertext. Warum da die
Klammern nötig sind, weiß ich wirklich nicht. So stehts im Handbuch, und
nur so funktioniert's auch.
Mit Beckertext ist es nicht möglich, einen Block einzeln abzuspeichern.
Also: Neues Dokument öffnen, Block hineinkopieren, Dokument als reinen Text
abspeichern. Und jetzt das gleiche rückwärts für Wordworth: Neues Dokument
öffnen, mit der richtigen Schrift formatieren, ins "richtige" Dokument
kopieren, fertig.
5.4.2. Typisch Multitasking...
Als nächstes möchte ich euch noch ein Skript vorstellen, an dem eine Menge
Programme beteiligt sind: Wordworth, GoldEd, Database Pro, YAM. Dieses
Skript habe ich geschrieben, um die Texte, die ich schreibe, archivieren,
ausdrucken, im Großdruck für meinen Opa ausdrucken, an Freunde in
verschiedenen Dateiformaten mailen zu können. Und das alles in einem
Aufwasch. :)
Selbst wenn Du einige der Programme nicht selbst hast, hoffe ich, daß Du
den einen oder anderen Kniff brauchen kannst. Schau's Dir mal an.
/* $VER: 1.1. 19.8.97 - 23.1.98*/
options results
Wordworthport=Address()
/*Das Folgende ist eine Zeile*/
wizardreq title "Ansprache versenden" label "Bitte Nummer der Ansprache
eingeben." textbox 1 "_Nummer:" textbox 2 "In _DB übernehmen (J/N):"
textbox 3 "_Großdruck erstellen (J/N):" textbox 4 "_Mail verschicken (J/N)"
textbox 5 "Anzahl N_ormaldrucke:" Button 1 "_Ok" Button "-1" "_Abbruch"
/*bis hier*/
if result = "-1" then do
exit
end
Wizard_Gettextbox (1)
Nummer=Right(Result,3,"0")
Wizard_Gettextbox (2)
DB=Result
Wizard_Gettextbox (3)
Grossdruck=Result
Wizard_Gettextbox (4)
Mail=Result
Wizard_Gettextbox (5)
Normaldruck=Result
/* bis hierher wird überprüft, welche der Aktionen tatsächlich durchgeführt
werden sollen. */
/*Meine Ansprachen sind durchnumeriert, und zwar nach dem Schema
002.Beschreibung */
if Normaldruck="J" then Normaldruck=1
if Normaldruck>0 then do
SAVEAS NAME "Text:Wordworth7/Dokumente/Ansprachen/000.TEMP"
end
/*Wenn ein Ausdruck in der "Normalform" gewünscht ist, muß die Datei
zwischengespeichert werden.*/
/*Den tatsächlichen Namen des Textes kann man mit Wordworth leider nicht
herausfinden.*/
if DB="J" then do
if ~show("P",DataBase) then address command "run Text:DBProV3.1/db"
end
if Mail="J" then do
'SAVEAS RTF Name T:Ansprache.rtf'
'SAVEAS WORDPERFECT Name T:Ansprache.wpf'
if ~show("P",YAM) then address command "run Yam:Yam"
end
/*Hier werden die jeweils benötigten Programme gestartet:*/
/*DBPRo, falls eine Aufnahme in die Datei gewünscht ist,*/
/*und YAM, falls die Ansprachen per EMail verschickt werden sollen.*/
address command
if ~Exists("Text:Wordworth7/Dokumente/Ansprachen/"||Nummer||".kurz")
then do
/*Das Folgende ist eine Zeile*/
"echo > Text:Wordworth7/Dokumente/Ansprachen/"||Nummer||".kurz"
'"Ansprache Nr. '||Nummer||'"'
/*bis hier*/
"echo >> Text:Wordworth7/Dokumente/Ansprachen/"||Nummer||".kurz" '"Text:
"'
"echo >> Text:Wordworth7/Dokumente/Ansprachen/"||Nummer||".kurz"
'"Datum: "'
"echo >> Text:Wordworth7/Dokumente/Ansprachen/"||Nummer||".kurz" '"Ort:
"'
"echo >> Text:Wordworth7/Dokumente/Ansprachen/"||Nummer||".kurz"
'"Stichworte: "'
"echo >> Text:Wordworth7/Dokumente/Ansprachen/"||Nummer||".kurz"
'"Beschreibung: "'
end
/*Hier gebe ich mir selbst ein kleines Formular für eine Kurzbeschreibung
vor.*/
/*Der doppelte Pfeil nach echo bewirkt, daß der Text an die bestehende
Datei*/
/*angehängt wird.*/
/*Ein Teil davon wird in der Datenbank weiterverwendet, die ganze Datei
auf*/
/*jeden Fall mit der entsprechenden Nummer und dem Anhängsel .kurz
abgespeichert.*/
"ged Text:Wordworth7/Dokumente/Ansprachen/"||Nummer||".kurz sticky"
/*GoldEd wird gestartet, damit ich meine Kurzbeschreibung bearbeiten
kann.*/
/*Die Option sticky bewirkt, daß das Skript erst dann weiterläuft, wenn
ich*/
/*GoldEd wieder beendet habe.*/
if Mail="J" then do
if ~show("P",GOLDED.1) then address command ged
"sys:rexxc/Waitforport GOLDED.1"
address GOLDED.1
Lock current release 4
'open t:Ansprache.rtf'
replace string "ä" by "'8a" all quiet
replace string "ö" by "'9a" all quiet
replace string "ü" by "'9f" all quiet
replace string "ß" by "'a7" all quiet
unlock
'save all nolf exit'
/* Was soll das nur schon wieder sein? Hier ersetze ich alle ä,ö,ü,ß*/
/* durch die entsprechenden Codierungen, wie sie im RTF-Format eigentlich*/
/* verwendet werden - nur Wordworth macht das leider nicht. Zumindest*/
/* WW6 nicht - ich habe WW7 darauf noch nicht überprüft.*/
address command
'echo >t:Ansprachemailtext "Hallo!"'
'echo >>t:Ansprachemailtext "Anbei eine Ansprache von mir."'
'echo >>t:Ansprachemailtext "Viele Grüße"'
'echo >>t:Ansprachemailtext'
'echo >>t:Ansprachemailtext "Heiko"'
'echo >>t:Ansprachemailtext "Hier die Kurzfassung:"'
/*Das Folgende ist eine Zeile*/
'join t:Ansprachemailtext
Text:Wordworth7/Dokumente/Ansprachen/'||Nummer||'.kurz to
t:Ansprachemailtext2'
/*bis hier*/
"sys:rexxc/Waitforport YAM"
address YAM
mailwrite
/* writemailto "Tscho"
"writesubject Ansprache_von_Heiko"
"writeletter t:Ansprachemailtext2"
writequeue
mailwrite*/
writemailto "ThoVo"
"writesubject Ansprache_von_Heiko"
"writeletter t:Ansprachemailtext2"
"writeattach t:Ansprache.rtf"
writequeue
mailwrite
writemailto "Reinhard"
"writesubject Ansprache_von_Heiko"
"writeletter t:Ansprachemailtext2"
"writeattach t:Ansprache.wpf"
writequeue
end
/*OK, jetzt werden die Dateien verschickt. Einmal nur die
Kurzbeschreibung,*/
/*einmal als RTF-Datei, einmal als WordPerfect-Datei.*/
if DB="J" then do
address DataBase
GETFILENAME
if Result=0 then do
SAVE
end
'OPEN Text:DBProV3.1/Aufsätze/Aufsätze.db'
'DEMARKRANGE $F1 "#?"'
'SHOW ALL'
'SETSEARCH FIELD PART'
'SEARCHFIELD $F1'
'SEARCH eig. Anspr.'
'SEARCHFIELD $F2'
'SETSEARCH GREATER'
'SEARCHNEXT ' Nummer
if RC=0 then do
GETDATA $F1
IF RESULT="EIG. Anspr." THEN DO
SCHONDA=1
END
END
/* Hier wird in DBPro erstmal überprüft, ob nicht schon ein Eintrag für*/
/* diese Ansprache vorhanden ist. Ein neuer wird nur gemacht, wenn diese*/
/* Nummer nicht gefunden wurde. (SCHONDA=0)*/
IF SCHONDA ~=1 THEN DO
'ADD'
'PUTDATA $F1 eig. Anspr.'
'PUTDATA $F2' NUMMER
'PUTDATA $F3 Kuschel, H.'
/*Das Folgende ist eine Zeile*/
Erfolg=OPEN("Kurzdatei","Text:Wordworth7/Dokumente/Ansprachen/"||Nummer||".
kurz","R")
/*bis hier*/
If Erfolg then do
Do while ~EOF("Kurzdatei")
Zeile=Readln("Kurzdatei")
Select
when abbrev(Zeile,"Text")=1 then do
'PUTDATA $F4 'substr(Zeile,7)
end
when abbrev(Zeile,"Datum")=1 then do
DatumOrt=substr(Zeile,8)
end
when abbrev(Zeile,"Ort")=1 then do
DatumOrt=DatumOrt||", "||substr(Zeile,6)
'PUTDATA $F7 'DatumOrt
end
when abbrev(Zeile,"Stichworte")=1 then do
'PUTDATA $F12 'substr(Zeile,13)
end
Otherwise do
NOP
end
end
end
end
/* Jetzt werden die Daten in die einzelnen Felder meiner Datei
geschrieben:*/
/* $F1 ist der Oberbegriff, $F2 die Nummer, $F3 der Autor. Alles andere*/
/* lese ich aus der Kurzdatei, die ich vorhin angelegt habe. Das wird
dann*/
/* automatisch an die richtige Stelle geschrieben.*/
'SORT $F1 $F2'
'SAVE'
end
end
/*Sortieren, speichern, Ende.*/
if Grossdruck = "J" then do
address value Wordworthport
SAVEAS NAME "Text:Wordworth7/Dokumente/Ansprachen/000.GROSSDRUCK"
DOCUMENT A4 "2cm" "2cm" "1.67cm" "2.54cm" 1 "2cm" LANDSCAPEOFF
CTRLDOWN
CURSOR UP
SHIFTDOWN
CURSOR DOWN
FONT SIZE "24pt"
PARAGRAPH 0 0 0 FULL AUTO ONEHALF
PRINTOPTIONS REVERSE BLACKANDWHITE ODDANDEVENPAGES
SAVE
PRINT
end
/*Großdruck, falls gewünscht. Das Dokumentformat muß geändert werden,*/
/*weil ich normalerweise DinA4 quer zweispaltig bevorzuge.*/
/*Durch den ganzen Sermon mit CTRLDOWN etc. wird der gesamte Text*/
/*markiert. Dann stelle ich die Schriftgröße 24pt. ein, ein geeignetes*/
/*Absatzformat, und ab in den Drucker damit. */
If Normaldruck>0 then do
address value Wordworthport
OPEN FILENAME "Text:Wordworth7/Dokumente/Ansprachen/000.TEMP" FORCE
PRINTOPTIONS REVERSE BLACKANDWHITE COLLATE COPIES NORMALDRUCK
ODDANDEVENPAGES
PRINT
end
/*Die "normale" Druckvariante kommt nach dem Großdruck, weil sie viel
länger*/
/*dauert. Querformat ist ziemlich langsam mit Wordworth. :( */
/*Beachte bei PRINTOPTIONS, daß eine initialisierte Variable drin ist!*/
/*An einer Stelle steht NORMALDRUCK. In dieser Variable ist gespeichert,*/
/*wie viele Ausdrucke ich davon haben will.*/
address command
If Mail="J" then do
"delete >NIL: t:Ansprache.rtf"
"delete >NIL: t:Ansprachemailtex#?"
"delete >NIL: t:Ansprache.wpf"
If Normaldruck>0 then do
"delete >NIL: Text:Wordworth7/Dokumente/Ansprachen/000.TEMP"
END
/*Ein bißchen aufräumen muß sein. :) */
|
So, das war ein ziemlich langes Programm. Viele weitere Programme, oft auch
kommentierte, findest Du im Aminet, im Verzeichnis util/rexx. Schau Dich
ruhig einmal um. Evtl. findest Du dort auch schon das, was Du gerade
schreiben wolltest... oder auf jeden Fall gute Anregungen fürs eigene
Programmieren.
5.5. Das Ende
Das war der ARexx-Kurs. Geschafft. Ich hoffe, Du hattest Spaß daran, und
ich konnte das meiste halbwegs verständlich erklären. Wenn Du Probleme
haben solltest, wende Dich an meine Adresse.
Ich möchte demnächst den ganzen Kurs ins AmigaGuide-Format umwandeln und
dann im Aminet veröffentlichen. Er wird voraussichtlich veröffentlicht
unter docs/help/ARexx-Kurs.lha Da ich dabei ein paar AGuide-Kniffe einbauen
will, bräuchte ich jemanden, der/die diesen Guide unter AmigaOS 2.x testet.
Ich weiß nämlich nicht, wie es da funktioniert. Außerdem suche ich Leute,
die mir ein paar Kurzinformationen zu anderen Texteditoren als GoldEd geben
können, damit ich auch diese Editoren berücksichtigen kann.
Solltest Du Dich hier irgendwo angesprochen fühlen, melde Dich doch bitte
mal bei mir. Danke!
Heiko«