%macrotopsis(data_name=,var_name=,var_keep=&var_name,weight=0);
%let i=1;
%let var&i=%scan(&var_name,&i,'');
%do %until(&&var&i=);
%let i=%eval(&i+1);
%let var&i=%scan(&var_name,&i,'');
%end;
%let var_num=%eval(&i-1);
%if &weight=1 %then %do;
data top_1top_2;
set&data_name end=last;
if last thenoutput top_2;
else outputtop_1;
run;%end;
%else %do;
data top_1;
set&data_name;
data top_2;
%do i=1 %to &var_num;
&&var&i=1;
%end;
run;%end;
data _null_;
set top_1end=last;
if last thencall symput('obj_num',compress(_n_));
%let sqr_str=;
data top_a;
set top_1end=last;
%do i=1 %to &var_num;
&&var&i.._2=&&var&i ** 2;
%let sqr_str=&sqr_str&&var&i.._2;%end;
proc transposedata=top_a(keep=&sqr_str)prefix=top_m out=top_b;
proc transposedata=top_a(keep=&var_name)prefix=top_n out=top_C;
proc transposedata=top_2(keep=&var_name)prefix=top_w out=top_w;
data top_d;
set top_b;
z=sum(oftop_m1-top_m&obj_num);
%let min_str=;%letmax_str=;
data top_e;
merge top_ctop_d top_w;
%do i=1 %to &obj_num;
z&i=top_n&i/sqrt(z);%end;
max=max(ofz1-z&obj_num);
min=min(ofz1-z&obj_num);
%do i=1 %to &obj_num;
d_max&i=top_w1*(z&i-max)**2;
d_min&i=top_w1*(z&i-min)**2;
%let max_str=&max_strd_max&i;
%let min_str=&min_strd_min&i;%end;
proc transposedata=top_e(keep=&max_str) prefix=max out=top_f;
proc transposedata=top_e(keep=&min_str) prefix=min out=top_g;
datatop_h(keep=&var_keep d_max d_min c);
merge top_1top_f top_g ;
max_sum=sum(ofmax1-max&var_num);
min_sum=sum(ofmin1-min&var_num);
d_max=sqrt(max_sum);
d_min=sqrt(min_sum);
C=d_min/(d_max+d_min);
proc rankdata=top_h descending out=topsis_result;
ranks order;
var c;
proc print;run;
%mend topsis;