sas宏(3)宏,调试宏,创建带参数的宏,理解符号表(全局宏与局部宏解析),宏条件运算符,在宏中进行运算

宏类似于c中的函数,传入指定参数后执行,并且宏内部可以包含data步程序和条件运算符号。

宏变量只是小小的变量、、、、(by the way作用也很大)

1:宏的基本语法

如何创建一个简单的宏并使用?

%macro prtlast;
proc print data=&syslast (obs=5);
title "Listing of &syslast data set";
run;
%mend;

%prtlast    /*不要加分号,加了有可能出错*/

宏创建过程中做了什么工作?

1:提交程序后会传递给word scanner,扫描分解为tokens,然后再传给宏处理器

2:检查所有宏语法,其他的不是宏的部分在执行时再检查(比如上面的程序,即使proc写成pro c在宏创建时也不会报错,他只会检查&%这些地方或者条件语句中的%do等部分)

3:如果有错误,则创建dummy (non-executable) macro

4:如果无错误则会保存在work.sasmacr目录下,并命名为macro-name.macro

哪些关键字不能给宏命名?

ABORT ACT ACTIVATE
BQUOTE BY
CLEAR CLOSE CMS COMANDR COPY
DEACT DEL DELETE DISPLAY DMIDSPLY DMISPLIT DO
EDIT ELSE EVAL
FILE
GLOBAL GO GOTO
IF INC INCLUDE INDEX INFILE INPUT
KEYDEF
LENGTH LET LIST LISTM LOCAL
MACRO METASYM
NRBQUOTE NRQUOTE NRSTR
ON OPEN
PAUSE PUT
QSCAN QSUBSTR QSYSFUNC QUOTE QUPCASE
RESOLVE RETURN RUN
SAVE SCAN STR SUBSTR SUPERQ SYSCALL SYSEVALF SYSEXEC SYSFUNC SYSGET SYSRPUT
THEN TO TSO
UNQUOTE UNSTR UNTIL UPCASE
WHILE WINDOW

如何查看宏是否创建成功?(调试宏选项)

mcompilenote=none/noautocall/all

none不会在日志中输出信息

noautocall会在日志中输出非autocall macros的所有宏的信息

all输出所有信息

1 options mcompilenote=all;
2 %macro mymacro;
3 %mend mymacro;
NOTE: The macro MYMACRO completed compilation without errors.

 宏是如何被运行的?

1. searches the designated SAS catalog (Work.Sasmacr by default) for an entry named Macro-name.Macro.
2. executes compiled macro language statements within Macro-name.(执行被编译好的宏的部分)
3. sends any remaining text in Macro-name to the input stack for word scanning.(执行其余的文本部分,比如上面的print过程)
4. suspends macro execution when the SAS compiler receives a global SAS statement or when it encounters a SAS step boundary.
5. resumes execution of macro language statements after the SAS code executes.

宏运行过程可以和两部分打交道,第一部分为符号表,第二部分为input stack

2:调试宏

2.1:当调用宏时,宏中不是宏语言的部分不会在log中显示,可以用如下选项将其显示

options mprint/nomprint

the text that is sent to the SAS compiler as a result of macro execution is printed in the SAS log

23   options mprint;
24   %prtlast
MPRINT(PRTLAST):   proc print data=WORK.SALES (obs=5);
MPRINT(PRTLAST):   run;

2.2:prints messages that indicate macro actions that were taken during macro execution.

OPTIONS MLOGIC | NOMLOGIC;

provide feedback in the log about the parameter values passed into this macro when invoked

看看啥叫feedback!!!注意后三行

MLOGIC(MAKEPGM): 准备开始执行。
MLOGIC(MAKEPGM): 参数 NEWNAME 的值为 res
MLOGIC(MAKEPGM): 参数 SETNAME 的值为 sashelp.class
MLOGIC(MAKEPGM): 参数 PRINT 的值为 YES
/*红色字体为作用效果*/options nomprint mlogic;
107 %prtlast
MLOGIC(PRTLAST): Beginning execution.
NOTE: There were 1 observations read from the dataset
WORK.SALES.
NOTE: PROCEDURE PRINT used:
real time 0.02 seconds
cpu time 0.02 seconds
MLOGIC(PRTLAST): Ending execution.

2.3:log中打印内部宏的步骤,打印内部宏的逻辑

OPTIONS MPRINTNEST | NOMPRINTNEST;

OPTIONS MLOGICNEST | NOMLOGICNEST;

2.4:SOURCE2 writes source statements that are inserted by %INCLUDE statements

3:创建带参数的宏

3.1:Macros That Include Positional Parameters

