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
Obsidian | Level 7

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.

hackathon24-white-horiz.png

The 2025 SAS Hackathon Kicks Off on June 11!

Watch the live Hackathon Kickoff to get all the essential information about the SAS Hackathon—including how to join, how to participate, and expert tips for success.

YouTube LinkedIn

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