Ablauf des Tutoriums Einführung in die SAS Makro Sprache z Zeitrahmen z z z Ablauf z z z z Grischa Pfister z z iCASUS GmbH Vangerowstraße 2 69115 Heidelberg [email protected] Arbeitsfelder z z z z Anwendungsentwicklung AF, IntrNet, Java Data Warehouse Balanced Scorecard Schulungen im Bereich BASE, AF, Java Programme & PPT Agenda z z z z z z Immer und jederzeit Unterlagen z Zur Person Vortrag Anwendungsbeispiele Fragen z z 09:15 – 12:00 Uhr Pausen und Übungen auf Zuruf z z z Einleitung Makrovariablen Makros Makro-Statements Makro-Funktionen Interaktion mit dem Data Step Debugging Deployment 1 Einleitung z Einleitung Warum eine Makro Sprache? z z z z z Durch Kollegen SAS community z z z z Automatisierte Programme z z z In einem Programm werden Platzhalter referenziert Beim Verarbeiten werden Platzhalter ersetzt Grundprinzip ist die Textersetzung Æ Makros sind Code-Generatoren z Ergebnis ist SAS/BASE Programm (bzw. ein Teil davon) Einleitung Was sind Makros? z Platzhalter-Prinzip Definierte Analyseverfahren Einleitung z z Standardisierung z Wie funktionieren Makros? Leichtere Pflege Bessere Lesbarkeit Wiederverwendung z z z Vereinfachung des Codes z Die SAS Macro Facility besteht aus z Parametrisierung Modularisierung Konditionelle Ausführung von Programmteilen Macro Language z Programmiersprache in SAS/BASE z z z z z Fokus bei Entwicklung liegt auf Effizienz der Programmierung, nicht auf inhaltlicher Fragestellung z Macro Processor z z Variablen Statements Makro-Funktionen Globale Optionen Interpreter Standards für die Bereitstellung 2 Vom Programm zum Makro Vom Programm zum Makro z Beispiel z Proc Print data=Sashelp.Class; Run; Vom Programm zum Makro z Wie werden Makros entwickelt? z z z z SAS/BASE Programm schreiben Allgemein verwendbare Teile identifizieren (modularisieren) Variable Teile identifizieren Programm in ein Makro übersetzen Wie SAS ein Makro verarbeitet 3 Wie SAS ein Makro verarbeitet z Kompilierungsphase z z z z SAS verarbeitet Code Wenn Fehler auftritt Æ Fehlermeldung od. dummy macro Kompiliertes Makro in Work.Sasmacr gespeichert Aufruf des Makros z z z z SAS lädt Makro Makrovariablen werden aufgelöst Logik des Makros wird verarbeitet Resultierendes BASE-Programm wird von SAS abgearbeitet Wie SAS ein Makro verarbeitet 1. 2. 3. 4. 5. 6. 7. Makro-Statements I Word Scanner ließt token aus Input Stack Word Scanner erkennt Makro-Trigger [%,&] Kompiliertes Makro wird geöffnet Lokale Symbol-Tabelle wird angelegt Wert für Table wird gespeichert Makro Processor ließt Tokens aus kompiliertem Makro und schreibt Ergebnis in Input Stack zurück Word Scanner ließt token aus Input Stack Makro-Statements I Compiler Macro Processor z Makro Definition z %Macro Name; ... %Mend <Name>; Symbol Table(s) Word Scanner z Positional Parameter z Keyword Parameter z Input Stack z %PrintTable(Sashelp.Class) %Macro Name(parameter1<, parameter2, ...>) %Macro Name(para=defaultwert<, para=defaultwert, ...>) Kompiliertes Makro %Macro PrintTable(table); Proc Print data=&table; Run; %Mend; 4 Makro-Statements I z %Let-Statement z z z Legt eine MVAR an Ordnet MVAR einen Wert zu %Let %Let %Let %Let x = 5; text = Dies ist ein Text; x = Variable Y hat den Wert "&text"; z =; Makro-Statements I z Kommentare z Makrovariablen I z %* Makro-Kommentar-Text ; z z z Makrovariablen I z Kommentar bis zum nächsten Semikolon Abschalten einer Zeile / eines Statements /* Normaler Kommentar-Text kommentiert auch enthaltene MakroAufrufe und Makrovariablen */ Automatische MVARs z z z * BASE-Kommentar-Text ; z z z Makro-Aufrufe, -Statements sind nicht auskommentiert! Problem wenn vor %Else Vorteil: werden in LOG ausgegeben wenn Option MPRINT gesetzt ist Automatic / global / local Benutzerdefinierte MVARs z z z Dictionary.Macros / Sashelp.Vmacro MVARs besitzen scope: z z Als Parameter bei Makro-Aufruf Definiert mit %Let-Statement %Let mvar = wert; Auflösung nur in „…“, nicht ‚…‘ Fehlermeldung wenn nicht deklariert 5 Vom Programm zum Makro z Bestehendes Programm erweitern z Makrovariablen II z z z z Überprüfung ob Variable existiert Abbruch wenn nicht Wenn gesetzt ODS Statements erzeugen Definition z Globaler Schalter für Ausgabe in HTML z z %Let mvar = wert; Überprüfen der Existenz z %Symexist(mvar) [ab V9] z Dictionary.Macros (für globale mvars) Löschen [ab V8] z z %Symdel mvar <mvar ...>; [Call Symdel("mvar <mvar ...>");] Makrovariablen II z SQL z Makrovariablen II Nach SQL-Step werden automatisch globale MVARs gesetzt z z z z Anzahl der gefundenen Sätze Return Code des Steps Anzahl der Schleifenläufe Nachzulesen in z z z SQLOBS SQLRC SQLOOPS SQL: Dictionary.Macros Sashelp.Vmacro Scope z Automatic / global / local 6 Makro-Statements II z Schleifen z Makro-Statements II z z %Do %While ( bedingung ); ... %End; %Do %Until ( bedingung ); ... %End; %Do i=1 %To n <%By step>; … %End; z z z Es gibt keine LEAVE Anweisung z Makro-Statements II z Ablaufsteuerung z Verzweigung mit z z z %If - %Then - %Else %Do ... %End Analog zum Data Step Sprungmarken z z %Goto label; … %label: <macro statement>; z Operatoren z z Teilmenge der SAS/BASE Operatoren Arithmetisch z z z z z z %Return; [ab V9] %Goto %Abort (setzt Fehlercode) ^, &, | NOT, AND, OR Nicht z z **, +, -, *, /, <, > <=, >=, =, ^= LT, LE, EQ, NE, GT, GE Logisch z Abbruch des Makros z Æ vorzeitiges Verlassen der Schleife nur mit %Goto Makro Statements II z z i wird automatisch als MVAR angelegt (!) Impliziter Aufruf von %Eval Min, max, : Auswertung arithmetischer Ausdrücke z Erfolgt ganzzahlig! 7 Makro-Statements II z %Put-Statement z z z Schreibt Text in das LOG-Fenster Fehlersuche bei Entwicklung Kontrollierte (Fehler-)Meldungen Neues Beispiel z Makro-Funktionen I Für alle Tabellen einer Library z Makro-Funktionen I z %Let mvar = %Funktion(para1<,para2,…>); z Alphanumerisch Variablenliste ausgeben z z z Proc Contents Ods Select Schleife über alle Tabellen z z Woher kommen die Namen der Tabellen? Wieviele Tabellen gibt es? z z z z z z %Index(mvar,text) %Length(mvar) %Scan(mvar,n<,delimiter>) %Substr(mvar,start<,end>) %Upcase(mvar) … 8 Makro-Funktionen I z Numerisch z Bei Statements implizite Konvertierung Grundsätzlich ganzzahlig [-264 - 1,264 - 1] %Eval( ausdruck ) %Sysevalf( ausdruck ) für Fließkommadarstellung z Ergebnis ist aber immer eine Zeichenkette! z z z z Zurück zum Beispiel z Die elegante Variante z Tabellen-Namen und -Anzahl aus Steuerdatei lesen z z Per SQL Mit Hilfe des Data Step Schnittstelle zu allen Data-Step Funktionen z %Sysfunc() Makro-Funktionen I z Eigene Makro-Funktionen z Makro mit Rückgabewert z %Macro name; ... &mvar %Mend; z Darf nur Makro-Statements enthalten SAS Autocall Macros z.B. %Left z Makrovariablen III 9 Makrovariablen aus SQL erstellen z Select Into :mvar Separated By „ “ z z z Enthält Anzahl der gefundenen Sätze Æ Makro-Schleife über &sqlObs, mit %Scan den jeweiligen Wert lesen Makrovariablen dem Data Step erstellen z End = eof setzen z z Makrovariablen IV Mvar SQLOBS z z Erzeugt Liste aller Werte Trennzeichen frei vergebbar Um am Ende Anzahl der Sätze zu schreiben Call Symput(„mvar“,“wert“); z Makrovariablen IV z Scope von Variablen z z Im Open Code immer Global Schachtel-Prinzip z Für jeden gelesenen Wert wird eine Variable erstellt z z Æ Makro-Schleife über die Anzahl Sätze z z Auflösung der Makrovariable erfolgt von links nach rechts &&table&i z z Nach erster Auflösung Æ &table1 Nach zweiter Auflösung Æ Class Jedes Makro hat lokale Symbol-Tabelle Jedes Makro kann die Symbol-Tabelle der umgebenden Makros sehen (und schreiben) %Let faktor = 5; %Macro a(para1); Global faktor = 5 %Let para2 = %Eval(&para1 * &faktor); %b(&para2); Makro a %Mend; para1 = 11 %Macro b(para1); para2 = 55 %Put in B: para1 = &para1; %Mend; Makro b para1 = 55 %a(11); 10 Makrovariablen IV z Neues Beispiel Probleme mit nicht explizit deklarierten MVARs z SAS durchsucht alle umgebenden Symbol-Tabellen z z Wenn MVAR vorhanden wird dort ersetzt (z.B. Schleifenzähler &i !!) z Makros die ODS-Kanal öffnen und schließen z z %OdsOpen %OdsClose Gleichnamige Variablen müssen mit explizit definiert werden z z Als Übergabeparameter %Local-Statement z Wenn in globale MVAR geschrieben werden soll z Wenn in die existierende MVAR aus einem umgebenden Makro geschrieben werden soll z Sonderfall Call Symput() z z %Global-Statement Weder %Local noch %Global Makrovariablen IV z Bei Unsicherheit z Das %Put Statement z Vordefinierte Listen von Makrovariablen z z z _global_ _local_ _user_ z %Symglobl(mvar) [V9] z %Symlocal(mvar) [V9] z %Symexist(mvar) [V9] z z z Makrovariablen V alle globalen MVARs alle lokalen MVARs alle benutzerdefinierten MVARS Testet ob MVAR global ist Testet ob MVAR local ist Testet ob MVAR existiert 11 Makrovariablen V z Sonderzeichen in Makrovariablen z z Werden als Teil der Makro-Sprache interpretiert z z z z z Execution time z z Wenn MVAR befüllt oder übergeben wird Alle Funktionen maskieren z Alle Operatoren Leerzeichen, Komma &, % Müssen maskiert werden Compile time z Makrovariablen V z z z z Operatoren Leerzeichen Semikolon Komma Sonderzeichen ‘ “ ( ) z z Alle „B“ Funktionen und %superq maskieren automatisch Bei den anderen muss % vor dem Sonderzeichen stehen Wenn MVAR in einem Makro aufgelöst wird Makrovariablen V z %Str und %NrStr %Bquote und %NrBquote z %Superq z z NR z B z Bedeutet not resolved z By itself (für normalerweise paarweise auftretende tokens wie Anführungszeichen oder Klammern) Debugging 12 Good Programming Practice z Standards schaffen und einhalten z z z z z Debugging z Ein Makro je Datei Dokumentations-Header und Kommentare Einrückung von Blöcken (zwei Zeichen) Namenskonventionen (Variablen, Makronamen,…) Schreibweisen (Groß-/Kleinschreibung) Das %Put Statement z Gibt Zeichenkette in LOG aus z z z Vordefinierte Listen von Makrovariablen z z z z z z Makros bei der Definition schachteln z z z z alle globalen MVARs alle lokalen MVARs alle automatischen MVARs alle benutzerdefinierten MVARS Unperformant Unübersichtlich Debugging z Globale SAS Optionen z [No]mprint z [No]mlogic z [No]symbolgen z z Makrovariablen z _global_ _local_ _automatic_ _user_ Reduktion von Komplexität Module einzeln testen Weiteres Makro bündelt die Aufrufe Bad Programming Practice z z Modular arbeiten %Put mvar = &mvar; %Put mvar = „&mvar“; Nicht sauber zwischen globalen und lokalen Variablen trennen z z Zeigt den von Makros generierten BASE Code Zeigt Programmfluss des Makros Zeigt die aufgelösten Makrovariablen [No]source und [No]source2 13 Debugging z Eigene Logging-Mechanismen z z z In externe Datei schreiben Eigene Meldungen ausgeben Fehlerdatenbank aufbauen Debugging z Deployment Wenn SAS nicht mehr reagiert z Makro Compiler hat %Mend nicht gelesen z z z z z Æ Aller weiterer Input wird als zum Makro gehörig interpretiert %Mend solange absetzen bis zugehörige Fehlermeldung kommt (s.u.) Einzelnes Anführungszeichen (o.ä.) ist durchgerutscht z Deployment z Autocall Facility z z z Option sasautos sasautos = (fileref <fileref ...> sasautos) Option mautosource Filename gpMacro "d:\temp"; Options sasautos=(gpMacro sasautos); *‘; *“;*);*/; %Mend; run; Æ String solange absetzen, bis zugehörige Fehlermeldung kommt (s.u.) Fehlermeldung z ERROR: No matching %MACRO statement for this %MEND statement. z Æ Jetzt ist der Makro Compiler wieder zurückgesetzt 14 Deployment z Stored Compiled Macro Facility z z z Optionen store und source bei Makro-Definition %Macro test / store source des="text"; ... %End; Option sasmstore = libref setzen Option mstored setzen Literatur z Books By Users z z Michele M. Burlew SAS Macro Programming Made Easy Art Carpenter Carpenter's Complete Guide to the SAS Macro Language, Second Edition Literatur z Offizielle SAS-Dokumentation z z z Online-Hilfe Online-Doc Download von support.sas.com z z base_macro_6997.pdf Online verfügbare Tutorien z z Fragen ? Fragen ! SAS Anwender Handbuch im Netz „googeln“ 15