12.07.2015 Aufrufe

SAS-Makro-Programmierung: - Urz

SAS-Makro-Programmierung: - Urz

SAS-Makro-Programmierung: - Urz

MEHR ANZEIGEN
WENIGER ANZEIGEN
  • Keine Tags gefunden...

Erfolgreiche ePaper selbst erstellen

Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.

Universitätsrechenzentrum Heidelberg<strong>SAS</strong>-<strong>Makro</strong>-<strong>Programmierung</strong>:Eine EinführungHolger Geißler & Dr. Carina OrtseifenOktober 1995Universitätsrechenzentrum Heidelberg, 1995, Im Neuenheimer Feld 293, D-69120 Heidelberg


VORWORT.................................................................................................................................................................4LEGENDE ..................................................................................................................................................................51. EINFÜHRUNG .................................................................................................................................................61.1 WAS IST EIN <strong>SAS</strong>-MAKRO?.................................................................................................................................61.2 WO WIRD DIE <strong>SAS</strong>-MAKRO-SPRACHE EINGESETZT? ...........................................................................................61.3 ELEMENTE DER MAKRO-SPRACHE......................................................................................................................62. <strong>SAS</strong>-MAKROVARIABLEN ............................................................................................................................72.1 AUTOMATISCHE MAKROVARIABLEN...................................................................................................................82.2 BENUTZERDEFINIERTE MAKROVARIABLEN.......................................................................................................102.2.1 Erzeugung von benutzerdefinierten <strong>Makro</strong>variablen...............................................................................102.2.2 Ausgabe des Wertes benutzerdefinierter <strong>Makro</strong>variablen........................................................................102.2.3 Verkettung von <strong>Makro</strong>s ............................................................................................................................102.2.4 Indirekte Zuweisung von Werten..............................................................................................................112.2.5 Das Auflösen von mehrfachen Ampersands .............................................................................................11ÜBUNGSAUFGABEN.................................................................................................................................................113. DIE %MACRO-ANWEISUNG.....................................................................................................................133.1 DEFINITION UND AUFRUF VON <strong>SAS</strong>-MAKROS...................................................................................................133.2 MAKRO-NAME..................................................................................................................................................133.3 MAKRO-PARAMETER ........................................................................................................................................133.3.1 Positions- und Schlüsselparameter ..........................................................................................................14ÜBUNGSAUFGABEN.................................................................................................................................................154. LOKALE UND GLOBALE MAKROVARIABLEN...................................................................................164.1 ERZEUGUNG VON LOKALEN UND GLOBALEN MAKROVARIABLEN......................................................................164.1.1 Die %Global-Anweisung..........................................................................................................................174.1.2 Die %Local-Anweisung............................................................................................................................184.2 MAKROS INNERHALB VON MAKROS..................................................................................................................18ÜBUNGSAUFGABEN.................................................................................................................................................195. <strong>SAS</strong>-MAKRO-PROGRAMMANWEISUNGEN...........................................................................................205.1 %*-ANWEISUNG ...............................................................................................................................................205.2 %PUT-ANWEISUNG...........................................................................................................................................215.3 %INPUT-ANWEISUNG........................................................................................................................................215.4 %IF - %THEN / %ELSE-ANWEISUNG.................................................................................................................225.5 %DO - %END-ANWEISUNG...............................................................................................................................22ÜBUNGSAUFGABE...................................................................................................................................................235.6 %DO - %TO - %END-ANWEISUNG (ITERATIVE %DO-ANWEISUNG) .................................................................235.7 %DO - %UNTIL - %END-ANWEISUNG...............................................................................................................245.8 %DO - %WHILE - %END-ANWEISUNG..............................................................................................................255.9 %GOTO LABEL; %LABEL-ANWEISUNG..............................................................................................................255.10 %SYSEXEC-ANWEISUNG.................................................................................................................................265.11 %KEYDEF-ANWEISUNG ..................................................................................................................................28ÜBUNGSAUFGABEN.................................................................................................................................................285.12 %WINDOW-ANWEISUNG.................................................................................................................................285.12.1 Fensteroptionen......................................................................................................................................295.12.2 Felddefinitionen .....................................................................................................................................305.12.3 Gruppen-Definition ................................................................................................................................315.12.4 Automatische Variablen .........................................................................................................................315.13 %DISPLAY-ANWEISUNG..................................................................................................................................33ÜBUNGSAUFGABE...................................................................................................................................................346. <strong>SAS</strong>-MAKRO-FUNKTIONEN.......................................................................................................................346.1 FUNKTIONEN ZUR BEARBEITUNG VON ZEICHENKETTEN ...................................................................................366.1.1 %INDEX-FUNKTION .......................................................................................................................................366.1.2 %LENGTH-FUNKTION ....................................................................................................................................376.1.3 %SCAN- UND %QSCAN-FUNKTION................................................................................................................376.1.4 %SUBSTR- UND %QSUBSTR-FUNKTION.........................................................................................................392


6.1.5 %UPCASE- UND %QUPCASE-FUNKTION ........................................................................................................39ÜBUNGSAUFGABE...................................................................................................................................................406.2 %EVAL FUNKTION ZUR AUSWERTUNG VON LOGISCHEN UND NUMERISCHEN AUSDRÜCKEN.............................416.2.1 %EVAL-FUNKTION.........................................................................................................................................41ÜBUNGSAUFGABEN.................................................................................................................................................436.3 FUNKTIONEN ZUR BEARBEITUNG VON SPEZIELLEN ZEICHEN (TEXTFUNKTIONEN) ............................................436.3.1 %QUOTE-FUNKTION ......................................................................................................................................456.3.2 %BQUOTE-FUNKTION....................................................................................................................................456.3.3 %NRQUOTE-FUNKTION..................................................................................................................................466.3.4 %NRBQUOTE-FUNKTION................................................................................................................................466.3.5 %UNQUOTE-FUNKTION..................................................................................................................................466.3.6 %STR-FUNKTION ...........................................................................................................................................476.3.7 %NRSTR-FUNKTION.......................................................................................................................................476.3.8 %SUPERQ-FUNKTION.....................................................................................................................................48ÜBUNGSAUFGABEN.................................................................................................................................................487. BERÜHRUNGSPUNKTE ZWISCHEN MAKRO-SPRACHE UND DATENSCHRITT .........................497.1 ZUGRIFF AUF DATEN IN <strong>SAS</strong>-MAKROS .............................................................................................................497.1.1 SYMGET-FUNKTION .......................................................................................................................................497.1.2 SYMPUT-FUNKTION .......................................................................................................................................527.1.3 RESOLVE-FUNKTION......................................................................................................................................547.2 %SYSPROD-FUNKTION......................................................................................................................................557.3 EXECUTE-ROUTINE...........................................................................................................................................56ÜBUNGSAUFGABEN.................................................................................................................................................588. AUFRUF VON <strong>SAS</strong>-MAKROS......................................................................................................................588.1 NAMED STYLED MAKROS .................................................................................................................................598.2 STATEMENT STYLED MAKROS ..........................................................................................................................598.3 COMMAND STYLED MAKROS ............................................................................................................................609. MAKRO-BIBLIOTHEKEN (AUTOCALL-FACILITY).............................................................................609.1 AUTOMATISCHER AUFRUF VON MAKROS (AUTOCALL FACILITY) .....................................................................609.2 AUTOMATISCHES SPEICHERN VON KOMPILIERTEN MAKROS .............................................................................629.3 ALLGEMEINE SYSTEMOPTIONEN .......................................................................................................................6410. FEHLERMELDUNGEN UND MÖGLICHE URSACHEN.......................................................................65LÖSUNGVORSCHLÄGE ZU DEN ÜBUNGSAUFGABEN ...........................................................................66ZUSÄTZLICHE ÜBUNGSAUFGABEN ...........................................................................................................71LITERATURLISTE: ...........................................................................................................................................74INDEX...................................................................................................................................................................753


VorwortFür wen ist dieses Skript gedacht?Dieses Skript ist eine Einführung in die <strong>Makro</strong>programmierung mit <strong>SAS</strong>, keine Einführung in<strong>SAS</strong>. Der mit <strong>SAS</strong> vertraute Anwender wird mit diesem Skript eine erste Anleitung zurErstellung eigener <strong>Makro</strong>s finden. Für Anwender, die <strong>SAS</strong> bislang nicht oder nur selten benutzthaben, wird dieses Skript keine Hilfe sein, da es auf einem grundlegenden Verständnis von <strong>SAS</strong>aufbaut und bestimmte Kenntnisse voraussetzt. Es liegt im Wesen der <strong>Makro</strong>s, daß es erst dannSinn macht die <strong>Makro</strong>programmierung zu lernen, wenn Sie bestimmte Abläufe in <strong>SAS</strong> öfterswiederholen müssen.Was will dieses Skript?Eine Einführung in die <strong>Makro</strong>programmierung sein. Der erfahrene <strong>SAS</strong>-<strong>Makro</strong>-programmiererwird hier wenig Neues finden. Die AnwenderIn, die ihre ersten Schritte in die Welt der <strong>Makro</strong>sunternehmen will, soll nach Lektüre des Skripts in der Lage sein, einfachere <strong>Makro</strong>s zuschreiben. Vermittelt werden soll außerdem, ein grundlegendes Verständnis für den Aufbau unddie Struktur von <strong>Makro</strong>s in <strong>SAS</strong>.Wie arbeiten Sie am Besten mit diesem Skript?Am Besten, indem Sie vorne anfangen, und es bis zum Schluß aufmerksam lesen. Außerdemsollten Sie die Übungsaufgaben bearbeiten, da gerade bei der Arbeit mit dem Computerpraktisches Ausprobieren unerläßlich ist. Es gibt zu jedem größeren Abschnitt (meist ist dies einKapitel) mehrere Übungsaufgaben, die nach dem Studium des jeweiligen Abschnitts gelöstwerden sollten. Wenn es mal gar nicht funktioniert, bleibt natürlich immer noch der Blick in dieLösungen, die sich im hinteren Teil des Buches befinden.Das vorliegende Skript basiert auf Kursunterlagen, die für <strong>SAS</strong>-<strong>Makro</strong>programmierkurse amUniversitätsrechenzentrums erstellt wurden.Die Literatur, die in diesem Skript verwendet wurde, ist ausnahmslos in der Bibliothek desUniversitätsrechenzentrum verfügbar.Bei Fragen und Hinweise erreichen Sie uns entweder über Telefon oder per E-Mail.Holger Geißler, 565582, E-Mail: holger.geißler@urz.uni-heidelberg.deCarina Ortseifen, 564541, E-Mail: carina.ortseifen@urz.uni-heidelberg.de4


Legende<strong>SAS</strong>-Schlüsselworte, -Anweisungen und sonstige Programmzeilen sind in Courier geschrieben:%macro, %nrstr; C:\<strong>SAS</strong>,Hervorhebungen im Text sind Fett gesetzt:<strong>Makro</strong>-Parameter können entweder als Positionsparameter (posparm) oder Schlüsselparameter(keyparm) übergeben werden. Benennungen, die variabel sind, werden in derOptionen und Argumente, die der Benutzer wählen kann, sind kursiv in Times New Romangeschrieben:%keydef key-name | 'key-name' | "keyname" ;Numerierungen in schwarzen Kreisen sind Erläuterungen zu Beispielprogrammen: Mit dieser %let-Anweisung wird die <strong>Makro</strong>variable name global definiert.5


1. Einführung1.1 Was ist ein <strong>SAS</strong>-<strong>Makro</strong>?Ein <strong>SAS</strong>-<strong>Makro</strong> ist ein in der <strong>SAS</strong>-<strong>Makro</strong>-Sprache geschriebenes Programm, welches aus <strong>SAS</strong>-Elementen wie z.B. Proc- und Data-Schritten bestehen kann. Falls Sie regelmäßig die gleichenProgrammanweisungen durchführen müssen, kann es zeitsparend sein, sich dafür ein <strong>Makro</strong> zuschreiben. Nachdem das <strong>Makro</strong> einmal aktiviert ist, kann es immer wieder allein durch seinenNamen aufgerufen und benutzt werden.Das <strong>Makro</strong> spricht einen eigens für die <strong>Makro</strong>-Sprache bereitgestellten Prozessor an, der durchSchlüsselzeichen, wie z.B. das Prozentzeichen "%" aktiviert wird. Dieser Prozessor nennt sich<strong>Makro</strong>-Prozessor. Mit Hilfe der <strong>SAS</strong>-<strong>Makro</strong>-Sprache können Sie mit ihm kommunizieren.Beispiel:Aufruf:%macro aufruf;libname co v604 'N:\<strong>SAS</strong>urz\daten';libname co608 v608 'N:\<strong>SAS</strong>urz\daten';libname daten 'M:\<strong>SAS</strong>\daten';libname b 'B:\';libname a 'A:\';libname library 'M:\<strong>SAS</strong>\formate';%mend aufruf;%aufrufBevor Sie mit einem <strong>Makro</strong> arbeiten können, müssen sie es kompilieren. Dies geschieht dadurch,das sie das gesamte <strong>Makro</strong> submittieren. Durch den Aufruf wird der <strong>Makro</strong>-Prozessor aktiviert, dernun die Programmanweisungen durchführt. Das <strong>Makro</strong> aufruf setzt alle notwendigen Libname-Anweisungen. Da sie normalerweise bei jeder <strong>SAS</strong>-Sitzung gesetzt werden müssen, ist eszeitsparend, sie durch ein <strong>Makro</strong> zusammenzufassen.1.2 Wo wird die <strong>SAS</strong>-<strong>Makro</strong>-Sprache eingesetzt?Die <strong>SAS</strong>-<strong>Makro</strong>-Sprache wird an folgenden Stellen eingesetzt:• Zusammenfassung von Proc- und Data-Schritten, die häufig wiederholt werden müssen• Erzeugung von Anwendungen, die das <strong>SAS</strong>-System bisher nicht anbietet, z.B. derJonckheere-Test• Erzeugung von datenabhängigen Programmen durch eine Schnittstelle zu <strong>SAS</strong>-Dateien(DATA Step Interface)• Entwicklung von Eingabefenstern• Automatische Einbindung von Systeminformationen (z.B. Datum, Uhrzeit undBetriebssystem)• Bedingtes Ausführen von Daten- und Prozedurschritten1.3 Elemente der <strong>Makro</strong>-SpracheEs gibt vier wesentliche Elemente der <strong>SAS</strong>-<strong>Makro</strong>-Sprache:• <strong>Makro</strong>variablen• <strong>Makro</strong>-Programmanweisungen• <strong>Makro</strong>-Funktionen• <strong>Makro</strong>-Routinen6


<strong>Makro</strong>variablen unterscheiden sich grundlegend von den Variablen einer <strong>SAS</strong>-Datei. Der Werteiner Datenschritt-Variablen hängt von der Beobachtung ab, die sie gerade darstellt. Datenschritt-Variablen können nur in Data- oder Proc-Schritten verwendet werden. <strong>Makro</strong>variablen sind dagegenüberall einsetzbar. Sie haben einen konstanten Wert, den ihnen zugewiesen oder vorgegeben wird.<strong>Makro</strong>variablen speichern Zeichenketten ab und können manipuliert werden. Es gibt zweiunterschiedliche Arten von <strong>Makro</strong>variablen: Benutzerdefinierte und Automatische Variablen.Benutzerdefinierte <strong>Makro</strong>variablen können, wie der Name schon sagt, vom der Benutzer selbstbestimmt werden. Sie können lokal oder global vereinbart werden. (siehe Kap. 2.2). Ihrzugewiesener Wert bleibt konstant bis er explizit geändert wird.Automatische <strong>Makro</strong>variablen beginnen immer mit den Buchstaben SYS. Sie enthalten z.B.Informationen über das Datum, das Betriebssystem oder den Ausführungsmodus.<strong>Makro</strong>-Programmanweisungen sind den Anweisungen im Datenschritts ähnlich. Der Unterschiedbesteht darin, daß <strong>Makro</strong>-Programmanweisungen immer mit "%" beginnen, auf das ein <strong>Makro</strong>-Schlüsselwort folgt. Sie können z.B. Variablen verändern, Werte zuweisen und ausgeben, und siekönnen Verzweigen und bedingtes Ausführen (%IF..%THEN) von <strong>SAS</strong>-Anweisungen herbeiführen.<strong>Makro</strong>-Funktionen verarbeiten Argumente (z.B. Zeichenketten). Sie können z.B. logischeAusdrücke auswerten und Zeichenketten zählen. Sie sind den Funktionen im Datenschritt ähnlich,weisen darüber hinaus aber auch spezielle Möglichkeiten auf, die nur im <strong>Makro</strong>bereich gelten.<strong>Makro</strong>-Funktionen sind auch im Data- oder Proc-Schritt einsetzbar.<strong>Makro</strong>-Routinen bewerkstelligen z.B. den Datenaustausch zwischen <strong>Makro</strong>s und Data-Schritt(SYMPUT, SYMGET) oder rufen Anwendungen innerhalb eines <strong>Makro</strong>s auf.2. <strong>SAS</strong>-<strong>Makro</strong>variablenSyntax: &VariablennameLänge: 1-8 Zeichen, der Variablenname muß mit einem Buchstaben oder einemUnterstrich beginnen, gefolgt von Buchstaben, Zahlen oder Unterstrichen.Beispiel: &SYSDATE&SDS&HANSI<strong>SAS</strong>-<strong>Makro</strong>variablen sind gekennzeichnet durch ein Ampersand (&) gefolgt von mindestens einemnichtleeren Zeichen.Es gibt• automatische <strong>Makro</strong>variablen (die direkt vom <strong>SAS</strong> System zur Verfügung gestellt werden)und• benutzerdefinierte <strong>Makro</strong>variablen.Der <strong>Makro</strong>-Prozessor setzt an die Stelle des Variablennamens den entsprechenden Wert ein(Textstring). Dieser Textstring kann mindestens 1024 Zeichen lang sein, der maximale Wert ist vomBetriebssystem abhängig.7


2.1 Automatische <strong>Makro</strong>variablenAutomatische <strong>Makro</strong>variablen werden automatisch vom <strong>Makro</strong>-Prozessor zur Verfügung gestellt.Sie beginnen alle mit den Buchstaben SYS. Da diese Kombination für das <strong>SAS</strong>-System reserviertist, sollten Sie deshalb nie diese Kombination am Anfang eines Variablennamens benutzen.Die wichtigsten automatischen <strong>Makro</strong>variablen und ihre Funktion:SYSDATESYSDAYSYSTIMESYSENVSYSSCPSYSVERSYSDEVICSYSSCPLSYSERRSYSINFOSYSFILRCSYSLIBRCSYSRCSYSLASTSYSDSNAktuelles Datum des ProgrammstartsWochentag des ProgrammstartsZeit des ProgrammstartsAusführungsmodus, FORE=interaktiv, BACK=BatchjobBetriebssystem (als Abkürzung)<strong>SAS</strong>-Versionaktueller Device Driverausführlichere Infos zum Betriebssystem (ab <strong>SAS</strong>-Version6.10)Fehlerinformation (Return Code) von Prozedurenähnlich wie SYSERRReturn Code der letzten Filename-AnweisungReturn Code der letzten Libname-AnweisungReturn Code des letzten Betriebssystem-KommandosName der zuletzt erzeugten <strong>SAS</strong>-Dateilibref.dateiname (ein Name)Name der zuletzt erzeugten <strong>SAS</strong>-Dateilibref dateiname (zwei Namen)Verwendet werden können diese Variablen u.a. in Textzeilen, die mit• Title-Anweisungen,• Footnote-Anweisungen• Note-Anweisungen und• Put-Anweisungenerzeugt werden.Falls Sie, wie z.B. im nächsten Beispiel, Title- und Footnote-Anweisungen benutzen, müssen Siedoppelte Anführungszeichen (Gänsefüßchen) verwenden, da ansonsten die automatischen<strong>Makro</strong>variablen nicht aufgelöst werden.Beispiel:proc gslide;title "Heute ist &sysday, der &sysdate,&systime Uhr";footnote "<strong>SAS</strong>-Version &sysver";run;Anmerkung: Die automatischen <strong>Makro</strong>variablen geben ihre Information in englischer Sprache aus.Alle automatischen <strong>Makro</strong>variablen finden Sie auf den Seiten 55-59 im "<strong>SAS</strong> Guide to <strong>Makro</strong>Processing" beschrieben.8


