一、简介
SAS通过宏过程可以把 数据步或者过程步的功能进行封装,在宏过程中可以定义参数,通过调用宏过程把实参传递给形参进行引用。宏过程就相当于关系数据库中的存储过程,调用时只需要知道宏过程名就可以,具体的内部如何实现不用了解,实现了程序的封装。
二、宏过程执行机制
对于宏语言,SAS有自己的内部处理机制,宏程序编写好后,首先进行宏编译,生成宏程序,调用时通过宏分析器解析,然后在编译过程中如果宏程序有错误,会在日志中显示。
宏执行的流程:
SAS程序先提交进入缓冲区,然后通过字符扫描组件识别到宏程序,调用宏TOKEN解析器,TOKEN解析器的四个普通组件对宏程序进行解析,解析完成交给编译器编译程序,若有错误,程序编译阶段会在日志中显示错误信息,没有错误编译通过,用户通过调用宏语法,调用执行宏。
TOKEN解析器的四个组件及其功能如下:
(1)Literal组件
Literal组件解析用单引号或双引号括起来的字符串,如'yang',"chang"。
(2)Number组件
Number组件解析数值类型、日期类型、时间类型和十六进制数值,如23、'20110323'd。
(3)Name组件
Name组件解析以字母或下划线开始的字符串,如c_b、_d。
(4)Special组件
Special组件解析一些特殊字符串或字符串组,如@、#、*、/、+、-、**、;、$、()、.、&、%、=等。
下边我们介绍一个简单的程序讲解宏程序执行机制,如下:
%let x=5;
%MACRO add;
%let y=%eval(&x+1);
%put y=&y;
RUN;
%MEND add;
%add;
宏功能总结如下:
1)实现程序的重复利用,减少了文本的输入量。
2)实现了程序功能的封装。
3)实现变量的传递。
4)获取SAS系统信息与其他系统的交互。
5)不同数据步与过程步之间传递数据与参数。
三、宏的定义和使用
宏变量和数据步中的变量是不同的,宏变量可以在SAS程序的任何地方引用和定义,属于弱类型语句。宏变量有两种,一种是用户定义的宏变量,一种是SAS系统内部具有的自动宏变量。对于用户定义的宏变量是指用户根据需求定义的变量,对于用户定义的宏变量用户可以给变量赋值,也可以为空,可以指定范围,通过%GLOBAL声明可以定义全局宏变量,默认是全局宏变量。
1)用户定义的宏变量
宏变量的定义语法是:%let 宏变量名 <= 赋实际值>;
对于宏变量的引用,需要“&”符号,具体语法如:&宏名
注意:间接引用宏变量要用两个&&符号,如“&&v_var1.&v_var2”,这里的点“.”属于间接引用分隔,告诉SAS系统是两个宏变量,“&&v_var1”中的第一个“&”符号是告诉SAS系统启动宏TOKEN解析器,然后读到“&v_var1”引用此宏变量。
一个小例子
%let x=5;
%let y=&x;
程序中定义的宏变量x,在定义的宏变量y中的引用。
通过符号“&”把x宏变量的值赋给y宏变量。
所谓的自动宏变量是SAS系统内部已经定义好的变量,不需要用户再定义,用到时直接调用。
常用的自动宏变量如下:
系统内部自动宏变量 | 说明 |
_AUTOMATIC | 查看所有系统自动宏变量 |
SYSDATE | 查看当前日期 |
SYSVER | 查看SAS当前版本 |
SYSLAST | 查看SAS当前最新生成的数据集信息 |
SYSTIME | 查看当前系统时间 |
SYSSCP | 查看用户所使用的操作系统 |
SYSDAY | 查看当前星期几 |
_ALL_ | 查看用户创建的宏变量 |
_USER_ | 查看用户定义的宏变量 |
_GLOBAL_ | 查看用户定义的全局宏变量 |
_LOCAL_ | 查看用户定义的局部宏变量 |
注意:(1)对于自动宏变量_AUTOMATIC_引用是比较特殊,不需要符号&,直接引用,方式为%PUT _AUTOMATIC_。
(2)对于文本串中的引用宏变量,必须用双引号括起来,而不能用单引号。如:
%let city=beijing;
DATA c;
x="I am from &city"; /*引用宏变量city*/
RUN;
%let v_var=%宏函数();
3)宏过程
宏过程内部可以调用数据步或过程步的机制,可以包含循环和分支语句。对于宏过程而言,用户所调用的宏过程都是已经编译好的,宏过程中包含一个写程序的声明,接收外部传递的参数。
宏过程的语法格式: %MACRO 宏名 <(宏参数)> </参数选项>;
宏功能语句:%MEND <宏名>
例子:编写一个宏过程,实现加法运算。
%MACRO add_sum(v_x,v_y); /*宏过程开始,定义宏名*/
%let v_sum=%eval(&v_x+&v_y); /*调用宏函数%eval(),实现整数运算*/
%put &v_sum; /*宏变量引用要用&符号,输出到日志窗口*/
%MEND add_sum; /*宏过程结束标志,结束宏名*/
%add_sum(2,6); /*调用宏过程*/
(1)宏过程add_sum包含两个形参,SAS系统对编辑好的宏过程提交后先输入带缓冲区,然后通过字符扫描组件判断出是宏过程,调入TOKEN解析器,通过TOKEN解析器四个组件解析宏语句,解析完成,传送到编译器编译程序,检查没有语法错误后,编译通过。
(2)%add_sum(2,6)调用宏过程,并把实参2传递给v_x变量,6传递给v_y变量,实现求和运算。
注意:SAS中引用宏变量要加“&”符号。宏过程中可以通过“%put”语句把宏变量值输出到日志(LOG)窗口,通过这个可以调试宏过程。
四、宏常用语句
1)%PUT
%PUT宏语句可以把信息输出到日志窗口,帮助调试程序。
语法格式:%PUT <选项语句>;
%PUT:输出宏语句如果后边不带选项语句,则输出一个空行到SAS日志窗口。
因此%PUT宏语句在调试程序BUG时经常用,可以把信息显示到日志窗口,便于查找程序错误。
五、宏过程调用
宏过程调用语法格式: %宏过程名 <(实参)>;
%:百分号是调用宏过程的语法关键字,必选项。
下边是一个例子:
%MACRO xy; /*无参数宏过程*/
PROC print data=sashelp.buy;
RUN;
%MEND xy;
%xy; /*无参数宏过程调用*/
解读:宏过程封装了打印过程,打印逻辑库sashelp中的数据集buy,
无参数。“%xy”直接写宏过程名,此处不需要参数项。
宏语句 | 说明 |
%ABORT | 结束当前宏运行,属于宏定义中的语句 |
%COPY | 从SAS宏逻辑库中复制指定的对象 |
%GLOBAL | 创建全局宏变量语句 |
%LOCAL | 创建局部宏变量语句 |
%LET | 定义宏变量语句 |
%PUT | 输出文本或宏变量信息到日志窗口展示 |
%IF %THEN %ELSE | 条件选择宏语句 |
%DO %UNTIL | 重复执行语句块中的宏语句,知道UNTIL后条件为真 |
%DO %WHILE | WHILE语句后条件为真,重复执行语句块中的宏语句 |
%DO %TO | 循环宏语句 |
%DO %END | 宏子功能块语句 |
%DO %TO<%BY> | 循环迭代语句 |
七、宏函数
1)宏计算函数
宏计算函数实现加、减、乘、除四则运算的功能。
宏计算函数 | 功能 |
%EVAL | 实现整数运算 |
%SYSEVALF | 实现浮点数据运算 |
例子:
1.%EVAL()宏函数
函数格式: %EVAL(整数的数学运算)
%MACRO cum(x,y); /*定义宏过程*/
%let z=%eval(&x*&y); /*%eval函数进行整数运算*/
%put &z;
%MEND cum; /*宏过程结束标志*/
%cum(88,11); /*调用宏过程*/
程序解读:
%EVAL宏函数实现z=x*y 两个整数的乘法运算,日志窗口显示z=968
2.%SYSEVALF()宏函数
函数格式:%SYSEVALF(浮点数,<数值类型>)
%MACRO cumf(x,y); /*定义宏过程*/
%let f=%sysevalf(&x+&y); /*%sysevalf函数进行浮点数运算*/
%put &f;
%MEND cumf; /*宏过程结束标志*/
%cumf(98.2,1.1); /*调用宏过程*/
程序解读:
%SYSEVALF函数计算x+y的浮点数运算,通过日志窗口显示信息可以看到f=x+y=99.3
2)宏字符处理函数
宏字符处理函数只对字符类型的值进行处理。
宏字符处理函数 | 功能 |
%TRIM | 过滤文本尾部的空格 |
%QTRIM | 过滤包含特殊字符文本的尾部空格 |
%LENGTH | 计算字符串变量长度 |
%INDEX | 查找一个字符串中字符出现的位置 |
%SUBSTR | 从指定的字符串中提取子串 |
%UPCASE | 将指定的字符串转化为大写 |
%QSCAN | 根据特殊分隔符查找,并提取子串 |
%SCAN | 根据指定分隔符查找,并提取子串 |
3)其他常用重要宏函数
其他常用重要宏函数,不能归于上面两类的宏函数,也是经常用到的。
宏函数 | 功能 |
%INCLUDE | 指明包含的外部文件路径 |
%SYSFUNC | 宏变量中调用SAS内部函数或者用户自定义函数 |
%STR | 引用包除特殊符号的固定文本,特殊符号如# % & |
%NRSTR | 引用包含特殊符号的固定文本 |