2014-10-21 7 views
5

Ich bin ein Makro mehrere Male in SAS läuft wie folgt:In SAS, Ausführen eines Makros ohne Semikolon?

%mymac(a,b); 
%mymac(a,c); 
. 
%mymac(a,a) 
%mymac(a,w); 
. 

Mein Programm/Makro ähnelt:

/* begin program here */ 

data original_data; 
set mylib.mydata; 
run; 

%macro mymac(x,y); 

data mydata1; 
set original_data; 
where school_district="&x"; 
run; 

proc means data=mydata1; 
var income; 
run; 

%mend mymac; 

Ich erkannte, hatte ich ein Semikolon vergessen (wie in der (a, a) eins) und SAS schien es nicht zu kümmern. Es führte alle Makroaufrufe ohne ein Problem aus. Ich habe die Ausgabe verglichen, als ich ein Semikolon eingefügt habe und ich konnte keinen Unterschied sehen.

Ist das normal, dass SAS mit dem fehlenden Semikolon keinen Fehler gibt?

+1

Also wenn ich das alles richtig verstehe, brauche ich kein Semikolon am Ende des obigen Makros, weil die allerletzte Anweisung ein Semikolon enthält, also würde ein Semikolon zu% mymac (a, a) hinzugefügt werden im Wesentlichen ist das gleiche wie Tippen ausführen ;; am Ende der Mittelanweisung? – user27008

+1

Ja, das ist genau richtig. –

Antwort

3

Es ist normalerweise in Ordnung. Die wichtigste Sache, die man über SAS Macro verstehen sollte, ist, dass es ein Code-generierendes Werkzeug ist, keine echte Programmiersprache. Während %my_mac(x,y); wie ein traditioneller Funktionsaufruf in einer C-ähnlichen Sprache aussieht, in der Sie jede Anweisung mit einer ; beenden möchten, hat hier eine abschließende ; keine wirkliche Bedeutung. Es ist vielmehr der SAS-Code, der innerhalb von %my_mac(x,y) generiert wird. In Ihrem Fall ist dieser Code grammatikalisch SAS und ist in Ordnung. Wenn Sie den %my_mac(x,y) Aufruf mit dem Code ersetzen, den er erzeugt (d. H. data mydata.....run;), sehen Sie, dass es auch ohne Ende %my_mac(x,y) mit einem ; grammatisch ist. Wenn Sie stattdessen %my_mac(x,y); schreiben, würde es nur data mydate.....run;; generieren, was in Ordnung ist, aber die ; ist redundant.

In der Tat ist das Überspringen eines Semikolons auch ein Hack für einen Rückgabewert für ein Makro. Zum Beispiel:

%MACRO x_plus_n (x = , y=); 
    %SYSEVALF (&x + &y) 
%MEND; 

%LET x = 3 ; 
%LET y = 4 ; 
%LET z = %x_plus_n (x = &x , y= &y) is the result; 
%PUT ------------- &z; 

Beachten Sie die fehlende ; auf der% SYSEVALF Linie. Dies ermöglicht, dass das Makro nicht bis zum Ende der Zeile endet, die %LET z = .... beginnt, wo es eine ; gibt. Die von x_plus_n erstellte Ausgabe wird zu einer Art Rückgabewert für das Makro.

+0

Grundsätzlich erstellt mein Makro bei jedem Aufruf den Datensatz my mydata1. Ich bin nicht der beste mit Makros und bin mir nicht sicher, ob ich dein Beispiel vollständig verstehe. – user27008

+3

@sparc_spread - Ich habe das Beispiel sinnvoller gemacht, indem ich Text zwischen dem Makroaufruf und dem Semikolon eingefügt habe. Ohne zusätzlichen Text ist der Punkt, den Sie versuchen zu machen, nicht so offensichtlich. –

+1

@RobertPenridge - Ich mag es, danke! –

2

