SAS Macro Language



SAS Macro Language

SAS macro is a very powerful tool in the global SAS environment. It can perform, but not limited to, the following tasks:

• Displaying system information

• Conditional processing out side the SAS data step and procedures

• Automation for repetitive tasks

• Create data-driven applications

• Dynamically generate SAS code at run time

How the SAS compiler and word scanner works

Tokenization: The SAS word scanner recognize four class of tokens:

• Literals: String of characters in quote. E.g. ‘VAR1=’ “Today is”

• Numbers: 101 3.14 ‘29mar2003’d

• Names: data proc infile date7. dollar8.2

• Special: Characters that have reserved meanings to the compiler.

• / + - ** ; $ ( ) . & %

Tokenization example:

Input var x1-x10 z7. ;

Tokens: 1. Input 2. var 3. x1 4. - 5. x10 6. z7. ;

Macro Trigger: % followed by a name token ( Example: %let)

& followed by a name token (&sysdate)

SAS macro maintains a separate Symbol Table for macro variables. Once a

macro trigger is detected, the macro processor will process the token and send the

results to the Symbol Table.

Global Macro Variables: There are two types of global macro variables.

Automatic Variables (or System defined variables)

User-defined variables

To display automatic variables, use: %put _automatic_;

To display user defined variables, use: %put _user_;

To display all macro variables, use: %put _all_;

To Reference a macro variable: Use ampersand (&) followed by the variable name.

Example: %put &sysdate; The macro processor will return the macro

Variable sysdate’s value and put it into the log.

Example: var1=&sysdate; The macro processor will return the macro

Variable sysdate’s value and assign it to var1.

To reference a macro variable within a literal, enclose the literal in double quotes.

Example: Title “Sale Report As of &sysdate”;

How to create user defined macro variables

1. Use %LET statement: %LET varname=value;

• varname can be any name following the SAS naming convention.

• If the value is already exist in the symbol table, it will over write.

• If varname or value contains macro trigger, the trigger is evaluated first then perform assignment.

• The maximum length for value can be 32K characters

• All values are character strings

• Mathematical expression are not evaluated

• Values are case sensitive

• No quote is needed. If quote exist, it is treated as part of the value

• Leading and trailing blanks are removed

Examples:

Valur

%let name = John Smith; John Smith

%let title = ‘As of &sysdate’; ‘As of &sysdate’

%let title = “As of &sysdate”; “As of 29MAR2003”

%let blank = ;

%let math = 1+1; 1+1

%let myvar= var1; var1

%let myvar= Annual Report; Annual Report

2. Use CALL SYMPUT routine: CALL SYMPUT(varname, value);

• Varname is the name of the macro variable.

• The varname can be character literal. Eg: ‘myvar’

• The name can be data step variable name

• Value can be a data step variable name, a macro reference, or hard coded character literal.

• Maximum length of the value can be 32767 characters.

• The leading and trailing blanks in the data step variable’s value are preserved.

• Numeric expressions are automatically converted to character using best12. format.

Examples:

Libname cdat '/courses/ddbf9765ba27fe300';

%let numobs=2;

data _null_;

set cdat.stocks2 nobs=totobs;

call symput('numobs',totobs);

stop;

run;

%put &numobs;

data _null_;

set cdat.stocks2;

call symput(ticker,price);

run;

%put _user_;

data _null_;

call symput('ATT2', &att);

run;

%put &att2;

3. Us SQL Procedure

4. Use %do statement

5. Use Macro Call Parameters

How to DELETE user defined macro variables

%symdel macro-variable(s);

Example:

%let a=aaaa;

%put &a;

%symdel a;

%put &a;

Comments in Macro Programs

1. Use %* : To comment one line in SAS macro program. The comment will be ended at a semicolon (;).

Example:

%* The following is a macro program;

%macro get_ymd; %* Start the macro;

%let dt=&sysdate9.; %* get system date;

%put &dt;

%let year =%sysfunc(year("&dt"d)); %* get year;

%put &year;

%let month=%sysfunc(month("&dt"d)); %* get month;

%put &month;

%let day =%sysfunc(day("&dt"d)); %* get day;

%put &day;

%mend;

%get_ymd;

2. Use /* : You can start your comments with /*

and end your comments with */

Macro functions

