Say here is a dataset contain 10 rows, and each row contains parameters for calling a macro(return a value) ... how to make doable?!
data ds_para;
input ind indst indend sign;
datalines;
1 800 1100 -1
2 4000 5000 1
3 6000 7000 -1
4 7500 8500 1
5 9000 9500 -1
6 14000 15000 1
7 18000 20000 -1
8 20500 21500 1
9 22000 23000 -1
10 23000 24000 1
10 24000 25000 -1
;run;quit;
%macro macro2call(ind, indst, indeend, sign);
.....
&ReturnVar
%mend;
If the macro does not generate any SAS code then use the RESOLVE() function.
data want;
set ds_para ;
result=resolve(cats('%macro2call(',catx(',',ind,indst,indend,sign),')'));
run;
If the macro generates SAS code then CANNOT return the results as if it was a function. In that case look into use DOSUBL() function call so that the macro does not generate any SAS code in the current session.
The best outcome would be a dataset with 10 rows, each has the ReturnVar
One approach is to use CALL EXECUTE like in this post: https://communities.sas.com/t5/SAS-Programming/Assigning-value-to-a-macro-variable-within-a-datastep...
Thanks,
But somehow %let ReturnVar=%eval(&indst.+&indend.); complains?!
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand
is required. The condition was: indend+
3704 call execute(%macro2call(indst, indend));
If %let ReturnVar=%eval(5+8); then it is fine. Confused ...
data ds_para;
input ind indst indend sign;
datalines;
1 800 1100 -1
2 4000 5000 1
3 6000 7000 -1
4 7500 8500 1
5 9000 9500 -1
6 14000 15000 1
7 18000 20000 -1
8 20500 21500 1
9 22000 23000 -1
10 23000 24000 1
;run;quit;
%global ReturnVar;
%macro macro2call(ind, indst, indend, sign);
/*%let ReturnVar=%eval(5+8); works*/
%let ReturnVar=%eval(&indst.+&indend.);/*?!*/
&ReturnVar
%mend;
data ds_para;
set ds_para;
call execute(%macro2call(indst, indend));
mmind=&ReturnVar.;
run;quit;
If the macro does not generate any SAS code then use the RESOLVE() function.
data want;
set ds_para ;
result=resolve(cats('%macro2call(',catx(',',ind,indst,indend,sign),')'));
run;
If the macro generates SAS code then CANNOT return the results as if it was a function. In that case look into use DOSUBL() function call so that the macro does not generate any SAS code in the current session.
Tom:
Thanks a huge. It indeed works. But how to save out the result on each call(the results are diff. but I can only save out the last call result).
/* pass coln as para
call macro within dataset*/
data ds_para;
input ind indst indend sign;
datalines;
1 800 1100 -1
2 4000 5000 1
3 6000 7000 -1
4 7500 8500 1
5 9000 9500 -1
6 14000 15000 1
7 18000 20000 -1
8 20500 21500 1
9 22000 23000 -1
10 23000 24000 1
;run;quit;
data tempx;
do i=1 to 30000;
x=ranuni(0);
output;
end;
run;quit;
%global ReturnVar;
%macro test(ind, indst, indend, sign);
%if &sign=-1 %then %do;
proc sql noprint;
select i into: ReturnVar
from tempx
where i between &indst. and &indend.
having x=min(x);
quit;
%end;
%if &sign= 1 %then %do;
proc sql noprint;
select i into: ReturnVar
from tempx
where i between &indst. and &indend.
having x=max(x);
quit;
%end;
%put "ReturnVar=&ReturnVar.";
%mend;
/* works below: resolve() but only without "any" sas code
DOSUBL() if sas code
*/
data want ;
set ds_para ;
/*result=resolve(cats('%test(',catx(',',ind,indst,indend,sign),')'));*/
t=DOSUBL(cats('%test(',catx(',',ind,indst,indend,sign),')'));
res="&ReturnVar.";
result=put("&ReturnVar.",8.);
run;
April 27 – 30 | Gaylord Texan | Grapevine, Texas
Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!
Still thinking about your presentation idea? The submission deadline has been extended to Friday, Nov. 14, at 11:59 p.m. ET.
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.