2.2 Benutzerdefinierte <strong>Makro</strong>variablenSie können eigene <strong>Makro</strong>variablen auf verschiedene Weise definieren. Die einfachste undgebräuchlichste Art ist die Verwendung von "%let". Weitere Möglichkeiten der Erzeugungbenutzerdefinierter <strong>Makro</strong>variablen finden Sie im Kapitel 4.1.2.2.1 Erzeugung von benutzerdefinierten <strong>Makro</strong>variablenSyntax:Beispiel:%let makrovariable=wert;%let A=13;%let Name=Alois Vorderhuf%let Monat=NovemberDie Variable makrovariable wird erzeugt, falls diese nicht bereits existiert, und sie bekommt denWert wert zugewiesen. Falls Sie der gleichen Variablen nacheinander mehrere Werte zuweisen,wird der Wert überschrieben. Als Wert können Sie beliebige Zeichenketten zuweisen. Es ist auchmöglich, <strong>Makro</strong>variablen bereits bestehende <strong>Makro</strong>variablen als Wert zuzuweisen.Beispiel:%let Datum=&SYSDATE;Die Zuweisung erfordert keine Anführungszeichen. Werden diese trotzdem verwendet, werden sieals Teil des Wertes interpretiert. Die %LET-Anweisung entfernt führende und nachfolgendeLeerzeichen des zugewiesenen Textes. Wollen Sie nachfolgende Leerzeichen berücksichtigen oderein Semikolon als Textzeichen verwenden, müssen Sie die "%STR-Funktion" (siehe Kap. 6.3.6)verwenden.Beispiel: %let Name=%STR( Herr Hans Ulrich Meier);%let Druck=%STR(Proc Print; Run;);Falls Sie dagegen nur %let druck=Proc print;run;schreiben, hat ihre Variable druck nurden Wert "Proc print", da die %let-Anweisung nur bis zum Semikolon liest.2.2.2 Ausgabe des Wertes benutzerdefinierter <strong>Makro</strong>variablenWenn Sie sich den Wert ihrer <strong>Makro</strong>variablen anzeigen lassen wollen, verwenden Sie ameinfachsten die "%put-Anweisung". Sie schreibt den Wert ihrer <strong>Makro</strong>variablen ins LOG-Fenster.(Analog zur Put-Anweisung für die Ausgabe von normalen Variablen.)Beispiel: %put &Name;Ausführlich beschrieben wird die "%put-Anweisung" in Kapitel 5.2.2.2.3 Verkettung von <strong>Makro</strong>sSie können Text direkt an einen <strong>Makro</strong>-Namen anhängen. Damit läßt sich z.B. eine Variablenlistefür die Keep-Anweisung erzeugen:Beispiel:Ergebnis:%LET start=1;%LET ende=10;keep var&start-var&ende;keep var1-var109


Wollen Sie <strong>Makro</strong>variablen voranstellen, müssen Sie dies folgendermaßen tun:Beispiel: %let prefix=item;var &prefix.1-&prefix.10;Der Punkt beendet die <strong>Makro</strong>-Anweisung und es wird die var-Anweisung var item1-item10erzeugt. Ohne den Punkt sucht der <strong>Makro</strong>-Prozessor nach den <strong>Makro</strong>variablen &prefix1, bzw.&prefix10.Zur Erzeugung eines zweiteiligen <strong>SAS</strong>-Dateinamens sind daher zwei hintereinander folgendePunkte zu verwenden: Einen zum Beenden der <strong>Makro</strong>variablen, den anderen zur Abtrennung desLibrefs vom Dateinamen:Beispiel:%let lref=mein;%let dat=eins;data &lref&dat; erzeugt data meineins;data &lref.&dat; erzeugt ebenfalls data meineins;data &lref..&dat;erzeugt dagegen data mein.eins;2.2.4 Indirekte Zuweisung von WertenBeispiel:Ergebnis:%let device=hp7475a;%let &device=online;%put &device=&hp7475a;hp7475a=onlineDie Zeile %put der &device ist &hp7475a..; liefert der hp7475a ist online, da dieeingesetzte <strong>Makro</strong>variable &device zu hp7475a aufgelöst wird.2.2.5 Das Auflösen von mehrfachen AmpersandsZwei Ampersands (&&) lösen sich zu einem Ampersand (&) auf. Mehrfache Ampersands sindsinnvoll beim Auflösen von Variablen, die einen gemeinsamen Stamm und numerische Endungenhaben.Beispiel:%Let device1=hp7475a;%Let device2=hp7475b;%Let device3=xcolor;%Let device4=ps300;%let n=3;Ergebnis:%put &device&n; erzeugt einen Fehler, da &device nicht referenziert ist.%put &&&device&n; löst zuerst && zu & auf, danach &n zu 3 und letztendlich &device3 zuxcolor.Übungsaufgaben1. Welchen Wert nehmen die Variablen an, wenn Sie die folgenden Anweisungen der Reihe nachausführen? Überlegen Sie sich die Antworten zunächst ohne Zuhilfenahme von <strong>SAS</strong> undüberprüfen Sie danach am Computer, indem Sie die Anweisungen ausführen, ob ihre Antwortenrichtig waren.AnweisungWert10


%let vname=hans;%let name=&vname Schreiner;%let nachname=Schreiner;%let nname=&&nachname;2. Im Verzeichnis n:\<strong>SAS</strong>urz\daten finden Sie die <strong>SAS</strong>-Datei IRIS.SSD mit denMeßergebnissen von Fishers berühmtem Experiment mit seinen Iris-Arten.Schreiben Sie ein <strong>SAS</strong>-Programm zum Ausdruck der Datei (proc print).Übergeben Sie Libref und Dateinamen über <strong>Makro</strong>variaben. Bilden Sie eine Titel-Anweisung, die aussagt, um welche Datei es sich handelt. Versehen Sie die Fußnote mit demaktuellen Datum und der Uhrzeit.3. Gegeben seien folgende %let Anweisungen%let a=Hallo;%let a1=Auf Wiedersehen;%let b=Gutes Gelingen;%let c=Tschuess;Überlegen Sie, was die folgenden %put-Anweisungen erzeugen und überprüfen Sie es:%put &a,&b;%put c&a,&b;%put c&a.&b;%put &c,&a1;%put &c,&a.1;4. Submittieren Sie folgendes Programm. Woran liegt es, daß der <strong>Makro</strong>-Prozessor dieautomatischen <strong>Makro</strong>variablen nicht auflöst?proc gslide;title 'Grafik vom &Sysdate, <strong>SAS</strong>-Version &sysver';run;TIP! Verwenden Sie folgende System-Optionen, die Ihnen bei der Fehlersuche behilflich sind:• MPRINT• MLOGIC• SYMBOLGENAlle drei System-Optionen geben zusätzliche Informationen über das ablaufende <strong>SAS</strong>-<strong>Makro</strong> imLog-Fenster aus. Sie aktivieren sie, indem sie die Options-Anweisung entsprechend einstellen.Aufruf:options symbolgen mlogic mprint;MPRINT: Der <strong>Makro</strong>-Prozessor gibt den aufgelösten <strong>SAS</strong>-Code aus. Sie erfahren dadurch, ob eine<strong>Makro</strong>-Programmanweisung ausgeführt wurde oder nicht.MLOGIC: Spiegelt den Ablauf des <strong>Makro</strong>s, indem es zeitgleich die Programmanweisungen ins Log-Fenster schreibt.SYMBOLGEN: Zeigt <strong>Makro</strong>-Referenzen an, z.B. ob eine Variable aufgelöst wurde und welchen Wertdie Variable besitzt.Alle drei Optionen werden mit nomprint, nomlogic und nosymbolgen wieder zurückgesetzt.11


3. Die %Macro-Anweisung3.1 Definition und Aufruf von <strong>SAS</strong>-<strong>Makro</strong>sEin <strong>SAS</strong>-<strong>Makro</strong> ist ein Text zwischen einer %macro und einer %mend-Anweisung.Syntax:Beispiel:Aufruf:%macro name(parameter) / optionen;<strong>Makro</strong>text;%mend name;%macro datum;Title "Heute ist &sysday, der &sysdate";%mend datum;%datumDas <strong>Makro</strong> %datum erzeugt automatisch eine Überschrift mit dem aktuellen Datum.Die %macro-Anweisung•beginnt die Definition des <strong>Makro</strong>s,• weist dem <strong>Makro</strong> einen Namen zu und• kann (optional) eine Parameterliste und Optionen übergeben.3.2 <strong>Makro</strong>-NameDer Name des <strong>Makro</strong>s muß ein gültiger <strong>SAS</strong>-Name sein.Es gibt reservierte Worte, die nicht verwendet werden dürfen, etwa GO,RUN,OPEN usw.. WerdenSie trotzdem verwendet, erscheint folgende Fehlermeldung:ERROR: Macro NAME has been given a reserved name.ERROR: A dummy macro will be compiled.3.3 <strong>Makro</strong>-Parameter<strong>Makro</strong>-Parameter sind <strong>Makro</strong>variablen, die mit dem Aufruf an das <strong>Makro</strong> übergeben werden. Diesist, neben der %let-Anweisung, eine weitere Art, <strong>Makro</strong>variablen zu bilden.Beispiel:Aufruf:%macro mittel (SDS);Proc means data=&SDS;run;%mend mittel;%mittel(co.blutbild)In Klammern steht der Wert, der an die <strong>Makro</strong>variablen SDS übergeben wird. In diesem Beispielbekommt der Parameter SDS den Wert co.blutbild zugewiesen.Die Parameter in der <strong>Makro</strong>-Definition• sind in Klammern eingeschlossen,• werden durch Kommas getrennt,• können mit ihrer Position oder mit einem Schlüsselwort spezifiziert werden und12


• definieren lokale <strong>Makro</strong>variablen, d.h. Variablen, die nur während der Ausführung<strong>Makro</strong>s gültig sind. (Im Gegensatz zu globalen <strong>Makro</strong>variablen, siehe Kap. 4.)des3.3.1 Positions- und Schlüsselparameter<strong>Makro</strong>-Parameter können entweder als Positionsparameter (posparm) oder Schlüssel-parameter(keyparm) übergeben werden. Der wesentliche Unterschied zwischen beiden besteht darin, daß das<strong>Makro</strong> Positionsparameter allein durch ihre Position beim Aufruf erkennt, und Schlüsselparametermit Variablennamen und Gleichheitszeichen aufgelistet werden müssen.Beispiel für Positionsparameter:Beispiel für Schlüsselparameter:%macro name(posparm-1, posparm-2);%macro name(keyparm-1=wert1, keyparm-2=wert2);Die Positionsparameter• erscheinen ohne Gleichheitszeichen,• müssen in der im <strong>Makro</strong>-Aufruf definierten Reihenfolge aufgelistet werden,• haben den Wert Null zum Zeitpunkt der Defintion und können diesen beibehalten, wenn einKomma als Platzhalter beim Aufruf eingesetzt wurde.Die Schlüsselparameter• werden mit einem Gleichheitszeichen aufgelistet,• können in beliebiger Reihenfolge angegeben werden,• können mit Defaultwerten (auch Null) versehen werden und• brauchen beim Aufruf nicht genannt zu werden.Positions- und Schlüsselparameter können auch gemeinsam in <strong>Makro</strong>s auftreten, doch müssen diePositionsparameter zuerst aufgelistet werden.Beispiel 1: %macro print (var1,var2,var3,sds=_last_);proc print data=&SDS;var &var1 &var2 &var3;run;%mend print;Aufruf:%print(albumin,calcium,alter,SDS=co.blutbild);Die Positionsparameter Var1, Var2 und Var3 erhalten die Werte Albumin, Calcium undAlter. Der Schlüsselparameter SDS erhält den Wert co.blutbild. Der Defaultwert ist auf_last_ gesetzt; dies bedeutet, daß automatisch der zuletzt bearbeitete Datensatz verwendet wird,falls im <strong>Makro</strong>aufruf kein neuer Dateiname angegeben wird.Beispiel 2: %macro ttest (var1,var2,classvar,sds);proc ttest data=&SDS;class &classvar;var &var1 &var2 ;run;%mend ttest;Aufruf 1: %ttest (calcium,albumin,pille, co.blutbild);Aufruf 2: %ttest (calcium,,pille, co.blutbild);Im zweiten Beispiel werden die Positionsparameter var1, var2, classvar und sds verwendet.Beim zweiten Aufruf soll der T-Test nur für eine Variable berechnet werden. Um eine13


Fehlermeldung zu vermeiden, muß anstelle eines Wertes für var2 ein Komma angegeben werden.Durch das Komma überspringt der <strong>Makro</strong>-Prozessor diesen Wert, und erkennt die nachfolgendenVariablen richtig.Probieren Sie aus, was passiert, wenn sie bei Aufruf 2 das Komma weglassen.Übungsaufgaben5. Welcher <strong>SAS</strong>-Code wird mit folgendem <strong>Makro</strong> erzeugt:%macro meintitl;title "Heute ist &sysday, &sysdate";%mend meintitl;Wie lautet der Aufruf dieses <strong>Makro</strong>s?6. Schreiben Sie ein <strong>Makro</strong> %sortier, das die Proc Sort aufruft. Übergeben Sie dieInformationen über den zu bearbeitenden Datensatz und die by-Variable überPositionsparameter.7. Fügen Sie in das <strong>Makro</strong> %Sortier folgende Ergänzungen ein:• die Prozedur Print zur Kontrolle und• eine Titel-Zeile mit dem aktuellen Datum.8. Schreiben Sie ein <strong>Makro</strong> %Plotte, das die Prozedur Gplot aufruft. Das <strong>Makro</strong> sollte 3Schlüsselparameter haben:• Name der zu verwendenden <strong>SAS</strong>-Datei,• Name der Variable, die auf der x-Achse aufgetragen wird und• Name der Variable, die auf der y-Achse aufgetragen wird,a. Ergänzen Sie das <strong>Makro</strong> um eine dritte Variable z, die als Gruppierungsvariable fungieren soll.(plot x*y=z).b. Bearbeiten Sie mit dem <strong>Makro</strong> den Beispieldatensatz IRIS, den sie im Verzeichnis'N:\<strong>SAS</strong>URZ\DATEN' finden. Plotten sie PL gegen PW, mit der Variable BLUME alsGruppierungsvariable.c. Fügen Sie eine where-Anweisung für die Variable z ein, und übergeben Sie dieEinschränkungsbedingung als Positionsparameter.d. Fertigen Sie sich für jede der drei Blumenarten ein eigenes Schaubild an.9. Schreiben Sie ein <strong>Makro</strong> KREUZTAB, das die Prozedur FREQ aufruft. Das <strong>Makro</strong> sollte dreiParameter haben: Zwei Positionsparameter für die Variablen in den Zeilen und den Spalten undein Schlüsselparameter für den Namen des <strong>SAS</strong>-Datensatzes.Klassifizieren Sie die Variable SL so, daß vier etwa gleichgroße Gruppen entstehen. Dazumüssen sie sich ein Format definieren. Erzeugen Sie danach eine temporäre Datei IRIS, in der siedas Format zuweisen. Rufen Sie das <strong>Makro</strong> für die temporäre Datei IRIS auf und tragen Sie dieklassifizierte Variable SL gegen BLUME auf. (Tip: Quartil-Bildung mit PROC UNIVARIATE,Klassifizierung mit PROC FORMAT.)14


4. Lokale und globale <strong>Makro</strong>variablenDas <strong>SAS</strong>-System unterscheidet zwischen• globalen und• lokalen <strong>Makro</strong>variablen.Die globalen <strong>Makro</strong>variablen gelten während der gesamten <strong>SAS</strong>-Sitzung und können an beliebigerStelle verwendet werden, sobald sie definiert wurden. Globale Variablen sind z.B. die unter Kap.2.1 beschriebenen automatischen <strong>Makro</strong>variablen wie &sysdate oder &systime.Im Unterschied dazu gelten die lokalen <strong>Makro</strong>variablen nur in der Umgebung, die während eines<strong>Makro</strong>aufrufs angelegt wird. Diese Variablen sind daher nur innerhalb des <strong>Makro</strong>s oder innerhalbdarin verschachtelter <strong>Makro</strong>s verfügbar.Die Werte der <strong>Makro</strong>variablen werden in Symboltabellenabgelegt: die Werte der globalen Variablenin einer einzigen globalen Tabelle, die Werte der lokalen Variablen in jeweils eigenen lokalenSymboltabellen.4.1 Erzeugung von lokalen und globalen <strong>Makro</strong>variablen<strong>Makro</strong>variablen können auf verschiedene Weise erzeugt werden:• vom <strong>SAS</strong>-System (automatische Variablen, Kap.2.1),• mit der Symput-Routine (siehe Kap. 7.1.2),• durch die Parameter beim <strong>Makro</strong>-Aufruf (siehe Kap. 3.3),• mit der %input-Anweisung (siehe Kap. 5.3),• mit der %let-Anweisung (siehe Kap. 2.2),• mit der %global-Anweisung (siehe Kap. 4.1.1),• mit der %local-Anweisung (siehe Kap. 4.1.2).Die Stelle, an der die Variable erzeugt wird, entscheidet, ob die Variable global oder lokal ist:wie wo wasautomatisch beim <strong>SAS</strong>-Aufruf global (immer)%let-Anweisung außerhalb eines <strong>Makro</strong>s global (aktuelle Sitzung)%let-Anweisung innerhalb eines <strong>Makro</strong>s lokal<strong>Makro</strong>-Parameter Parameterliste beim Aufruf lokal%input-Anweisung innerhalb und außerhalb von global (aktuelle Sitzung)<strong>Makro</strong>ssymput-Routine innerhalb und außerhalb von global (aktuelle Sitzung)<strong>Makro</strong>s%global-Anweisung innerhalb und außerhalb von global (aktuelle Sitzung)<strong>Makro</strong>s%local-Anweisung innerhalb eines <strong>Makro</strong>s lokalBeispiel:%let name=WILHELM;%macro chameleo;%let name=HANS;%put &name;%mend chameleo;15


%chameleo%put &name;Überprüfen Sie am Computer, was passiert. Mit dieser %let-Anweisung wird die <strong>Makro</strong>variable name global definiert.Falls Sie die erste %let-Anweisung weglassen, ist die <strong>Makro</strong>variable name nur lokal definiert unddie Variable wird nicht richtig aufgelöst, wenn Sie sie außerhalb des <strong>Makro</strong>s verwenden wollen.Sie erhalten folgende Mitteilung:WARNING: Apparent symbolic reference NAME not resolved. 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 und dann HANS an.4.1.1 Die %Global-AnweisungDie %global-Anweisung erzeugt globale <strong>Makro</strong>variablen, d.h. Variablen, die sowohl innerhalb alsauch außerhalb von <strong>Makro</strong>s benutzt werden können. Mit der %global-Anweisung bilden siezunächst lediglich eine Variable, weisen ihr aber im Unterschied zur %let-Anweisung noch keinenWert zu. Sie vereinbaren damit den Status der <strong>Makro</strong>variablen, in diesem Fall global.Syntax:Beispiel:%global <strong>Makro</strong>variablenname;%global Gfirst;Sie haben nun eine globale <strong>Makro</strong>variable Gfirst angelegt, die aber bislang keinen Wert hat. Denweisen Sie ihr mit der %LET-Anweisung zu.Da Sie global vereinbarte <strong>Makro</strong>variablen sowohl innerhalb als auch außerhalb eines <strong>Makro</strong>sverwenden können, ist es möglich z.B. mittels globaler <strong>Makro</strong>variablen Informationen eines <strong>Makro</strong>sin ein anderes <strong>Makro</strong> zu transportieren.Beispiel:Aufruf:%let sds=co.blutbild;%macro compute;%global monat;%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;%compute%writeSubmittieren Sie dieses Programm zuerst ohne und dann mit der %global-Anweisung , undachten Sie auf die Überschrift (title) im Output-Fenster. Wenn Sie die %global-Anweisungweglassen, erscheint im Log-Fenster für das <strong>Makro</strong> write folgende Mitteilung:WARNING: Apparent symbolic reference MONAT not resolved.16


Dies bedeutet, daß der <strong>Makro</strong>-Prozessor die <strong>Makro</strong>variable monat nicht auflösen kann, da diese nurlokal für das <strong>Makro</strong> compute vereinbart wurde. Fügen Sie jetzt die %global-Anweisung wiederhinzu, ist die Variable monat global vereinbart und kann überall verwendet werden.Ausnahme: Globale <strong>Makro</strong>variablen können nicht innerhalb eines <strong>Makro</strong>s verwendet werden,wenn die <strong>Makro</strong>variablen 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 <strong>Makro</strong>s.4.1.2 Die %Local-AnweisungSyntax: %local <strong>Makro</strong>variablenname;Beispiel:%local nummer;Die %local-Anweisung benennt Variablen, die nur innerhalb des aktuellen <strong>Makro</strong>s Gültigkeithaben. Dies ist nur dann notwendig, wenn die Variable bereits außerhalb existiert. Dies kann z.B.zum Schutz von Indexvariablen sein, die nicht überschrieben werden sollen. Die %local-Anweisung kann nur innerhalb von <strong>Makro</strong>s verwendet werden. Variablen, die mit einer %local-Anweisung definiert wurden, besitzen den Wert 0, solange ihnen kein anderer Wert mittels einer%let-Anweisung zugewiesen wurde. Dieser Wert gilt aber nur innerhalb des <strong>Makro</strong>s.Variablen mit gleichem Namen, die bereits in der Umgebung definiert wurden, behalten ihren zuvorvereinbarten Wert.4.2 <strong>Makro</strong>s innerhalb von <strong>Makro</strong>sWird in einem <strong>Makro</strong> ein anderes <strong>Makro</strong> aufgerufen, spricht man von verschachtelten (odergenesteten) <strong>Makro</strong>s. Die globale äußere Umgebung wird als Niveau 0 bezeichnet. Je tiefer dieVerschachtelung fortschreitet, desto höher wird das Niveau gezählt.Eine <strong>Makro</strong>variable ist innerhalb der Umgebung, in der sie definiert wurde und in jeder höherenUmgebung referenzierbar (also in den verschachtelten <strong>Makro</strong>s).Beispiel: %macro drei;proc means data=&sds;NIVEAU 3 var &xvar &yvar;run;%mend drei;%macro zwei;proc gplot data=&SDS;NIVEAU 2 plot &yvar*&xvar;run;%drei%mend zwei;%macro eins(SDS,yvar,xvar);proc print data=&SDS;NIVEAU 1 var &yvar &xvar;run;%zwei%mend eins;Aufruf: %eins(co.blutbild,alter,albumin)17


