Makros

<< Click to Display Table of Contents >>

Navigation:  Arbeit mit GESStabs > Nützliche Werkzeuge >

Makros

Macros werden mit #MACRO definiert und können dann einzeln oder in Makroschleifen aufgerufen werden.

Zu Verwendung wiederkehrender Argumente können #EXPANDS in Makros aufgerufen werden.
Makros können auch verschachtelt werden: Macros in Macros.
Das expandierte Produkt eines Makros kann mit MACROPROTOCOLL eingesehen werden.


#Macro

Mit #MACRO und #ENDMACRO kann man Textmacros mit Parametern definieren. Definiert man z.B. das Macro #TEST

#MACRO #TEST ( &p1 &p2 &p3 )

SUM dummyvar = &p1 &p2 &p3 ;

IF ABS( dummyvar - 100.0 ) > 0.1

PRINT "Summe aus &p1 &p2 &p3 ergibt nicht 100%" &p1 &p2 &p3 ;

#ENDMACRO

kann man es anschließend beliebig oft aufrufen:

#TEST ( f1a f1b f1c )

#TEST ( f2a f2b f2c )

usw. Im ersten Aufruf wird dann 'f1a' anstelle des ersten im Makro definierten Parameters (&p1), 'f1b' anstelle des zweiten Parameter (&p2) und 'f1c' anstelle des dritten Parameters (&p3) eingesetzt.

Macros können bis zu 50 Parameter haben. Die Länge der formalen Parameternamen ist auf 10 Zeichen beschränkt. Die Namen von Parametern müssen mit dem &-Zeichen beginnen. Das Schlüsselwort #ENDMACRO ist bedeutungsgleich mit #MACROEND.

Die Ersetzung in einem Macro ist eine reine Textersetzung; die Zeichenfolgen, die den formalen Parameternamen entsprechen, werden also auch innerhalb von Strings oder als Bestandteil eines Tokens ersetzt. Also geht auch:

#MACRO #bimbam( &p1 )

COMPUTE &p1.recoded = &p1;

RECODE &p1.recoded 1:100=1/101:200=2/201:300=3;

#ENDMACRO

#bimbam( Betrag ) erzeugt dann eine Variable des Namens "Betrag.recoded".


Makroschleifen

Mit der Anweisung #DOMACRO kann man Makros in Schleifen aufrufen. Wenn man ein Macro mit nur einem Parameter hat, z.B. ein Makro #tab( &1 ), so kann man dies mit #DOMACRO mehrfach aufrufen.

Syntax:

#DOMACRO( <Macroname> <Schleifenliste> )

Beispiel:

#tab( 1 )

#tab( 2 )

#tab( 3 )

kann man als

#DOMACRO( tab 1:3 )

abkürzen.

#DOMACRO( tab 1:3 5 6 11:23 ) 

und so weiter ist auch möglich.

Das ist nicht auf numerische Verwendungen beschränkt, man kann auch beliebige Listenkonstrukte benutzen wie z.B.:

#DOMACRO( tab f1 f2 f3 f4,1 f4.2 f4.5 )

#DoMacro2

Syntax:

#DOMACRO2( <Macroname> <Schleifenliste> ; <weitere parameter> )

#DoMacro2 ist eine Erweiterung des #DOMACRO. Beispiel:

#DOMACRO2( macroname a b c 1 : 4 ; parm2 parm3 parm4 )

Hinter dem Semikolon dürfen (fast) beliebig viele weitere Parameter stehen, die als Parameter 2 und folgende an das aufgerufene Macro übergeben werden.

#DoMacro3

Syntax:

#DOMACRO3 ( <macroname> <filename> )

Wie #DOMACRO und #DOMACRO2 dient das #DOMACRO3-Statement der wiederholten Abarbeitung von Macros. Die Macro-Parameter werden hierbei aus einer CSV-Datei entnommen, die am einfachsten mit einem Tabellenverarbeitungsprogramm erzeugt werden kann. Dadurch bietet es eine Schnittstelle zu MitarbeiterInnen, die nicht im Scripting versiert sind.