%UPCASE(argument): %let var1=%upcase(abcd); %put &var1;

%SUBSTR(ARGUMENT, POSITION, ): Returns the portion of the

ARGUMENT from the POSITIONth character to Nth character.

Example:

%let var1=A23456789; %put &var1;

%let var2=%substr(&var1,4); %put &var2;

%let var3=%substr(&var1,4,3); %put &var3;

%let var4=%substr(A23456789,4,3); %put &var4;

%let var5=%substr('A23456789',4,3); %put &var5;

%LENGTH(argumet); Return the length of the argument.

%let var1=A23456;

%let vlen =%length(&var1);

%let vlen2=%length(A23456);

%put &vlen &vlen2;

%INDEX(source, except); Search for the first occurrence of the string identified in

except.

Examples;

%let msg=The message is: ERROR detected;

%let msg2=%index(&msg,ERROR);

%let msg3=%index(&msg,%upcase(error));

%let msg4=%index(&msg,error);

%put &msg2;

%put &msg3;

%put &msg4;

%SCAN(argument, n ); Return the nth word of the argument separated

by dlimiters. If the delimiter is not specified, the following default delimiters will

be used:

blank . ( & ! $ * ) ; - / , %

Examples:

%let var1=Today is 29MAR03.;

%let dt =%scan(&var1,3); /* ,%str( ) */

%put &dt;

%EVAL(expression); Evaluate arithmetic and logical expressions. The %eval function only perform integer arithmetic.

Example:

%let a=1;

%let b=4;

%let c=1+4; %put c= &c;

%let d=%eval(1+4); %put d= &d;

%let e=%eval(&a+&b); %put e= &e;

%let f=%eval(1/3); %put f= &f; %* &f=0 not &f=0.33333333333333;

%SYSEVALF(expression); Evaluate floating point arithmetic.

This is a new feature for SAS version 8.

Example:

%let f=%sysevalf(1/3); %put f= &f; %* &f=0.33333333333333;

%SYSFUNC(function(argument(s)) ); All SAS functions used in SAS data step can be used with %SYSFUN except:

DIF DIM HBOUND

IORCMSG INPUT LAG

LBOUND MISSING PUT

RESOLVE SYMGET All variable information functions

Example:

%let td =%sysfunc(today()); %put td = &td;

%let td2=%sysfunc(today(),date9.); %put td2= &td2;

%let modv=%sysfunc(mod(8,3)); %put modv=&modv;

%let maxv=%sysfunc(max(3,6,9)); %put maxv=&maxv;

Combing Macro Variable References with Text

Examples:

%let yy=2003;

%let mm=03;

%let ext=txt;

%let fname =data&yy&mm; %put fname = &fname;

%let fname2=_&yy&mm.data; %put fname2= &fname2;

%let fname3=report.&ext; %put fname3= &fname3;

%let fname4=rpt&yy&mm.txt; %put fname4= &fname4;

%let fname5=rpt&yy&mm..txt; %put fname5= &fname5;

Note: Macro variable name delimiter: The period (.) is a special character that is treated as part of the macro variable reference and does not appear when the macro variable is resolved.

filename myfile "c:\sas_class\data\rpt&yy&mm..txt";

%* The following program create a macro variable serious, their values are the value of variable TICKER in SAS data set stocks2. ;

%let in=cdat;

data _null_;

set &in..stocks2;

call symput('var'||left(_n_), ticker); %* left function hac to be used to

remove the leading blanks;

run;

%* The following program print the values of macro variables var1 to var16 into log for checking. The macro language will be explained later;

%macro check;

%do i=1 %to 16;

%put var&i = &&var&i;

%end;

%mend;

%check;

Quoting in SAS MACRO

In SAS data step, the quote is by single or double quote. However, these quotes are treated as character value in sas macro. Therefore, different method has to be used in SAS macro quoting.

%STR function: This function remove the normal meaning of a semicolon (;) and the following special tokens:

+ = * / , < > = blank LT EQ GT AND OR NOT LE GE NE

Examples:

%* The following code will not run because of error. ;

%let prog= data aa; a=1; run;

&prog;

%* The following three programs are all run with no error.;

%let prog= %str(data aa; a=1; run;);

&prog;

%let prog=data aa %str(;) a=1 %str(;) run %str(;);

&prog;

%let s=%str(;);

