%macro a(no);
data DS&no;
a=&no;
run;
%mend a;
このマクロaのパラメータを1から7で実行したいと思えば
%macro tloop;
%do i = 1 to 7 ;
%a( &i )
%end;
%mend tloop;
として、
%tloop
とすればできます。
ではパラメータが1 3 5 7のように非連続であればどうしましょう?
%macro _tloop;
%do i = 1 , 3 , 5 , 7 ;
%a( &i )
%end;
%mend _tloop;
%_tloop
とかって書きたいところですが、こいつは漏れなくエラーです。
通常のデータステップのdoステートメントでは
do i = 1 , 3, 5, 7;end; のような非連続値をリスト形式で指定して回せますが
マクロの%do はできません。基本的には別物だと考えた方がいいでしょう。
でも、どうしても、非連続のループがやりたいのって場合はどうするか。
ぱっと思いつく範囲で書いてみました。
まずパターン1として、今回はパラメータを変えながらマクロを実行したいだけなので
ループ用マクロを作らずに通常のデータステップの、do ループで値を遷移させて
call executeしちゃうパターン
data _null_;
do i = 1 , 3 , 5 , 7;
call execute( cats( '%a(' , i ,')' ));
end;
run;
つづいてパターン2 として minoperator オプションを使って
マクロ内でのin演算子を有効にし、ループ変数の最小最大値でループして
inでターゲットの非連続値の値が来た時のみ実行するパターン
%macro loop;
options minoperator;
%do i = 1 %to 7;
%if &i in 1 3 5 7 %then %a(&i);
%end;
options nominoperator;
%mend loop;
%loop
パターン3はインデックス値をマクロ変数で与えて%scanで代入していくパターン
%macro loop2 ;
%let loopval =1 3 5 7;
%let i = 1 ;
%do %until(%scan(&loopval,&i) eq) ;
%let j = %scan(&loopval,&i);
%a(&j)
%let i = %eval(&i+1) ;
%end ;
%mend loop2;
%loop2
パターン4 はパターン3と発想は同じで、よりシンプルな書き方
%macro loop3;
%let loopval=1 3 5 7;
%do i=1 %to %sysfunc(countw(&loopval));
%let j=%scan(&loopval,&i);
%a(&j)
%end;
%mend;
%loop3;
パターン2以外は、多分ループ用に与えたい値が文字であっても
そのまま応用できると思います。
また、多分、他にもいろいろ書けるとは思います