In diesem Beispiel ruft das tiefste <strong>Makro</strong> eins, das höher verschachtelte <strong>Makro</strong> zwei auf, welcheswiederum das <strong>Makro</strong> drei aufruft. Sowohl <strong>Makro</strong> zwei, als auch <strong>Makro</strong> drei verwenden die<strong>Makro</strong>variablen sds, yvar und xvar, die im <strong>Makro</strong> eins definiert wurden.Übungsaufgaben10. Beantworten Sie zu dem folgenden <strong>SAS</strong>-<strong>Makro</strong> untenstehende Frage:%let id=ssn;%macro write(SDS=_last_);%let ort=NEW YORK;proc sort data=&SDS;by &id;proc print;title1 "Arbeiter im &ort Büro";title2 "aufgelistet nach &id";footnote "Stand: &sysdate";run;%mend write;Welche der folgenden Variablen sind lokal, welche global? Warum?id, SDS, ort, sysdate;11. Welcher <strong>SAS</strong>-Code wird von dem <strong>Makro</strong>%let first=Text außerhalb des <strong>Makro</strong>s definiert;%macro refs;%local first;%global second;%let first=Text innerhalb des <strong>Makro</strong>s definiert;%let second=Zweite Textzeile;%let third=Dritte Textzeile;%put first;%put second;%put third;%mend refs;erzeugt, wenn nacheinander die Zeilen%refs%put &first;%put &second;%refs%put &first;%put &second;%put &third;submittiert werden?12. Schreiben Sie ein <strong>Makro</strong> %machdat, mit dem sie sich einen Datensatz erstellen können, derzwei zufällig normalverteilte Variablen besitzt (x und y) und eine Indexvariable i, die gleichzeitigdie Anzahl der Beobachtungen sein soll. Übergeben Sie an das <strong>Makro</strong> außerdemeinenSchlüsselparameter, der den Dateinamen enthält (Variable dateinam) (Tip: Verwenden Siedie rannor-Funktion und eine do-Anweisung).Schreiben Sie ein zweites <strong>Makro</strong> %prinsort, das Datensätze sortieren und ausgeben kann(Proc Sort und Proc Print). Verschachteln Sie dieses <strong>Makro</strong> im <strong>Makro</strong> %machdat, sodaß sieden soeben erstellten Datensatz damit bearbeiten können (Zusatz: Vereinbaren Sie dieVariable, die den Dateinamen enthält als globale <strong>Makro</strong>variable).5. <strong>SAS</strong>-<strong>Makro</strong>-Programmanweisungen18


<strong>Makro</strong>-Programmanweisungen sind die Datenschritt-Anweisungen der <strong>Makro</strong>-Sprache. Sieunterscheiden sich oftmals nur dadurch, daß die <strong>Makro</strong>-Programmanweisungen mit einem "%"beginnen und dadurch den <strong>Makro</strong>-Prozessor ansprechen.Sie können alle <strong>Makro</strong>-Programmanweisungen innerhalb von <strong>Makro</strong>s benutzen, manche zusätzlichauch außerhalb von <strong>Makro</strong>s.<strong>Makro</strong>-Programmanweisungen und wo sie benutzt werden können:Anweisungen, die überall benutzt werdenkönnenAnweisungen, die nur innerhalb von <strong>Makro</strong>sbenutzt werden können%* %MACRO %DO %IF-%THEN%DISPLAY %MEND %DO %UNTIL Iteratives %DO%GLOBAL %PUT %DO %WHILE %label%INPUT %SYSEXEC %END %LOCAL%KEYDEF %WINDOW %GOTO%LET5.1 %*-AnweisungDiese Anweisung dient der Kommentierung des <strong>Makro</strong>s. Sie kann überall verwendet werden. ImUnterschied zu normalen Kommentarzeilen (*..;) erscheinen die <strong>Makro</strong>-Kommentare nicht imLog-Fenster. Wie gewohnt können Sie aber auch mit der Zeichenfolge /*......*/kommentieren.Syntax:%*Kommentar;Beispiel: %macro kommenta(sds,x);%*Dieses <strong>Makro</strong> überprüft, ob versehentlich eineIdentifikationsnummer vergeben wurde, diekleiner als 0 ist.;data _null_;%***Schreibe die Beobachtungen mit x


%mend testput;%testput;Ergebnis: <strong>Makro</strong> TESTPUT beginnt die Ausführung<strong>Makro</strong> TESTPUT beginnt am Friday.Semikolons(;) beenden <strong>SAS</strong>-Anweisungen.Fisher's exakter Test Die erste %put-Anweisung schreibt eine einfache Textzeile. Es müssen am Satzende zwei Punkte verwendet werden, da ein Punkt automatisch alsBegrenzungszeichen erkannt wird und erst der zweite Punkt den Satz beendet. Um ein Semikolon als Textzeichen zu verwenden, muß die %str-Funktion verwendet werden,die Sonderzeichen als Text behandelt. Produziert eine Leerzeile; Diese %put-Anweisung erzeugt ein offenes Anführungszeichen. Dies erkennt <strong>SAS</strong> nur dann alsTextzeichen, wenn das Prozentzeichen davor steht. Probieren Sie aus, was passiert, wenn Siedas Prozentzeichen weglassen.5.3 %Input-AnweisungMit der %input-Anweisung ist es möglich, während des Ablaufs eines <strong>Makro</strong>s Daten vomBenutzer zu erfragen. Diese können sogleich im <strong>Makro</strong> verwendet werden, indem der erfragte Werteiner <strong>Makro</strong>variable zugewiesen wird.Die %input-Anweisung kann innerhalb und außerhalb von <strong>Makro</strong>s verwendet werden, allerdingsnur im interaktiven Modus. Werte mit Leerzeichen müssen in Anführungszeichen eingegebenwerden, z.B. bei Vor- und Nachname.Syntax:Beispiel:Aufruf:%INPUT name1 name2...;%macro identi;%put Nennen Sie Ihren Namen und Wohnort;%input Name Ort;%put Nennen Sie Ihr Alter;%input alter;%put &Name wohnt in &ort, und ist &alter alt.;%mend identi;%identi;Wenn Sie das <strong>Makro</strong> %identi submittieren und aktivieren, erscheint der Text der %put-Anweisungen im Log-Fenster und verlangt die Eingabe ihrer Daten. Sie schreiben diese in denProgramm Editor und submittieren anschließend. Mit Hilfe der %input-Anweisung erfasst der<strong>Makro</strong>-Prozesor nun den Wert ihrer Variable.Werden mehr Werte angegeben, als Variablen definiert sind, werden diese in der automatischenVariable SYSBUFFR gespeichert (siehe Seite 80 in "<strong>SAS</strong> Guide to Macro Processing").Der einfachste Weg, einen aus mehreren Teilen bestehenden Wert aufzunehmen, ist der Umwegüber die SYSBUFFR-Variable.Beispiel:%macro vornach;%put Geben Sie ihren vollen Namen an;%input;%let name=&sysbuffr;20


%put &name;%mend vornach; Der <strong>Makro</strong>-Prozessor schreibt zunächst die Antwort auf die erste %put-Anweisung in dieautomatische Variable &SYSBUFFR. Danach wird mit der %let-Anweisung vereinbart, daß der Inhalt von SYSBUFFR in die Variablename geschrieben wird.5.4 %If - %Then / %Else-AnweisungMit dieser Anweisung können Anweisungen bedingt ausgeführt werden.Die %if-%then/%else-Anweisung der <strong>Makro</strong>-Sprache funktioniert synonym zur if-then/elseAnweisung im Datenschritt. Sie kann nur innerhalb von <strong>Makro</strong>s verwendet werden.Syntax:%IF logischer Ausdruck %THEN <strong>SAS</strong>-Anweisung;%ELSE <strong>SAS</strong>-Anweisung;Die %else-Anweisung ist optional.Die <strong>SAS</strong>-Anweisungen, die %then und %else folgen, können• <strong>Makro</strong>-Programmanweisungen,• konstanter Text und• logische Ausdrückesein.Beispiel: %if &i=1 and &j>5%then %put Überprüfen Sie die Indexvariablen.;%else %put Alles Okay;Wenn die <strong>Makro</strong>variablen i gleich 1 und j größer als 5 sind, dann, und nur dann, soll ins Log-Fenster Überprüfen Sie die Indexvariablen geschrieben werden. Sonst (%else) soll imLog-Fenster Alles okay erscheinen.5.5 %Do - %End-AnweisungSie können mit der %do und der %end-Anweisung eine Do-Gruppe definieren, die als Blockausgeführt wird. In Verbindung mit der %if-%then-Anweisung können Sie auf diese Weisemehrere <strong>SAS</strong>-Anweisungen ausführen. Die %do-%end-Anweisung kann nur innerhalb eines<strong>Makro</strong>s verwendet werden.Syntax:%do;%end;Text und <strong>Makro</strong>-ProgrammanweisungenBeispiel:%macro frage(aaa,sds);%if &aaa=1 %then %do;Proc Print data=&sds;run;%end;%else %do;Proc contents data=&sds;run;%end;%mend frage;21


Aufruf:%frage(1, co.iris)%frage(Unsinn, co.iris) Falls die Variable aaa den Wert 1 annimmt, wird die Prozedur Print verwendet. Falls die Variable aaa einen anderen Wert als 1 zugewiesen bekommt, wird die ProzedurContents ausgeführt.Übungsaufgabe13. Erzeugen Sie ein <strong>Makro</strong> NUMMER, das zuerst abfragt, welchen Datensatz Sie bearbeitenwollen, und danach folgenden Text im Log-Fenster erzeugt:Wählen Sie eine der beiden Möglichkeiten:Ausdruck (geben Sie eine 1 ein)Mittelwerte (geben Sie eine 2 ein).Je nachdem, welche Entscheidung der Benutzer getroffen hat, soll nun entweder ProcPrint oder Proc Means ausgeführt werden. Kommentieren Sie das <strong>Makro</strong> entsprechendseinen Programmteilen.5.6 %Do - %To - %End-Anweisung (Iterative %Do-Anweisung)Die %Do-%To-%End-Anweisung führt bis zu einem definierten Endpunkt immer wieder diegleichen Programmteile aus. Man spricht von iterativen %Do-Schleifen (loops).Iterative %Do-Schleifen sind nicht mit %while und %until verknüpfbar.Syntax:%do <strong>Makro</strong>variable=Start %to Stop ;Text und <strong>Makro</strong>-Programmanweisungen%end;<strong>Makro</strong>variableBenennt eine <strong>Makro</strong>variable, deren Wert die Anzahl der %Do-Schleifen regelt.Existiert diese Indexvariable noch nicht, wird sie vom <strong>Makro</strong>-Prozessorangelegt.start Startpunkt der %Do-Schleifen, muß ganzzahlig sein.stop Endpunkt der %Do-Schleifen, muß ganzzahlig seinInkrement Mit der optionalen %by-Anweisung kann vereinbart werden, in welchenSchritten die %DO-Schleife ausgeführt wird (Standard=1).Beispiel 1: %macro create;%do i=1 %to 3;data monat&i;infile in&i;input produkt kosten datum;run;%end;%mend create;Aufruf: %create;Ergebnis: data monat1;infile in1;input produkt kosten datum;run;data monat2;22


infile in2;input produkt kosten datum;run;data monat3;infile in3;input produkt kosten datum;run;Die %do-Schleife wird 3 mal hintereinander ausgeführt. Die Indexvariable i wird in jedemDurchgang um das Inkrement 1 erhöht.Es ist auch möglich %Do-Schleifen zu verschachteln:Beispiel 2: %macro create2;%do jahr=90 %to 92;%do mon=1 %to 12;data dat_&jahr&mon;infile in&jahr&mon;input person umsatz zeit;run;%end;%end;%mend create2;Aufruf: %create2;Die Schleife wird 36 mal(3*12) durchgeführt, und erzeugt für jeden Monat der Jahre 90 bis 92 einenDatenschritt (siehe Ergebnis des ersten Beispiels).5.7 %Do - %Until - %End-AnweisungDie %Do - %Until -Anweisung führt die %Do-Schleife so lange aus, bis eine zuvor vereinbarteBedingung erfüllt ist.Syntax:Beispiel:Aufruf:%do %until (Ausdruck);Text und <strong>Makro</strong>-Programmanweisungen%end;%macro tue_bis(num);%put Start Macro tue_bis: num ist &num;%do %until(&num>10);%put ****&num****;%let num=%eval(&num+1);%end;%put Ende Macro tue_bis: num ist &num;%mend tue_bis;%tue_bis(-23)In unserem Beispiel soll die %do-%until-Schleife so lange ausgeführt werden, bis die VariableNUM größer als 10 ist. Nach jedem Durchgang bekommt die Variable NUM mit Hilfe der %eval-Funktion (siehe Kap. 6.2) zu ihrem Ausgangswert (im Beispiel -23) eine 1 aufaddiert, und erhältsomit einen neuen Wert. In dem Moment, in dem dieser Wert größer als 10 (also bei 11) gewordenist, bricht das <strong>Makro</strong> ab und es erscheint die Meldung, daß das <strong>Makro</strong> beendet ist.5.8 %Do - %While - %End-Anweisung23


