Hallo zusammen,
ich würde gerne über ein Makro eine Liste von Variablen erzeugen, z.B. im Kontext einer Format-Anweisung oder
auch für ein Array.
Mein Ziel ist die Code-Zeile:
AY(3) X2 X3 X4;
Diese Zeile soll dabei dynamisch über ein Macro erzeugt werden, ungefähr so:
%let O = 4;
%let U = 2;
AY(%eval(&O-&U+1)) %do i=&U %to &O; X&i; %end;
Leider klappt das aber so nicht.
Weiß hier jemand Rat?
Beste Grüße
Wolfgang Müller
Hallo Herr Müller,
das Semikolon bei X&i. ist an der falschen Stelle. Folgendermaßen geht es:
%macro a;
%let U=2;
%let O=4;
data a;
array AY(%eval(&O.-&U.+1))
%do i = &U. %to &O.;
X&i.
%end;
;
run;
%mend a;
%a;
Viele Grüße
Wolfgang Hornung
In Erweiterung dessen, was Wofgang schon festgestellt hat:
alles, was zwischen dem Semikolon am Ende des %do statements und dem %end steht, wird Teil des generierten Texts, also auch dort befindliche Semikolons. In den meisten Fällen macht man beim Arbeiten mit der SAS-Makrosprache zu viele Semikolons, die aber sehr oft nur leere Statements ohne syntaktische Probleme zur Folge haben.
Hallo Herr Müller,
hier bietet sich eine Makro-Funktion an, die als Rückgabewert einen String mit den erzeugten Variablennamen erhält. Hier ein kleines Beispiel:
Options mcompilenote=all;
%Macro varsList(prefix,start,end);
%Local i varsList;
%Do i=&start %To &end;
%Let varsList = &varsList &prefix.&i;
%End;
&varsList
%Mend;
%Put NOTE: varsList(test,0,10): %varsList(test,0,10);
Data _null_;
Retain %varsList(a,12,15) 0;
Put (_all_)(=);
Run;
Data _Null_;
Length %varsList(a,1,10) 8;
Array aVars a:;
Put aVars(*)=;
Run;
Der Parameter PREFIX entspricht dem eigentlichen Variablennamen, durch START und END wird die Numerierung festgelegt. Die Liste lässt sich dann in den unterschiedlichsten Kontexten verwenden, hier Beispiele für %PUT, Retain und Length Statements.
Viele Grüße,
Grischa Pfister
Hallo zusammen,
besten Dank für die schnelle kompetente Rückmeldung: es funktioniert!
Schade nur, dass man die Anweisung zuerst in ein "externes" Makro packen muss,
dies macht den Code doch etwas unübersichtlich. Aber das lässt sich vermutlich nicht beheben
ERROR: The %DO statement is not valid in open code.
Beste Grüße
Wolfgang Müller
Für die Iteration braucht es den Makro-Compiler, weil das doch schon sehr high-level ist.
Der C Preprocessor kennt zB gar keine Iterationen, nur simple if-Konditionen, die dort auch überall verwendet werden können.
Hallo, Herr Müller,
ich denke, in vielen Fällen geht es auch ohne Makro. Hier ein Beispiel mit ARRAY-Deklaration, RETAIN-, PUT- und KEEP-Statement:
%let O=4;
%let U=2;
data test;
array ay x&U-x&O;
retain x&U-x&O 2016;
put (x&U-x&O)(=);
keep x&U-x&O; /* nur zur Demonstration */
run;
Da die Variablenliste doch durchgehend nummeriert sein soll, kann man die Variablenlistenschreibweise "Xm-Xn" verwenden, braucht also keine %DO-Schleife. In der Array-Deklaration ergibt sich die Dimension des Arrays automatisch aus der Anzahl der Variablen in der Liste (hier: 3) und steht danach bei Bedarf auch als dim(ay) zur Verfügung.
Available on demand!
Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.