LesezeichenAbonnierenRSS-Feed abonnieren
wmueller
Fluorite | Level 6

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

 

6 ANTWORTEN 6
WolfgangHornung
Fluorite | Level 6

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

Kurt_Bremser
Super User

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.

GrischaPfister
Fluorite | Level 6

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

wmueller
Fluorite | Level 6

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

 

Kurt_Bremser
Super User

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.

FreelanceReinh
Jade | Level 19

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.

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

Diskussionsstatistiken
  • 6 Antworten
  • 1605 Aufrufe
  • 3 Kudos
  • 5 in Unterhaltung