Lokale und globale Makrovariablen

Aus SAS-Wiki
Wechseln zu: Navigation, Suche

Einleitung

Das SAS-System unterscheidet zwischen

  • globalen und
  • lokalen Makrovariablen.

Die globalen Makrovariablen gelten während der gesamten SAS-Sitzung und können an beliebiger Stelle verwendet werden, sobald sie definiert wurden. Globale Variablen sind z.B. die unter SAS-Makrovariablen beschriebenen automatischen Makrovariablen wie &Sysdate oder &Systime.

Im Unterschied dazu gelten die lokalen Makrovariablen nur in der Umgebung, die während eines Makroaufrufs angelegt wird. Diese Variablen sind daher nur innerhalb des Makros oder innerhalb darin verschachtelter Makros verfügbar.

Die Werte der Makrovariablen werden in Symboltabellen abgelegt: die Werte der globalen Variablen in einer einzigen globalen Tabelle, die Werte der lokalen Variablen in jeweils eigenen lokalen Symboltabellen.

Erzeugung von lokalen und globalen Makrovariablen

Makrovariablen können auf verschiedene Weise erzeugt werden:

Die Stelle, an der die Variable erzeugt wird, entscheidet, ob die Variable global oder lokal ist:

wie wo was
automatisch beim SAS-Aufruf global (immer)
 %Let-Anweisung außerhalb eines Makros global (aktuelle Sitzung)
 %Let-Anweisung innerhalb eines Makros lokal
Proc SQL außerhalb eines Makros global (aktuelle Sitzung)
Proc SQL innerhalb eines Makros lokal
Makro-Parameter Parameterliste beim Aufruf lokal
 %Input-Anweisung außerhalb eines Makros global (aktuelle Sitzung)
 %Input-Anweisung innerhalb eines Makros lokal
symput-Routine innerhalb und außerhalb von Makros global (aktuelle Sitzung)
 %Global-Anweisung innerhalb und außerhalb von Makros global (aktuelle Sitzung)
 %Local-Anweisung innerhalb eines Makros lokal
Beispiel
%Let name=WILHELM; 1)
  %Macro chameleo;
    %Let name=hans; 2)
    %Put &name;
  %Mend chameleo;
%chameleo
%Put &name; 3)

Überprüfen Sie am Computer, was passiert.

1) Mit dieser %Let-Anweisung wird die Makrovariable name global definiert.

Falls Sie die erste %Let-Anweisung weglassen, ist die Makrovariable name nur lokal definiert und die Variable wird nicht richtig aufgelöst, wenn Sie sie außerhalb des Makros 3) verwenden wollen. Sie würden folgende Mitteilung erhalten:

WARNING: Apparent symbolic reference NAME not resolved.

2) Ist die Variable global definiert, so trägt sie den Wert, den sie zuletzt zugewiesen bekommen hat. In diesem Beispiel nimmt die Variable name zuerst den Wert WILHELM 1) und dann hans 3) an.

Die %Global-Anweisung

Die %Global-Anweisung erzeugt globale Makrovariablen, d.h. Variablen, die sowohl innerhalb als auch außerhalb von Makros benutzt werden können. Mit der %Global-Anweisung bilden sie zunächst lediglich eine Variable, weisen ihr aber im Unterschied zur %Let-Anweisung noch keinen Wert zu. Sie vereinbaren damit den Status der Makrovariablen, in diesem Fall global.

Syntax
%Global Makrovariablenname;
Beispiel
%Global gfirst;

Sie haben nun eine globale Makrovariable gfirst angelegt, die aber bislang keinen Wert hat. Den weisen Sie ihr z.B. mit der %LET-Anweisung zu.

Da Sie global vereinbarte Makrovariablen sowohl innerhalb als auch außerhalb eines Makros verwenden können, ist es möglich z.B. mittels globaler Makrovariablen Informationen eines Makros in ein anderes Makro zu transportieren.

Beispiel
%Let sds=sashelp.class;
%Macro compute;
  %Global monat; 1)
  %Let monat=juli;
  Proc Means Data=&sds;
    Title "report für &month";
  Run;
%Mend compute;
%Macro write;
  Proc Print Data=&sds;
    Title "report für &monat";
  Run;
%Mend write;
Aufruf
%compute
%write

Submittieren Sie dieses Programm zuerst ohne und dann mit der %Global-Anweisung 1) , und achten Sie auf die Überschrift (title) im Output-Fenster. Wenn Sie die %Global-Anweisung weglassen, erscheint im Log-Fenster für das Makro write folgende Mitteilung:

WARNING: Apparent symbolic reference MONAT not resolved.

Dies bedeutet, dass der Makro-Prozessor die Makrovariable monat nicht auflösen kann, da diese nur lokal für das Makro compute vereinbart wurde. Fügen Sie jetzt die %Global-Anweisung wieder hinzu, ist die Variable monat global vereinbart und kann überall verwendet werden.

