%macro a2;
data a;
window inform color=yellow
#6 @12 "请输入相应的信息"
#9 @12 "还款月数"
@21 dl attr=underline
#11 @12"本金"
@17 money attr=underline
#13 @12"贷款时间"
@21 time attr=underline
#15 @12"月收入"
@19 wage attr=underline
#17 @12"允许承受的范围%"
@27 sus attr=underline
#20 @12 "请按回车键输入";
display inform;
informat dl 4. money 8. time yymmdd8. wage 8. sus 2.;
do obs=1 to 16;/*数据集中调整时间变化时,需调整16(贷款利率表的观测行数)*/
if dl<6 then set bank.loan(keep=_col0 _col1 rename=(_COL1=mr));
if 6<=dl<12 then set bank.loan(keep=_col0 _col2 rename=(_COL2=mr));
if 12<=dl<36 then set bank.loan(keep=_col0 _col3 rename=(_COL3=mr));
if 36<=dl<60 then set bank.loan(keep=_col0 _col4 rename=(_COL4=mr));
if 60<=dl then set bank.loan(keep=_col0 _col5 rename=(_COL5=mr));
output;
end;
label dl="还款月数/月";
label money="本金/元";
label time="贷款时间";
label wage="月收入/元";
label sus="允许承受的范围%";
run;
%mend a2;
/*根据贷款日期找出相应的利率*/
%macro a3;
data b;
set a nobs=nobs;
mu=time-_col0;
if mu>=0 then do;
mrf=mr;
output b;
end;
data b;
set b nobs=nobs;
if _n_=nobs;
drop obs;
drop mu;
run;
%mend a3;
%macro a4;
data c;
set b;
sust=sus*wage/100;/*每个月还款数的上限*/
/*计算等额本息(每月)用于判断能否承受*/
m1=money*mrf/100/12*(1+mrf/100/12)**dl/((1+mrf/100/12)**dl-1);
/*计算等额本息一共该还本金和利息*/
sm1=m1*dl;
/*计算双周供(次月后每月)用于判断能否承受(月收入)*/
m2=m1/2*3;
/*计算双周该还多久,单位为双周(用于与本金最终应还本息总数做比较)(每期还款为m1/2)*/
dd=(log(m1/2)-log(m1/2-money*mrf/100/360*14))/log(1+mrf/100/360*14);
/*计算双周供一共该还的本金和利息*/
sdm=m1/2*dd;
/*计算等额本金每月应还本息数*/
mo=money/dl;/*每月应还本金数*/
do i=1 to dl;
m=money/dl+(money-(i-1)*mo)*mrf/12/100;/*每月应还本金利息数*/
output;
end;
label m1="等额本息首月应还款/元";
label sm1="等额本息应还总数/元";
label sdm="双周供应还总数/元";
label m="等额本金每月应还款/元";
label m2="双周供承受标准/元";
label dd="双周供还款期数/双周";
label sust="个人每月承受上限/元";
label mrf="年利率%";
label mo="等额本金每月应还本金数/元";
label _col0="贷款利息调整时间";
drop mr;
run;
%mend a4;
/*等额本金每月还款金额*/
%macro a5;
data a1;
set c;
keep i m;
label i="期次(每月一期)"
run;
%mend a5;
%macro a6;
data d1 d3;
set c;
/*等额本金首月应还款*/
if _N_=1 then mm=m;
/*等额本金应还总额*/
retain sm 0;
sm+m;
if _N_=dl then smz=sm;
label mm="等额本金首月应还款/元";
label sm="等额本金每月累积还款/元";
label smz="等额本金应还总额/元";
if _n_=1 then do;
k=1;
drop sm;
output d1;
end;
if _N_=dl then do;
k=1;
drop sm;
output d3;
end;
run;
%mend a6;
/*包含用于承受力判断的各个变量*/
%macro a7;
data d4;
update d3 d1;
by k;
call symput("m1",m1);
call symput("sust",sust);
call symput("m2",m2);
call symput("mm",mm);
call symput("smz",smz);
call symput("sdm",sdm);
call symput("dd",dd);
call symput("sm1",sm1);
drop m;
drop k;
drop i;
drop mo;
run;
%mend a7;
%macro pro;
proc print data=a1;
title "等额本金每月应还款/元";
run;
%mend pro;
/*选择相应的还款方式*/
%macro d5;
%a2;%a3;%a4;%a5;%a6;%a7;
/*等额本息不能承受*/
%if %sysevalf(&m1>&sust) %then %do;
%a2;%a3;%a4;%a5;%a6;%a7;%d5;/*等额本息不能承受,则让用户重新输入相关信息*/
%end;
/*等额本息能承受,双周供不能承受,本金能承受*/
%if %sysevalf(&m1<&sust) and %sysevalf(&m2>&sust) and %sysevalf(&mm<&sust) %then %do;
%put 选择等额本金;
%pro;
%end;
/*等额本息能承受,双周供不能承受,等额本金不能承受*/
%if %sysevalf(&m1<&sust) and %sysevalf(&m2>&sust) and %sysevalf(&mm>&sust) %then %do;
%put 选择等额本息;
%put 每月还款如下;
%put &m1;
%put 应还总额;
%put &sm1;
%end;
/*等额本息能承受,双周供能承受,等本金不能承受*/
%if %sysevalf(&m1<&sust) and %sysevalf(&m2<&sust) and %sysevalf(&mm>&sust) %then %do;
%put 选择双周供;
%put 每期应还款;
%let l=%sysevalf(&m1/2);
%put &l;
%put 还款期数;
%put &dd;
%put 应还总额;
%put &sdm;
%end;
/*等额本息能承受,双周供能承受,等额本金能承受,双周供总额比等额本金少*/
%if %sysevalf(&m1<&sust) and %sysevalf(&m2<&sust) and %sysevalf(&mm<&sust) and %sysevalf(&sdm<&smz) %then %do;
%put 选择双周供;
%put 每期应还款;
%let l=%sysevalf(&m1/2);
%put &l;
%put 还款期数;
%put &dd;
%put 应还总额;
%put &sdm;
%end;
/*等额本息能承受,双周供能承受,等额本金能承受,双周供总额比等额本金多*/
%if %sysevalf(&m1<&sust) and %sysevalf(&m2<&sust) and %sysevalf(&mm<&sust) and %sysevalf(&sdm>&smz) %then %do;
%put 选择等额本金;
%pro;
%end;
run;
%mend d5;
%d5;
这个是一个用来计算房贷金额的程序 但是运行之后总会出现
WARNING: 没有解析符号引用 M1。
WARNING: 没有解析符号引用 SUST。
WARNING: 没有解析符号引用 M1。
WARNING: 没有解析符号引用 SUST。
ERROR: 在需要数值操作数的 %EVAL 函数或 %IF 条件中发现字符操作数。条件是: &m1>&sust
ERROR: %EVAL 函数没有要求值的表达式,或 %IF 语句没有条件。
ERROR: 宏 D5 将终止执行。
然而实际上这个程序是成功过的- -没有任何改动的情况下 但是之后又不能成功了
我知道这是M1和sust没有被运行出来的原因 但是为什么会不能出来呢 为什么有时又能成功呢?
请高手解答
有一个需要外部引用的数据集和程序本身包含在附件里