Die %Do-%While-%End-Anweisung wiederholt Programmanweisungen, solange eine Bedingungerfüllt bleibt.Syntax:%Do %While(logischer Ausdruck);Text und <strong>Makro</strong>-Programmanweisungen;%End;Beispiele: %do %while(&a


un;%kurz: proc print data=_last_(obs=10);run;%mend info;Aufruf:%infoDas <strong>Makro</strong> Info kann über den zuletzt benutzten Datensatz (data=_last_) optional kurz oderlang Auskunft geben. Wenn eine 2 eingegeben wird, springt der <strong>Makro</strong>-Prozessor automatisch zurSprungmarke %kurz und führt die Prozedur Print für 10 Beobachtungen durch.5.10 %Sysexec-AnweisungMit Hilfe der %sysexec-Anweisung können innerhalb und außerhalb von <strong>Makro</strong>s Betriebssystemkommandosausgeführt werden.Syntax:Beispiel:Beispiel:Aufruf:%sysexec Kommando;%sysexec cd\;%sysexec time;%macro makedir;if %upcase(&sysscp)=WIN %then%do;%sysexec cd\;%sysexec md Aufgabe;%end;%else %if %upcase(&sysscp)=RS6000 %then%do;%sysexec mkdir aufgabe;%end;%mend makedir;%makedir;Das <strong>Makro</strong> makedir erstellt auf Betriebssystemebene, wenn Sie unter <strong>SAS</strong> für Windows arbeiten,im Laufwerk D: das Verzeichnis aufgabe. Falls Sie unter AIX arbeiten, wird das Verzeichnisaufgabe in ihrem Home-Verzeichnis angelegt.25


5.11 %Keydef-AnweisungDie %keydef-Anweisung ermöglicht die Definition und Abfrage von Funktionstastenbelegungen.Sie ist sowohl lokal als auch global verwendbar. Die Definition gilt nur für die aktuelle Sitzung odersolange, bis sie geändert wird. Sie können so z.B. <strong>Makro</strong>s über Funktionstasten aufrufen.Syntax:%keydef key-name | 'key-name' | "keyname" ;key-name ist der Name einer beliebigen Funktionstaste, z.B. F1. Die maximale Längefür keyname ist 8 Zeichentext kann jeder beliebiger Text sein, die maximale Länge beträgt 80 Zeichen. FallsSie Anführungszeichen, Semikola u.ä. verwenden wollen, müssen Sie denText in Anführungszeichen setzen.Beispiele: %keydef f12 zoom;%keydef f5 "clear log; clear output";%keydef f11 %makedir;Übungsaufgaben14. Erzeugen Sie ein <strong>Makro</strong> MENUE, das folgenden Text im Log-Fenster erzeugt:Sie haben folgende Möglichkeiten:1. Patientenaufnahme2. Löschen eines Patienten3. Listenausdruckmit Sortierreihenfolgea. Familiennameb. WohnortTreffen Sie Ihre Entscheidung: ___(Tip: %input und %str.)15. Schreiben Sie ein <strong>Makro</strong> PROMPT, das den Namen einer <strong>SAS</strong>-Prozedur und den Namen des<strong>SAS</strong>-Datensatzes erfragt und die gewünschte Prozedur ausführt (Hinweis: Dies ist nicht füralle Prozeduren möglich).5.12 %Window-AnweisungDie %Window-Anweisung erzeugt Fenster, die vom <strong>Makro</strong>-Prozessor gesteuert werden. <strong>Makro</strong>-Windows können Text darstellen und Eingabe aufnehmen. Sie haben verschiedene Gestaltungsoptionen,z.B. Farbe, Schriftpositionierung usw.Mit der %window-Anweisung definierte Fenster, können mit der %display-Anweisung (siehe5.13) am Bildschirm anzeigt werden. Einmal definiert, gilt das Fenster bis zum Ende der aktuellen<strong>SAS</strong>-Sitzung. Der Name des Fensters erscheint in der Kopfzeile. Es kann sowohl über Kommandoalsauch über Message-Zeilen verfügen. Anstatt der Kommandozeile kann man dem Fenster auchein Pull-Down-Menü zuweisen, welches man zuvor mit der PMENU-Routine gebildet hat.Syntax:%window Fenstername Feld-Definition-1;%window Fenstername Gruppen-Definition-1;26


Fenstername benennt das Fenster und muß angegeben werden. Es gelten dieüblichen <strong>SAS</strong>-Namenskonventionen.Fensteroptionen spezifizieren allgemeine Eigenschaften des Fensters.Felddefinitionen Felder verbinden Text oder <strong>Makro</strong>variablen mit einer Position imFenster und dessen EigenschaftenGruppen definiert eine Gruppe von Feldern, die gleichzeitig angezeigtwerden.Beispiel:Aufruf:%window fenster color=black irow=5#10 @10 'Dies ist mein erstes Fenster' color=white;%display fenster;FensternameFensteroptionenFelddefinitionen5.12.1 FensteroptionenEs gibt folgende Optionen für die Fenstergestaltung, die Sie verwenden können:columns=SpaltenanzahlHier bestimmen Sie die Anzahl der Spalten des Fensters, inklusive dem Rand. Wenn Siedies nicht ausdrücklich festlegen, wird die größtmöglichste Spaltenanzahl, die auf demjeweiligen Monitor möglich ist, gewählt.rows=ZeilenanzahlAnzahl der Zeilen des Fensters inkl. Rand, auf die das Fenster plaziert wird (Die Anzahlder Zeilen ist abhängig vom verwendeten Monitor).icolumn=SpalteSteht für "Initial Column" (frei übersetzt "anfängliche Spalte"). Definiert die Spalte, auf diedas Fenster plaziert wird (Default=1, dies ist die linke obere Ecke des Fensters).irow=ZeileSteht für "Initial Row". Bestimmt die Zeile, auf die das Fenster plaziert wird (def.=1).color=FarbeSpezifiziert die Hintergrundfarbe des Fensters.Die Darstellung der Farben ist abhängig vonihrem Bildschirm. Folgende Farben können Sie wählen:Black Gray (oder Grey) PinkBlue Green RedBrown Magenta WhiteCyan Orange Yellowkeys=keys-entrySie können an dieser Stelle bestimmen, in welchem Katalog ihreFunktionstastenbelegungen zu finden sind. Ohne Katalogangabe wird der von <strong>SAS</strong>angelegte Katalog sasuser.profile verwendet.menu=pmenu-entryFalls Sie sich mit der Prozedur PMENU ein eigenes Pull-Down-Menü angelegt haben,können sie an dieser Stelle den Katalog vereinbaren, in dem das PMENU abgelegt ist. OhneKatalogangabe wird der von <strong>SAS</strong> angelegte Katalog <strong>SAS</strong>user.profile verwendet.5.12.2 Felddefinitionen27


Feld-Definitionen verbinden konstanten Text oder <strong>Makro</strong>variablen mit einer Position im Fensterund dessen Attributen.Konstanter Text muß in Anführungszeichen stehen.Felder dürfen sich nicht überlappen. Es können sonst Fehler auftauchen, wie z.B. die inkorrekteZuweisung von Werten zu einer <strong>Makro</strong>-Variable, da diese an einer falschen Stelle vereinbart sind.Syntax einer Feld-Definition mit konstantem Text: 'Text' | "Text“ Syntax einer Feld-Definition mit <strong>Makro</strong>variable: <strong>Makro</strong>-Variable rowcolumnbezeichnet die genaue Position einer <strong>Makro</strong>-Variable oder eines konstanten Textes imFenster.Sie vereinbaren die Position mit Hilfe von Zeilen- bzw. Spaltenpointern:Zeilenpointer (row): # und / (bewegt den Pointer in die nächste Zeile, auf Spalte 1)Spaltenpointer (column): @ und + (bewegt den Pointer in derselben Zeile, um eine von ihnenbestimmte Anzahl von Spalten weiter.)Beispiel: #3 @5 "Geben Sie ihren Vornamen ein";Der Text erscheint in der dritten Zeile, beginnend mit der fünften Spalte.'Text' | "Text"An dieser Stelle können Sie einen konstanten Text darstellen. Der Text muß inAnführungszeichen geschrieben sein.<strong>Makro</strong>-Variablebenennt eine <strong>Makro</strong>-Variable, deren Wert entweder erscheinen soll, oder die an dieser Stelleeinen Wert erhalten soll.Feldlängedefiniert, wie lang die Eingabe des Wertes der <strong>Makro</strong>-Variable sein soll. Dies beeinflußtallerdings nicht die vereinbarte Länge der <strong>Makro</strong>-Variable. Wenn Sie lediglich den Wert einer<strong>Makro</strong>variablen darstellen wollen, wählt der <strong>Makro</strong>-Prozessor automatisch die ihrer Größeentsprechende Länge der Variablen.OptionenEs gibt folgende Optionen:ATTR=attribute (Abkürzung A=)Mit Hilfe dieser Option können Sie vereinbaren, wie ihr Feld aussehen soll.Es gibt folgende Möglichkeiten:BLINK (blinkendes Feld)HIGHLIGHT (hell leuchtendes Feld)REV_VIDEOUNDERLINE (Feld wird unterstrichen)COLOR=color (Abk. C=)spezifiert die Farbe, in der ihr Feld erscheinen soll.28


PROTECT=YES|NOFalls Sie PROTECT=YES angeben, ist ihr Feld geschützt und kann nicht überschriebenwerden. Dies ist nur dann sinnvoll, wenn Sie eine <strong>Makro</strong>-Variable in einem Felddarstellen wollen; konstanter Text ist automatisch geschützt.REQUIRED=YES|NOvereinbart, daß eine Eingabe ins Feld erfolgen muß, da der <strong>Makro</strong>-Prozessor sonstnicht zum nächsten Feld springt.DISPLAY=YES|NObestimmt, ob die Eingabe am Bildschirm erscheint oder nicht, z.B. bei der Abfrage vonPasswörtern.AUTOSKIP=YES |NO (Abkürzung Auto=)Kontrolliert, ob der Cursor automatisch auf das nächste Eingabefeld springt oder erstnach Drücken der Enter-Taste. Wenn Sie AUTOSKIP=YES angeben, springt derCursor automatisch in das nächste ungeschützte Eingabefeld.5.12.3 Gruppen-DefinitionDie Gruppendefinition definiert eine Gruppe von Feldern, die gleichzeitig in einem Fensterangezeigt werden.Syntax:GROUP=GruppennameDer Gruppenname muß den üblichen <strong>SAS</strong>-Namenskonventionen entsprechen.Zum Aufruf ist dann sowohl der Name des Fensters, als auch der Gruppenname anzugebenBeispiel: Fenster.monatDamit wird die Gruppe monat des Fensters Fenster aufgerufen.5.12.4 Automatische VariablenDie %window-Anweisung generiert automatisch die beiden folgenden Variablen:SYSCMD,die den Text des letzten Fensterkommandos enthält undSYSMSG,die den Text enthält, der in der Message-Zeile (erscheint unter der Komanndozeile)ausgegeben werden kann. Der Wert der Variable SYSMSG kann z.B. über eine %let-Anweisung definiert werden.BeispieleBeispiel 1:Das erste Fenster soll nur drei Textzeilen anzeigen.%window grusswin color=white#9 @32 'Guten Tag, hier ist ihr <strong>SAS</strong> System!'attr=highlight color=black#11 @35 "Heute ist &sysday, der &sysdate.." color=black#17 @28 'Drücken Sie die Enter-Taste um weiterzumachen.'color=blue;%display grusswin;29


Das Fenster grusswin begrüßt den Benutzer und zeigt das aktuelle Datum (mit Hilfe der beidenautomatischen <strong>Makro</strong>variablen &sysday und &sysdate) an. Die Hintergrundfarbe ist Gelb, derText erscheint Schwarz und Blau. Außerdem hat die erste Zeile das Attribut highlight.Um das Fenster am Bildschirm anzeigen zu lassen, ist folgende <strong>Makro</strong>-Programmanweisung nötig:%display grusswin;Folgendes Fenster erscheint auf dem Bildschirm:Beispiel 2:Im zweiten Beispiel werden zwei Gruppen definiert, die wahlweise angezeigt werden sollen.%window eingabe color=whitegroup=lang#3 @5 "Geben Sie in die folgenden Zeilen bitte die Daten ein." c=black#5 @5 "Bedenken Sie dabei, das Sie für das Geschlecht" c=black#7 @5 "folgende Codierung vornehmen müssen:" c=black#9 @5 "Frauen=1, Männer=0" c=blackgroup=kurz#11 @8 "Name:" c=black @20 name 34 attr=underline required=yes c=black#13 @8 "Geschlecht:" c=black @20 sex 1 attr=underline required=yesc=black#15 @8 "Alter:" c=black @20 alter 2 attr=underline required=yesc=black;%macro DISP(typ);%if &typ=lang %then %display eingabe.lang noinput;%display eingabe.kurz;%mend DISP;In dem Fenster EINGABE enthält die Gruppe LANG eine ausführliche Anleitung zur Dateneingabe,die Gruppe KURZ zeigt dagegen lediglich die Variablennamen an.Das <strong>Makro</strong> DISP zeigt entweder beide Gruppen des Fensters an oder nur die kürzere Version, jenachdem welchen Wert die Variable Typ besitzt.Der Aufruf %DISP(lang)führt dazu, daß beide Gruppen des Fensters angezeigt werden, wie inBild 2 zu sehen ist.30


Bild 2: <strong>Makro</strong> DISP zeigt beide Gruppen des Fensters an.Falls die <strong>Makro</strong>variable TYP allerdings einen anderen Wert als "lang" zugewiesen bekommt, wirdnur die kurze Version am Bildschirm präsentiert, z.B. %DISP(x).Bild 3: <strong>Makro</strong> DISP zeigt nur die Gruppe "kurz" an.5.13 %Display-AnweisungMit Hilfe der %Display-Anweisung können <strong>Makro</strong>-Windows angezeigt werden. Wenn ein Fenstermit geschützten Feldern (Protect=YES) angezeigt wird, kann die Anzeige durch Drücken derEnter-Taste beendet werden. Wenn das Fenster ungeschützte Felder enthält, müssen zuerst Werte indie Felder eingegeben werden, bevor das Fenster geschlossen werden kann.Syntax:%DISPLAY Fenster ;Fenster benennt das Fenster, das angezeigt werden soll Falls das Fenster Gruppen enthält (siehe Bsp. 5.12), müssen an dieserStelle auch die Gruppen angegeben werden (müssen durch einenPunkt voneinander getrennt sein).NOINPUT Verhindert, das Werte in ein Feld eingegeben werden können.Außerdem können Sie die NOINPUT-Option verwenden, wenn Siemehrere Gruppen eines Fensters gleichzeitig anzeigen wollen. Durchdie NOINPUT-Option bleibt die Gruppe sichtbar, auch wenn spätereGruppen angezeigt werden.31


BLANK Löscht die Anzeige. Nur dann sinnvoll, wenn die %Display-Anweisung innerhalb eines <strong>Makro</strong>s verwendet wird, da ansonsten dieAnzeige automatisch nach Ausführung der %Display-Anweisungentfernt wird.BELL Sobald die Anzeige erscheint, ertönt ein kurzer Klingelton.DELETE Löscht den Fensterinhalt, nach dem das Fenster verarbeitet wurde(erst ab <strong>SAS</strong>-Version 6.10).Beispiel:%Display eingabe.kurz noinput bell;Übungsaufgabe16. Schreiben Sie ein <strong>Makro</strong> BEGINN, daß ein Fenster Anfang aufruft, das Sie am Anfangjeder <strong>SAS</strong>-Sitzung fragt, ob Sie folgende libname-Anweisungen setzen wollen:libname b'B:\';libname a'A:\';libname co 'N:\sasurz\daten';Falls die Abfrage mit JA (oder einer 1) beantwortet wird, sollen die Libname-Anweisungengesetzt werden.6. <strong>SAS</strong>-<strong>Makro</strong>-Funktionen<strong>Makro</strong>-Funktionen verarbeiten <strong>Makro</strong>ausdrücke, sogenannte Argumente, wie z.B. Variablen oderZahlenketten, und erzeugen daraus ein Resultat, z.B. einen Buchstaben oder eine Zahl. <strong>Makro</strong>-Funktionen sind sowohl lokal als auch global zu verwenden.Beispiel:%put %eval(200+400);In diesem Beispiel wird mit Hilfe der %Eval-Funktion die Summe der beiden Argumente 200 und400 berechnet. Mit Hilfe der %put-Anweisung wird das Resultat 600 ausgegeben.Die <strong>Makro</strong>-Funktionen lassen sich in vier Kategorien einteilen:1. Bearbeitung von Zeichenketten2. Auswertung von logischen und numerischen Ausdrücken3. Behandlung von speziellen Zeichen4. Interaktion mit Dateivariablen (siehe Kap. 7)32


6.1 Funktionen zur Bearbeitung von Zeichenketten%index%length%scan%substr%upcase%qscan, %qsubstr%qupcaseFindet das erste Auftreten einer ZeichenketteBestimmt die Länge des ArgumentsSucht nach WortenErzeugt einen SubstringVerwandelt Klein- in Großbuchstabenanalog zu oben, führen aber zusätzliche Quotierungendurch6.1.1 %Index-FunktionDie Funktion sieht nach, ob ein Argument in einer Zeichenkette (Quelle) vorhanden ist, und gibt diePosition, an der sich das Argument zum ersten Mal in der Zeichenkette befindet, zurück. Ist dasArgument nicht in der Quelle enthalten, wird eine 0 zurückgegeben.Syntax:%index(Quelle, Argument);Die Quelle und das Argument können• konstanter Text,• referenzierte <strong>Makro</strong>-Variable• andere <strong>Makro</strong>-Funktion und• <strong>Makro</strong>-Aufrufsein.Beispiel 1: %let a=ein sehr langer Wert;%let b=%index(&a,n);%put I erscheint an Position &b;Ergebnis: I erscheint an Position 3Im Beispiel 2 wird die %index-Funktion dazu benutzt, zu bestimmen, ob ein Datensatz (dsn)permanent oder temporär ist. Es wird überprüft, ob das Argument &dsn einen Punkt enthält. Enthältdas Argument keinen Punkt, so ist die If-Bedingung erfüllt, und der Datensatz wird als temporärerkannt.Beispiel 2:%macro check(dsn);%global name;%if %index(&dsn,.)=0%then %put Der Name des temporären Datensatz ist work.&dsn;%else %put Der Name des permanenten Datensatz ist &dsn;%mend check;Der Aufruf %check(report) liefert den SatzDer Name des temporären Datensatz ist work.report.Der Aufruf %check(daten.report) liefert als Ergebnis den SatzDer Name des permanenten Datensatz ist &daten.report.33


6.1.2 %Length-FunktionDiese Funktion ermittelt die Länge eines Arguments. Wenn das Argument einen Nullwert hat, gibtdie Funktion 0 zurück.Syntax:%length(Argument)Das Argument kann• konstanter Text,• referenzierte <strong>Makro</strong>-Variable• andere <strong>Makro</strong>-Funktion und• <strong>Makro</strong>-Aufrufsein.Beispiel:%let a=Guten;%let b=Tag;%put *%length(&a)* **%length(&b)** ***%length(&a&b)***;Ergebnis: *5* **3** ***8***6.1.3 %Scan- und %Qscan-FunktionDie Funktion %scan gibt das n-te Wort des argument zurück, wobei Worte Zeichenketten inargument sind, die durch Trennzeichen (delimiters) getrennt sind.Syntax:%scan(argument,n


Beispiel 1: %macro Verglei;%put Geben Sie ihr Geschlecht an (w für weiblich,m für männlich):;%input sex;%if &sex =W %then %put weiblich;%else %put männlich;%mend verglei;Aufruf: %vergleiEingabe: wErgebnis: männlich Wenn Sie für Geschlecht ein W eingeben, soll weiblich ausgegeben werden. In diesemBeispiel passiert dies allerdings nur, wenn sie ein großes W eingeben. Bei einem kleinenBuchstaben erscheint männlich.Beispiel 2: %macro Verglei;%put Geben Sie ihr Geschlecht an (W für weiblich,M für männlich):;%input sex;%if %upcase(&sex) =W %then %put weiblich;%else %put männlich;%mend verglei;Aufruf: %vergleiEingabe: wErgebnis: weiblich Mit Hilfe der %upcase-Funktion wird auch das kleine w als weiblich erkannt.Die Funktion ist identisch mit der %upcase-Funktion, mit dem Unterschied, daß sie ein quotiertesResultat liefert (zu Quoting siehe Kap. 6.3).Syntax:%qupcase(argument)Beispiel: Ergebnis:%let x=%nrstr(%eval(5+23)); *%eval(5+23)* *%EVAL(5+23) *28*%put *&x* *%qupcase(&x)*%upcase(&x)*;Übungsaufgabe17. Verwenden Sie die <strong>Makro</strong>-Funktionen, um aus einem zweiteiligen <strong>SAS</strong>-Dateinamen denLibref und den eigentlichen Dateinamen herauszulesen. Vereinbaren Sie, daß als Default- Wertimmer der zuletzt verwendete Datensatz verwendet wird (Tip: syslast).36


6.2 %Eval Funktion zur Auswertung von logischen und numerischenAusdrückenZur Auswertung von logischen und numerischen Ausdrücken steht die %eval-Funktion zurVerfügung. Da der <strong>Makro</strong>-Prozessor buchstabenbasiert arbeitet, werden Zahlen normalerweise alsBuchstaben behandelt.Beispiel: %let y=100+200; erzeugt nicht y=300, sondern y=100+200.%let %eval(100+200); erzeugt y=300.6.2.1 %Eval-FunktionDie Funktion %eval• wertet logische und numerische Ausdrücke aus• erlaubt nur ganzzahlige Arithmetik (keine nichtganzzahlige),• schneidet nichtganzzahlige Werte ohne Warnung ab (rundet somit immer ab),• erlaubt keine Verkettung (||,concatenation) und kein Minimum und Maximum (> LT, GT kleiner als, größer als 6= LE, GE kleiner gleich, größer gleich 6¬= ^= ~= NE ungleich 1) 6& AND logisches Und 7| OR logisches Oder 81)Die Symbole hierfür sind tastaturabhängig.Mnemonic ist eine alternative Schreibweise.37


Beispiele:%let wert=%eval(50+60);%put Der wert ist:&wert;%let x=50;%let y=60;%let wert=%eval(&x+&y);%put Der wert ist:&wert;%let wert=%eval(&x+&y/11);%put Der wert ist:&wert;%let wert=%eval((&x+&y)/11);%put Der wert ist:&wert;Ergebnisse:Der wert ist:110Der wert ist:110Der wert ist:55(sollte eigentlich 55,4545 sein, die %eval-Funktion rundet aber immer ab)Der wert ist:10Übungsaufgaben18. Lassen Sie sich mit Hilfe von <strong>Makro</strong>funktionen ihren Namen in Großbuchstaben ausgeben unddie Anzahl der Buchstaben.19. Erstellen Sie ein <strong>Makro</strong> INTSUM, das die Zahlen von 1 bis N aufsummiert, wobei N alsArgument mitgegeben wird und das <strong>Makro</strong> nur das Ergebnis zurückgeben soll (Tip: Die Formeldazu lautet n(n+1)/2).a) Rufen sie das <strong>Makro</strong> mit N=10 in einer %let-Anweisung und weisen Sie das Ergebnis derVariable TOTAL zu, die mit einem anschließenden %put ausgegeben wird.b) Behandeln sie das <strong>Makro</strong> wie eine Funktion, indem Sie das Ergebnis in einem Datenschritt einerVariable SUM zuweisen und mit put (nicht %put) ausgegeben.c) Schreiben Sie ein <strong>Makro</strong> GETSUM (ohne Parameter), das das <strong>Makro</strong> INTSUM als Funktionverwendet, indem INTSUM in einem Datenschritt für die Werte N=1, 2, 3, 4 und 5 aufgerufenwird. GETSUM soll den gesamten Datenschritt mitsamt PUT-Anweisungen zur Ausgabe derErgebnisse erzeugen.d) Erweitern Sie das <strong>Makro</strong> GETSUM durch Aufrufparameter, die das erste und letzte N angeben,für die die Summen gebildet werden sollen und eventuell die Zwischenschritte (Inkrements)(Tip: %Do-Schleife).6.3 Funktionen zur Bearbeitung von speziellen Zeichen (Textfunktionen)Da bestimmte Textzeichen, wie z.B. Prozentzeichen, Semikolon oder Anführungszeichen für den<strong>Makro</strong>-Prozessor eine andere Bedeutung haben, bzw. der <strong>Makro</strong>-Prozessor anders darauf reagiert,als im normalen <strong>SAS</strong>-System, bedarf es spezieller Funktionen, der Quoting-Funktionen, um deren"normale" Bedeutung innerhalb des <strong>Makro</strong>systems zu erzielen, und sie als Teil des Textes zuinterpretieren.Folgende Zeichen werden vom <strong>Makro</strong>-Prozessor nicht als Textzeichen interpretiert:Zeichen Bedeutung; Ende einer Anweisung, Trennung von Argumenten einer Funktion/ eines <strong>Makro</strong>s&, %Referenz auf <strong>Makro</strong>- Variablen und -Aufruf+,-,*,/, u.ä. werden als arithmetische und Vergleichsoperatoren erkanntLT, NE, u.ä. werden als logische Operatoren erkanntLeerzeichen nicht unterdrücken38


Übersicht über die Textfunktionen:Funktion Berücksichtigte Zeichen Beschreibung%str ; , + - * / ** | = LT quotiert konstanten Text zur Zeit derLE u.ä.Kompilierung%nrstr s.o., zusätzlich % und & s.o.%quote ; , + - * / ** | = LT quotiert konstanten Text zur Zeit derLE u.ä.<strong>Makro</strong>-Ausführung%bquote siehe %quote, zusätzlich offene s.o.Anführungszeichen & Klammern(unmatched)%nrquote siehe %quote, zusätzlich % und & s.o.%nrbquote vereinigt die Funktionen von s.o.%bquote und %nrquote%unquote löst Quotierungen wieder auf löst Quotierungen zur Zeit der<strong>Makro</strong>-Ausführung wieder auf%superq & und % verhindert das Auflösen von<strong>Makro</strong>ausdrücken bei der Auflösungvon <strong>Makro</strong>variablen.6.3.1 %Quote-FunktionDie %quote-Funktion quotiert während der <strong>Makro</strong>-Ausführung konstanten Text. Die Funktionentfernt allerdings nicht die Bedeutung von Hochkommata, Klammern oder <strong>Makro</strong>hinweiszeichen,wie % und &.Syntax:Beispiel:%quote(Argument)%macro dept1(bdl);%if %quote(&bdl)=bw %then %put Bundesland BadenWürttemberg;%else %put Bundesland;%mend dept1;6.3.2 %Bquote-FunktionDie Funktion verarbeitet Argumente, die besondere Zeichen enthalten, welche der <strong>Makro</strong>-prozessornormalerweise nicht als Textzeichen interpretieren würde, z.B. offene Anführungs-zeichen undKlammern.Syntax:Beispiel:Aufruf:%bquote(Argument)%macro bq;%global platz;%put Geben Sie den Treffpunkt ein.;%input;%let platz=%bquote(&sysbuffr);%put &platz;%mend bq;%bqEingabe: Rick's Café39