%let prog=data aa&s a=1 &s run &s;

&prog;

%STR function can also quote the following characters: ‘ “ ( ). But before each of these characters in the argument, a percent sign (%) must be used.

Example:

%* The following code is wrong;

%let store =%str(John's Pizza); %put &store;

%* The following code is correct.;

%let store2=%str(John%'s Pizza); %put &store2;

%NRSTR function: This function is basically the same as %STR function, but it also quote (or mask) & and %.

Example:

%let a=ABC;

%let b=Value of &a is ABC; %put &b;

%let b=%nrstr(Value of &a is ABC); %put &b;

SAS Data Step Interface

Example:

data _null_;

a=1;

if a=1 then %let msg= Great! A equals to 1;

if a ne 1 then %let msg= Why it is not working?;;

run;

%put msg= &msg;

In the log wondow:

356 %put msg= &msg;

msg= Why it is not working?

In th above code, even though a=1, but the value of macro variable msg is Why it is not working?. The reason is that the action of the %LET statement is performed at compile time, not at run time. So, the value of msg is always the value of the last assignment by %let statement.

To create global macro variable at run time from within data step, use CALL SYMPUT routine.

CALL SYMPUT(varname, value);

For th above example, using call symput will be:

data _null_;

a=1;

if a=1 then call symput('msg', 'Great! A equals to 1');

if a ne 1 then call symput('msg', 'Why it is not working?');

run;

%put msg= &msg;

Example:

data _nul_;

pi=3.14;

td=today();

call symput('number',1/3);

call symput('number2',1/4);

call symput('number3',pi);

call symput('number4',left(pi));

call symput('number5',trim(left(pi)));

call symput('Today', put(td,date9.));

run;

%put ***&number ***;

%put ***&number2 ***;

%put ***&number3 ***;

%put ***&number4 ***;

%put ***&number5 ***;

%put &today;

Indirect Reference to Macro

If the first macro variable’s value is the second macro variable’s name, and you try to reference the value of the second macro variable by the first macro variable’s name, it is an indirect reference.

Rules for indirect reference

• Multiple ampersands or percent signs preceding a name token cause the macro processor to rescan the reference.

• Two ampersands (&&) resolve to one ampersand (&).

Example:

%let vara=A123; %put &vara; | &vara = A123

%let varb=vara; %put &varb; | &varb = vara

%let varc=&varb; %put &varc; | &varc = vara

%let vard=&&varb; %put &vard; | &&vard = vara

%let vare=&&&varb; %put &vare; | &&&vare = &varb = A123

%let a2=AAA;

%let i =2;

%let b=&&&a&i; %put &b; %* &&&b&i = AAA;

Example:

data _null_;

set cdat.stocks2;

call symput(ticker,price);

call symput('indust',industry);

run;

%let var1=ATT;

data _null_;

set cdat.stocks2;

where ticker="&var1";

put "The price for &var1 is %left(&&&var1)";

run;

data _null_;

set cdat.stocks2;

call symput(ticker,industry);

run;

%let var1=ATT;

proc print data=cdat.stocks2;

where ticker="&var1";

Title "The price for company &var1 is %trim(&&&var1)";

run;

Example:

proc sort data=cdat.for_proc out=for_proc;

by extractdt risklevel score1 score2;

run;

data for_proc(drop=cnt);

length dt $4;

retain cnt 0;

retain dt;

set for_proc;

by extractdt;

if first.extractdt then

do;

cnt=cnt+1;

dt='DT'||trim(left(cnt));

end;

run;

data _null_;

set for_proc;

by extractdt;

if first.extractdt;

call symput(dt,left(extractdt));

run;

options symbolgen mprint;

%let dtname=dt2;

proc print data=for_proc;

by extractdt;

Where extractdt=&&&dtname * 1;

title "Data Extracted at &&&dtname";

run;

SYMGET function: Obtaining macro variable values during execution or run time.

Both SYMGET function and macro reference (&) obtain macro variable value. In

Most cases, they perform the same function, therefore, the macro reference (&) is

more convenient to use. But in the following case, SYMGET function is different.

• For compiled and stored SAS programs, SQL view and SCL language programs, the macro reference is constant, while the SYMGET function is not.

• SYMGET function is a data step function, therefore it can perform variable name concatenation before obtaining the macro variable value.

Example:

Libname cdat '/courses/ddbf9765ba27fe300';

data _null_;

set cdat.stocks2 end=last;

call symput('price'||left(_n_),price);

if last then call symput('nobs',trim(left(_n_)));

run;

data test;

array p(&nobs) p1-p&nobs;

do i=1 to &nobs;

p(i)=symget('price'||left(i)); *** p(i)=&price||left(i);

end;

run;

Macro Programs

Define a Macro:

%MACRO macro-name ;

macro-text

%MEND ;

macro-name: The macro-name must be a valid SAS name. You cannot use a macro expression to generate a macro name in a %MACRO statement.

In addition, the following reserved words cannot be used as a macro name:

ABEND ABORT ACT ACTIVATE BQUOTE BY

CLEAR CLOSE CMS COMANDR COPY DEACT

DEL DELETE DISPLAY DMIDSPLY DMISPLIT DO

EDIT ELSE END EVAL FILE GLOBAL

INFILE INPUT KEYDEF LENGTH LET LIST

LISTM LOCAL MACRO MEND METAAYM NRBQUOTE

NRQUOTE NRSTR ON OPEN PAUSE PUT

QSCAN QSUBSTR QSYSFUNC QUOTE QUPCASE RESOLVE

RETURN RUN SAVE SCAN STOP STR

SUBSTR SUPERQ SYSCALL SYSEVALF SYSEXEC SYSFUNC

SYSGET SYSRPUT THEN TO TSO UNQUOTE

UNSTR UNTIL UPCASE WHILE WINDOW

Parameters: Will be discussed later.

Macro_text can be:

• Any text

• SAS data steps or procs

• Macro variables, functions, or statements

• Any combination of the above

%MEND; To end the macro. %mend is required for all macro. The macro-name is optional. If omitted, the last macro will be ended.

To call a macro: %macro-name ;;

Example: Once submitted, a macro can be called repeatedly and is very efficient.

%macro plast;

proc print data=&syslast (obs=10);

title "Listing of the %trim(&syslast) data set";

run;

%mend;

data a;

a=1;

run;

%plast;

data b;

b=2;

run;

%plast;

Macro Parameter List: Macro parameters are assigned in a macro call.

• They are enclosed in parentheses

• They are separated with commas

• They can be null values, text, macro variable reference, or macro calls

• If comma (,) is part of the text or macro reference value, it should be quoted by %str() function.

Two type of parameter list:

• Positional Parameters

General form: %macro-name(value-1, value-2,…,value-n);

Positional parameters can be defined in any order. But in macro invocation, their value must appear in the same order in which the parameter names appear in the %macro statement.

• Keyword Parameters

General form: %macro-name(key-word-prm-1=,

key-word-prm-2=,



key-word-prm-n=,);

Keyword Parameters for macro definition and macro invocation don’t have to be in the same order, but it is a good habit to keep them in order.

• Priority: If both positional and keyword parameters appears in the parameter, the positional parameter must come first;

Example: Positional parameters

%let name=John Smith;

%let p2=BBB;

%macro test(a,b);

%put &a;

%put &b;

%mend;

%test(John Smith, BBB);

%test(&name, &p2);

%test(Smith, John, BBB); %* ERROR ERROR ;

%test(%str(Smith, John), BBB); %* use %str() to quote comma;

%macro test2; %* Create a macro;

%str(Smith, John);

%mend;

%test(%test2, &p2); %* Use macro call as parameter;

Example: Keyword parameters;

%macro test(a,b);

%put a= &a;

%put b= &b;

%mend;

%test(a=%str(Smith, John), b=BBB);

%test(b=BBB, a=%str(Smith, John));

Reference Environments: Use the following rule

1. When a macro statement that can create macro variable is executed, the macro processor attempts to change the value of an existing macro variable, regardless of environment, rather than creating a new macro variable.

Therefore, always try to avoid using the same variable name in different reference environment of the same SAS session.

2. The macro processor creates the variable in the current environment if no macro variable with the same name in available to it.

3. The %GLOBAL statement creates a variable in the global environment if a variable with the same name does not already exist there, regardless of which environment is current.

4. The %LOCAL statement creates a variable in the current local environment if a variable with the same name does not already exist there, even if variable with those names exist in other environments.

5. CALL SYMPUT routine is a special case.

• When the routine is used outside any macro, it create global variable.

• When the routine is used inside a macro, it follows the following rules:

1. If the current reference environment is not empty, i.e. there is at least one macro parameter or macro statement, the CALL SYMPUT routine will create a local macro variable.

2. If the current reference environment is empty, i.e. there is no macro parameter or macrostatement, the CALL SYMPUT routine will create a global macro variable in the current reference environment.

6. One rule that was not stated in SAS book is: macro parameter always create local macro variable.

Example: Demonstration for rule 1, 2.

%let a=BBB;

%macro renv;

%let a=AAA; %put &a;

%mend;

%renv;

%put &a;

Example: Demonstration for rule 3.

%macro test_global;

%global a;

%let a=GLOBAL; %put &a;

%let b=LOCAL; %PUT &b;

%mend;

%test_global;

%put &a;

%put &b;

Example: Demonstration for rule 4.

%let a=BBB; %put &a;

%macro renv;

%local a;

%let a=AAA; %put &a;

%mend;

%renv;

%put &a;

Example: Demonstration for call symput routine, rule 5;

%let vara=AAA;

%macro test; %* Reference environment is empty;

data _null_;

call symput('var_global','GLOBAL'); %* var_global is global;

run;

%mend;

%test;

%put &var_global;

%macro test(notemp); %* Reference environment is not empty;

data _null_;

call symput('var_local','LOCAL'); %* var_local is local;

run;

%mend;

%test(Not Empty);

%put &var_local;

%macro test; %* Reference environment is not empty;

%let mstatment= There is a macro statement;

data _null_;

call symput('var_local','LOCAL'); %* var_local is local;

run;

%mend;

%test;

%put &var_local;

Example: Demonstration for rule 6.

%macro a(a,b);

%global a b;

%mend;

%a(AAA, BBB);

%put &a;

%put &b;

An Integrated Example

The following program demonstrates a data driven automated process by using SAS macro. The purpose of the program is to separate the SAS data set cdat.for_proc into many small dataset according to the value of variable EXTRACTDT. After separation, perform some data manipulation for each data set, then produce report.

The %do … %to… %end statement will be discussed in detail in the next class.

Libname cdat '/courses/ddbf9765ba27fe300';

%let lib=cdat ;

%let dsn=for_proc ;

proc sort data=&lib..&dsn out=ym_list(keep=extractdt) nodupkey;

by extractdt;

run;

data _null_;

set ym_list end=last;

call symput('ym'||left(_n_),trim(left(extractdt)));

if last then call symput('numobs',trim(left(_n_)));

run;

options mprint mlogic symbolgen;

options nonumber nodate center ls=100;

%macro separate(obsn);

%do i=1 %to &numobs;

data extdt&&ym&i.;

set &lib..&dsn;

where extractdt=&&ym&i * 1;

run;

proc sort data=&syslast;

by risklevel score1 score2;

run;

proc print data=extdt&&ym&i(drop=bal obs=&obsn.) noobs;

Title "Listing Report For &&ym&i Data";

run;

%end;

%mend;

%separate(max)

Another example:

data aa;

input c1 c2 c3 c4;

cards;

1 11 21 31

2 12 22 32

3 13 23 33

4 14 24 34

;

run;

%macro doit;

%let dlist=;

%do i=1 %to 4;

data d&i(keep=cc);

set aa;

keep c&i;

rename c&i=cc;

run;

%let dlist=&dlist d&i;

%end;

data vert;

set &dlist;

run;

%mend;

%doit;

Frequently used system option for debugging

MLOGIC | NOMLOGIC: Traces execution of macro code, and print messages related the following:

• When a macro begins executing

• The value of any parameters

• When any program statement executes

• The status of any %IF or %DO condition

• When a macro stops executing

MPRINT | NOMPRINT: The MPRINT system option specifies whether the macro processor displays SAS statements generated by macro execution in an easy-to-read form.

SYMBOLGEN | NOSYMBOLGEN: Specifies whether the macro processor displays the result of resolving macro variable references.

Example:

options mprint mlogic symbolgen;

options nomprint nomlogic nosymbolgen;

Macro Statement

%IF %THEN … %ELSE Statement

General form:

%IF expression %THEN macro-expression;

%IF expression %THEN

%DO;

Any SAS code;

%END;

%ELSE

%DO;

Any SAS code;

%END;

This is similar as the data step IF … THEN … statement. But there are several differences:

1. The macro %IF… %THEN statement has to be used inside a macro.

Example: The following code will get OPEN CODE error message.

%let a=A;

%IF &a=A %then %let aa=AA;

%put &aa;

Example: The above code run correctly inside a macro.

%let a=A;

%macro test;

%IF &a=A %then %let aa=AA;

%put &aa;

%mend;

%test

2. It can be used both inside and outside the data step or proc step. As shown in the above example, they don’t have to be inside the data step.

3. The expressions can be macro expressions or macro calls. But it can not use data step variable. Data step variable expressions should use data step IF … THEN, macro %IF … %THEN … should use macro variables.

Example: Incorrect example.

%macro test;

data _null_;

a=1;

%if a=1 %then %put "Variable a equals 1";

%else %put "This is not working";

run;

%mend;

%test

Example: Correct example. Note: The data _null_ and run here is not necessary.

%macro test;

%let a=1;

data _null_;

%if &a=1 %then %put "Variable a equals to 1";

%else %put "This is not working";

run;

%mend;

%test

4. You can conditionally generate any SAS code. Because data step IF … THEN … condition is execution time statement, therefore, non-executable SAS statement can not be the conditional statement after THEN, such as LENGTH statement, ARRAY statement, etc. But this is not the case for macro %IF…%THEN.

• The data step IF…THEN… statement determine what to do with the data.

• The macro %IF…%THEN… statement determine what SAS code to run. Therefore it is frequently used for generating data dependent SAS code.

Example: In the following example, data step IF…THEN… has no effect on the

Length and Array statements. All variables with length and array

Statements are defined in the work.test data set.

%let a=1;

data test;

* a=1;

if &a=1 then

do;

length varb $8;

array varc(10);

end;

else

do;

length varg $8;

array varh(10);

end;

run;

proc contents data=test;

run;

Example: The following example using macro %IF…%THEN… works as we

wantted. Only the varb and array var1-varc10 are defined for the data set

work.test.

%macro ifthen;

%let a=1;

data test;

%if &a=1 %then

%do;

length varb $8;

array varc(10);

%end;

%else

%do;

length varg $8;

array varh(10);

%end;

run;

proc contents data=test;

run;

%mend;

%ifthen

Example: Another example of data dependent SAS code.

libname cdat 'c:\sas_class\classdata';

%macro test(indata);

data stocks;

set &indata end=last;

if last then call symput('numobs',trim(left(_n_)));

run;

%if &numobs>1 %then

%do;

proc print data=_last_;

run;

%end;

%else

%do;

data &indata;

do i=1 to 10;

a=i*2;

output;

end;

run;

proc print data=_last_;

run;

%end;

%mend;

data aa;

run;

%test(aa);

%test(cdat.stocks2)

%DO statement

General form:

%DO;

Text or macro program statement;

%END;

• Like the data step do statement, the macro %do always has to be ended by %END.

• Like macro %IF…%THEN statement, %DO statement has to be inside the %macro definition. Open code is not allowed.

• The macro %DO statement don’t have to be inside the SAS data step.

Iterative %DO statement

General form:

% DO macro-variable=start %TO stop ;

Text and macro program statemenjts;

%END;

• The variable after iterative %DO statement is a macro variable, therefore, it is another way to create macro variables.

• Mathematical expression for start and stop are automatically evaluated.

• %BY is optional.

• Others are the same as the non-iterative %DO statement.

Example: To demonstrate: 1) i is a macro variable. 2) &a+&b is automatically evaluated. No %eval function is needed.

