、それだけでは純粋なSASの機能を使用していないのに、私は解決策を自分自身を発見しました。誰かがより単純な解決法を提案した場合、私はそれをアップホートし、最終的な答えとしてそれを受け入れます。
ジムアンダーソン氏がこの問題に取り組んでいるSASカンファレンスの記事は、for loop macroです。 このマクロを考えると、私たちは、私が念頭に置いていたまさにある
%for(tables, values=FitStatistics Type3_Tests LSM Diff, do= %nrstr(
PROC EXPORT DATA= WORK.&tables
OUTFILE="file.xls"
DBMS=EXCEL REPLACE;
SHEET=&tables;
RUN;
))
を行うことができます。死んだリンクの問題を避けるために、私はここで彼の記事で与えられたマクロを引用しています。それは動作しますが、私にとってはあまりわかりません。
%macro for(macro_var_list,data=,values=,array=,to=,from=1,by=1,do=,delim=%str(
),length=);
%global _for_loop_gen;
%if &_for_loop_gen=%str() %then %let _for_loop_gen=0;
%local _for_loop_itid _for_loop_ct _for_loop_code _for_loop_i
_for_loop_val1 _for_loop_var1 _n_ _for_loop_set
_for_loop_arrays _for_loop_values _for_loop_to
_for_loop_var_num;
%let _for_loop_set=%length(&data);
%let _for_loop_arrays=%length(&array);
%let _for_loop_values=%length(&values);
%let _for_loop_to=%length(&to);
%if (&_for_loop_set>0)+(&_for_loop_arrays>0)+
(&_for_loop_values>0)+(&_for_loop_to>0)>1 %then
%do;
%put ERROR: "for" macro only one of "data=", "to=", "values=" or "array=" allowed;
%return;
%end;
%let _for_loop_code=&do;
%if %eval(%index(&do,%nrstr(%if))+%index(&do,%nrstr(%do))) %then
%do; %* conditional macro code - need to embed in macro;
%let _for_loop_gen=%eval(&_for_loop_gen+1);
%unquote(%nrstr(%macro) _for_loop_&_for_loop_gen(); &do %nrstr(%mend;))
%let _for_loop_code=%nrstr(%_for_loop_)&_for_loop_gen();
%end;
%let _for_loop_ct=0;
%if &_for_loop_set %then
%do; %* loop over dataset;
%let _for_loop_itid=%sysfunc(open(&data));
%if &_for_loop_itid=0 %then
%do;
%put ERROR: cant open dataset data=&data;
%return;
%end;
%do %while(%sysfunc(fetch(&_for_loop_itid,NOSET))>=0);
%let _for_loop_ct=%eval(&_for_loop_ct+1);
%let _n_=&_for_loop_ct;
%let _for_loop_i=1;
%let _for_loop_var1=%scan(¯o_var_list,1,%str());
%do %while(%str(&_for_loop_var1) ne %str());
%let _for_loop_var_num=%sysfunc(varnum(&_for_loop_itid,&_for_loop_var1));
%if &_for_loop_var_num=0 %then
%do;
%put ERROR: "&_for_loop_var1" is not a dataset variable;
%return;
%end;
%if %sysfunc(vartype(&_for_loop_itid,&_for_loop_var_num))=C %then
%do; %* character variable;
%let _for_loop_val1=%qsysfunc(getvarc(&_for_loop_itid,&_for_loop_var_num));
%if %sysfunc(prxmatch("[^\w\s.]+",&_for_loop_val1)) %then
%let &_for_loop_var1=%qtrim(&_for_loop_val1);
%else
%let &_for_loop_var1=%trim(&_for_loop_val1);
%end;
%else
%do; %* numeric variable;
%let &_for_loop_var1=%sysfunc(getvarn(&_for_loop_itid,&_for_loop_var_num));
%end;
%let _for_loop_i=%eval(&_for_loop_i+1);
%let _for_loop_var1=%scan(¯o_var_list,&_for_loop_i,%str());
%end;
%unquote(&_for_loop_code)
%end;
%let _for_loop_i=%sysfunc(close(&_for_loop_itid));
%return;
%end;
%else %if &_for_loop_arrays %then
%do; %* loop over one or more arrays;
%local _for_loop_arrays _for_loop_array1 _for_loop_len;
%if ¯o_var_list=%str() %then %let macro_var_list=&array;
%let _for_loop_arrays=&array;
%let _for_loop_array1=%scan(&array,1,%str());
%if &length ne %str() %then
%let _for_loop_len=&length;
%else
%do; %* getnumber of iterations from first macro array;
%if %symexist(&_for_loop_array1.n) %then
%let _for_loop_len=&&&_for_loop_array1.n;
%else
%do;
%put ERROR: "for" macro for arrays needs "length=" argument;
%return;
%end;
%end;
%do _for_loop_ct=1 %to &_for_loop_len;
%let _n_=&_for_loop_ct;
%let _for_loop_i=1;
%let _for_loop_var1=%scan(¯o_var_list,1,%str());
%do %while(%str(&_for_loop_var1) ne %str());
%let _for_loop_array1=%scan(&_for_loop_arrays,&_for_loop_i,%str());
%if &_for_loop_array1=%str() %then
%do; %* more variables than arrays;
%put ERROR: "for" macro has more variables than arrays;
%return;
%end;
%let _for_loop_val1=%superq(&_for_loop_array1&_n_);
%if %sysfunc(prxmatch("[^\w\s.]+",&_for_loop_val1)) %then
%let &_for_loop_var1=%qtrim(&_for_loop_val1);
%else
%let &_for_loop_var1=%trim(&_for_loop_val1);
%let _for_loop_i=%eval(&_for_loop_i+1);
%let _for_loop_var1=%scan(¯o_var_list,&_for_loop_i,%str());
%end;
%unquote(&_for_loop_code)
%end;
%return;
%end;
%else %if &_for_loop_values ne 0 %then
%do; %* loop over list of values;
%local _for_value_index _for_loop_values _for_loop_delim _for_loop_extra;
%let _for_loop_values=&values;
%let _for_loop_delim=&delim;
%let _for_value_index=1;
%if ¯o_var_list=%str() %then
%do; %*empty variable list - perhaps (s)he just wants &_n_;
%let macro_var_list=_for_loop_extra;
%end;
%do %while(1);
%let _for_loop_ct=%eval(&_for_loop_ct+1);
%let _n_=&_for_loop_ct;
%let _for_loop_i=1;
%let _for_loop_var1=%scan(¯o_var_list,1,%str());
%do %while(%str(&_for_loop_var1) ne %str());
%let _for_loop_val1=%scan(&_for_loop_values,&_for_value_index,&_for_loop_delim);
%let _for_value_index=%eval(&_for_value_index+1);
%if %length(&_for_loop_val1)=0 %then
%do; %* end of values before end of variables, terminate iteration;
%return;
%end;
%let &_for_loop_var1=&_for_loop_val1;
%let _for_loop_i=%eval(&_for_loop_i+1);
%let _for_loop_var1=%scan(¯o_var_list,&_for_loop_i,%str());
%end;
%unquote(&_for_loop_code)
%end;
%end;
%else %if &_for_loop_to %then
%do; %* loop from &from to &to by &by;
%*local ¯o_var_list;
%let _for_loop_var1=%scan(¯o_var_list,1,%str());
%let _for_loop_ct=1;
%do _for_loop_i=&from %to %eval(&to) %by &by;
%let _n_=&_for_loop_ct;
%if %str(&_for_loop_var1) ne %str() %then %let &_for_loop_var1=&_for_loop_i;
%let _for_loop_ct=%eval(&_for_loop_ct+1);
%unquote(&_for_loop_code)
%end;
%return;
%end;
%put ERROR: for macro requires a "data", "values", "to" or "array" keyword;
%mend for;
私はちょうどあなたの解決策をテストしなければなりません。私がすでに訂正したいくつかのタイプミスと名前のクラッシュのほかに、それは魅力のように機能します。興味のある人は%TSLIT(&sheet)を使って必要ならばリスト項目を引用符で囲むことができます。 – cuffel
唯一の問題は、ファイルステートメントの引用符です。他に何かありましたか? – Reeza
マクロには先頭の**%**がありません。マクロ名として_iterm_を使用すると構文エラーが発生します。 – cuffel