3.2:Macros That Include Keyword Parameters

Keyword parameters can be listed in any order. Whatever value you assign to each parameter (or variable) in the %MACRO statement becomes its default value. Null values are allowed.

When you call a macro whose definition includes keyword parameters, you specify both the keyword and the value for each parameter, in any order. If you omit a keyword parameter from the macro call, the keyword variable retains its default value,引用时一定要列出keyword和value,如果不列出则表示使用默认值

关键字参数可以摆放在任意位置,赋值的话即为默认值,默认值可以为null

其实这里的形式和c++中函数的默认参数十分类似,赋值为默认的话调用时省略不写即为调用默认

使用方式

%macro-name(keyword-1=value-1<,...,keyword-n=value-n>)
将course_code course_title days赋值给vars%macro printdsn(dsn=sasuser.courses,vars=course_code course_title days);
proc print data=&dsn;
var &vars;
title "Listing of %upcase(&dsn) data set";
run;
%mend;

%printdsn() /*调用参数为默认参数的情况*/

3.3:Macros That Include Mixed Parameter Lists

All positional parameter variables in the %MACRO statement must be listed before any keyword parameter variable is listed

所有位置参数要列在关键字参数前(调用时原则也是这样)

4:理解符号表

全局符号表的生存周期

The global symbol table is created during the initialization of a SAS session and is deleted at the end of the session

?? are available anytime during the session
?? can be created by a user
?? have values that can be changed during the session (except for some automatic macro variables).

创建全局宏变量的几种方式

?? a %LET statement (used outside a macro definition)
?? a DATA step that contains a SYMPUT routine
?? a SELECT statement that contains an INTO clause in PROC SQL
?? a %GLOBAL statement.

The %GLOBAL statement

能定义多个全局宏,可以再宏定义中也可以在宏定义外,对已经生成了的宏无用

局部宏的生存周期

A local symbol table is created when a macro that includes a parameter list is called or when a request is made to create a local variable during macro execution. The local symbol table is deleted when the macro finishes execution

一句话:the local symbol table exists only while the macro executes.

局部宏的创建方式

?? parameters in a macro definition
?? a %LET statement within a macro definition
?? a DATA step that contains a SYMPUT routine within a macro definition
?? a SELECT statement that contains an INTO clause in PROC SQL within a macro definition
?? a %LOCAL statement.

着重介绍%local

只能在宏定义中出现,能定义多个变量,对已存在的变量无效

%let dsn=sasuser.courses;/*全局宏*/
%macro printdsn;
%local dsn;/*局部*/
%global hehe;/*全局*/
%let dsn=sasuser.register;
%let hehe = ‘say hehe‘;
%put The value of DSN inside Printdsn is &dsn;
%mend;
%printdsn
%put The value of DSN outside Printdsn is &dsn;

全局变量与局部变量的关系

这里的关系和c++中的作用域类似,当全局和局部中有同名变量时,局部覆盖全局,越局部,越优先考虑使用局部的变量。

这里做个例子来描述全局宏与局部宏的关系

宏的更新机制如下:如果在局部出现就先看看局部符号表中有没有对应变量(有就更新),没有就看全局(有就更新),没有就创建一个局部变量

下例中,dsn在全局有,所以更新全局的,但是这里要注意了,前一个put输出的是register后一个无输出,为啥?

因为在宏中更新的全局符号表中的值,当宏执行完后,自动销毁了,所以第二个put输出为缺失

如果将注释去掉,那么就以为着新建了一个局部变量,这样输出的值就各是各的了!

options symbolgen;
options nomlogic;
%let dsn=sasuser.courses;
%macro printdsn;
*%local dsn;
%let dsn=sasuser.register;
%put The value of DSN inside Printdsn is &dsn;
%mend;
%printdsn
%put The value of DSN outside Printdsn is &dsn;

5:条件运算符

这里就是普通的运算符前面加%,nothing important to say

6:在宏中进行运算

6.1:The %EVAL function(不支持小数运算)

?? translates integer strings and hexadecimal strings to integers.
?? translates tokens representing arithmetic, comparison, and logical operators to macro-level operators.
?? performs arithmetic and logical operations.

The %EVAL function does not convert the following to numeric values:

?? numeric strings that contain a period or E-notation
?? SAS date and time constants.

6.2:%sysevalf function支持小数运算

%macro figureit(a,b);
%let y=%sysevalf(&a+&b);
%put The result with SYSEVALF is: &y; /*101.59*/
%put BOOLEAN conversion: %sysevalf(&a +&b, boolean); /*1*/
%put CEIL conversion: %sysevalf(&a +&b, ceil);/*102*/
%put FLOOR conversion: %sysevalf(&a +&b, floor);/*101*/
%put INTEGER conversion: %sysevalf(&a +&b, integer);/*101*/
%mend figureit;
%figureit(100,1.59)
时间: 2024-10-10 23:08:11