Aufruf:%end;%put Ergebnis: &wert1 &op &wert2 =%eval(&wert1 %unquote(&op) &wert2);%ende:%mend rechne;%rechne(18,25,op=ADD);%rechne(18,25,op=diff);%rechne(18,25,op=mal); Wenn die Variable op den Wert ADD zugewiesen bekommt, wird sie in ein Pluszeichen (+)verwandelt. Durch die %str-Funktion wird das Pluszeichen von seiner Funktion als arithmetischesOperator enthoben. Es wird jetzt vom <strong>Makro</strong>-Prozessor als "normales" Textzeichen behandelt. Durch die %unquote-Funktion wird dem Pluszeichen (+) seine ursprüngliche Bedeutungzurückgegeben, und es kann als arithmetischer Operator verwendet werden.Ohne Rück-Quotierung durch die %unquote-Funktion taucht folgende Fehlermeldung auf: ERROR:A character operand was found in the %EVAL function or %IF conditionwhere a numeric operand is required.6.3.6 %Str-FunktionDie %str-Funktion quotiert konstanten Text zur Zeit der Kompilierung (Konstruktion). DerZeitpunkt der Quotierung ist der grundlegende Unterschied zur %quote-Funktion, die bei jeder<strong>Makro</strong>-Ausführung neu durchgeführt wird. Wenn es darum geht, einen <strong>Makro</strong>-Ausdruckaufzulösen, sollte die %quote-Funktion benutzt werden.Die %str-Funktion entfernt nicht die Bedeutung von Ampersands, Prozentzeichen und nichtgeschlossenenHochkommata. Um nicht geschlossene Hochkommata zu quotieren, muß einProzentzeichen vor das Zeichen gesetzt werden:Beispiel:%let place=%str(Clinton%'s America);Die %str-Funktion sollte bei folgenden Gegebenheiten verwendet werden:• Wenn ein Semikolon statt als <strong>Makro</strong>ausdruck als Textzeichen verwendet werden soll.• Um ein Leerzeichen (Blank) bedeutsam zu machen.• Um ein nicht geschlossenes Hochkomma oder eine offene Klammer, die mit einemProzentzeichen versehen sind, zu benutzen.Syntax: %str(argument)Beispiele: %let p=%str(Proc Print; run;);%put &p;%let time=%str(now);6.3.7 %Nrstr-FunktionDie %nrstr-Funktion quotiert, zusätzlich zu den Funktionen der %str-Funktion, auchProzentzeichen und Hochkommata.Beispiel:%let p=%nrstr(%rechne);%put &p;41


6.3.8 %Superq-FunktionDiese Funktion verhindert die Auflösung von <strong>Makro</strong>-Ausdrücken bei der Auflösung von<strong>Makro</strong>variablen. Die %superq-Funktion ist in folgenden Fällen nützlich:• Bei Benutzung einer <strong>Makro</strong>variablen, die mit einer %Input- oder %Window- Anweisungdefiniert wurde und ein Ampersand oder Prozentzeichen enthält.• Bei Benutzung einer <strong>Makro</strong>variablen, die mit der SYMPUT-Routine geschaffen wurde undein Ampersand oder Prozentzeichen enthält.Syntax:%superq(<strong>Makro</strong>variable)Beispiel: %input x;%testvariable&anton%put Der Inhalt der Variablen x ist: %superq(x).;Ergebnis: Der Inhalt der Variablen x ist: %testvariable&antonÜbungsaufgaben20. Erzeugen Sie eine %put-Anweisung, die folgenden Text ins Log-Fenster schreibt:Der Wert von %sysdate ändert sich nicht innerhalb eines <strong>SAS</strong> Programms.21. Geben Sie folgende Sätze mit Hilfe von %put-Anweisungen im Log-Fenster aus:Das ist der Schnupperhund von C&A.Die Gewinner waren die Nummern 3;12;1 & 7So 'n Blödsinn!22. Stellen Sie sich vor, Sie arbeiten in der Univerwaltung und sind für die Adreßkartei derStudenten zuständig.Schreiben Sie ein <strong>Makro</strong>, das Ihnen schnell summarische Informationen über die Studentenliefern kann.Das <strong>Makro</strong> soll in einem Fenster die Variablen darstellen, die erfragt werden können, etwafolgendermaßen:Gruppierung nach1. Wohnort2. Semesterzahl3. Studienfach4. Abschlußart(Tip: Prozedur Freq mit by-Anweisung.)23a) Erstellen Sie ein <strong>Makro</strong> <strong>SAS</strong>ERROR, das es <strong>SAS</strong>-Benutzern ermöglicht, auftretendeFehlermeldungen in einer Datei abzulegen. Die Fehlermeldungen müssen dazu aus dem Log-Fenster in den Zwischenspeicher kopiert werden und dann über ein %input- Statementeingelesen werden.b) Vervollständigen Sie das <strong>Makro</strong> <strong>SAS</strong>ERROR, indem Sie es ermöglichen Erläuterungen (z.B.Kontext und Situation) zu den Fehlermeldungen abzulegen. Verändern Sie das <strong>Makro</strong>dahingehend, das die Fehlermeldungen in eine permanente Datei STAMM hinzugefügt werden,in der die Fehlermeldungen gesammelt werden (Tip: Proc Append). Überprüfen Sie in dem<strong>Makro</strong>, ob die Datei STAMM bereits existiert; falls nicht, soll diese gebildet werden.42


7. Berührungspunkte zwischen <strong>Makro</strong>-Sprache und Datenschritt7.1 Zugriff auf Daten in <strong>SAS</strong>-<strong>Makro</strong>sDas <strong>SAS</strong>-System stellt zwei Funktionen bereit, die den Austausch zwischen <strong>SAS</strong>-Datenschritt und<strong>Makro</strong>-Sprache erlauben:• symget: transferiert Inhalt einer <strong>Makro</strong>-Variable in den Datenschritt und• symput: transferiert Datenschritt-Informationen in eine <strong>Makro</strong>-Variable.Dieser Austausch ist notwendig, da die Variablen des <strong>SAS</strong>-Datenschritts und die <strong>Makro</strong>-Sprache inunterschiedlichen Speichern abgelegt werden. Die Datenschritt-Variablen werden in einen Speichernamens "Programm Data Vektor" geschrieben, die <strong>Makro</strong>-Sprache legt ihre Variablen inSymboltabellen ab (siehe Kap. 4). Um zwischen diesen Speichern Informationen auszutauschen,benötigen Sie die Funktionen symput und symget.<strong>SAS</strong>-Data-SchrittProgramm DataVektorSYMGET<strong>Makro</strong>-SpracheSymboltabellenDatenschrittvariablenSYMPUT<strong>Makro</strong>variablenDer verwendete Speicher hängt ab:• von der Stelle, wo der Datenschritt aufgerufen wird,• von der Verschachtelung der Umgebungen und• von der Definition lokaler und globaler Variablen.7.1.1 Symget-FunktionSyntax:symget(argument)datenschritt-variable=symget(argument);Das argument kann• eine in Anführungszeichen eingeschlossen <strong>Makro</strong>variable,• eine Datenschritt-Zeichenkettenvariable oder• ein Datenschritt-Zeichenkettenausdrucksein.43


Die Datenschritt-Variable• kann zuvor als Charakter- oder Numerische Variable definiert sein,• wird ansonsten als Charakter-Variable mit Länge 200 definiert,• wird - falls länger - auf 200 Zeichen gekürzt und• wird als Numerische-Variable definiert, falls die symget-Funktion in einen arithmetischenAusdruck eingesetzt wird.Beispiele1. Das Argument ist eine ZeichenketteBeispiel:%let name=recklinghausen;data loc;input land $;stadt=symget('name');cards;Deutschland;proc print;run;Ergebnis: OBS LAND STADT1 Deutschl recklinghausenDer <strong>Makro</strong>variablenname muß in Anführungszeichen eingeschlossen sein.Beachtenswert ist, daß die durch die symget-Funktion referenzierte Datenschrittvariable einenWert mit mehr als 8 Buchstaben (bis zu 200 Buchstaben, recklinghausen=14 Buchstaben)annehmen kann, wobei bei der Variablen land die Eingabe standardmäßig auf 8 Zeichen begrenztist. Dies ist durch die unterschiedlichen Speicher bedingt und kann Probleme mit derSpeicherkapazität verursachen, da jede <strong>Makro</strong>variable standardmäßig mit 200 Zeichen abgelegtwird, auch wenn diese nur 14 Zeichen hat. Durch Vereinbaren eines Input-Formats können sie diesbegrenzen (siehe Beispiel 3).2. Das Argument ist eine DatenschrittvariableBeispiel:%let fluss=arno;%let land=Italien;%let stadt=roma;data loc;input gebiet $ Zahl;name=symget(gebiet);cards;stadt 12land 34fluss 83gebirge 97;proc print;run;Ergebnis: OBS GEBIET ZAHL NAME1 stadt 12 roma2 land 34 Italien3 fluss 83 arno4 gebirge 9744


Die Ausprägung der Variable muß ein gültiger <strong>SAS</strong>-<strong>Makro</strong>variablenname sein. Es werden 3 <strong>Makro</strong>variablen gebildet. Die 3 <strong>Makro</strong>variablen werden als gebiet definiert. Beim Einlesen dieser Beobachtung wird überprüft, ob eine <strong>Makro</strong>variable mit dem Namenstadt existiert. Wenn dies der Fall ist, wird ihr Wert aus dem <strong>Makro</strong>-Speicher übernommen. Da keine <strong>Makro</strong>variable gebirge vereinbart wurde, bekommt die Variable name an dieserStelle einen Nullwert. Außerdem erscheint folgende Mitteilung:NOTE: Invalid argument to function SYMGET at line 218 column 6.RULE:--+----1----+----2----+----3----+----4----+----5----+----6----+----7--220GebirgeGEBIET=Gebirge NAME=_ERROR_=1 _N_=13. Bildung von numerischen VariablenBeispiel:%let einheit=1.50;data dollars;input dm;dollar=dm*input(symget('einheit'),4.);cards;2.0013.5;proc print;run;Ergebnis: OBS DM DOLLAR1 2.0 3.02 13.5 20.25 Hier wird die symget-Funktion dazu benutzt, einen numerischen Wert, der mit Hilfe der <strong>Makro</strong>-Sprache definiert wurde, in einem arithmetischen Ausdruck eines Datenschritts zu benutzen. Mit derInput-Funktion wird das Format 4. zugewiesen.ERROR 85-322: Expecting a format name.NOTE: The <strong>SAS</strong> System stopped processing this step because of errors.WARNING: The data set WORK.DOLLARS may be incomplete. When this step wasstopped there were 0 observations and 2 variables.WARNING: Data set WORK.DOLLARS was not replaced because this step wasstopped.7.1.2 Symput-FunktionDie symput-Funktion kann einen Wert aus einem <strong>SAS</strong>-Datenschritt an eine <strong>Makro</strong>variableübergeben. Die symput-Funktion kann dazu benutzt werden,• Informationen einer Prozedurausgabe in eine <strong>Makro</strong>variable zu transferieren,• Möglichkeiten des Datenschritts (z.B. Input) zur Bildung von <strong>Makro</strong>variablen zu verwenden,• <strong>SAS</strong>-Datensatz-Informationen, z.B. label, Format, in <strong>Makro</strong>s zu transportieren.Syntax:call symput(argument1, argument2)Die Funktion weist den Wert von argument2 der <strong>Makro</strong>variablen argument1 zu.argument1 ist der Name der <strong>Makro</strong>variablen.argument2 gibt den Wert an, der der <strong>Makro</strong>variablen zugewiesen werden soll.45


Die argumente können• Zeichenketten sein,• Datenschritt-Zeichenkettenvariablen oder• Datenschritt-Zeichenkettenausdrückesein.Beispiele1. Beide Argumente sind ZeichenkettenBeispiel:data;call symput ('stadt', 'London');run;%put Stadt=&stadt;Ergebnis: Stadt=LondonDie Argumente müssen in Anführungszeichen eingeschlossen werden.2. Beide Argumente sind DatenschrittvariablenBeispiel:data loc;input gebiet $ name $;call symput(gebiet,name);cards;stadt Londonland Englandfluss Themse;%put Stadt=&stadt Land=&land Fluss=&fluss;Ergebnis: Stadt=London Land=England Fluss=ThemseDie Argumente dürfen nicht in Anführungszeichen eingeschlossen sein und der Wert des 1. Argumentsmuß ein gültiger <strong>Makro</strong>variablenname sein.Es werden 3 <strong>Makro</strong>variablen hergestellt (alle Ausprägungen der unter die Variablen gebiet).Durch die symput-Funktion bekommen sie die Werte London England Themse zugewiesen.3. Argument2 ist das Ergebnis einer Datenschritt-FunktionBeispiel:data;call symput('datum', put(today(),ddmmyy8.));run;%put datum=&datum;Ergebnis: datum=13/07/95In diesem Beispiel wird das argument1 durch eine Put-Funktion referenziert. Die <strong>Makro</strong>variabledatum ist das Ergebnis der today-Funktion des Datenschritts (Die leere Klammer hinter dertoday-Funktion teilt <strong>SAS</strong> mit, daß es sich um eine Datenschrittfunktion handelt, und nicht um eineVariable). Mit Hilfe der %put-Anweisung wird dieser Wert raus-geschrieben.46


7.1.3 Resolve-FunktionDiese Funktion weist einer Datensatz-Variablen einen Wert zu. Die Länge, der mit Hilfe derresolve-Funktion hergestellten Variablen, beträgt standardmäßig 200 Zeichen, was sich beigrößeren Datenmengen auf die Rechengeschwindigkeit auswirken kann. Die resolve-Funktion isterst ab <strong>SAS</strong>-Version 6.07 verfügbar.Syntax:resolve(Argument)argument ist ein <strong>Makro</strong>-Ausdruck:• Textstring in Anführungszeichen (Die Anführungszeichen hindern den <strong>Makro</strong>-Prozessoran der Auflösung des <strong>Makro</strong>ausdrucks während des Datenschritts.)name=resolve('%locate');• Name einer Datensatz-Variable (Der Inhalt der Datensatz-Variablen sollte ein <strong>Makro</strong>-Ausdruck sein.)adresse='%identi'Name=resolve(adresse)• Zeichenkette, die einen <strong>Makro</strong>-Ausdruck erzeugt.region=resolve('%land'||left(id))Wenn Sie den Wert einer Variable mit resolve bilden, hängt dieser von der Ausführung desDatenschritts ab. Wird der Wert als <strong>Makro</strong>-Variable gebildet, bleibt er während des Datenschrittskonstant. Im Unterschied zu symget erlaubt resolve zusätzliche Argumentformen und istflexibler einsetzbar, allerdings auch Ressourcen-intensiver.Beispiel:%let event=lousisiana purchase;%macro date;1803%mend date;%let person1=Thomas Jefferson;data _null_;length var1-var4 $20.;YEAR='%date';var1=resolve('&event');var2=resolve('%date');var3=resolve(year);var4=resolve('&person'||left(_n_));put var1--var4;run;Ergebnis: lousisiana purchase 1803 1803 Thomas Jefferson Die length-Anweisung definiert die Variablen var1-var4 mit einer Länge von 20 Zeichen.(Der Standard wäre 200 Zeichen.) Die Variablen var1 und var2 werden zu Zeichenketten aufgelöst. var1 erhält den Wertlouisiana purchase (Der Wert der <strong>Makro</strong>variable event); var2 erhält durch die Auflösungdes <strong>Makro</strong>s date den Wert 1803. var3 erhält den Wert der Datenschrittvariablen YEAR, der wiederum einen <strong>Makro</strong>aufrufbeinhaltet, und löst sich somit ebenfalls zu 1803 auf. var4 kombiniert die Zeichenkette &person und den Wert der automatischen Zählvariablen _N_,um die <strong>Makro</strong>-Variable &person1 zu referenzieren, und letztendlich zu Thomas Jeffersonaufzulösen. (Die left-Funktion schneidet die Leerzeichen ab die links von _N_ auftauchen.)47


Die put-Anweisung schreibt das Ergebnis ins Log-Fenster.7.2 %Sysprod-FunktionDie %sysprod-Funktion erinnert in ihrer Funktionalität an die automatischen <strong>Makro</strong>variablen,siehe Kap. 2.1. Sie überprüft, ob ein <strong>SAS</strong>-Modul in der installierten <strong>SAS</strong>-Version lizensiert ist odernicht. Dies ist etwa dann interessant. wenn Sie mit einem <strong>Makro</strong> arbeiten wollen, daß das Modul<strong>SAS</strong>-IML verwendet, sie dieses Produkt aber nicht lizensiert haben. Die Funktion ist erst ab <strong>SAS</strong>-Version 6.07 realisiert.Syntax:%sysprod(argument)Das argument kann eine beliebige Zeichenkette sein. Sinnvoll sind aber nur die Namen von <strong>SAS</strong>-Modulen, wie z.B. ACCESS, AF, BASE, ETS,GRAPH, IML, QC,STAT.Die %sysprod-Funktion gibt nach der Überprüfung folgende Werte zurück:1 das Produkt ist lizensiert,0 das Produkt ist nicht lizensiert,-1 das Argument ist kein <strong>SAS</strong>-ProduktBeispielErgebnis%put sysprod(base); 1%put sysprod(QC); 0%put sysprod(Blödsinn); -1Beispiel:Aufruf:%macro plotte(sds,x,y);%if %sysprod(graph)=1 %then%do;title "dies ist ein hochauflösender Plot";proc gplot data=&sds;plot &x*&y;run;quit;%end;%else%do;title "<strong>SAS</strong>-Graph ist nicht lizensiert";proc plot data=&sds;plot &x*&y;run;quit;%end;%mend plotte;%plotte(sasuser.fitness,age, weight) Wenn das Modul <strong>SAS</strong>-GRAPH lizensiert ist, gibt die %sysprod-Funktion den Wert 1 zurück,und es wird die Prozedur Gplot ausgeführt. Ist das Modul nicht lizensiert, wird stattdessen dieProzedur Plot verwendet.7.3 Execute-RoutineDie execute-Routine kann innerhalb eines Datenschritts ein <strong>Makro</strong> aufrufen, das am Ende desDatenschritts ausgeführt wird. Diese Funktion ist erst ab <strong>SAS</strong>-Version 6.07 verfügbar.48


Syntax:call execute(argument);Das argument kann• eine in einfache Anführungszeichen eingeschlossene Zeichenkette sein, (Die Anführungszeichenhindern den <strong>Makro</strong>-Prozessor am Auflösen des <strong>Makro</strong>-Ausdrucks während desDatenschritts.)call execute('%sales');• eine Datenschrittvariable sein, deren Wert ein <strong>Makro</strong>-Aufruf ist,findit='%finde';call execute(findit);• eine Zeichenkette sein, die einen <strong>Makro</strong>-Ausdruck erzeugt.call execute('%sales('||month||')');Beispiel:%macro mak1;proc print data=neu;where ware=1;sum anzahl;title "Anzahl aller bestellten Mixer";run;%mend mak1;%macro mak2;proc print data=neu;where ware=2;sum anzahl;title "Anzahl aller bestellten Waagen";run;%mend mak2;Data Bestell;input ware anzahl;datalines;1 122 243 832 0;run;Data neu;set bestell;if anzahl=0 then delete;if ware=1 then call execute('%mak1');else if ware=2 then call execute('%mak2');run; In diesem Beispiel wird mit Hilfe der execute-Routine das <strong>Makro</strong> mak1 aufgerufen, daß dieProzedur Print aufruft, und ausgibt, ob ware mit der Ausprägung 1 bestellt wurde. Für ware=2wird das <strong>Makro</strong> mak2 aufgerufen.49


Übungsaufgaben24. Erzeugen Sie ein <strong>Makro</strong>, das abhängig von ihren Daten Referenzlinien in einen Scatterploteinzeichnet. Die Referenzlinien sollen eingetragen werden für den Mittelwert und Mittelwertplus/minus einmal die Standardabweichung.Verwenden Sie als Beispieldatensatz die Blutbilddaten, tragen Sie Cholesterin gegen Alter aufund zeichnen Sie die entsprechenden Referenzlinien ein.25. Schreiben Sie ein <strong>Makro</strong> BUILDFMT, das die Informationen in einer <strong>SAS</strong>-Datei nutzt, einFormat mit PROC FORMAT zu erzeugen.Das <strong>Makro</strong> sollte folgende Schlüsselworte unterstützen:•= Name des zu bildenden Formats•= <strong>SAS</strong>-Datei mit der Formatinformation•= Variable, die die Originalwerte enthält•= Variable, die die Formatwerte enthältFür die Beispiel-Formatdatei: BSPFORMWert Formwert0 gar nichts1 wenig2 etwas3 viel4 ganz vielsollte mit dem Aufruf:%buildfmt(fname=tform,sds=bspform,voriwert=wert,varform=formwert)etwa jener <strong>SAS</strong>-Code erzeugt werden:proc format;value tform 0="gar nichts"1="wenig "2="etwas "3="viel "4="ganz viel ";run;(Tip: Option CNTLIN der Prozedur Format)8. Aufruf von <strong>SAS</strong>-<strong>Makro</strong>sEs gibt drei Arten von <strong>SAS</strong>-<strong>Makro</strong>s• Named styled <strong>Makro</strong>s• Statement styled <strong>Makro</strong>s und• Command styled <strong>Makro</strong>s,die sich in Definition, Aufruf und Funktion unterscheiden. Alle bisherigen Beispiele in diesemSkript waren "Named styled" <strong>Makro</strong>s.Übersicht:Art des <strong>Makro</strong>s Aufruf Ort des AufrufsNamed styled <strong>Makro</strong> %makroname(makroparameter) Programm EditorStatement styled <strong>Makro</strong> makroname makroparameter Programm EditorCommand styled <strong>Makro</strong> makroname makroparameter Kommando-Zeile50


8.1 Named styled <strong>Makro</strong>s"Named styled" <strong>Makro</strong>s werden im Programm Editor aufgerufen. Sie beginnen immer mit einemProzentzeichen. Ihre Parameter erscheinen in Klammern hinter dem <strong>Makro</strong>namen. "Named styled"<strong>Makro</strong>s können nur im Programm Editor aufgerufen werden.Aufruf:%makroname(makroparameter)Beispiele: %print(albumin, calcium,alter, SDS=co.blutbild);%makedir;%tu_solan(7);8.2 Statement styled <strong>Makro</strong>s"Statement styled" <strong>Makro</strong>s machen es möglich, <strong>Makro</strong>aufrufe wie gewöhnliche <strong>SAS</strong>-Anweisungenaussehen zu lassen. Der Aufruf beginnt mit dem <strong>Makro</strong>namen ohne Prozentzeichen, die<strong>Makro</strong>parameter erscheinen nicht in Klammern und sind jeweils durch ein Leerzeichen voneinandergetrennt. Positionsparameter müssen deshalb in der Reihenfolge ihrer Definitionangegeben werden. Der Aufruf muß mit einem Semikolon enden. Es ist nicht möglich ein"Statement styled" <strong>Makro</strong> in einer anderen <strong>SAS</strong>-Anweisung aufzurufen; der Aufruf muß allein ineiner Zeile stehen.Um ein <strong>Makro</strong> als "Statement styled" zu definieren, ist die Option stmt in der <strong>Makro</strong>definitionnotwendig.Um ein "Statement styled" <strong>Makro</strong> zu verwenden, muß die Systemoption IMPLMAC gesetzt sein, daansonsten der <strong>Makro</strong>name nicht als solcher erkannt wird.Definition: %macro makroname(makroparameter) / stmt;<strong>Makro</strong>text;%mend makroname;Aufruf:makroname makroparameter;Beispiele: option implmac;%macro print (var1,var2,var3,sds=_last_) / stmt;proc print data=&SDS;var &var1 &var2 &var3;run;%mend print;Aufruf:print albumin calcium alter SDS=co.blutbild; Ohne die Systemoption implmac erscheint folgende Fehlermeldung:ERROR 180-322: Statement is not valid or it is used out of properorder. Ohne die Option stmt wäre das <strong>Makro</strong> ein "Named styled" <strong>Makro</strong> und müßte mit%print(....);aufgerufen werden.51


8.3 Command styled <strong>Makro</strong>s"Command styled" <strong>Makro</strong>s lassen sich wie <strong>SAS</strong>-Kommandos, nur in der Kommandozeile aufrufen.<strong>Makro</strong>parameter sind ohne Klammer, getrennt durch Leerzeichen, in der Reihenfolge ihrerDefinition anzugeben.Um ein <strong>Makro</strong> als "Command styled" zu definieren, ist die Option cmd in der <strong>Makro</strong>definitionerforderlich. Außerdem muß die Systemoption CMDMAC gesetzt sein. Das <strong>Makro</strong> sollte außerdemnur Display Manager Kommandos enthalten. "Command styled" <strong>Makro</strong>s sind erst ab <strong>SAS</strong>-Version6.07 möglich.Definition: %macro makroname(makroparameter) / cmd;<strong>Makro</strong>text;%mend makroname;Aufruf:makroname makroparameter;Beispiele: options cmdmac;%macro colors(fenster)/cmd;&fenster;color banner green;color source yellow;color warning cyan;color error red;%mend colors;Aufruf in der Kommandozeile: colors logDas <strong>Makro</strong> colors führt Farbänderungen im jeweiligen Fenster durch. Durch die Systemoption cmdmac werden "Command styled" <strong>Makro</strong>s ermöglicht. Durch die Option cmd wird das <strong>Makro</strong> colors als "Command styled" definiert.9. <strong>Makro</strong>-Bibliotheken (Autocall-Facility)<strong>SAS</strong>-<strong>Makro</strong>s werden (temporär oder permanent) in Bibliotheken abgelegt und können automatischzur Verfügung gestellt werden. Die <strong>Makro</strong>s werden in <strong>SAS</strong>-Katalogen unter dem <strong>Makro</strong>-Namenabgespeichert.Die <strong>Makro</strong>s können als• Quelltext oder• kompiliertes Programmabgespeichert werden. Quelltext-<strong>Makro</strong>s müssen von <strong>SAS</strong> zunächst kompiliert werden, d.h. manlädt das <strong>Makro</strong> in den Programmeditor und submittiert es.9.1 Automatischer Aufruf von <strong>Makro</strong>s (Autocall Facility)Es gibt verschiedene Systemoptionen, mit deren Hilfe Sie direkt auf ihre <strong>Makro</strong>bibliothekenzugreifen können, ohne sie als Quelltext in den Programm Editor zu laden. Den automatischen<strong>Makro</strong>aufruf nennt man 'Autocall'. Wo genau <strong>SAS</strong> nach <strong>Makro</strong>s sucht, steht in der Dateiconfig.sas.52


SystemoptionErklärungmautosource/Bestimmt, ob die automatische <strong>Makro</strong>suche (AutocallnomautosourceFacility) eingeschaltet werden soll.Sasautos=<strong>Makro</strong>bibliothek Definiert die <strong>Makro</strong>-Bibliothek. Es gibt drei Möglichkeitenauf ihre <strong>Makro</strong>bibliothek zu verweisen:• über Fileref,• über eine Filename-Anweisung• oder mit direktem Namen in Anführungszeichen.mrecall/nomrecall Veranlasst den <strong>Makro</strong>-Prozessor nach <strong>Makro</strong>bibliotheken zusuchen, die nicht bei der ersten Suche gefunden wurden.Die Default-Einstellungen sind unterstrichen.Der <strong>Makro</strong>-Prozessor sucht <strong>Makro</strong>s sequentiell in den <strong>Makro</strong>-Bibliotheken. Er sucht immer zuerstim Katalog WORK.<strong>SAS</strong>MACR, in die kompilierte <strong>Makro</strong>s automatisch während einer Sitzungabgespeichert werden (Siehe Kap. 9.2).Beispiel: Ihre <strong>Makro</strong>bibliothek, in die Sie ihre <strong>Makro</strong>s abgelegt haben, befindet sich im Verzeichnis'C:\sas\makros'. Außerdem befinden sich einige <strong>Makro</strong>s im Verzeichnis 'N:\sasurz\makros'.filename urzmac 'n:\sasurz\makros';filename mymac 'c:\sas\makros';options sasautos=(mymac urzmac);oder:options sasautos=('c:\sas\makros' 'N:\sasurz\makros');Sie können ihre <strong>Makro</strong>s jetzt direkt aufrufen, indem sie den <strong>Makro</strong>aufruf im Programm-Editorsubmittieren.%ttest(calcium,,pille,co.blutbild);%nobs(sasuser.crime);Der <strong>Makro</strong>-Prozessor sucht jetzt zunächst im Katalog WORK.<strong>SAS</strong>MACR und erst danach in denVerzeichnissen c:\sas\makros und N:\sasurz\makros.<strong>SAS</strong> stellt selbst einige <strong>Makro</strong>s bereit. Sie befinden sich im Verzeichnis '<strong>SAS</strong>ROOT\core\sasmacro'.Um auf diese <strong>Makro</strong>s zuzugreifen muß das obige Beispiel folgendermaßen ersetzt werden: (Das<strong>SAS</strong>ROOT-Verzeichnis ist im URZ N:\saswn610.)optionssasautos=('N:\sasurz\makros' mymac'N:\saswn610\core\sasmacro');Die vollständige Liste aller von <strong>SAS</strong> zur Verfügung gestellten <strong>Makro</strong>s finden Sie im '<strong>SAS</strong> Guide forMacro Processing', Version 6, 2. Edition, Seiten 186-187.Folgende Fehlermeldung taucht auf, wenn Sie z.B. vergessen haben, die Filename-Anweisung fürmymac zu setzen:WARNING: No logical assign for filename MYMAC.WARNING: Source level autocall is not found or cannot be opened. Autocall hasbeen suspended and OPTION NOMAUTOSOURCE has been set. To use theautocall facility again, set OPTION MAUTOSOURCE.WARNING: Apparent invocation of macro DATATYP not resolved.53


Sie beheben dies, in dem Sie die Filename-Anweisung richtig setzen, und außerdem dieSystemoptions mautosource und mrecall bei der Options-Anweisung mitangeben(mautosource ist durch den Fehler ausgeschaltet worden).9.2 Automatisches Speichern von kompilierten <strong>Makro</strong>sStandardmäßig werden alle <strong>Makro</strong>s, die Sie während einer Sitzung kompilieren, im KatalogWORK.<strong>SAS</strong>MACR abgespeichert. Sobald Sie die Sitzung verlassen, wird dieser Katalog gelöscht.Um kompilierte <strong>Makro</strong>s in einem anderen Katalog (permanent) abzuspeichern, sind folgendeSystem-Optionen notwendig:System-OptionErklärungmstored/nomstored Erlaubt die Speicherung von <strong>SAS</strong>-<strong>Makro</strong>s, in einem mitsasmstore vereinbarten Libref.sasmstore=libref Referenziert die <strong>SAS</strong>-<strong>Makro</strong>-Bibliothek, die die kompilierten<strong>SAS</strong>-<strong>Makro</strong>s speichert.Die Default-Einstellungen sind unterstrichen. Diese Optionen sind erst ab <strong>SAS</strong> Version 6.07 realisiert.Außerdem ist die %macro-Option store notwendig, ansonsten wird das kompilierte <strong>Makro</strong> imKatalog WORK.<strong>SAS</strong>MACR gespeichert.Beispiel: Sie wollen das <strong>Makro</strong> Nichts als kompiliertes <strong>Makro</strong> in dem Verzeichnis 'D:\<strong>Makro</strong>s'abspeichern.libname meinmak 'd:\makros';options mstored sasmstore=meinmak;%macro Nichts /store des='Nichts tut es';%put Dieses <strong>Makro</strong> macht nichts;%mend Nichts; Sie referenzieren einen permanenten <strong>Makro</strong>-Katalog, in dem ihre kompilierten <strong>Makro</strong>sgespeichert werden sollen. Sie setzen die Optionen, und verweisen auf die vereinbarte Libref. Sie geben mit der %macro-Option store an, daß dieses kompilierte <strong>Makro</strong> permanent alskompiliertes <strong>Makro</strong> abgspeichert werden soll. Außerdem können sie mit der Option des= eine biszu 40 Zeichen lange Beschreibung des <strong>Makro</strong>s mitspeichern, die im Katalog-Fenster erscheint.Tip! Wenn Sie ein <strong>Makro</strong> in kompilierter Form ablegen, können Sie es nicht mehr als Quelltext inden Programm Editor laden. Speichern sie es deshalb zusätzlich als Quelltext ab.Wollen Sie <strong>Makro</strong>s aus dem permanenten <strong>Makro</strong>-Katalog bei der nächsten Sitzung verwenden,müssen sie erneut folgende Optionen setzen:libname meinmak 'd:\makros';options mstored sasmstore=meinmak;, sonst wird das <strong>Makro</strong> nicht gefunden.Sie können permanente <strong>Makro</strong>s über das Katalog-Fenster (Kommandozeile catalog eingeben)oder über die Prozedur Catalog löschen.54


9.3 Allgemeine SystemoptionenSystem-Optionmacro/nomacroimplmac/noimplmaccmd/nocmdmerror/nomerrorserror/noserrormprint/nomprintmlogic/nomlogicsymbolgen/nosymbolgenDie Default-Einstellungen sind unterstrichen.ErklärungEntscheidet ob der <strong>Makro</strong>-Prozessor in der aktuellen Sitzung zurVerfügung steht oder nicht.Erlaubt das Arbeiten mit "Statement styled" <strong>Makro</strong>sErlaubt das Arbeiten mit "Command styled" <strong>Makro</strong>sDer <strong>Makro</strong>-Prozessor schreibt folgende Warnung ins Log-Fenster,wenn er das <strong>Makro</strong> nicht finden kann:WARNING: Apparent invocation of macro X not resolved.Der <strong>Makro</strong>-Prozessor schreibt folgende Warnung ins Log-Fenster,wenn er die <strong>Makro</strong>-Variable nicht finden kann:WARNING: Apparent symbolic reference X not resolved.Zeigt <strong>SAS</strong>-Anweisungen im Log-Fenster an, die durch ein <strong>Makro</strong>generiert wurden.Gibt Informationen über die Ausführung des <strong>Makro</strong>s ins Log-Fenster.Zeigt an, ob <strong>Makro</strong>-Variablen aufgelöst wurden oder nicht.55


10. Fehlermeldungen und mögliche UrsachenHier finden Sie eine Auswahl von Fehlermeldungen, die bei der <strong>Makro</strong>programmierung auftauchenkönnen. Die Auswahl ist aber nicht vollständig.ERROR: Macro NAME has been given a reserved name.ERROR: A dummy macro will be compiled.Es wurde ein von <strong>SAS</strong> reservierter Name für das <strong>Makro</strong> verwendet, z.B. go, run, open. ZurFehlerbeseitigung einfach einen anderen Namen auswählen, z.B. durch Anhängen einer Ziffer odereines Buchstaben.WARNING: Apparent symbolic reference XXXX not resolved.Deutet darauf hin, daß der <strong>Makro</strong>-Prozessor eine <strong>Makro</strong>variable nicht auflösen konnte.Mögliche Ursachen können sein:•= die <strong>Makro</strong>variable ist nicht global definiert, wird aber außerhalb eines <strong>Makro</strong>s verwendet (sieheKap.4.1).•= es gibt keine <strong>Makro</strong>variable mit diesem Namen. Ursache kann z.B. ein Schreibfehler sein.Beispiel: %let name=holger;%put &nam;Die <strong>Makro</strong>variable heißt name und nicht nam.ERROR: Literal contains unmatched quoteDeutet auf die Anwesenheit von offenen Anführungszeichen hin, z.B. in Textzeilen wie Rick’sCafé. Lösung sind Quoting-Funktionen (siehe Kap.6.3).ERROR: A character operand was found in the %EVAL function or %IFcondition where a numeric operand is required.Deutet z.B. daraufhin, daß ein quotierter Wert in der %eval-Funktion auftaucht, der nicht alsnumerischer Operator erkannt wird (siehe Kap. 6.3.5).WARNING: Source level autocall is not found or cannot be opened. Autocall hasbeen suspended and OPTION NOMAUTOSOURCE has been set. To use the autocallfacility again, set OPTION MAUTOSOURCE.WARNING: Apparent invocation of macro DATATYP not resolved.Das <strong>Makro</strong> wurde über die Autocall-Facility nicht gefunden. Die Option Mautosource wurdeausgeschaltet. Mögliche Fehlerquelle ist die Option sasautos.Kontrolle mit Proc Options; run;(siehe Kap. 8 und 9).WARNING: Apparent invocation of macro HOLGER not resolved.ERROR 180-322: Statement is not valid or it is used out of proper order.Das <strong>Makro</strong> Holger wurde nicht gefunden. Dadurch wird der <strong>Makro</strong>aufruf nicht als solcher erkannt,und die Fehler-Meldung taucht auf.Mögliche Lösung: Nachsehen, wo das <strong>Makro</strong> sich befindet, gegebenfalls muß es noch kompiliertwerden.56


Lösungvorschläge zu den ÜbungsaufgabenBei den unten vorgestellten Lösung handelt es sich lediglich um Lösungvorschläge. Es gibtsicherlich zu jeder Aufgabe mehrere Wege, die zum gleichen Weg führen. Bei den Aufgaben, wodie Lösung sehr leicht am Computer nachzuprüfen ist, wurde auf einen Lösungsvorschlagverzichtet.2. %let lib=co.;%let dat=iris;proc print data=&lib&dat;title "Ausdruck der Datei &lib&dat";footnote "&sysdate, &systime";run;4. Es liegt an den einfachen Anführungszeichen, die durch doppelte ersetzt werden müssen.5. Das <strong>Makro</strong> erzeugt eine Titelzeile. Sie müssen dazu das <strong>Makro</strong> innerhalb einer Prozeduraufrufen, z.B.: Proc print data=co.iris; %meintitl; run; .6. Das <strong>Makro</strong> sollte so aussehen:%macro sortier(sds,by);Proc sort data=&sds;by &by;run;%mend sortier;7. Mit den Ergänzungen sieht es so aus:%macro sortier(sds,by);Proc sort data=&sds;by &by;run;Proc print data=&sds;run;title "Heute ist der &sysdate";%mend sortier;Sie könnten allerdings statt der title-Anweisung, einfach auch das <strong>Makro</strong> %meintitl aufrufen.8. %macro plotte(sds=,y=,x=);proc gplot data=&sds;plot &y*&x;run;%mend plotte;a. Das ergänzte <strong>Makro</strong> sieht so aus:%macro plotte(sds=,y=,x=,z=);proc gplot data=&sds;plot &y*&x=&z;run;%mend plotte;b. Der <strong>Makro</strong>aufruf lautet folgendermaßen:%plotte(sds=co.iris,y=pw,x=pl,z=blume);c. Mit der where-Anweisung hat sich das <strong>Makro</strong> wie folgt verändert:%macro plotte(bed,sds=,y=,x=,z=);proc gplot data=&sds;where &z=&bed;plot &y*&x=&z;run;%mend plotte;Die Positionsparameter müssen immer zuerst genannt werden, sonst erscheint folgende Fehlermeldung:ERROR: All positional parameters must precede keyword parameters.57


d. Sie benötigen 3 verschiedene Aufrufe:%plotte(1,sds=co.iris,y=pw,x=pl,z=blume);%plotte(2,sds=co.iris,y=pw,x=pl,z=blume);%plotte(3,sds=co.iris,y=pw,x=pl,z=blume);9. %macro kreuztab(zeile,spalte,sds=);proc freq data=&sds;tables &zeile*&spalte;run;%mend kreuztab;Für den zweiten Aufgabenteil benötigen Sie folgende Schritte:proc format ;value sl6.4-7.9='a'5.8-6.3='B'5.1-5.7='c'4.3-5.0='d';run;data iris;set co.iris;format sl:sl.;run;%kreuztab(sl,blume,sds=iris)10. id=global %let-Anweisung außerhalb eines <strong>Makro</strong>ssds=lokal<strong>Makro</strong>-Schlüsselparameterort=lokal%let-Anweisung innerhalb eines <strong>Makro</strong>ssysdate=global automatische <strong>Makro</strong>variable12. %macro machdat(i,seedy,seedx,dateinam=);%global SDS;%let sds=&dateinam;data &sds;do i=1 to &i ;y=rannor(&seedy);x=rannor(&seedx);output;end;run;%prinsort;%mend machdat;%macro prinsort;proc sort data=&sds;by x;proc print data=&sds;run;%mend prinsort;Sie müssen die Variable sds nicht global definieren, da <strong>SAS</strong> standardmäßig den zuletzt benutztenDatensatz bearbeitet, und das <strong>Makro</strong> %prinsort den richtigen Datensatz findet.13. %macro nummer;%*Dieses <strong>Makro</strong> fragt danach, welchen Datensatz sie entweder mit derProzedur Print oder Means bearbeiten wollen.;%put Welchen Datensatz wollen Sie bearbeiten?;%input sds;%put Wählen Sie eine der drei Möglichkeiten:Ausdruck (geben sie eine 1 an)Mittelwerte ( geben sie eine 2 an);%input a;%*Falls a=1 ist, dann wird die Prozedur Print ausgeführt.;%if &a=1 %then%Do;58


Proc print data=&sds;run;%end;%* Falls a=2 ist, dann wird die Prozedur Means ausgeführt.;%else %do;Proc means data=&sds;run;%end;%mend nummer;14. %macro menue;%put Sie haben folgende Möglichkeiten:;%put;%put %str( 1. Patientenaufnahme);%put %str( 2. Löschen eines Patienten);%put %str( 3. Listenausdruck);%put %str( mit Sortierreihenfolge);%put %str( a. Familienname);%put %str( b. Wohnort);%put;%put %str( Treffen Sie Ihre Entscheidung: ___);%input entsch;%mend menue;15.%Macro prompt;%put Geben Sie den Namen ihres Datensatzes an;%input sds;%put Welche Prozedur wollen Sie damit Ausführen?;%input proz;Proc &Proz Data=&SDS;run;%Mend prompt;%prompt ;16. %window anfang color=white#11 @23 'Hallo, hier ist ihr <strong>SAS</strong>-System' c=red#13 @23 'Falls Sie die folgenden Libname-Anweisungen gesetzt habenwollen' c=red#15 @23 'geben Sie bitte eine 1 ein' color=red @53 wert 1 attr=underlinec=green#17 @27 'b=Laufwerk B'#18 @27 'a=Laufwerk A'#19 @27 'co=N:\sasurz\daten' ;%macro beginn;%display anfang delete;%if &wert=1 %then%do;libname b'B:\';libname a'A:\';libname co 'N:\sasurz\daten';%end;%mend beginn;17. %macro dateinam(sds=&syslast);%put Die Libref heißt: %scan(&sds,1,.);%put Die eigentliche Datei hat den Namen: %scan(&sds,2,.);%mend dateinam;18. %let name=holger geißler;%put Mein Name ist: %upcase(&name);%put Die Länge meines Namens ist %eval(%length(&name)-1) Buchstaben;19. Das <strong>Makro</strong> intsum sieht folgendermaßen aus:%macro intsum(n);%eval(&n*(&n+1)/2);%mend intsum;a) %let total=%intsum(10);59


%put Das Ergebnis ist &total;Das Ergebnis ist 55b) data test;sum=%intsum(10);put sum;run;c) %macro getsum;data _null_;sum1=%intsum(1);sum2=%intsum(2);sum3=%intsum(3);sum4=%intsum(4);sum5=%intsum(5);put sum1--sum5;run;%mend getsum;d) %macro getsum(anfang=,ende=,by=1);%do n=&anfang %to &ende %by &by;%put ****%intsum(&N)****;%end;%mend getsum;20. %input x;%sysdate%put Der Wert von %superq(x) ändert sich nicht innerhalb eines <strong>SAS</strong>Programms.;21. %let x=%nrbquote(Das ist der Schnupperhund von C&A);%put &x;%put &x;(Erst beim zweiten Mal verschwindet die Warnung)%put %quote(Die Gewinner waren die Nummern 3;12;1 & 7);%put %bquote(So 'n Blödsinn);22. %macro verwalt;%window verwalt#9 @32 'Gruppierung nach'#11 @35 '1. Wohnort'#12 @35 '2. Semesterzahl'#13 @35 '3. Studienfach'#14 @35 '4. Abschlußart'#16 @32 'Geben Sie die gewünschte Gruppierungsart ein' @77 sortart 1attr=underline;%display verwalt;%if &sortart =1 %then %let by=WOHNORT;%else %if &sortart=2 %then %let by=SEMZAHL;%else %if &sortart=3 %then %let by=STUDFACH;%else %if &sortart=4 %then %let by=ABSCHLUS;%put &by;proc sort data=studi;by &by;proc freq data=studi;tables STUDFACH*ABSCHLUS*SEMZAHL*WOHNORT;by &by;run;%mend verwalt;23. Das <strong>Makro</strong> legt eine temporäre Datei Fehler an, in die die Fehlermeldungen abgelegtwerden.%macro saserror;60


%put Fügen sie die Fehlermeldung über den Zwischenspeicher in denProgrammeditor ein;%input;%let Fehlmeld=%nrbquote(&sysbuffr);data Fehler;fehler=symget('Fehlmeld');run;%mend saserror;b) Der zweite Teil der Lösung sieht folgendermaßen aus:%macro exist(dsn);%global exist;%if &dsn ne %then %str(data _null_;if 0 then set &dsn;stop;run;);%if &syserr=0 %then %let exist=yes;%else %let exist=no;%mend exist;[Mit diesem <strong>Makro</strong> kann überprüft werden, ob ein Datensatz existiert oder nicht, siehe <strong>SAS</strong> Guideto Macro Processing, Seite 265)]%macro saserror;%put Fügen Sie die Fehlermeldung über den Zwischenspeicher in denProgrammeditor ein;%input;%let Fehlmeld=%nrbquote(&sysbuffr);%put Sie können an dieser Stelle Erläuterungen hinzufügen;%input;%let erlauter=%nrbquote(&sysbuffr);data Fehler;fehler=symget('Fehlmeld');erlauter=symget('erlauter');run;%EXIST(STAMM);%if &exist=no %then%do;data stamm;set fehler;%end;%else %do;proc append base=stamm data=Fehler;run;%end;%mend saserror;24. %macro refline(sds=_last_,xvar=,yvar=);%*Ausrechnen des Mittelwerts und der Standardabweichung;Proc means data=&sds mean std noprint;var &xvar &yvar;output out=outdat mean=xmean ymean std=xstd ystd;run;%*Übergabe der Datenschrittvariablen in die <strong>Makro</strong>-Sprache;data aa;set outdat;u_xstd=xmean-xstd;o_xstd=xmean+xstd;u_ystd=ymean-ystd;o_ystd=ymean+ystd;call symput('xmean',xmean);call symput('ymean',ymean);call symput('xstd', xstd);call symput('ystd', ystd);call symput('u_xstd',u_xstd);call symput('o_xstd',o_xstd);61