%macro test;

%let a=10;

%let b=5;

%do i=1 %to &a+&b;

%put &i;

%end;

%mend;

%test

Example: Concatenate a variable list.

%macro var_list;

%let vlist=;

%do i=1 %to 10;

%let vlist=&vlist var&i;

%end;

%put &vlist;

%mend;

%var_list

An Integrated Example

The following program demonstrates a data driven automated process by using SAS macro. The purpose of the program is to separate the SAS data set cdat.for_proc into many small dataset according to the value of variable EXTRACTDT. After separation, perform some data manipulation for each data set, then produce report.

%let lib=cdat ;

%let dsn=for_proc ;

proc sort data=&lib..&dsn out=ym_list(keep=extractdt) nodupkey;

by extractdt;

run;

data _null_;

set ym_list end=last;

call symput('ym'||left(_n_),trim(left(extractdt)));

if last then call symput('numobs',trim(left(_n_)));

run;

options mprint mlogic symbolgen;

options nonumber nodate center ls=100;

%macro separate(obsn);

%do i=1 %to &numobs;

data extdt&&ym&i.;

set &lib..&dsn;

where extractdt=&&ym&i * 1;

run;

proc sort data=&syslast;

by risklevel score1 score2;

run;

proc print data=extdt&&ym&i(drop=bal obs=&obsn.) noobs;