Als erster Parameter wird der Macroname übergeben, als zweiter Paramater der Pfad einer CSV-Datei, die zeilenweise die Parameter enthält, die an das genannte Macro übergeben werden sollen. Jede Zeile der CSV-Datei generiert einen Macro-Aufruf. Die einzelnen Felder (durch ; getrennt) werden als die einzelnen Parameter interpretiert.

Ein einfaches Beispiel. Gegeben sei folgendes Macro:

#MACRO #table( &1 &2 )

 TABLE = &1 BY &2;

#ENDMACRO

und folgender Aufruf:

#DOMACRO3(table, macrocalls.csv )

Die CSV-Datei namens 'macrocalls.csv' enthält folgende Zeilen:

a11;a12;

a11;a13;

a11;a14;

a11;a15;

a11;a16;

a11;a17;

Hierdurch würden 6 verschiedene Tabellen erzeugt: a11 by a12, a11 by a13 und so weiter.

#DoMacro4

Syntax:

#DOMACRO4 ( <filename> )

Einen ähnlichen Hintergrund hat auch das #DOMACRO4-Statement. Der Unterschied ist, dass der Name des Macros nicht im Script festgelegt wird, sondern als erstes Feld in der CSV-Datei benannt wird.

Der Aufruf

#DOMACRO4( macrocalls4.csv )

bei folgendem Inhalt der Datei namens 'macrocalls4.csv'

table;a11;a12;

tablea;a11;a13;

tableb;a11;a14;

tablea;a11;a15;

tableb;a11;a16;

table;a11;a17;

würde die Existenz von drei Makros voraussetzen: #table, #tablea und #tableb.

Wenn geeignete Tabelliermacros vorliegen, können so auch MitarbeiterInnen, die mit dem Tabellieren nicht vertraut sind, in ihrer bekannten Umgebung (Excel), leicht eigene Tabellen definieren.


ExpandInDoMacro

Syntax:

EXPANDINDOMACRO = [ YES | NO ];

Wenn dieser Schalter auf YES steht, dann darf die Argumentliste von #DOMACRO und #DOMACRO2 ein #EXPAND sein, um die Verwendung von wiederkehrenden Argumenten zu vereinfachen.

Zulässig ist zum Beispiel:

ExpandInDomacro = yes;

#expand #range 1 23 5 7 22

##domacro( doit #range )

Der #EXPAND wird vor der Übergabe an die Macroschleife expandiert. Sollte dies Verhalten an einer Stelle nicht erwünscht sein, kann man es mit ExpandInDomacro = NO; wieder ausschalten.


Macro in Macro

Man kann ein Macro auch innerhalb eines Macros definieren. Innere Macros werden erst während der Expansion des äußeren Macros gebildet. Damit kann auch die Formulierung des Macros durch die Parameter des äußeren Macros modifiziert werden. Dieser Vorgang funktioniert rekursiv: auch im Inneren des inneren Macros können Macros definiert werden.

Das folgende Beispiel ist formal zulässig (erhebt keinen Anspruch darauf, etwas besonders Sinnvolles zu tun):

#macro #out( &o1 &o2 )

#macro #in( &i1 )

variable fz&i1 = &i1;

labels = 1 "&o2";

table = 1 by fz&i1;

#endmacro

#in( &o1 )

#endmacro

#domacro2( out 1:22 ; "label für 1" )

Im inneren Macro können sowohl die Parameter des inneren als auch die des äußeren Macros verwendet werden.


MacroProtokoll

Manchmal kann es bei komplexen Macros nicht ganz einfach sein, die Ursache eines Syntaxfehlers zu erkennen; man sieht ja im Quelltext nur die Macroanweisungen, aber nicht das expandierte Produkt. Deshalb gibt es die Möglichkeit, die expandierten Macros in eine Textdatei auszugeben. So sind sie einfacher überprüfbar. Siehe MacroProtokoll.