call symput('u_ystd',u_ystd);call symput('o_ystd',o_ystd);run;%*Jetzt wird der Plot ausgeführt;proc gplot data=&sds;plot &xvar*&yvar/ vref=&u_xstd &xmean &o_xstd href=&u_ystd &ymean&o_ystd;run;%mend refline;25. Zur Erläuterung der Option CNTLIN, siehe <strong>SAS</strong> Procedures Guide, Version 6, Auflage 3, Seite310.%macro buildfmt(fname=,sds=, voriwert=, varform=);%*Aufbereiten des Datensatzes für die Proc Format;data hhhhh (rename=(&voriwert=start &varform=label));set &sds;fmtname=symget('fname');%*Vereinbaren des Formates;proc format cntlin=hhhhh;run;%mend buildfmt;Zusätzliche ÜbungsaufgabenDiese Aufgaben dienen der weiteren Vertiefung in die <strong>Makro</strong>programmierung. Es sind Aufgaben,die in den <strong>SAS</strong>-<strong>Makro</strong>programmierkursen verwendet wurden. Da sie den Übungsaufgaben desSkripts in Struktur und Inhalt ähneln, wurde darauf verzichtet, Lösungsvorschläge dafür zu geben.1. Gegeben seien folgende %let-Anweisungen%let a=romeo;%let &a=und;%let b=w;%let c=shake;%let d=speare;%let e=h;%let f=%str( );%let und=Julia;Überlegen Sie, was die folgenden %put-Anweisungen erzeugen undÜberprüfen Sie es:%put b&romeo.st&romeo;%put &b&&&a;%put &f&e&romeo&c;%put &a &&&a &&&romeo;%put by &c&d, &b..;2. Geben Sie die aktuellen Werte von SYSDATE, SYSDAY, SYSVER und SYSSCP aus.3. Gegeben sei folgendes <strong>Makro</strong>:libname co 'n:\sasurz\daten';%macro liste(art,sds=_last_);data;set &sds;if blume=&art;proc print;title "Iris-Art &abtnr - Liste der Meáergebnisse";run;%mend liste;62


