Community deutschsprachiger SAS-Anwender und -Programmierer

Antworten
Dies ist eine offene Gruppe. Melden Sie sich an und klicken Sie auf die Schaltfläche „Gruppe beitreten“, um Mitglied zu werden und damit zu beginnen, Beiträge in dieser Gruppe zu veröffentlichen.
Highlighted
Occasional Contributor
Beiträge: 15
Erzeuge Text/VariablenListe im Code mittels Macro - quasi C++ INLINE

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

 

Occasional Contributor
Beiträge: 7
Re: Erzeuge Text/VariablenListe im Code mittels Macro - quasi C++ INLINE

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

Esteemed Advisor
Beiträge: 5.995
Re: Erzeuge Text/VariablenListe im Code mittels Macro - quasi C++ INLINE

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.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Contributor
Beiträge: 21
Re: Erzeuge Text/VariablenListe im Code mittels Macro - quasi C++ INLINE

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

Occasional Contributor
Beiträge: 15
Re: Erzeuge Text/VariablenListe im Code mittels Macro - quasi C++ INLINE

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

 

Esteemed Advisor
Beiträge: 5.995
Re: Erzeuge Text/VariablenListe im Code mittels Macro - quasi C++ INLINE

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.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Trusted Advisor
Beiträge: 1.114
Re: Erzeuge Text/VariablenListe im Code mittels Macro - quasi C++ INLINE
[ Bearbeitet ]

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.