Ausnahme: Globale Makrovariablen können nicht innerhalb eines Makros verwendet werden, wenn die Makrovariablen dort bereits lokal verwendet werden. Die %Global-Anweisung hat keine Auswirkung, wenn die Variable bereits global definiert wurde, z.B. mit einer %Let-Anweisung außerhalb eines Makros.

Die %Local-Anweisung

Syntax
%local Makrovariablenname;
Beispiel
%local nummer;

Die %Local-Anweisung benennt Variablen, die nur innerhalb des aktuellen Makros Gültigkeit haben. Dies ist vor allem dann notwendig, wenn die Variable bereits außerhalb existiert. Um ein Fehlverhalten zu vermeiden, sollten deshalb generell sämtliche Makrovariablen mit %local als lokal deklariert werden. Dies kann z.B. zum Schutz von Indexvariablen sein, die nicht überschrieben werden sollen. Die %Local-Anweisung kann nur innerhalb von Makros verwendet werden. Variablen, die mit einer %Local-Anweisung definiert wurden, besitzen den Wert NULL bzw. 0, solange ihnen kein anderer Wert mittels einer %Let-Anweisung zugewiesen wurde. Dieser Wert gilt aber nur innerhalb des Makros.

Variablen mit gleichem Namen, die bereits in der Umgebung definiert wurden, behalten ihren zuvor vereinbarten Wert.

Makros innerhalb von Makros

Wird in einem Makro ein anderes Makro aufgerufen, spricht man von verschachtelten (oder genesteten) Makros. Die globale äußere Umgebung wird als Niveau 0 bezeichnet. Je tiefer die Verschachtelung fortschreitet, desto höher wird das Niveau gezählt.

Eine Makrovariable ist innerhalb der Umgebung, in der sie definiert wurde und in jeder höheren Umgebung referenzierbar (also in den verschachtelten Makros).

Beispiel Niveau 3
%Macro drei;
  Proc Means Data=&sds;
    Var &xvar &yvar;
  Run;
%Mend drei;
Niveau 2
%Macro zwei;
  Proc Gplot Data=&SDS;
    Plot &yvar*&xvar;
  Run;
  %drei
%Mend zwei;
Niveau 1
%Macro eins(sds,yvar,xvar);
  Proc Print Data=&sds;
    Var &yvar &xvar;
  Run;
  %zwei
%Mend eins;
Aufruf
%eins(sashelp.class,Age,Height)

In diesem Beispiel ruft das tiefste Makro eins, das höher verschachtelte Makro zwei auf, welches wiederum das Makro drei aufruft. Sowohl Makro zwei, als auch Makro drei verwenden die Makrovariablen sds, yvar und xvar, die im Makro eins definiert wurden.

Die Verschachtelung von Makros verdeutlicht auch die Notwendigkeit, Makrovariablen, die nur innerhalb des aktuellen Makros Gültigkeit haben sollen, grundsätzlich mit %Local zu deklarieren. Sehen wir uns folgendes Beispiel an.

Beispiel
%Macro outer;
  %Local i;
  %Put ###################################;
  %Do i=1 %To 2;
    %Put outer: i = &i;
    %inner;
  %End;
  %Put ###################################;
%Mend;
%Macro inner;
  %Local i;
  %Do i=1 %To 3;
    %Put -> inner: i = &i;
  %End;
%Mend;
%outer;

Wie man sieht, wurde in beiden Makros die Makrovariable i als Schleifenvariable verwendet. Durch die Deklaration mit %Local wird eine gegenseitige Beeinflussung verhindert und folgender Output wird erzeugt:

###################################
outer: i = 1
-> inner: i = 1
-> inner: i = 2
-> inner: i = 3
outer: i = 2
-> inner: i = 1
-> inner: i = 2
-> inner: i = 3
###################################

Lässt man die %Local Anweisungen in beiden Makros weg, kommt es zur gegenseitigen Beeinflussung und zu folgendem nicht erwünschten Ergebnis:

###################################
outer: i = 1
-> inner: i = 1
-> inner: i = 2
-> inner: i = 3
###################################

Die Schleife in %outer soll zweimal durchlaufen werden. Beim ersten Durchlauf wird %inner aufgerufen. In diesem Augenblick hat die Variable i den Wert 1. Das Makro %inner durchläuft die Schleife dann wie vorgesehen dreimal. Beim Verlassen der Schleife hat i den Wert 4. Mit diesem Wert in i kommen wir zurück zum Makro %outer. Dadurch, dass i den Wert 4 aus %inner mit nach %outer genommen hat, ist der Schleifenendwert von 2 nun schon überschritten. Die Schleife wird deshalb sofort beendet, obwohl wir die Schleife tatsächlich erst einmal durchlaufen haben.

Siehe auch

Literatur

  • Ortseifen, C.(1993): Einführung in die SAS-Makro-Programmierung - Begleitskript zur Vorlesung Wintersemester 1993/1994 - nicht veröffentlicht.
  • SAS 9.3 Macro Language – Reference.