Welcher <strong>SAS</strong>-Code wird mit folgenden Aufrufen erzeugt?%liste(2,sds=co.iris);%liste(3);%liste(,sds=co.iris);4. Der Datensatz KLASSENKlasse Vorname Name Alter Sex1 Heribert Schuster 21 M2 Klaus Maier 20 M1 Friedel Schulze 21 M2 Gabi Maier 18 W2 Ursula Schmidt 22 W2 Ilse Bisen 20 W1 Friedel Schulze 21 Msoll mit einem <strong>Makro</strong> LISTE ausgegeben werden. Die Klassenlehrer wünschen sich Liste fürdie einzelnen Klassen, der Vertrauenslehrer hätte gerne eine Aufstellung getrennt nach demGeschlecht.Erstellen Sie das <strong>Makro</strong>, das die beiden Listen anfertigen kann.Erstellen Sie ein <strong>Makro</strong> FINDE, das alle Schüler mit einem bestimmten Nachnamenheraussucht. (Tip: Verwenden Sie die INDEX-Funktion.)Erstellen Sie ein <strong>Makro</strong> DOPPEL, das die Doppeleinträge in einer Klasse herausschreibt.Übergeben Sie die Klassennummer und den Dateinamen als Parameter. (Tip: Sortieren derDaten nach Name und Vorname und verwende FIRST.name und LAST.name.)5. Welchen <strong>SAS</strong>-Code erzeugt das <strong>Makro</strong>%let fname=Franklin;%let lname=Roosevelt;%macro first;%global mname;%local fname lname;%let fname=Ted;%put A1: &fname &mname &lname;%middle;%put A2: &fname &mname &lname;%let mname=Delano;%put A3: &fname &mname &lname;%mend first;%macro middle;%local lname;%let mname=Fitzgerald;%put B1: &fname &mname &lname;%last;%put B2: &fname &mname &lname;%mend middle;%macro last;%local mname;%let fname=John;%let lname=Kennedy;%put C1: &fname &mname &lname;%mend last;wenn nacheinander die Zeilen63


%first%put D1: &fname &mname &lname;aufgerufen werden.6. Schreiben Sie ein <strong>Makro</strong> IRISART, das die Mittelwerte der Variable SL der drei Iris- Artennacheinander ohne Sortiervorgang bestimmt. (Tip: %do - %to).Gegeben sei folgende %input-Anweisung:%input userid username telefon ortBestimmen Sie die Belegung der Variablen USERID, USERNAME, TELEFON, ORTSYSBUFFR, wenn folgende Zeilen eingegeben werden:undHTR123 SMITH 45321 HDJKD123 SMITH,JAMES 55216 MA-LUOIU222 LUDWIG,11116,KA,2XYU233 HARRIG, J.R. 1886 MA-3 R-3PSK238 'KRANICH, R.S.' '46890' 'HD-BOXBERG' 'KA'7. Welcher <strong>SAS</strong>-Code wird von folgendem <strong>Makro</strong> erzeugt:%macro prtall(n);%do i=1 %to &n;data ort&i;set orte;if ort=&i;proc print data=ort&i;title "Ausdruck der Ortschaft &i";%end;run;%mend prtall;wenn es mit %prtall(2) aufgerufen wird?8. Schreibe ein <strong>Makro</strong>, das die Werte der automatischen Variablen SYSDATE, SYSDAY,SYSENV, SYSSCP, SYSTIME und SYSVER ausgibt, jede Variable mit Name und Wert ingetrennten Zeilen.Rufen Sie das <strong>Makro</strong> auf.9. Schreiben Sie ein <strong>Makro</strong> KOMBI, das zwei Dateien verknüpft (merge und set), abhängigvon Aufrufparametern. Das <strong>Makro</strong> soll Schlüsselparameter erhalten für• erste Eingabedatei (Default = letzte benutzte Datei)• zweite Eingabedatei (Default = Nullwert)• Ausgabedatei (Default = Nullwert)• Typ der Operation• BY-Variable, wenn notwendigEine Fehlermeldung soll einen ungültigen Aufruf anzeigen.10. Schreiben Sie ein <strong>Makro</strong> ALTER, das Name und Geburtsdatum am Terminal erfragt undanschließend das aktuelle Alter errechnet und ausgibt.64


11. Schreiben Sie ein <strong>Makro</strong> PLOTTER, das mehrere Plot-Anweisungen ausführen kann.So soll z.B. für die <strong>SAS</strong>-Datei BLUTBILD die Variablen Cholestr gegen Alter und Calciumgegen Gewicht dargestellt werden.Ändern Sie das Plotter-<strong>Makro</strong> ab, indem Sie die Overlay-Option optional zulassen.(Plotten Sie Cholesterin und Calcium gegen Alter für die Blutbild-Datei.)Literaturliste:<strong>SAS</strong> Guide to Macro Processing, Version 6, 2. Edition, Cary, NC:<strong>SAS</strong> Institute, 1990<strong>SAS</strong> Views: <strong>SAS</strong> Macro Language Cary, NC:<strong>SAS</strong> Institute, 1986<strong>SAS</strong> Language: Reference, Version 6, 1. Edition, Cary, NC:<strong>SAS</strong> Institute, 1990<strong>SAS</strong>-Technical Report P-222, Changes and Enhancements to Base <strong>SAS</strong> Software, Release 6.07Cary, NC:<strong>SAS</strong> Institute, 1991<strong>SAS</strong>-Software, Changes and Enhancements, Release 6.10, Cary, NC:<strong>SAS</strong> Institute, 1994<strong>SAS</strong> Procedures Guide, Version 6, 3. Edition, Cary, NC:<strong>SAS</strong> Institute, 1990Ortseifen, C.(1993): „Einführung in die <strong>SAS</strong>-<strong>Makro</strong>-<strong>Programmierung</strong>“, Begleitskript zur VorlesungWintersemester 1993/1994, nicht veröffentlicht.65


Index%%bquote ............................... 39%by ...................................... 22%display............................... 31%do - %end-......................... 21%do - %to - %end ................ 22%do - %until - %end ............ 23%do - %while - %end........... 24%eval..................24; 32; 37; 56%global .......................... 15; 16%goto ................................... 24%if - %then/%else................ 21%index ................................. 33%input............................ 15; 20%keydef ............................... 26%label .................................. 24%length ................................ 34%let ............................9; 15; 17%local ............................ 15; 17%macro .......................... 12; 54%nrbquote............................ 40%nrquote.............................. 40%nrstr................................... 41%put ............................... 19; 47%qscan ................................. 34%qsubstr............................... 35%quote ................................. 39%qupcase ....................... 35; 36%scan ................................... 34%str ................................ 20; 41%substr................................. 35%superq................................ 42%sysexec.............................. 25%sysprod.............................. 48%unquote ............................. 40%upcase ............................... 35%window.............................. 26__last_.............................. 13; 25AAddition ............................... 37Ampersands................7; 40; 41Auflösen von ................... 10Mehrfache........................ 10Anführungszeichen....................................20; 38; 40; 43; 44doppelte............................. 8offene......................... 39; 56Argumente...................... 32; 39Aufruf von <strong>Makro</strong>s............... 50Ausgabe benutzerdefinierter<strong>Makro</strong>variablen ................. 9Austausch zwischen <strong>Makro</strong>-Sprache und Datenschritt. 43Auswertung von logischen undnumerischen Ausdrücken......37Autocall Facility ...................52Autocall-Facility...................56Automatische <strong>Makro</strong>suche....53Automatische<strong>Makro</strong>variablen.......................8AutomatischeVariablen ................... 7; 15; 29Automatisches Speichern vonkompilierten <strong>Makro</strong>s........54BBenutzerdefinierte<strong>Makro</strong>variablen..............7; 9Betriebssystemkommandos...25Bibliotheken .........................52Blank ...........Siehe Leerzeichenbuchstabenbasiert..................37Ccall execute .........Siehe executecall symput.......... Siehe symputCharakter-Variable ...............44cmd .......................................52cmd/nocmd ...........................55CMDMAC............................52Command styled <strong>Makro</strong>s 50; 52config.sas..............................53DDatensatz-Variablen .............47Datenschritt........ 43; 45; 47; 49Datenschrittfunktion .............47Datenschrittvariablen.................. 44; 48; 49Datenschritt-Zeichenkettenausdruck.....................43;46Datenschritt-Zeichenkettenvariable .............................................43; 46Default-Delimiter..................34Defaultwerte ...................13; 53delimiters .. Siehe TrennzeichenDisplay ManagerKommandos..........................52Division ................................37Eexecute..................................49Execute-Routine ...................49FFehler................. 40; 41; 53; 56Fehlersuche ......................11reservierte Worte .............12Ursachen von ...................56Felddefinitionen..............27; 28Feldergeschützte ........................31Optionen ..........................28FensterAnzeige von..................... 31Fenstername .................... 27Fensteroptionen.................... 27Filename-Anweisung............ 53Funktionen ........................... 43Funktionstasten .................... 26Funktionstastenbelegungen .. 26Gganzzahlige..................... 37; 38Gestaltungsoptionen............. 26Großbuchstaben ................... 35Gruppen ............................... 27Definition von ................. 29HHochkommata ...................... 41IIMPLMAC........................... 51implmac/noimplmac............. 55Indexvariablen................ 17; 23Indirekte Zuweisung von Werten......................................... 10Inkrement ............................. 23Input-Format ........................ 44Input-Funktion...................... 45Iterative %do-Anweisung..... 22KKataloge ............................... 52automatische.................... 53permanente <strong>Makro</strong>-Kataloge.................................... 54keyparm................................ 13Klammern.................39; 40; 41Kleinbuchstaben................... 35Kommentierung von<strong>Makro</strong>s ................................. 19kompilieren ............................ 6kompiliertes Programm........ 52Kompilierung ................. 39; 41Llabel...................................... 45Länge eines Arguments ........ 33Leerzeichen.......................... 41length.................................... 47Mmacro/nomacro..................... 55<strong>Makro</strong>aufruf ......................... 53Nichterkennen ................. 56<strong>Makro</strong>ausdruck..................... 47<strong>Makro</strong>-Bibliotheken............. 52<strong>Makro</strong>-Funktionen............ 7; 32<strong>Makro</strong>namen ........................ 51<strong>Makro</strong>parameter............. 15; 5166


<strong>Makro</strong>-Programmanweisungen .... 7; 19<strong>Makro</strong>-Prozessor ..6; 17; 47; 55<strong>Makro</strong>-Quoting-Funktionen ..................... 20; 38<strong>Makro</strong>-Routinen ..................... 7<strong>Makro</strong>s ........................... 50; 52Aufruf von ....................... 12automatischer Aufruf von 52Definition von.................. 12genestete.......................... 17Kommentierung von........ 19kompilierte ...................... 53<strong>Makro</strong>name...................... 12<strong>Makro</strong>-Parameter............. 12<strong>Makro</strong>s innerhalb von <strong>Makro</strong>s.................................... 17verschachtelte .................. 17von <strong>SAS</strong> bereitgestellte ... 53<strong>Makro</strong>-Sprache............... 19; 43<strong>Makro</strong>variablen .....................................7; 12; 15; 17; 28; 43Auflösung von ........... 39; 56automatische.............. 15; 48globale.................15; 16; 43Länge von........................ 44lokale...................13; 15; 43Übergabe von Datenschrittinformationen .................. 45Verhindern vonAuflösung ........................ 42Warnung.......................... 55mautosource ......................... 53Maximum............................. 37merror/nomerror................... 55Minimum.............................. 37MLOGIC.............................. 11mlogic/nomlogic................... 55Module ................................. 48MPRINT .............................. 11mprint/nomprint ................... 55mrecall/nomrecall................. 53mstored/nomstored............... 54Multiplikation....................... 37NNamed styled <strong>Makro</strong>s........... 50nomlogic............................... 12nomprint............................... 12nosymbolgen ........................ 12Numerische Variablen.......... 44OOperationen ..........................37PParameterliste .......................12PMENU-Routine ..................26Positionsparameter................13posparm.....Siehe PositionsparameterPotenzieren ...........................37Programm Data Vektor.........43Prozedurausgabe...................45Prozentzeichen.......................................... 19; 38; 40; 41; 51Pull-Down-Menü ..................26Put-Funktion .........................47QQuelltext ...............................52Quotiertes Resultat ...............35QuotierungAuflösung von..................40Rück-................................41Quoting-Funktionen..............56Siehe <strong>Makro</strong>-Quoting-FunktionenRReservierte Namen................56Reservierte Worte.Siehe Fehlerresolve-Funktion...................47S<strong>SAS</strong> für Windows.................25<strong>SAS</strong>-Anweisungen................51Sasautos ................................53<strong>SAS</strong>-<strong>Makro</strong>...........................12<strong>SAS</strong>-<strong>Makro</strong>-Sprache...............6sasmstore ..............................54<strong>SAS</strong>ROOT............................53Schleifen...............................22Schlüsselparameter ...............13Schlüsselzeichen.....................6Sequentielle <strong>Makro</strong>suche......53serror/noserror ......................55Spaltenpointer.......................28Speicherkapazität..................44Speichern..............................43Sprungmarke.........................24Statement styled <strong>Makro</strong>s.......50stmt .......................................51store ......................................54Subtraktion........................... 37SYMBOLGEN............... 11; 55Symboltabellen............... 15; 43symget ......................43; 44; 47symput................15; 43; 45; 46SYS ........................................ 8SYSBUFFR.......................... 21SYSDATE.............................. 8SYSDAY................................ 8SYSDEVIC............................ 8SYSDSN ................................ 8SYSENV................................ 8SYSERR ................................ 8SYSFILRC............................. 8SYSINFO............................... 8SYSLAST .............................. 8SYSLIBRC ............................ 8SYSMSG.............................. 29SYSRC................................... 8SYSSCP ................................. 8SYSSCPL............................... 8System-Optionen.................11; 51; 53; 54; 55SYSTIME .............................. 8SYSVER ................................ 8TTextzeichen.......................... 38today-Funktion ..................... 47Trennzeichen........................ 34ÜÜberlappung von Feldern..... 28UUnquotiertes Resultat........... 35VVerkettung............................ 37Verkettung von <strong>Makro</strong>s.......... 9Verschachtelung................... 43Vorzeichen ........................... 37WWORK.<strong>SAS</strong>MACR ............. 53ZZeichenketten.................33; 35; 44; 46; 49Zeilenpointer ........................ 2867