Makros sind nur Textersatz. Sie sind normalerweise keine ausführbaren Anweisungen selbst (obwohl sie manchmal Anweisungen unter Verwendung von %SYSFUNC ausführen können). Daher ist ein Semikolon nach einem Makroaufruf nicht erforderlich, es sei denn, es wäre nach dem Text erforderlich, der in dem Makro enthalten ist (und nicht tatsächlich in dem Makro selbst enthalten ist).

IE:

%macro test; 
proc freq data=sashelp.class; 
run 
%mend test; 

hat als

%test; 

ausgeführt werden, weil die run nicht das Terminal Semikolon haben. Wenn Sie ein Semikolon nach run in das Makro einfügen, können Sie es als %test ohne Semikolon ausführen.

Behalten Sie den ersten Satz oben im Kopf: Makros sind nur Textersetzungen. Der Text, der vom Makro erzeugt wird, wird dann in das SAS-Programm eingefügt und ausgeführt, als ob Sie es eingegeben hätten (vielleicht haben Sie %do i=1 %to 100; verwendet - also 100 Kopien von dem, was in der Schleife ist) - aber es ist so, als ob Sie alle 100 selbst eingegeben hätten). Daher hängt die Notwendigkeit für eine ; davon ab, ob es für Sie erforderlich wäre, es einzugeben.

4

Semikolons sind nicht erforderlich für Makroaufrufe.

Oft sind sie enthalten, da Leute Semikolons als eine Möglichkeit zum "Beenden der Anweisung" oder zum Beenden der Zeile gewohnt sind. Ich persönlich bevorzuge es, sie wenn möglich einzuschließen, da ich glaube, dass es meinen Code lesbarer macht.

Denken Sie daran, dass Makros sich einfach auswerten und zurückgeben, was auch immer es ist, dass sie zu lösen, an dem ein Block von Code sein könnte, der wie eine Zahl aussieht, eine Zeichenfolge, oder irgendetwas anderes ...

Nehmen Sie dieses Beispiel, wo keine Semikolon verwendet:

%macro field_list(); 
    name, 
    age, 
    sex, 
    height 
%mend; 

proc sql; 
    select %field_list() 
    from sashelp.class 
    ; 
quit; 

Probieren sie es auf Ihrem eigenen Rechner mit option mprint; aktiviert ausgeführt wird. Das Ergebnis der Ausführung des Makros gibt einfach den darin enthaltenen Code-Block zurück. Dies führt zu dem folgenden Code wird ausgeführt:

proc sql; 
    select name, age, sex, height 
    from sashelp.class 
    ; 
quit; 

Wenn wir ein Semikolon nach dem Aufruf unserer Makro, hatte dann den Code, der SAS versuchen würde, das Semikolon zu laufen würde, die ungültige Syntax wie so (Anmerkung wäre das Semikolon nach Höhe):

proc sql; 
    select name, age, sex, height ; 
    from sashelp.class 
    ; 
quit; 

Dies liegt daran, das Semikolon nicht für den Aufruf von Makros erforderlich ist, so es wird in der Ausführung des Schrittes hinter und enthielt nur links.

Wenn Sie ein Makro wie im obigen Beispiel aufrufen, ist es gut, das Semikolon einzufügen, da Ihr Makro ein vollständig eigenständiger Schritt ist. Und in Open Source gibt es keinen Schaden wie so fremd Semikolons mit:

%macro example2(inDS=, outDs=); 
    data &outDs; 
    set &inDs; 
    run; 
%mend; 

%example2(inDS=sashelp.class, outDs=tmp_class); 

Dies wertet im Wesentlichen auf:

data tmp_class; 
    set sashelp.class; 
run;; 

Hinweis das zusätzliche Semikolon am Ende von unserem Anruf übrig? Wir konnten so viele wie wir und der Code wollten läuft immer noch gut, das heißt:

%example2(inDS=sashelp.class, outDs=tmp_class);;;;;; 

Beheben zu:

data tmp_class; 
    set sashelp.class; 
run;;;;;;; 

die noch gut laufen wird, da es gültige Syntax ist.