%if语句
不管是在data步中,还是在宏中,都是会有条件判断,在data步中有if ...then ...在宏中也是有该语句的,不过得加上%号,那就是 %if ....%then ...还是先来看一段代码,来看看宏中的%if语句...
代码语言:javascript复制%macro test(msg);
%put NOTE:%superq(msg);
%if %superq(msg) eq 你真美! %then %do;
%put NOTE:You are beautiful;
%end;
%else %if %superq(msg) eq 我真丑! %then %do;
%put NOTE:%str(I%'m ugly);
%end;
%else %do;
%put NOTE:ND;
%end;
%mend;
%test(你真美!);
%test(我真丑!);
%test();
很简单的,其实和data步中是一样的,只是关键词前加了%符号...那么在来看看日志的结果...
%if中的误区:如果是宏变量进行判断的时候,一般习惯写成,%if &msg. eq "你真美!"...这个时候是会有错误的,如果一边有引号,另外一边也需要引号,如果没有那么就都不要双引号..%if "&msg." eq "你真美!"; %if &msg. eq 你真美!
%put NOTE:%str(I%'m ugly);这里的%是什么含义?这里的%是转义符号,用来平衡后的'符号。。说到这里,那么SAS宏中是否可以用IN语句呢...是可以的,得加一个option设置一下
代码语言:javascript复制option minoperator mindelimiter=',';
%macro test(msg);
%put NOTE:%superq(msg);
%if %superq(msg) IN (你真美!,美,好看) %then %do;
%put NOTE:You are beautiful;
%end;
%else %do;
%put NOTE:ND;
%end;
%mend;
%test(你真美!);
%test(美);
%test(好看);
黑色部分的第一行代码就是控制这个的...mindelimiter=','表示 in后面括号内用此符号间隔开来...
%RETURN语句
写Macro的时候的,经常会输入一些参数,有时候会对输入的参数进行check避免输入的参数不合适,而继续执行程序,造成错误耽误时间等...因此在宏中常自动检测参数是否合适,不合适就跳出当前宏的执行...
代码语言:javascript复制/*比如:对输入的数据集进行检测,如果该数据集不存在则退出当前执行*/
%macro test(inds);
%if %sysfunc(exist(%superq(inds))) eq 0 %then %do;
%put NOTE:你输出数据集(%superq(inds))不存在...请核查!;
%return;
%end;
%put NOTE:你输出数据集(%superq(inds))不存在,该宏继续执行...;
%mend;
%test(a);
%test(SASHELP.CLASS);
来看看日志:
这里如果尝试 %let ss=sashelp.class; %test(&ss.)..猜一猜会有什么效果..这个大概是过俩天的要写的,也可能不写了...
%GOTO语句
很多时候也并不需要直接跳出宏的,而是满足一定条件,
直接跳到后面的某处开始执行....
经常会遇到,如果已有的数据满足某条件,就不需要经过加工...
如果不满足,则进行加工一步....下面看一个丑与美的例子~
代码语言:javascript复制option minoperator mindelimiter=',';
%macro test(msg);
%if &msg. in (美,好看) %then %do;
%goto flag;
%end;
%put NOTE:%str(你以前很丑,自从你去过某国回来后....);
%flag:
%put NOTE:You are beautiful;
%mend;
/*美的时候,则不需要整容*/
%test(美);
/*丑的时候,则需要整容*/
%test(丑);
上面的代码...执行后的日志会是怎么样的呢...接下来看一下日志
%do %while循环语句
SAS中的循环: (%do %while语句)
%do %while(true);
执行里面的内容;
%end;
否者就执行后面的... (先判断在执行)
下面来看一个例子,也是写宏中比较常见的一种定义宏参数的方式,通过一个宏参数....
代码语言:javascript复制%macro test;
%let dslist=ds1sheetname1contents1title1|ds2sheetname2contents2title2|ds3sheetname3contents3title3;
%let i=1;
%do %while(%qscan(&dslist,&i,|)^=%str());
%let list&i=%qscan(&dslist,&i,|);
%let dsn&i=%qscan(&&list&i.,1,);
%let sht&i=%qscan(&&list&i.,2,);
%let cnt&i=%qscan(&&list&i.,3,);
%let tle&i=%qscan(&&list&i.,4,);
%put NOTE:循环次数(&i.) &&dsn&i &&sht&i &&cnt&i &&tle&i;
%let i=%eval(&i 1);
%end;
%let _loop=%eval(&i-1);
%mend;
%test
那么来看看日志:(这部分来源于小编以前写的一个宏:Macro-Ods Excel Output)
这个例子可能不太能够简洁的看%do %while的结果...
代码语言:javascript复制%macro test;
%let i=1;
%do %while(&i. le 5);
%put NOTE:循环次数(&i.) 你真美!;
%let i=%eval(&i 1);
%end;
%let _loop=%eval(&i-1);
%mend;
%test
在来看看日志:
%do ..%until循环
SAS中的循环:
%do %until(true);
中止执行此处;
%end;
执行此处... (先执行后判断) 此处可以做延时处理措施...小编以前的推送中用过此处做延时处理:SAS- Send email&&Macro-Pyh_file2zip,在来看一个简单的例子..
代码语言:javascript复制%macro test;
%let i=1;
%do %until(&i. le 5);
%put NOTE:循环次数(&i.) 你真美!;
%let i=%eval(&i 1);
%end;
%mend;
%test
这里虽然最开始 i=1 小于5 是成立的,但是由于until是先执行后判断,所以还是会输出一个 %put后面的内容...
%do ... %to语句
SAS中的循环:
%do...%to...%by
这个最简单,就不多说了...还是用一个简单的例子来看一看...
代码语言:javascript复制%macro test;
%do i=1 %to 4 %by 2;
%put NOTE: i= &i.时,你真美!;
%end;
%mend;
%test;
来看一看日志:
今天就这么多了,后续内容,敬请期待~