jingju11 发表于 2013-9-25 00:41 
的确如此.
感觉楼主真有一览众山小的意味.无论提出问题还是解决问题,都非常不凡.
值得学习.
也分享下自己后来用宏写的方法, 里面有另两个宏函数,附在后面。
%macro AllComb(AStr=);
%global comb_list;
%DistinctStr(Str=&astr,deli="/" ,MacroName=astr);
%let astr_list=; %let lg=3;
%do astri=1 %to &astrn %by 1;
%let astr_list=&astr_list "&&astr&astri" ;
%let lg=%sysfunc(Max(&lg,%length(&&astr&astri)));
%end;
%put astr_list=&astr_list; %put lg=≶
%let null_list=;
%do astri=1 %to &astrn %by 1;
%let comb=;
%do l=1 %to &astri %by 1;
%if &l=1 %then %let comb=x&l;
%if &l>1 %then %let comb=&comb||" "||x&l;
%end;
%put comb=&comb;
Data _null;
array x[&astrn] $&lg (&astr_list);
n=dim(x);
ncomb=comb(n,&astri);
do j=1 to ncomb;
call allcomb(j, &astri, of x
); output; end; run;
Data _null_&astri;set _null;
comb=&comb;comb=compbl(comb); keep comb;
run;
%let null_list=&null_list _null_&astri;
%end;
Data comb;length Comb $%LengthVar(ds=_null_&astrn,var=comb);
set &null_list end=last;
call symput(("Comb_"||compress(_n_)),comb);
if last then call symput("Comb_N",compress(_n_));
run;
%let Comb_list=;
%do comb_i=1 %to &comb_n %by 1;
%if &comb_i=1 %then %let Comb_list=&&comb_&comb_i;
%if &comb_i>1 %then %let Comb_list=&comb_list/&&comb_&comb_i;
%end;
/*proc delete data=&null_list _null;run;*/
Data _null_;set comb;put _n_ ":" +5 comb;run;
/*%let Comb_list=%sysfunc(compbl(&Comb_list));*/
%put Comb_list=&Comb_list;
%mend;
%let ctlv=a/b/c/d/e/f/g/h/i/j/k/l;
%AllComb(AStr=&ctlv);
%Macro DistinctStr(Str=,deli=,MacroName=);
%global &MacroName.n;
%let i=1;
%put --------------------;
%do %until(%sysevalf(%quote(%Scan(&Str,&i,"&deli"))= ));
%global &MacroName.&i;
%let &MacroName.&i=%Scan(&Str,&i,"&deli");
%put ***&MacroName.&i=&&&MacroName.&i;
%let i=%eval(&i+1);
%end;
%put --------------------;
%let &MacroName.n=%eval(&i-1);
%put ***Number of &MacroName (&MacroName.n).: &&&MacroName.n;
%put --------------------; %put ;
%mend DistinctStr;
%macro LengthVar(ds=,var=);
%let dsid=%sysfunc(open(&ds,i));
%if &dsid %then %do;
%let lg_&var=%sysfunc(varlen(&dsid, %sysfunc(varnum(&dsid,&var))));
%let rc=%sysfunc(close(&dsid));
%end;
&&lg_&var
%put Lenght of &var in &ds is: &&lg_&var;
%mend LengthVar;