Chapter 21: Macro Programs: 21.1 Defining and Calling A Macro
Chapter 21: Macro Programs: 21.1 Defining and Calling A Macro
Chapter 21: Macro Programs: 21.1 Defining and Calling A Macro
1
Chapter 21: Macro Programs
2
Objectives
Define and call a simple macro.
Explore macro storage.
3
Defining a Macro
A macro or macro definition enables you to write macro
programs.
General form of a macro definition:
%MACRO
%MACRO macro-name;
macro-name;
macro-text
macro-text
%MEND
%MEND<macro-name>;
<macro-name>;
5
Macro Compilation
The MCOMPILENOTE=ALL option enables a note to be
written to the SAS log after a macro has compiled.
OPTIONS
OPTIONSMCOMPILENOTE=ALL|NONE;
MCOMPILENOTE=ALL|NONE;
6
Macro Compilation
Example: Submit a macro definition.
options mcompilenote=all;
%macro time;
%put The SAS session started at &systime;
%mend time;
SAS Log
1 options mcompilenote=all;
2 %macro time;
3 %put The SAS session started at &systime;
5 %mend time;
NOTE: The macro TIME completed compilation without errors.
pf21d01
7
Macro Storage
Example: Produce a list of compiled macros stored in the
default temporary catalog work.sasmacr.
m103d02
8
Calling a Macro
A macro call
causes the macro to execute
%macro-name
%macro-name
9
Calling a Macro
Example: Call the TIME macro.
%time
SAS Log
178 %time
The SAS session started at 10:40
pf21d01
10
11
21.01 Poll
Does the macro call below require a semicolon?
%time
Yes
No
12
21.01 Poll – Correct Answer
Does the macro call below require a semicolon?
%time
Yes
No
13
Simple Macro
A macro can generate SAS code.
%macro calc;
proc means data=orion.order_item &stats;
var &vars;
run;
%mend calc;
m103d03
14
Simple Macro
Example: Call the CALC macro. Precede the call with
%LET statements that populate macro
variables referenced within the macro.
%let stats=min max;
%let vars=quantity;
%calc
m103d03
15
Program Flow
When the macro processor receives %macro-name, it:
16
Program Flow
Example: Submit the %LET statements and call the
CALC macro.
17
Program Flow
The macro processor executes the %LET statements and
populates the symbol table.
18
Program Flow
When the macro processor receives %CALC, it locates
CALC.MACRO within the work.sasmacr catalog.
19
Program Flow
The macro processor opens CALC.MACRO. There are
no macro language statements to execute.
20
Program Flow
The macro processor places the text on the input stack.
21
Program Flow
Macro activity pauses while the word scanner tokenizes
text placed on the input stack by the macro processor.
22
Program Flow
Macro variable references are passed to the macro
processor.
23
Program Flow
Symbolic substitution is performed.
24
Program Flow
Macro activity pauses while the word scanner tokenizes
text placed on the input stack by the macro processor.
25
Program Flow
Word scanning continues.
26
Program Flow
Macro variable references are passed to the macro
processor.
27
Program Flow
Symbolic substitution is performed.
28
Program Flow
Macro activity pauses while the word scanner tokenizes
text placed on the input stack by the macro processor.
29
Program Flow
When a step boundary is encountered, SAS executes the
compiled step as macro activity remains paused. Macro
activity stops when the %MEND statement is encountered.
30
Macro Execution
The SAS log reflects execution of the PROC MEANS step.
SAS Log
52 %let stats=min max;
53 %let vars=quantity;
54 %calc
NOTE: There were 732 observations read from the data set ORION.ORDER_ITEM.
NOTE: PROCEDURE MEANS used (Total process time):
real time 0.03 seconds
cpu time 0.03 seconds
PROC MEANS source code does not appear in the SAS log
by default.
m103d03
31
Macro Execution
The MPRINT option writes to the SAS log the text sent
to the SAS compiler as a result of macro execution.
General form of the MPRINT|NOMPRINT option:
OPTIONS
OPTIONSMPRINT;
MPRINT;
OPTIONS
OPTIONSNOMPRINT;
NOMPRINT;
32
Macro Execution
Example: Set the MPRINT option before calling the macro.
NOTE: There were 732 observations read from the data set ORION.ORDER_ITEM.
NOTE: PROCEDURE MEANS used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
33
34
21.02 Poll
Will the macro definition below produce an error when
submitted (compiled)?
%macro test;
tainted love
%mend test;
Yes
No
35
21.02 Poll – Correct Answer
Will the macro definition below produce an error when
submitted (compiled)?
%macro test;
tainted love
%mend test;
Yes
No
36
37
Exercise
38
Chapter 21: Macro Programs
39
Objectives
Define and call macros with parameters.
40
Review
Example: Note macro variable references within the
CALC macro.
%macro calc;
proc means data=orion.order_item &stats;
var &vars;
run;
%mend calc;
m103d03
41
Review
Example: Call the macro twice, each time with different
values of the macro variables STATS and
VARS.
%let stats=min max;
%let vars=quantity;
%calc
The user must submit three lines of code for each macro
invocation. How can this be simplified?
m103d03
42
Macro Parameters
Example: Define a macro with a parameter list of macro
variables referenced within the macro.
%macro calc(stats=,vars=);
proc means data=orion.order_item &stats;
var &vars;
run;
%mend calc;
pf21d05
43
Local Symbol Table
When a macro with a parameter list is called, the
parameters are created in a separate local symbol table.
The macro call
%calc(stats=min max,vars=quantity)
44
Local Symbol Tables
A local symbol table is
created when a macro with a parameter list is called
45
46
21.03 Multiple Choice Poll
A %LET statement outside a macro definition creates a
macro variable in the
a. global symbol table
b. local symbol table
47
21.03 Multiple Choice Poll – Correct Answer
A %LET statement outside a macro definition creates a
macro variable in the
a. global symbol table
b. local symbol table
48
Keyword Parameters
A parameter list can include either keyword or positional
parameters.
General form of a macro definition with keyword
parameters:
%MACRO
%MACROmacro-name(keyword=value,
macro-name(keyword=value,…,
…,keyword=value);
keyword=value);
macro
macrotext
text
%MEND
%MEND<macro-name>;
<macro-name>;
49
Keyword Parameters
General form of a macro call with keyword parameters:
%macro-name(keyword=value,
%macro-name(keyword=value,…,
…, keyword=value)
keyword=value)
50
Keyword Parameters
Example: Assign default parameter values by defining a
macro with keyword parameters.
%macro count(opts=,start=01jan04,stop=31dec04);
proc freq data=orion.orders;
where order_date between
"&start"d and "&stop"d;
table order_type / &opts;
title1 "Orders from &start to &stop";
run;
%mend count;
options mprint;
%count(opts=nocum)
%count(stop=01jul04,opts=nocum nopercent)
%count()
m103d06b
51
52
21.04 Multiple Choice Poll
Which macro call is preferable?
%macro dog(name=spot);
%put My dog is &name;
%mend dog;
a. %dog
b. %dog;
c. %dog()
d. %dog();
53
21.04 Multiple Choice Poll – Correct Answer
Which macro call is preferable?
%macro dog(name=spot);
%put My dog is &name;
%mend dog;
a. %dog
b. %dog;
c. %dog()
d. %dog();
54
55
Exercise
56
Chapter 21: Macro Programs
57
Objectives
Conditionally process SAS code within a macro
program.
Monitor macro execution.
Insert entire steps, entire statements, and partial
statements into a SAS program.
58
Macro-Level Programming
Macro-level programming can generate code conditionally.
Conditions can be based on:
system values
parameter values
data values
59
Macro-Level Programming
proc print data=orion.order_fact;
Always Print where order_date="&sysdate9"d;
the var product_id total_retail_price;
title "Daily sales: &sysdate9";
Daily Report run;
60
Conditional Processing
Conditional processing is performed with %IF-%THEN
and %ELSE statements.
%IF
%IFexpression
expression%THEN
%THENtext;
text;
%ELSE
%ELSE text;
text;
61
Macro Expressions
Similarities to SAS expressions:
arithmetic operators
logical operators
case-sensitivity
62
Conditional Processing
These items can follow the keywords %THEN and %ELSE:
a macro programming statement
constant text
an expression
a macro call
63
Conditional Processing
The MLOGIC system option displays macro execution
messages in the SAS log, including messages about:
macro initialization
parameter values
macro termination
OPTIONS
OPTIONSMLOGIC;
MLOGIC;
OPTIONS
OPTIONSNOMLOGIC;
NOMLOGIC;
64
Processing Complete Steps
Method 1: Create separate macros for the daily and
weekly programs.
%macro daily;
proc print data=orion.order_fact;
where order_date="&sysdate9"d;
var product_id total_retail_price;
title "Daily sales: &sysdate9";
run;
%mend daily;
%macro weekly;
proc means data=orion.order_fact n sum mean;
where order_date between
"&sysdate9"d - 6 and "&sysdate9"d;
var quantity total_retail_price;
title "Weekly sales: &sysdate9";
run;
%mend weekly;
m105d01a
65 continued...
Processing Complete Steps
Method 1: Write a third macro that always calls the
DAILY macro and conditionally calls the
WEEKLY macro.
%macro reports;
%daily
%if &sysday=Friday %then %weekly;
%mend reports;
m105d01a
66
Monitoring Macro Execution
Example: Use the MLOGIC option to monitor the
REPORTS macro.
Partial SAS Log
494 %macro reports;
495 %daily
496 %if &sysday=Friday %then %weekly;
497 %mend reports;
498
499 options mlogic;
500 %reports
MLOGIC(REPORTS): Beginning execution.
MLOGIC(DAILY): Beginning execution.
MLOGIC(DAILY): Ending execution.
MLOGIC(REPORTS): %IF condition &sysday=Friday is TRUE
MLOGIC(WEEKLY): Beginning execution.
MLOGIC(WEEKLY): Ending execution.
MLOGIC(REPORTS): Ending execution.
67
Macro Syntax Errors
If a macro definition contains macro language syntax
errors, error messages are written to the SAS log and a
dummy (non-executable) macro is created.
68
Conditional Processing
Use %DO and %END statements following %THEN or
%ELSE to generate text containing semicolons.
%IF
%IFexpression
expression%THEN
%THEN%DO;
%DO;
statement;
statement;
statement;
statement;
...
...
%END;
%END;
%ELSE
%ELSE%DO;%DO;
statement;
statement;
statement;
statement;
...
...
%END;
%END;
69
Processing Complete Steps
Method 2: Use a single macro to generate the daily report
unconditionally and the weekly report on Friday.
%macro reports;
proc print data=orion.order_fact;
where order_date="&sysdate9"d;
var product_id total_retail_price;
title "Daily sales: &sysdate9";
run;
%if &sysday=Friday %then %do;
proc means data=orion.order_fact n sum mean;
where order_date between
"&sysdate9"d-6 and "&sysdate9"d;
var quantity total_retail_price;
title "Weekly sales: &sysdate9";
run;
%end;
%mend reports;
70 m105d01b
Processing Complete Statements
Example: Insert individual statements within a PROC step.
%macro count(type=,start=01jan2007,stop=31dec2007);
proc freq data=orion.order_fact;
where order_date between "&start"d and "&stop"d;
table quantity;
title1 "Orders from &start to &stop";
%if &type= %then %do;
title2 "For All Order Types";
%end;
%else %do;
title2 "For Order Type &type Only";
where also order_type=&type;
%end;
run;
%mend count;
options mprint mlogic;
%count()
%count(type=3)
m105d02
71
Processing Complete Statements
SAS Log
802 %count()
MLOGIC(COUNT): Beginning execution.
MLOGIC(COUNT): Parameter TYPE has value
MLOGIC(COUNT): Parameter START has value 01jan2007
MLOGIC(COUNT): Parameter STOP has value 31dec2007
MPRINT(COUNT): proc freq data=orion.order_fact;
MPRINT(COUNT): where order_date between "01jan2007"d and "31dec2007"d;
MPRINT(COUNT): table quantity;
MPRINT(COUNT): title1 "Orders from 01jan2007 to 31dec2007";
MLOGIC(COUNT): %IF condition &type= is TRUE
MPRINT(COUNT): title2 "For All Order Types";
MPRINT(COUNT): run;
NOTE: There were 148 observations read from the data set ORION.ORDER_FACT.
WHERE (order_date>='01JAN2007'D and order_date<='31DEC2007'D);
NOTE: PROCEDURE FREQ used (Total process time):
real time 0.03 seconds
cpu time 0.03 seconds
NOTE: There were 40 observations read from the data set ORION.ORDER_FACT.
WHERE (order_date>='01JAN2007'D and order_date<='31DEC2007'D) and
(order_type=3);
NOTE: PROCEDURE FREQ used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
74 pf21d03
Processing Complete Statements
SAS Log
828 %cust(place=us)
MLOGIC(CUST): Beginning execution.
MLOGIC(CUST): Parameter PLACE has value us
MLOGIC(CUST): %LET (variable name is PLACE)
MPRINT(CUST): data customers;
MPRINT(CUST): set orion.customer;
MLOGIC(CUST): %IF condition &place=US is TRUE
MPRINT(CUST): where country='US';
MPRINT(CUST): keep customer_name customer_address country;
MPRINT(CUST): run;
NOTE: There were 28 observations read from the data set ORION.CUSTOMER.
WHERE country='US';
NOTE: The data set WORK.CUSTOMERS has 28 observations and 3 variables.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
75
Processing Complete Statements
SAS Log
829 %cust(place=international)
MLOGIC(CUST): Beginning execution.
MLOGIC(CUST): Parameter PLACE has value international
MLOGIC(CUST): %LET (variable name is PLACE)
MPRINT(CUST): data customers;
MPRINT(CUST): set orion.customer;
MLOGIC(CUST): %IF condition &place=US is FALSE
MPRINT(CUST): where country ne 'US';
MPRINT(CUST): keep customer_name customer_address country location;
MPRINT(CUST): length location $ 12;
MPRINT(CUST): if country="AU" then location='Australia';
MPRINT(CUST): else if country="CA" then location='Canada';
MPRINT(CUST): else if country="DE" then location='Germany';
MPRINT(CUST): else if country="IL" then location='Israel';
MPRINT(CUST): else if country="TR" then location='Turkey';
MPRINT(CUST): else if country="ZA" then location='South Africa';
MPRINT(CUST): run;
NOTE: There were 49 observations read from the data set ORION.CUSTOMER.
WHERE country not = 'US';
NOTE: The data set WORK.CUSTOMERS has 49 observations and 4 variables.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
76
77
21.05 Quiz
What is the difference between macro and DATA step
conditional statements?
78
21.05 Quiz – Correct Answer
What is the difference between macro and DATA step
conditional statements?
%IF-%THEN performs text processing to determine
what SAS code to place on the input stack for
tokenization, compilation, and execution.
IF-THEN performs data processing to determine
which SAS statements to execute during each
iteration of the DATA step.
79
Processing Partial Statements
Conditionally insert text into the middle of a statement.
%counts()
%counts(rows=customer_age_group)
pf21d04
80
Processing Partial Statements
SAS Log
1798 %counts()
MPRINT(COUNTS): title 'Customer Counts by Gender';
MPRINT(COUNTS): proc freq data=orion.customer_dim;
MPRINT(COUNTS): tables customer_gender ;
MPRINT(COUNTS): run;
NOTE: There were 77 observations read from the data set ORION.CUSTOMER_DIM.
NOTE: PROCEDURE FREQ used (Total process time):
real time 0.03 seconds
cpu time 0.03 seconds
1799 %counts(rows=customer_age_group)
MPRINT(COUNTS): title 'Customer Counts by Gender';
MPRINT(COUNTS): proc freq data=orion.customer_dim;
MPRINT(COUNTS): tables customer_age_group * customer_gender ;
MPRINT(COUNTS): run;
NOTE: There were 77 observations read from the data set ORION.CUSTOMER_DIM.
NOTE: PROCEDURE FREQ used (Total process time):
real time 0.03 seconds
cpu time 0.03 seconds
81
Parameter Validation
Example: Validate a parameter value before generating
SAS code based on that value.
%macro customers(place=);
%let place=%upcase(&place);
%if &place=AU
or &place=CA
or &place=DE
or &place=IL
or &place=TR
or &place=US
or &place=ZA %then %do;
proc print data=orion.customer;
var customer_name customer_address country;
where upcase(country)="&place";
title "Customers from &place";
run;
%end;
%else %put Sorry, no customers from &place..;
%mend customers;
%customers(place=de)
82
%customers(place=aa) pf21d05a
83
21.06 Quiz
What are the disadvantages of the previous program?
%macro customers(place=);
%let place=%upcase(&place);
%if &place=AU
or &place=CA
or &place=DE
or &place=IL
or &place=TR
or &place=US
or &place=ZA %then %do;
proc print data=orion.customer;
var customer_name customer_address country;
where upcase(country)="&place";
title "Customers from &place";
run;
%end;
%else %put Sorry, no customers from &place..;
%mend customers;
%customers(place=de)
%customers(place=aa)
84
21.06 Quiz – Correct Answer
What are the disadvantages of the previous program?
Multiple references to &PLACE
85
Parameter Validation
Example: Use the IN operator for parameter validation.
%customers(place=de)
%customers(place=aa)
pf21d05b
86
Parameter Validation
SAS Log
955 %customers(place=de)
NOTE: There were 10 observations read from the data set ORION.CUSTOMER.
WHERE UPCASE(country)='DE';
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
956 %customers(place=aa)
Sorry, no customers from AA.
87
88
Exercise
89