Title "Listing Report For &&ym&i Data";

run;

%end;

%mend;

%separate(max)

%DO %UNTIL Statement

%DO %UNTIL(expression);

text and macro program statements

%END;

Do until the expression condition is true.

The %do %until statement is similar to the data step do until statement, but it has to be inside the macro, and don’t have to be inside the data step.

Example: The following example get the filename from a full path and filename string.

%macro getfname;

%let pathname=/user/username/project1/sas/report1.sas;

%let n=0;

%do %until(&temp=);

%let n=%eval(&n+1);

%let temp=%scan(&pathname, &n, '/');

%* %put &temp;

%end;

%let n=%eval(&n-1);

%let fname=%scan(&pathname,&n,'/');

%put The filename is &fname;

%mend;

%getfname

%DO %WHILE Statement

%DO %WHILE(expression);

text and macro program statements

%END;

Do while the expression condition is true.

Example: A similar example as the above.

%macro getfname;

%let pathname=/user/username/project1/sas/report1.sas;

%let n=0;

%let temp=START;

%do %while(&temp ne );

%let n=%eval(&n+1);

%let temp=%scan(&pathname, &n, '/');

%put &temp;

%end;

%let n=%eval(&n-1);

%let fname=%scan(&pathname,&n,'/');

%put The file name is &fname;

