我想重复一些代码,改变其中一个参数并测试是否满足条件。如果满足条件,我想退出循环,如果不满足,我想继续到参数的下一个值。我使用的是下面的代码,它工作得很好,只是它不会在我期望的时候离开循环。尽管摘要显示应该满足条件,但它似乎总是解析为False。
%macro set_downward_caps(year, in_year_tolerance, large, small, start, end, increment);
%do c = &start. %to &end. %by &increment.;
%let nominal_down_large_&year. = %sysevalf(&large. + (&c. / 1000));
%let nominal_down_small_&year. = %sysevalf(&small. + (&c. / 100));
%let real_down_large_&year. = %sysevalf((1 - &&nominal_down_large_&year.) * &&rpi&year.);
%let real_down_small_&year. = %sysevalf((1 - &&nominal_down_small_&year.) * &&rpi&year.);
%rates(&year.);
proc means data = output.s_&scenario. noprint nway;
var transbill&year.;
output out = temporary (drop = _type_ _freq_) sum=cost;
run;
data _null_;
set temporary;
call symput('cost', cost);
run;
data temp;
length scenario $ 30;
scenario = "&scenario.";
large = &&real_down_large_&year.;
small = &&real_down_small_&year.;
cost = &cost.;
run;
data output.summary_of_caps;
set output.summary_of_caps temp;
run;
%if %sysfunc(abs(&cost.)) le &in_year_tolerance. %then leave;
%end;
%mend set_downward_caps;
因此sumary_of_caps表包含的值表明以下条件应该已解析为true:
%if %sysfunc(abs(&cost.)) le &in_year_tolerance. %then leave;
我试着把它放在sysevalf中,但没有用。
我认为宏代码没有等效的LEAVE
。为什么不直接使用%GOTO
?或者,由于您似乎想完全离开宏,您可以使用%RETURN
。
此外,如果您正在比较浮点数,则需要使用%SYSEVALF()
。%IF
语句的隐含%EVAL()
调用将仅处理整数运算。
%if %sysevalf(%sysfunc(abs(&cost)) le &in_year_tolerance) %then %return;
为什么要在宏逻辑中进行计算?我不知道为什么你有所有这些宏变量,除非%RATES()
宏正在引用它们?但是,如果它需要它们,为什么它们不像您在&YEAR
中传递的那样成为宏的参数呢?
在当前代码中有大量的数据步骤,您可以在其中进行计算,并设置一个标志变量,用于控制是否退出循环。
%macro set_downward_caps
(year
,in_year_tolerance
,large
,small
,start
,end
,increment
);
%local c leave ;
%do c = &start %to &end %by &increment;
%local nominal_down_large_&year ;
%local nominal_down_small_&year ;
%local real_down_large_&year ;
%local real_down_small_&year ;
%let nominal_down_large_&year. = %sysevalf(&large. + (&c. / 1000));
%let nominal_down_small_&year. = %sysevalf(&small. + (&c. / 100));
%let real_down_large_&year. = %sysevalf((1 - &&nominal_down_large_&year.) * &&rpi&year.);
%let real_down_small_&year. = %sysevalf((1 - &&nominal_down_small_&year.) * &&rpi&year.);
%rates(&year.);
proc means data = output.s_&scenario. noprint nway;
var transbill&year.;
output out = temporary sum=cost;
run;
data temp;
length scenario $ 30;
scenario = "&scenario.";
large = &&real_down_large_&year.;
small = &&real_down_small_&year.;
set temporary (keep=cost);
call symputx('leave',abs(cost) le &in_year_tolerance);
put (_all_) (=);
run;
data output.summary_of_caps;
set output.summary_of_caps temp;
run;
%if (&leave) %then %goto quit;
%end;
%quit:
%mend set_downward_caps;