通过生成 PROFILE 报告创建宏函数

Create a macro function by generate PROFILE report

data PROFILE;
input ID $ NAME $ Birthday $  Sex $  State $  Cust_Type $ Product $ Balance Last_tran_date $;
cards;
1001 John 1/1/1969 M CA Gold Checking 1000 9/1/2015
1002 Mary 2/1/2072 F CA Silver Saving 2000 10/1/2015
1003 Peter 3/1/1982 M NY Gold Loan 3000 10/3/2016
1004 Mary 4/1/1992 F NY Silver Checking 4000 9/17/2016
;
run;

data profile;
set profile;
today=DATE();
age = FLOOR((INTCK('month',birthday,today) - (day(today) < day(birthday)))/12);
year = year(last_tran_date);
drop today;
run;

******;
%let today=%sysfunc(today(),date9.);
%put &today;
%let report =Detail Listing Of Account;
%put &report;

%macro profile (title=, state=, age=, year=,);
proc report data=profile nowd colwidth=10 spacing=5 headline headskip;
column id name state age year balance;
compute before;
line @20 "title: &report" @68 "Run Date: &today ";
/* line @20 "state: &state " @45 "Age: <= &age " @68 "Last_Tran_Date: &year ";  */
line @20 "state: &state "  @68 "Last_Tran_Date: &year ";
endcomp;
compute after; 
line 60* "_";
line @40 'total balance ='
balance.sum dollar6.;
endcomp;
run;
%mend;


%profile(title=report,state="NY",age=39, year=2016);

我需要这样的宏解决方案:

 %profile(Title = Report, state = %str('NY', 'CA'), age = 18-40, year = 2016, Total_balance=on); 
%profile(age = 39, year = 2016, Total_balance=off); 

任何人都可以帮助我处理年龄范围和 total_balance 打开或关闭的宏部分吗?试了很多次,还是可以 找不到完整的解决方案。非常感谢!

您需要添加的主要内容是使用参数值对数据进行子集化。最简单的方法是在生成的 SAS 代码中包含 WHERE 语句。包含一系列 WHERE ALSO 语句甚至更容易。

您也没有包含两个请求的参数。

您可能也应该将 TODAY 的定义移到宏中。

因此,假设您现有的 PROC REPORT 基本上可以正常工作,那么您的宏可能会像这样简单:

%macro profile 
(title=Detail Listing Of Account
,variables=id name state age year balance
,total=Y
,state=
,age=
,year=
);
%local today ;
%let today=%sysfunc(today(),date9.);

proc report data=profile nowd colwidth=10 spacing=5 headline headskip;
%if %length(&state) %then %do;
  where also state in (&state);
%end;
%if %length(&age) %then %do;
  where also age &age ;
%end;
%if %length(&year) %then %do;
  where also year(Last_tran_date) in (&year);
%end;
  column &variables;
  compute before;
    line @20 "title: &title" @68 "Run Date: &today ";
    line @20 "state: &state " @45 "Age: &age " @68 "Last_Tran_Date: &year ";  
  endcomp;
%if "&total"="Y" and %sysfunc(findw(&variables,BALANCE,,sit)) %then %do;
  compute after; 
    line 60* "_";
    line @40 'total balance ='
    balance.sum dollar6.;
  endcomp;
%end;
run;
%mend profile;

如果您使用这些设置调用它:

%profile(state='NY',age= >=40, year=2016);

将生成此程序:

MPRINT(PROFILE):   proc report data=profile nowd colwidth=10 spacing=5 headline headskip;
MPRINT(PROFILE):   where also state in ('NY');
MPRINT(PROFILE):   where also age >=40 ;
MPRINT(PROFILE):   where also year(Last_tran_date) in (2016);
MPRINT(PROFILE):   column id name state age year balance;
MPRINT(PROFILE):   compute before;
MPRINT(PROFILE):   line @20 "title: Detail Listing Of Account" @68 "Run Date: 22AUG2021 ";
MPRINT(PROFILE):   line @20 "state: 'NY' " @45 "Age: >=40 " @68 "Last_Tran_Date: 2016 ";
MPRINT(PROFILE):   endcomp;
MPRINT(PROFILE):   compute after;
MPRINT(PROFILE):   line 60* "_";
MPRINT(PROFILE):   line @40 'total balance =' balance.sum dollar6.;
MPRINT(PROFILE):   endcomp;
MPRINT(PROFILE):   run;

现在您可以尝试使用其他值组合:

state='CA'
state='CA' 'NY'
age= <18
age= in (18:40)
year=2017

请注意,与问题描述中给出的示例不同,不需要在州代码列表之间包含逗号。并且包含逗号将使用户更难调用宏,因为宏处理器已经使用逗号来分隔参数列表。

如果你想支持用户打字

age= 18-40

那么您必须让宏更智能地处理 AGE 参数。