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.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!