SAS-Macro 中的那些语句(三)

2019-10-21 17:30:29 浏览数 (1)

前面说了宏变量相关的,那么今天就来说几个宏中的关键字,判断语句,跳转语句,退出语句,循环语句...

%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;

来看一看日志:

今天就这么多了,后续内容,敬请期待~

sas

0 人点赞