1l‰?*,&.‹ŠŒ1`4m?s-Žb‹{4u‘’Ps/“”`.*Œ•-”`)–.s,&‹”`)*/‰nmn(o&˜—o14•,;14š4&†ˆ‡‹{4u‘’2”ltu*%›'1l.&4Žo5Œs,1;š4&‹1l(oœ7 &tu&.&(•-&†½Åý þ‹ÈÇÆÿÆ¡ Ñ¿'ÊÊ¢ O¤£ ¿¦¥Çʧ IΩ¨8Í Î ¼ZÐÇ礼Šrm?&ÇÔ~.”4šl.1;33+-&mn‰?&( ÙàbÙ`Þêá4à Üäü ëæçÞlöÚ{â~Ü{×Pöà{ßÙ`Û~ò-Ù##làóÜ"ïüæ ÙàbÙ`Þêá4à Ü©© £¡£¢¡¤£¦¥¨§ !#"%$'&()*,+-&.*/.&02143658789:1;3=


8ÔI’d){(oœXŒ1l)os,s->Š m?&˜$'&()*,+-&.Œ3YS )s,s,&(†šl.,){(œ‰?&-š;&(œ{&q !#"\[‹&({({*/({m?s,s,&˜)–(oœZ[‹&({({*/(–m?s,s,&˜mn( ‘1;*/.,mWV1l‰?š;&¢Q–.1Z3˜m?*]Q{.,mn(oš4&(b>Š8&.8£ mn(os,14*,+Ç4”`(ù‘’P›'mn.œé&B3˜—–t„”l“{‰?&(dtTS )–.8œm?&†‘14*/.,mWV”`—&.14*/m?”`(&(~>Zu‘’Ps,”l‰n‰?*,&a`cbed§fcg–&mn(š;&-s,&-*,+-*‹›'&.œ–&(b¡› &(–(†Šrm?1;š j žO&”kŠrm?1;š j ‘14*§kžI&B•-œ m?1;š j ‘1;*§k+4> $Œ>{ŠŒ14*,&(s,•,“–.,m?*,*,&Ç)–(oœYr.1l—{“–mn—{.”4+B&-œ ){.&(?kŒ”œ{&.jœ–1;s Ô .”Q–‰?&-3É3˜m?* &mn(o&-36‘1l.” š;&‰ S ”4s,* ›'&.œ{&(q41`(–(b>Züü茥ÇÊ¢ OÎu˜h „š OÂÁt œ›4¾Àâ”ÃÎœž2¿'ÊÈh * Ÿ—¢&“–‰?&(oœ{& ‡ &.*,&›'&.œ{&(Pmn( !–;ù‘’¸1l‰?sÇÔ~)–({{*˜š;&&(–({"†á4‖æ¡-äWÜ+-&m?•Å“{(&B*-Ž£~‰?&-3&({*%›'&m?s,&Çpr—&.14*/m?”l(o&(i1l){tWtu&“{‰?&(oœ–&( ‡ &.*,&Œ&.+B&)š;&(†Iʧ OÆv OÎrÁwp{¾rqNs–þ!˘¿'Ót¥uu‘’&(–({*î#;1`‰?1l.&4¡OžO&{*,”l.&()–(oœP‘14*/.,m?+B&(W¡O;”l(21`‰n—–“o1l"†á4‖æçˆä2ë9&mn‰?&({;&{*,”l.`Žð ‖æè ç~èéä~è ëOè4—1`‰?*,&({4&{*,”l.`Žp{Îh˜Çà ¢~ç OÂ\ÈÇÎü¥\« ‰nm?&tu&.*Œœm?&Ç4—1`‰?*,&(s/)o33&(W>Qt¨Œ1£x½˜¡½R¥\«:‰nm?&tu&.*Zœm?&¾Œ&-s,143Ç*,s/)3î3&­1`‰n‰?&.É‘14*/.,mWV&‰?&-3&({*,&4>Qt¨Œ1£x½˜¡Qt¨Œs/)o3 j 1¿k¢«m?s,*˜1Q&.‹&0&{*/m?4&.`¡~œ–1qs,•Å“{(o&‰n‰?&.){(œ.&-s,”`)–.•-&(s/—o1l"jk .&(oœ–&.`>‰?&-3î&({*,&4>œ–&.Œš;&t){(œ{&(o&(£j ‘14*/.,mWVŠ*/.,mWV s/mn(oœdœ)–.•,“X[‹”;331;*,1¹š;&-*/.&({({*->){“–.&(;1`(–(Z œ–1;shU (”`.31l‰?&iU‹¹+)3Éšl‰?&m?•,“o&(29–m?&‰btTSá4â€{ææêä2-/ëè çÑæPä2- $ ëOèqäæ¸æˆæbÜð ​‚%ጂ‚ ð ‚;è ‚%ØŒ‚ ‚‡¦‚\WÜo‹½]oS ”l({(o&(žO&{*,”l"‘ém?*Itu”`‰?š4&(oœ–&(ù‘’\"%¢–){({{*/m?”l(o&(é){(œqpr—&.14*,”l.&(é&.+-&)oš4*Œ› &.œ–&(WŽ.&(é){(oœ‘14*/.,m?+-&(á4âæ ) ëOÜ 9¦&mn‰?&({4&{*,”`.3Çm?*FŽxk á4âOò-æ ) ëóÜ #—o1l‰?*,&({;&{*,”l.Ç3Çm?*˜1;£?›'m?&-œ{&.‘1;*/.,mWV”l—&.1;*/m?”l(o&(2s/mn(oœ:({m?•,“{*Œ&.,‰?1`);Qo*->ð âæ ) ä~ÜØ4â{á ð Ü ‰nm?&tu&.*-Ž ò,ç‹- " ó >« Qt¨r‰?”• j 1¿¨¦k¢«1£ Q¥‡¨5ª«1¨ € A@ ¢B§C¢D ¡@¥ D £


Ê º¸· ³IL+OIËé³ ·¹®ÍÌ Î ± ® MXO ¬ Ë ®P· ® ± ®ÐÏÉ® O · ³ º ³IË ´ ³ILÓÒÔÒ ·Ñ£~‰?&-3&({*/›'&m?s,&³r.,){(œ.&-•,“&(o1l.*,&(WŽÕ½˜¡–"¡”À¹¡o ¡wÀ+À†‘1;*/.,mWVšl.,){(œ.&-•,“&(1`.*,&(~ŽÕÖ ¡tÖiÖ†Š mn.&{*,&-s8Ô .”œ)–{*-Ž?׆žO&.,( S )–—{t){(š{Ž4&.*/mn;1`‰4ØÙØn¡4“o”l.,m?+-”`({*,1l‰¢4†á ð Þ "ORQos,”l‰n)o*]Q&-*/.14š†{Ý4ß "OŠŒ&-*,&.3Çmn(1`({*,&&mn(o&.‹‘1;*/.,mWV†ÝÙ.{Ýlà "O£~m?š4&({›'&.*,&˜œ{&.8‘14*/.,mWV†ào×4Ö4ÚoáÛ "O(o”l.31`‰?4&.*,&mn‰?*,&q9–){tu1l‰n‰?s,+-1`“–‰†Õ{Ö{× ð ào×4Ö4Ú "*‘8”l.31`‰?4&.*,&mn‰n)–(ošs/t){(–{*/m¤”l(†.Ö{á4ø "OÔ~”l‰W^š;”l(†.4Õo×Ùà{ß " Ô~)–({{*,&Fmn( &mn(&-3ÉŠrm?1;šl.1;33††¤ÚTÚÚIÃ,Át O è ËN O¿IÁÃÍrÎu OÎá£I8Šr"%r({› &m?s/)–(oš–Ž ‰nm?&-s,*RžI1`.,m?1Q{‰?&( mn( ù‘’"/žO&{*,”`.&(ÿ)–(oœ="7Ø×2- ð Ûlö{ß ð Ù`Û~Ü 0”î(áÛÛ Ùà{ß{× OÜ (÷,’ ž~87 ”`—&.1l(oœt“« ”œ{&.8ÔIÔO£*‘ŒŠ’ ¢~7 pŒ‘ÿ31;*/.,mWV ’ £ .T¨Œ;&{*,”l.` œ{14*,&m ’ œ–1;*,&mn"%”l—o*/m?”l(o&(ˆ“ ’ ‡ –8£I7 £5!mn(ošl){(oš;“« Q¦&-œm?&‹m?3÷U (”`.31l‰?&(?Ub‹é&V4m?s/m?&.&(Pœm?&˜ ({›'&m?s/){(š;&(bŽ‡¢Ou’W£*‘Œ8‘£ †‡‘Œ¢Ou’W£ †‡‘ŒÔO53 †Qo+-›‹>–)o36&V*,&.,(o&‹¢Wmn‰?&-s‹+)&.+-&)oš4&(bŽ¢Ou’W£ †È©© £¡£¢¡¤£¦¥¨§Û ÜYÝšÜXÞ·ß L+O ·¹¬;· ® ¬®=ÜàÝáÜ1â³ãäm å&-›'&mn‰?s‹()–.î&mn(o& ŠŒ14*,&m'1`‰?s(–—{)*/"%Š814*,&m'){(oœP&mn(o&‹{4ù‘’ˆ“o14*¦¤)ošl){(oš–>ŠŒ1;*,&m~1`‰?s‹pr)o*/—–)o*/"%ŠŒ1;*,&m~+){.‹žO&.,tTS4”l‰n‰?s,*SŠrm?&1`(œm¤š4&Z’m?s,*,&Ñ1l‰n‰?&.Rpr—&.14*,”l.&(=&-*,•;>+~–(oœ–&( #m?& m?3‹{4ù‘’„–81l(oœ_Q{)•,“¸m?3RQos,•Å“{(–m?*,* U •r){m?•Åê7 &tu&.&(•-&iU@¡¢¦> C 0~>æ8½¼S 1l(oœ{&.*r(){.8œ m?&î„({—–)o*/"%ŠŒ1;*,&mu¡\({m?•,“{*Œœm?&Çpr)*/—{)*/"%Š814*,&mu>5‹£ˆ;&.&m?s/)–(oš–Ž{’b&-s,&"W){(oœé•,“–.&mxQo+)ošl.,mn021`)–tb&mn(o&RQ¦&-s,*,&“o&(œ{&£OŠ‹í3'"%r({›‹4"/Š814*,&m‰nmxQ–.&t > œ{14*,&m ’ œ–1;*,&mn"%”l—o*/m?”l(o&(ˆ“ ’ ‡ –8£I7 ££OŠ‹‡3mn(ošl){(oš;“« Q¦&-œ1`(œ{&.*Çs,”l› ”l“{‰'œm?& „({—{)*/"%ŠŒ1;*,&mu¡~1`‰?s‹1l)o•Å“2œm?& pr)o*/—–)o*/"£OŠ‹í3 4&.iSŠŒ1;*,&mu>k'7 £I*3 £ "%r({› &m?s/)–(oš–Ž £~.+-&)ošl){(oš6&mn(&.¸(&)o&( !#"%Š814*,&mmn(ù‘’£OŒ3 £P‰nmxQ–.&t,> œ{14*,&m ’ ž~87¸”l—&.1`(œt“« ”œ{&.k'7£OŒ3 £ ‰nmxQ–.&t > œ{14*,&m ’ ¢~7 pŒ‘ 3î14*/.,mWVk'7£ .T¨Œ4&{*,”`.`


"%r({› &m?s/)–(oš4&(u¢W"]3I–8£Œ‘!l£O’~£m?*,&.1;*/m?4&ÇžI&.1l.ùQ&m?*/){(ošé3˜m?* œ{&( r({›'&m?s/)–(oš4&(†Š‹pÑ5‘438ù’XQ&-œmn(š`)–(oš;«Z4—–.,){(oš41l({› &m?s/)–(oš4&(†’~‡‘5[ ‰?1Q&‰‡«j ù3R5r({*,&.s,•Å“{m?&-œé+)X‹p538pˆ&“{.*'’ í‘5[ˆ(o14•,“&mn(&-3Z£Œ3 5Œ7I‘Ñ›'m?&-œ{&.!1l(œm?&Çr)os,š41l(oš4s,s,*,&‰n‰?&¹+)–.¿S )o•Å> k7_38pŒÔI« ZŒ$ pŒ723« Z!Fy{w¦#"~wy{ƒy(©798;:¢=?A@,?AB)+#B *C1¢DE,?>;38pZ>?> ’ $®ñ ÚWÚ “«ZZ Š‹p‡ –!ù’b£1Q&-œmn(ošl){(š«W}~x`w¡W¦¦'}Çy{w¦`}~W…¦¦©¢¨¡\‚O}~ƒ?yÚo×4öoÛlàoálÚ{Ý~ò,á4Ö.4öÚoÝlà#ßæèá4Ö.4öÚoÝlà{ß{çbèà---ó~Üî'÷'å ÷ à{ø{ÝÙBÞlö4à.{ݨà Ü Úoá4ßÖÙOÜ ('0%Ü c%ciî‰?1Q&‰‡«Z ‹p538p31;*- k¢“«)–“{.,)–(oš† $'&B&(œm?šl){(ošé&mn(o&.‹ )s/tTSœ–&(Q&m?œ–&(ê .*,&( Q&-s,*,&“{*ŠŒ&.î&mn(o+m?š4&éx-y{z-¦-©¥~wy‚¸+-›'m?s,•,“&(Ç¢–){({{*/m?”l(os/"/‘”œ){‰?&˜&mn(o&. ‘1;*/.,mWV&mn(o&( ‡ &.*~+){›'&m?s,&(œ–1`.,mn(W¡{œ{1Z Ôr5! £’ 3&‰?œ)–(oš;“«”l({(&(d){(œ1l‰?s‹r.š`)3î&({*r#&mn(&){(œ{&¢~{(–m?&.*,&(ê‘14*/.,m?+-&(+){‰?14s/"?Su‘’\"§‰X†þÿ|W…s/mn(œNr.,){—{—&(î4”l( ù‘’"%r({›'&m?s/){(oš4&(b¡4œm?&'1`‰?s†S ”`(–(o&(b>Ô~.”4š`.1433&Œ#”43˜—{mn‰nm?&.*Ç›'&.œ{&(é(–m?•,“{*Œ&TV4m?s,*/m?&.&( )–(oœ&.+-&)oš4&( œ m?&-s,&Q&m $'&-œ{1l.,t,>N-W0„3 q ?AK2?A8^:#B#?AwfEK2@pEXB c>D#K2(z1¢DE,


И¿ Ê¢ ȘÎu˜ ÊÍ Ì'¿ Ê¢ Zþ~ŽÇÆ­Ð Í Ê s4é¿'ÐN OÊʧ ~Î › þ4sMêŸÊÍ){‰?sŒ“1;* 31l(:9o)ošl.,mn0 1l){tOœ m?&Çšl‰?”Q1`‰?& #"\3‹>r)`&.,“1`‰xQP&mn(o&-s8‘”œšl‰?”Q1`‰u>S ){.‘”œ)–‰?& 3˜m?*é .šl)o3&({*,&(¢S 1`.&mn(o&:‰?”`;1l‰?&24"\3›'mn.œ¸*,&-3Ç—”l.ôˆØ ) .{Û× ð áÛPôMØ4âë~ÜÙàbÙ`Þ Ü ÙàbÙ`Þ Üü~Ü ô ð ) Û× “oáÛ ôMô ð è˜Õ ð ÛÝÙ ð Ýlà ôM£ £*3R38pŒ7r4Œ£®¨r‰nmxQ–.&t,> •B14*,1l‰?”;š;« s/—&-+mx~+m?&.*œ{&( š4&¿S ”l0(o&"7*,&(Ó[‹14*,1l‰?”;š–>pr8Š ’ ‘14*/.,m?+-&(ˆ“ ’ 3”œ){‰?&¨ j ‘”œ )o‰?&k¢“« ‰\S 14œ{*‹œm?&‘14*/.,m?+-&(’1l{*/m?;&( r.ùQ&m?*,s]Q&.&m?•,“W>){(œ‘”œ)–‰?&Çmn(œ{&(£O‘ prž8£ ’ ‘14*/.,m?+B&(ˆ“ ’ 3 ){‰?&¨ j ‘”œ–){‰&§k¢“« ‰\S ”;s,•Å“{*‘14*/.,mn"7œ{&-3œ[‹14*,1l‰?”;š–>+-&(q)–(oœ‘”œ)–‰?&1`)sSŒŠ87 ‡ †ŒÔ p‹í‘43 †mn(œ{”`› sr){(œ †ˆ‡Š m?s/—–‰?1^ †üŒ©© £¡£¢¡¤£¦¥¨§• ³ILŠ– M ¬® ÜàÝáÜ1â³ãäm å”Q{m?&-*,&-*Ç&mn({m?š4&Yr.1~–t){({{*/m?”l(o&(W¡ 3˜m?*Çœ–&(o&(23î1l(2&mn({"‹{4ù‘’£~mn(P‘”œ)–‰O”`“–(o&Çr.šl)o3&({*8šl.&mnt„*Œ&¢Q&(–tu1`‰n‰?s‹1l){t'œm?&Çšl‰?”Qo1l‰?&q4"\3œ{&-s‘”œ)–‰?sq&.+-&)oš4*› &.œ–&(W¡Os/mn(oœ+)b>O‘14*/.,m?+-&(b¡'œm?&émn({(&.,“o1l‰xQtu1;•Å“o&‹+-›'&m?œm?3&(os/m?”l(o14‰?& Ô ‰?”;*,sŒ&.+B&)š;&(;1l({(WŽ† ŒÔ pŒ’ñ1l(oš4&‰?&-š4*->‘”œ)–‰?& ?S ”l({(&( 1l){tŒœm?&‰?”l;1l‰?&q3Rœ–&-sÇœ{1l.¿S )Q&.,"žO&.s,•Å“o14•,“{*,&‰?*,&j ŠŒ1;*,1 *,&—Yr.1l—{“{m?•-sÇ„({*,&.,t„14•-&kI?S ”`(–(o&( œm?&r“{({‰nm?•Å“+)o36Š‹‹‰nm?&-š;&(œ{&(2‘”œ){‰?sŒ+)ošl.&mnt„&(W>*,*/.,mxQ–)o*,&Çœ–&.!&mn(o+-&‰n(o&(2Ô~‰?”4*,&‰?&-3î&({*,&4¡bœ m?&Ô~‰?14+m?&.,)–(ošé){(œ 4;1l"1l(oœ–&.*î›'&.œ{&(2)–(oœPœm?&Xr.1~{&(‰nm?&.,){(š{¡'8•Å“os,&(P){(œ3~&V*Ç4&.iSá4âæ~Ü ð â{ç~ÜØ4â{ä~Ü‘ôˆá~è ð èéØ) .{Û× ð áÛPôMÞ4ß{á4ÖßPÚo×4öoÛæÜð Ü ô Õ ) .{Û× ð áÛPôMÕ{â{ámn(Y[‹14*,1`‰?”4š;&( 4&.› 1l‰?*,&-*8›'&.œ{&(W>Õ{Ö{×ظÙÚoÛ~Ü.{Þ4ß{á4ÖßOÜ ØáÛÛð ×âOòùêæ æ óÜð ×âOòùÐ æ¸æóÜ!Ö4öàˆÚo×4öoÛæÜð Ø Õ Ü ôˆØ Ù`Þ4ßñ{Ý4Öf’ álà{Ý4ÖßÕ{ÖÙà{ßêáß{á.â{×~òù~èæ~è/çóoÜôMÕ{Ö{ÝÙ`Þ4â{ãæè%ç~è,äWèè $ è/ïìWÜ.{×lÕoÝlà Ü ØáÛÛ.4ÕoÛ×!Oò] ð ×Oè]! ð ×óÜØáÛÛÞ4ß{á4ÖßPÚo×4öoÛç~ò,á~è ð óÜÕ{â{çô~ò,á ð óoÜ ô Õ ) Û× “oáÛ ôM.4Õo×Ùà{ßOò/ß{á.OèùÕÖ{Ý–Ù`ÞóoÜØáÛÛ.{Þo×4øOÜ ØáÛÛð âõ4öbÙ-ßOÜÖ4öàˆÚo×4öoÛç~ò,ábè,ØóÜð Ø Õ Ü ôˆØ Ù`Þ4ßñ{Ý4Öf’ álà{Ý4ÖßOèÇôMÕ{ÖÙà{ßêáÜ º¸·¹¬iý ² · ³ ® ˜ Ë ® m Ë Ï ± »;·¹® ± ®ÐÏ—L+O ³ ¬ H ·¹® m› ·¹¬ O · ³ · m ° Ë ´:»¬iý ² M ·¹¬ O ·¹®ªš){(oœ ”43Ç—–mn‰nm?&.*,& ù‘’\"%‘”œ)–‰?& ?S ”l({(&( mn( ‹4"‘14*/.,m?+B&([‹14*,1`‰?”4š;&(Pš;&-s/—&m?•,“o&.*Œ›'&.œ–&(b>tTSŠŒ1;*,&(&mn(š;1Q&XS )Q&. ‘1;s/&(³Q+-›‹>&mn(&(q3&(*S )oš4&-s,*,&)&.*,&(){.'œm?&Ô~.”4šl.1;331Q–‰?1`)–t j S1`“–({‰nm?•,“P›'m?&Œmn(‹4"/‘1`.”4s§k>ŠŒ&.*,1l(oœ{1l.œ41;*,1l‰?”;š–¡'mn(¸œ{&(ù‘’\"%£~‰?&-3&({*,&1Qš;&‰?&-š;*é›'&.œ{&(b¡m?s,*Œœ{&.!‹4"][‹1;*,1l‰?”;šé‹5‹£O7F> ù‘’ _38pŒ7‹>Ü º¸·¹¬iý ² · ³ ĩ· ³Pœ L » O8± ®´ªéª‹{4ù‘’.&B•Å“{* s/—&m?•,“o&.,mn({*,&(os/mŽ8¢5S )–.u¤,&Bœ–&-s £~‰?&-3&({*q&mn(o&.m?s,*3ŒpŒ7 4Œ£I« ‰nm?s,*,&B*Œœ{&(„({“1`‰?*Œœ{&-sI[‹14*,1`‰?”4š4s->–‹p ‡&.œ–&(ž¹$®^*,&-sr.&-s,&.4m?&.*-> j ªª $'&-”Q1;•Å“{*/){(oš4&(23Çm?*˜ ªiªª$®^*,&-s->xkžO1l.,m?1Q{‰?&(YQ&(ÕS’ ‘14*/.,m?+B&(ˆ“ ’ ‘ pŒŠ85Œ’b£¦¨ j ‘”œ)–‰?&§k¢“« s/—&m?•Å“o&.*œm?&38pŒ7 £‘14*/.,m?+B&()–(oœ‘”œ)–‰?&˜m?3[‹1;*,1l‰?”;š¹1QW>Þ4ß{×4Ö{Ý2á ðØ~ÜÞ4ß{×4Ö{ÝdÚo×4öoÛÝ4â4Úo×4öoÛ{æÜÛæ Úo×4öoÛçóÜÞ4ß{×4Ö{ÝdÚo×4öoÛÝ4âOòùÚ{×4öÞ4ß{×4Ö{Ý~Ü7 8 99;:= ¡£?>A@ §B§C¢D ¡@¥ D £


wu£#¤ }~¥~z`}~W…¦#¥~y{w¦#"~wy{ƒ@y¢¡‘14*/.,mWV3‹){‰?*/mn—–‰?mn1;*/m?”l(êRQw¨Œ• ÚÚ5ÚÚÚÚÚÚÚ5ÚÚÚÚÚÚÚ4ÚÚÚÚÚÚÚÚ5ÚÚÚÚÚÚÚ4ÚÚÚÚÚÚÚÚ5ÚÚÚÚÚÚÚ5ÚÚÚÚ "~y{z-|–x©¡z-y{'®SW}~x`w¡Wy{2}~W‚¯é\xBy{z "~z¢¡…¦z¨|x££dy ª«­¬¦ ‡ &m?*,&.&îpr—&.14*/m?”`(&( ÚÚÚÚÚÚ5ÚÚÚÚÚÚÚ5ÚÚÚÚÚÚÚ4ÚÚÚÚÚÚÚÚ5ÚÚÚÚÚÚÚ4ÚÚÚÚÚÚÚÚ5ÚÚÚÚÚÚÚ5ÚÚÚÚ ¬>'}W…z`w6· |}£!yM¸\xBy{zlWyž wuƒy¦ ª¤¢¨Ñvº¦© ‹z¢¡…z-|x££Pwy{z-x-y©¥~~w2–y{ «¹€z¨|M¼Gˆwu ±W²µ± ¤¢¨Ñv °»" y{w©¥Wy{z`P§¤¡¾¨¡\‚O}~ƒy{2}~W‚{¨ |{x`z`w„¨y{ °½¨±y{wx-y{z-y¨Á¤ ¡o…ƒuw„©#¥–y{wx-y{ °4¿³À'¡£¥`§ ©\© £\¡¤£Pî\2Ÿ²ÐL » O µ'˜· ³IH ·¹¬iý ² ®2¬;µã'® ¦ 4)33î&‹1l‰n‰?&.î91l“{‰?&(4”`(P

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!