sas宏(3)宏,调试宏,创建带参数的宏,理解符号表(全局宏与局部宏解析),宏条件运算符,在宏中进行运算的相关文章

在Oracle中如何创建带参数的视图?

本文介绍了oracle数据库中创建带参数视图的例子,有需要的朋友参考下. 在Oracle中如何创建带参数的视图? 在Oracle数据库中,视图不像存储过程和函数一样,可以定义输入参数,但可以变个方式,使用程序包来实现. 首先,定义程序包: 复制代码 代码示例: /* 按个人需要定义,我定义三个参数 ,因我项目程序需要,所以三个参数都是number ,当然可定义其它类型但切记,第二个create 的参数类型等需以第一个create一致,否则程序包创建失败*/create or replace pa

C#中创建线程,创建带参数的线程

线程操作主要用到Thread类,他是定义在System.Threading.dll下.使用时需要添加这一个引用.该类提供给我们四个重载的构造函 构造函数定义: 无参数委托 [SecuritySafeCritical] public Thread(ThreadStart start); [SecuritySafeCritical] public Thread(ThreadStart start, int maxStackSize); 有一个参数object委托 [SecuritySafeCriti

Pycharm,debug调试时怎样带参数

摘自:https://blog.csdn.net/sxd125/article/details/53138797 今天在网上找了一个例子敲代码,因为我使用的是PyCharm,例子运行时需要带参数,开始不知道怎么带参数,网上搜了大半天,最终才找到自己想要的方法,记录一下. 代码中有需要使用到参数,如下图: 因为开始不知道怎么带参数,直接运行时,报错,因为没参数 运行时,至少需要一个文件参数,添加参数 在PyCharm中选择'Run'->Edit Configurations,如下图 在scrip

C#创建带参数的线程

1.无参数线程的创建 Thread thread = new Thread(new ThreadStart(ShowMessage)); thread.Start(); private void ShowMessage() { Console.WriteLine("hello world"); } 2.带一个参数的线程 使用ParameterizedThreadStart,调用 System.Threading.Thread.Start(System.Object) 重载方法时将包含数

SQL_创建带参数的存储过程

SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[GetStuInf] @className nvarchar(50), @Age int as begin select * from Students where [email protected] and Age>@Age end

shell 创建带参数的命令方法

主要用到case in,和shift命令. shift 命令是从参数数组中,删除当前第一个参数. while [ "$1" != "" ] do case $1 in -pn | --prjname ) shift prj_name=$1 ;; -ge | --gitemail ) shift git_email=$1 ;; -gn | --gitname ) shift git_name=$1 ;; -h | --help ) usage exit 1 ;; *

带参数的存储过程

创建带参数的sql存储过程:创建带参数的存储过程首先要在存储过程中声明该参数,每个存储过程参数都必须用惟一的名称进行定义.与标准的Transact-SQL变量相同,参数名必须以@为前缀,创建带参数的存储过程创建带参数的存储过程首先要在存储过程中声明该参数,每个存储过程参数都必须用惟一的名称进行定义.与标准的Transact-SQL变量相同,参数名必须以@为前缀,并且遵从对象标识符规则.当用户不提供该参数的值时可以使用一个默认值来代替.在执行带参数的存储过程时,既可以通过显式指定参数名称并赋予适当

(二)创建带主键和约束的数据表

内容摘要 创建带主键和约束的表 创建带组合主键和外键的表 1. 创建带主键和约束的表 Student (学生表) CREATE TABLE Student ( sclass varchar(10) NOT NULL, --- 限制非空 snumb varchar(10) PRIMARY KEY, --- 设置为主键 sname varchar(40) NOT NULL, --- (下)设置默认值男,约束选项为男女 sgender varchar(4) DEFAULT '男' CONSTRAINT

JavaScript&amp;jQuery.带参数的函数

带参数的函数 创建带参数的函数 创建公式如下: function 函数名(参数1,参数2,...){ // 语句 } 同一节创建函数几乎一样,不同之处多了参数,参数可以是一个,也可以是多个. 参数在这里相当于变量,可是与声明变量不一样,不需要var关键字来声明. 调用带参数的函数 函数创建后,就可以调用,执行函数体内的语句--指令. 调用形式如下: 函数名(实参1,实参2,...); 带参数的函数和不带参数的函数对比,调用时需要传递参数进去,这个参数叫实参,即指定参数的实际值. 如果说形参相当于