%mend;

%getfname

%GOTO or %GO TO

%GOTO or %GO TO label;

Cause the macro processor to branch to the label specified in the statement.

Example: Terminate the macro at certain condition.

%macro branch;

data aa;

do i=1 to 10;

mis=i;

output;

end;

run;

proc summary data=aa;

var mis;

output out=bb;

run;

data _null_;

set bb ;

if _n_=1 then call symput('numobs',trim(left(mis)));

run;

%put Non-missing obs is: &numobs;

%if &numobs < 1 %then %goto out;

%else

%do;

proc print data=bb;

run;

%end;

%out: %mend;

%branch

%SYSEXEC

%SYSEXEC ;

The %sysexec statement allows your to use the host operating system command in open code or within a macro. This statement is amalogous to the X command.

Examples:

options noxwait;

%sysexec mkdir c:\sas_class\temp\zzz; * make a directory;

%sysexec rmdir c:\sas_class\temp\zzz; * delete a directory;

%sysexec c:\sas_class\classdata\stock.xls; * Start an excel spread

sheet;

%INCLUDE

The %include statement retrieve SAS source code from an external file.

General form:

%INCLUDE file-specification ;

file-specification: Can be full path and filename in quote or pre-defined fileref.

SOURCE2: cause the inserted SAS code to appear in the SAS log.

Example:

%include '/home/yihong1/demo/Program 1.sas';

%include '/home/yihong1/demo/Program 1.sas' / source2;

filename stock '/home/yihong1/demo/Program 1.sas';

%include stock / source2;

SAS Autocall Facility

Using auto call facility, user can use the SAS macro program by macro call directly.

The following is an example of how to setup an auto call process in Windows environment.

Step 1: Save the macro program in the same name as the macro name plus extension “.sas”. The following macro, named “get_ymd” is saved as “get_ymd.sas” in:

C:\sas_class\autocall directory.

%* The following macro program will create three global macro variables,;

%* Year (yyyy), Month (mm), and Day (dd). ;

%macro get_ymd; %* Start the macro;

%global year;

%global month;

%global day;

%let dt=&sysdate9.; %* get system date;

%let year =%sysfunc(year("&dt"d)); %* get year;

%let month=%sysfunc(month("&dt"d)); %* get month;

%if &month ................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download