SAS - Macro Language 1
SAS - Macro Language 1
Essentials
Course Notes
SAS® Macro Language 1: Essentials Course Notes was developed by Jim Simon. Additional contributions
were made by Linda Mitterling and Theresa Stemler. Editing and production support was provided by the
Curriculum Development and Support Department.
SAS and all other SAS Institute Inc. product or service names are registered trademarks or trademarks of
SAS Institute Inc. in the USA and other countries. ® indicates USA registration. Other brand and product
names are trademarks of their respective companies.
SAS® Macro Language 1: Essentials Course Notes
Copyright © 2016 SAS Institute Inc. Cary, NC, USA. All rights reserved. Printed in the United States of
America. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in
any form or by any means, electronic, mechanical, photocopying, or otherwise, without the prior written
permission of the publisher, SAS Institute Inc.
Book code E70750, course code LWMC1/MC1, prepared date 03Jun2016. LWMC1_003
ISBN 978-1-62960-434-3
For Your Infor mation iii
Table of Contents
Course Description ......................................................................................................vi
Course Description
This course focuses on the components of the SAS macro facility and how to design, write, and debug
macro systems. Emphasis is placed on understanding how programs with macro code are processed.
To learn more…
For information about other courses in the curriculum, contact the SAS
Education Division at 1-800-333-7660, or send e-mail to [email protected].
You can also find this information on the web at http://support.sas.com/training/
as well as in the Training Course Catalog.
For a list of other SAS books that relate to the topics covered in this
course notes, USA customers can contact the SAS Publishing Department
at 1-800-727-3228 or send e-mail to [email protected]. Customers outside
the USA, please contact your local SAS office.
Also, see the SAS Bookstore on the web at http://support.sas.com/publishing/
for a complete list of books and a convenient order form.
For Your Infor mation vii
Prerequisites
Before attending this course, you should have completed the SAS ® Programming 2: Data Manipulation
Techniques course or have equivalent knowledge. Specifically, you should be able to
use a DATA step to read from or write to a SAS data set or external file
use DATA step programming statements such as IF-THEN/ELSE, DO WHILE, DO UNTIL, and
iterative DO
use SAS data set options such as DROP=, KEEP=, and OBS=
use character functions such as SUBSTR, SCAN, INDEX, and UPCASE
form subsets of data using the WHERE clause
create and use SAS date values and constants
use SAS procedures such as SORT, PRINT, CONTENTS, MEANS, FREQ, TABULATE, and CHART.
viii For Your Information
Chapter 1 Introduction
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1.1 Course Logistics 1-3
Objectives
Describe the data that is used in the course.
Identify the interfaces that are available for workshops.
Specify the naming convention that is used for
course files.
Define the three levels of exercises.
Explain the extended learning for this course.
Execute a SAS program to create course data files.
Execute a SAS program to define the data location.
3
3
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1-4 Chapter 1 Introduction
1,000
employees
150,000
orders 90,000
customers
64 suppliers
5
5
SAS SAS
SAS
Windowing Enterprise
Studio
Environment Guide
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1.1 Course Logistics 1-5
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1-6 Chapter 1 Introduction
SAS Studio
SAS Studio is a web client that is accessed through
an HTML5-compliant web browser.
10
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1.1 Course Logistics 1-7
12
12
13
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1-8 Chapter 1 Introduction
Data
location?
cre8data.sas
libname.sas
14
14
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1.1 Course Logistics 1-9
This demonstration illustrates how to create the course data files and define the data location.
1. In your SAS session, open the cre8data program.
2. Find the following %LET statement:
%let path=s:/workshop;
3. If your data files are to be created at a location other than s:\workshop, change the value that
is assigned to the path micro variable to reflect the location. If your data files are created in
s:\workshop, then no change is needed.
The cre8data program uses forward slashes for portability across operating environments.
UNIX and Linux require forward slashes. Windows accepts forward slashes and might convert
them to back slashes.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1-10 Chapter 1 Introduction
Exercises
Required Exercise
You must complete the exercise to create the course data files. If you do not create the data files,
all programs in this course will fail.
The cre8data program uses forward slashes for portability across operating environments.
UNIX and Linux require forward slashes. Windows accepts forward slashes and might
convert them to back slashes.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1.1 Course Logistics 1-11
f. Open the libname program, which was created by the cre8data program.
%let path=s:/workshop;
libname orion "s:/workshop";
g. Submit the program.
h. View the log and verify that there are no errors or warnings.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1-12 Chapter 1 Introduction
Objectives
State the purpose of the macro facility.
View examples of macro applications.
18
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1.2 Purpose of the Macro Facility 1-13
20
21
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1-14 Chapter 1 Introduction
Conditional Processing
Macro programs support conditional construction
of SAS code.
Repetitive Processing
Macro programs support repetitive generation
of SAS code.
23
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1.2 Purpose of the Macro Facility 1-15
Data-Driven Applications
Macro programs support dynamic data-driven generation
of SAS code.
Example: Create separate subsets of a selected data set
for each unique value of a selected variable.
data AU CA DE IL TR US ZA;
set orion.customer;
select(country);
when("AU") output AU;
when("CA") output CA;
when("DE") output DE;
when("IL") output IL;
when("TR") output TR;
when("US") output US;
when("ZA") output ZA;
otherwise;
end;
run;
24
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1-16 Chapter 1 Introduction
30
31
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1.3 Program Flow 1-17
Objectives
Identify the tokens in a SAS program.
Describe how a SAS program is tokenized, compiled,
and executed.
35
Program Flow
When you submit a SAS program, it is copied
to a memory location called the input stack.
Input Stack
38
SAS macro language
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1-18 Chapter 1 Introduction
Program Flow
Input Stack
Batch or
SUBMIT Stored Noninteractive
Com m and Process Subm ission
data bonus; %STPBEGIN; //SYSIN DD *
set orion.staff; title 'New Data'; options nodate;
bonus=salary*.1; proc print data=new; title 'Staff';
run; run; proc sql;
proc print; proc means data=new; select *
title 'Bonuses'; run; from orion.staff;
run; %STPEND; quit;
39
Program Flow
When SAS code is in the input stack, a component
of SAS called the word scanner does the following:
reads the text in the input stack, character
by character, left to right, top to bottom
breaks the text into fundamental units called tokens
data
Word bonus
;
Scanner
set orion.staff;
bonus=salary*.1;
run;
Input proc print;
Stack title 'Bonuses';
run;
40
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1.3 Program Flow 1-19
Program Flow
The word scanner recognizes four classes of tokens:
name tokens
data
Word bonus
;
Scanner
set orion.staff;
bonus=salary*.1;
run;
Input proc print;
Stack title 'Bonuses';
run;
42 ...
Name tokens contain one or more characters beginning with a letter or underscore and continuing with
letters, underscores, or numerals.
Program Flow
The word scanner recognizes four classes of tokens:
name tokens
special tokens
data
Word bonus
;
Scanner
set orion.staff;
bonus=salary*.1;
run;
Input proc print;
Stack title 'Bonuses';
run;
43 ...
Special tokens can be any character, or combination of characters, other than a letter, underscore,
or numeral.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1-20 Chapter 1 Introduction
Program Flow
The word scanner recognizes four classes of tokens:
name tokens
special tokens
literal tokens
data
Word bonus
;
Scanner
set orion.staff;
bonus=salary*.1;
run;
Input proc print;
Stack title 'Bonuses';
run;
44 ...
Program Flow
The word scanner recognizes four classes of tokens:
name tokens
special tokens
literal tokens
number tokens
data
Word bonus
;
Scanner
set orion.staff;
bonus=salary*.1;
run;
Input proc print;
Stack title 'Bonuses';
run;
45
Number tokens can be integer numbers or floating-point numbers containing a decimal point,
an exponent, or both.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1.3 Program Flow 1-21
1.03 Poll
Blanks are tokens.
True
False
46
Tokenization
A token ends when the word scanner detects
a blank
the beginning of another token.
data
Word bonus
;
Scanner
set orion.staff;
bonus=salary*.1;
run;
Input proc print;
Stack title 'Bonuses';
run;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1-22 Chapter 1 Introduction
Program Flow
The word scanner passes tokens, one at a time,
to the appropriate compiler, as the compiler demands.
data bonus;
Compiler
set
orion
Word .
Scanner staff
;
bonus=salary*.1;
Input Stack run;
proc print;
title 'Bonuses';
run;
52
Program Flow
Compiler
Request tokens until
semicolon received
SAS
Step boundary
encountered;
Suspend compilation
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1.3 Program Flow 1-23
Program Flow
How does the macro language fit in?
data bonus;
Compiler
set
orion
Word .
Scanner staff
;
bonus=salary*.1;
Input Stack run;
proc print;
title 'Bonuses';
run;
54
Macro Triggers
During word scanning, two token sequences are
recognized as macro triggers:
55
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1-24 Chapter 1 Introduction
Program Flow
Where does the macro processor fit in?
Compiler
Word
Scanner
Input
Stack
56
Macro Processor
The macro processor executes macro triggers, including
macro variable resolution, macro language statements,
macro functions, and macro calls, requesting tokens
as necessary.
Compiler
Macro Processor
Word
Scanner
Input
Stack
57
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1.3 Program Flow 1-25
Macro Statements
The following are characteristics of macro statements:
begin with a percent sign (%) followed by a name token
end with a semicolon
represent macro triggers
are executed by the macro processor
58
%PUT Statement
Example: Write text to the SAS log.
SAS Log
12 %put Invalid code!;
Invalid code!
%PUT text;
59
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1-26 Chapter 1 Introduction
Program Flow
The %PUT statement is submitted.
Compiler
Macro Processor
Word
Scanner
Program Flow
The statement is tokenized.
Compiler
Macro Processor
Word %
Scanner put
Invalid
code
!
;
Input
Stack
61 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1.3 Program Flow 1-27
Program Flow
The macro trigger is passed to the macro processor.
Compiler
Macro Processor
Word %put
Scanner
Invalid
code
!
;
Input
Stack
62 ...
Program Flow
The macro processor does the following:
requests tokens until a semicolon is encountered
executes the macro language statement
Compiler
Macro Processor
Input
Stack
63
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1-28 Chapter 1 Introduction
Exercises
Level 1
a. Open the program m101e02 shown below into the Editor window.
%put NOTE: Is this a SAS note?;
%put WARNING: Is this a SAS warning?;
%put ERROR: Is this a SAS error?;
b. Submit the program and review the results in the SAS log. What is unusual about the results?
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
c. Replace the colon so that a hyphen follows the keywords NOTE, WARNING, and ERROR.
Submit the program and review the results in the SAS log. How do the results change?
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
d. Modify the program so that the keywords NOTE, WARNING, and ERROR are in lowercase.
Submit the program and review the results in the SAS log. Did the change affect the results?
_________________________________________________________ ________________
______________________________________________________________________________
______________________________________________________________________________
Level 2
4. Writing Special Characters to the SAS Log with the %PUT Statement
a. Submit the following %PUT statement:
%put Can you display a semicolon ; in your %PUT statement?;
b. Does the %PUT statement generate any text? If so, what is the text displayed in the SAS log?
______________________________________________________________________________
______________________________________________________________________________
c. Does the %PUT statement generate any error messages? If so, what is the cause of the error?
______________________________________________________________________________
______________________________________________________________________________
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1.3 Program Flow 1-29
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1-30 Chapter 1 Introduction
1.4 Solutions
Solutions to Exercises
1. Creating Course Data Files
This is exercise is self-guided, so no solution is needed.
2. Writing Text to the SAS Log with the %PUT Statement
%put Jane Doe;
3. Writing NOTE, WARNING, and ERROR Messages to the SAS Log with the %PUT Statement
a. Open the program into the Editor window.
%put NOTE: Is this a SAS note?;
%put WARNING: Is this a SAS warning?;
%put ERROR: Is this a SAS error?;
b. The keywords NOTE, WARNING, and ERROR make the results of the %PUT statements
resemble standard SAS NOTE, WARNING, and ERROR messages. Depending on the operating
environment, the messages might be color-coded or just displayed in bold.
c. The hyphen forces the keywords NOTE, WARNING, and ERROR to be suppressed.
d. The keywords NOTE, WARNING, and ERROR are case-sensitive and do not have the desired
effect when entered in lowercase.
4. Writing Special Characters to the SAS Log with the %PUT Statement
a. Submit the following %PUT statement:
%put Can you display a semicolon ; in your %PUT statement?;
b. The first semicolon in the %PUT statement is treated as a special token, not as plain text,
and ends the statement. The %PUT statement generates the following text:
Partial SAS Log
1 %put Can you display a semicolon ; in your %PUT statement?;
Can you display a semicolon
c. An error message is generated after the first semicolon because the word IN is interpreted
as an invalid keyword.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1.4 Solutions 1-31
d. Because of the first semicolon, the second %PUT is interpreted as a macro keyword that
generates the following text:
Partial SAS Log
statement?
The method for interpreting special tokens as plain text is addressed later in the course.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1-32 Chapter 1 Introduction
32
47
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
Chapter 2 Macro Variables
2.1 Introduction to Macro Variables................................................................................ 2-3
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.1 Introduction to Macro Variables 2-3
Objectives
Describe the purpose of macro variables.
Describe where macro variables are stored.
Identify the two types of macro variables.
Business Scenario
Production programs might need to be updated with
information, such as the current date, each time they
are run. Use macro variables to minimize typing
and make the code more flexible and reusable.
Macro Variable
4
4
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-4 Chapter 2 Macro Variables
Macro
Variables
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.1 Introduction to Macro Variables 2-5
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-6 Chapter 2 Macro Variables
10
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.2 Automatic Macro Variables 2-7
Objectives
Identify selected automatic macro variables.
Display automatic macro variables in the SAS log.
14
Business Scenario
Use automatic macro variables to minimize typing.
SYSDATE
SYSDATE9
SYSDAY
???
15
15
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-8 Chapter 2 Macro Variables
16
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.2 Automatic Macro Variables 2-9
18
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-10 Chapter 2 Macro Variables
2.02 Poll
Submit the statement below.
%put _automatic_;
20
Objectives
Explain how macro variable references are handled
by the word scanner and macro processor.
24
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.3 Macro Variable References 2-11
Business Scenario
Use automatic macro variables to generate footnotes with
the following information:
report time
Customer Country
report day
Country Frequency Percent
report date ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ
AU 8 10.39
CA 15 19.48
DE 10 12.99
IL 5 6.49
TR 7 9.09
US 28 36.36
ZA 4 5.19
25
25
26
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-12 Chapter 2 Macro Variables
Symbol Table
&sysday
sysday Tuesday
27
Symbol Table
&sysday
sysday Tuesday
28
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.3 Macro Variable References 2-13
Symbol Table
&sysday
sysday Tuesday
29
30
An equal sign between the ampersand and the macro variable name displays the macro variable’s name
followed by the macro variable’s value.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-14 Chapter 2 Macro Variables
Compiler
Macro Processor
Word
Scanner
Symbol Table
%put Today is &sysday;
Input
SYSDAY Tuesday
Stack
SYSLAST _NULL_
31 ...
Compiler
Macro Processor
Word %put
Scanner
Symbol Table
Today is &sysday;
Input
SYSDAY Tuesday
Stack
SYSLAST _NULL_
32 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.3 Macro Variable References 2-15
Compiler
Macro Processor
Word ; %put Today is &sysday
Scanner
Symbol Table
Input
SYSDAY Tuesday
Stack
SYSLAST _NULL_
33 ...
Compiler
Macro Processor
Word ; %put Today is &sysday
Scanner
Symbol Table
Input
SYSDAY Tuesday
Stack
SYSLAST _NULL_
34 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-16 Chapter 2 Macro Variables
Compiler
Macro Processor
Word ; %put Today is Tuesday
Scanner
Symbol Table
Input
SYSDAY Tuesday
Stack
SYSLAST _NULL_
35 ...
Compiler
Macro Processor
Word %put Today is Tuesday;
Scanner
Symbol Table
Input
SYSDAY Tuesday
Stack
SYSLAST _NULL_
36
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.3 Macro Variable References 2-17
m102d01
37
m102d01
39
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-18 Chapter 2 Macro Variables
m102d01
40
Compiler
Macro Processor
Word
Scanner
Symbol Table
proc print;
Input title "Today is &sysday"; SYSDAY Tuesday
Stack run;
SYSLAST WORK.ALL
41 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.3 Macro Variable References 2-19
proc print;
Compiler title
Macro Processor
Word "
Today
Scanner is
Symbol Table
Input &sysday"; SYSDAY Tuesday
Stack run;
SYSLAST WORK.ALL
42 ...
proc print;
Compiler title
Macro Processor
Word " &sysday
Today
Scanner is
Symbol Table
Input "; SYSDAY Tuesday
Stack run;
SYSLAST WORK.ALL
43 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-20 Chapter 2 Macro Variables
proc print;
Compiler title
Macro Processor
Word " &sysday
Today
Scanner is
Symbol Table
Input "; SYSDAY Tuesday
Stack run;
SYSLAST WORK.ALL
44 ...
proc print;
Compiler title
Macro Processor
Word "
Today
Scanner is
Symbol Table
Input Tuesday"; SYSDAY Tuesday
Stack run;
SYSLAST WORK.ALL
45 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.3 Macro Variable References 2-21
proc print;
Compiler title
Macro Processor
Word "
Today
Scanner is
Tuesday
"
Symbol Table
Input ; SYSDAY Tuesday
Stack run;
SYSLAST WORK.ALL
46 ...
proc print;
Compiler title "Today is Tuesday"
Macro Processor
Word
Scanner
Symbol Table
Input ; SYSDAY Tuesday
Stack run;
SYSLAST WORK.ALL
47 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-22 Chapter 2 Macro Variables
proc print;
Compiler title "Today is Tuesday";
Macro Processor
Word
Scanner
run;
Symbol Table
Input
SYSDAY Tuesday
Stack
SYSLAST WORK.ALL
48
49
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.3 Macro Variable References 2-23
Macro Processor
Word
Scanner run;
Symbol Table
proc print data=&syslast;
Input title "Listing of &syslast";
SYSDAY Tuesday
Stack run; SYSLAST ORION.ALL
51 ...
Macro Processor
Word &syslast
Scanner run;
Symbol Table
;
Input title "Listing of &syslast";
SYSDAY Tuesday
Stack run; SYSLAST ORION.ALL
52 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-24 Chapter 2 Macro Variables
Macro Processor
Word &syslast
Scanner run;
Symbol Table
;
Input title "Listing of &syslast";
SYSDAY Tuesday
Stack run; SYSLAST ORION.ALL
53 ...
Macro Processor
Word
Scanner run;
Symbol Table
ORION.ALL;
Input title "Listing of &syslast";
SYSDAY Tuesday
Stack run; SYSLAST ORION.ALL
54 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.3 Macro Variable References 2-25
Macro Processor
Word
Scanner run;
Symbol Table
Input title "Listing of &syslast";
SYSDAY Tuesday
Stack run; SYSLAST ORION.ALL
55 ...
Macro Processor
Word
Scanner run;
Symbol Table
Input SYSDAY Tuesday
Stack SYSLAST ORION.ALL
56
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-26 Chapter 2 Macro Variables
Unresolved Reference
Example: Reference a nonexistent macro variable within
a SAS literal.
Macro Processor
Word "
Expenses
Scanner for
R
Symbol Table
proc print data=orion.exp;
Input title "Expenses for R&D";
SYSDAY Tuesday
Stack run; SYSLAST ORION.ALL
57 ...
Unresolved Reference
The macro trigger is passed to the macro processor for
evaluation.
Macro Processor
Word " &D
Expenses
Scanner for
R
Symbol Table
";
Input run;
SYSDAY Tuesday
Stack SYSLAST _NULL_
58 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.3 Macro Variable References 2-27
Unresolved Reference
The macro processor issues a warning to the SAS log
when it cannot resolve a reference.
Macro Processor
Word " &D
&D
Expenses
Scanner for
R
Symbol Table
";
Input run;
SYSDAY Tuesday
Stack SYSLAST _NULL_
59 ...
Unresolved Reference
If the macro processor cannot resolve a reference,
the tokens are passed back to the word scanner.
The word scanner passes them to the compiler.
WARNING: Apparent symbolic
proc print data=orion.exp; reference D not resolved.
Compiler title "Expenses for R&D"
Macro Processor
Word ;
run
Scanner ;
Symbol Table
Input SYSDAY Tuesday
Stack SYSLAST _NULL_
60
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-28 Chapter 2 Macro Variables
Unresolved Reference
Example: Reference a nonexistent macro variable within
SAS code.
proc print data=&sydlast;
title "Listing of &syslast";
run;
61
Unresolved Reference
SAS Log
1 proc print data=&sydlast;
-
22
200
WARNING: Apparent symbolic reference SYDLAST not resolved.
ERROR: File WORK.SYDLAST.DATA does not exist.
ERROR 22-322: Expecting a name.
ERROR 200-322: The symbol is not recognized and will be ignored.
2 title "Listing of &syslast";
3 run;
NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.65 seconds
cpu time 0.09 seconds
62
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.3 Macro Variable References 2-29
Exercises
Submit a LIBNAME statement to assign the orion libref to the course SAS library according
to instructions provided by the instructor.
libname orion '________________________________';
Level 1
1. Displaying Automatic Macro Variables
a. Use the %PUT statement to list all automatic macro variables in the SAS log.
b. What are the values of the following automatic macro variables?
SYSLAST _____________________________________________________________
SYSUSERID _____________________________________________________________
SYSTIME _____________________________________________________________
SYSDATE9 _____________________________________________________________
c. Are the values for the automatic macro variables SYSTIME and SYSDATE9 accurate?
_____________________________________________________________________________
______________________________________________________________________________
Level 2
2. Using Automatic Macro Variables
a. Using the SORT procedure, sort the data set orion.continent by Continent_Name.
Use the OUT= option in the PROC SORT statement so that you do not overwrite
the original data set.
b. Using the PRINT procedure and an automatic macro variable, print the most recently created data
set and display the data set name in the title.
c. Submit the program and examine the results.
3. Using Automatic Macro Variables
a. What is the value of the automatic macro variable SYSLAST after the following DATA step
is submitted?
_____________________________________________________________________
data new;
set orion.continent;
run;
b. What is the value of the automatic macro variable SYSLAST after the following PROC PRINT
step is submitted?
_____________________________________________________________________
proc print data=orion.continent;
run;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-30 Chapter 2 Macro Variables
Challenge
4. Using SAS Date Constants
a. Open the m102e04 program shown below into the Editor window.
proc print data=orion.employee_payroll;
format Birth_Date Employee_Hire_Date date9.;
run;
b. Modify the program so that it subsets the data to return only the employees hired between
January 1, 2007, and today. Use the automatic macro variable SYSDATE9 to return today’s date.
PROC PRINT Output
Employee_ Birth_ Employee_ Employee_ Marital_
Obs Employee_ID Gender Salary Date Hire_Date Term_Date Status Dependents
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.4 User- Defined Macro Variables 2-31
Objectives
Create user-defined macro variables.
Display values of user-defined macro variables
in the SAS log.
66
Business Scenario
Further automate your programs with user-defined macro
variables.
&myvar
67
67
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-32 Chapter 2 Macro Variables
%LET Statement
The %LET statement creates a macro variable
and assigns it a value.
Symbol Table
name Ed Norton
68
69
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.4 User- Defined Macro Variables 2-33
70
71 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-34 Chapter 2 Macro Variables
72 ...
73 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.4 User- Defined Macro Variables 2-35
74 ...
75 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-36 Chapter 2 Macro Variables
76 ...
77 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.4 User- Defined Macro Variables 2-37
78 ...
79 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-38 Chapter 2 Macro Variables
80
%let x=15;
%let y=10;
%let z=&x-&y;
81
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.4 User- Defined Macro Variables 2-39
m102d02
83
%let units=4;
m102d02
84
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-40 Chapter 2 Macro Variables
%let units=4;
m102d02
85
m102d03
86
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.4 User- Defined Macro Variables 2-41
%let office=Sydney;
m102d03
87
m102d03
88
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-42 Chapter 2 Macro Variables
Order_
Obs Date Product_ID Quantity
90
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.4 User- Defined Macro Variables 2-43
SAS Log
%PUT _USER_;
175 %put _user_;
GLOBAL DATE1 25may2011
GLOBAL DATE2 15jun2011
GLOBAL OFFICE Sydney
GLOBAL UNITS 4
92
Use _ALL_ to display all user-defined and automatic macro variables in the SAS log, as follows:
%put _all_;
SAS Log
176 options symbolgen;
OPTIONS SYMBOLGEN;
177 %let office=Sydney;
178 proc print data=orion.employee_addresses;
179 where city="&office";
SYMBOLGEN: Macro variable OFFICE resolves to Sydney
180 var employee_name;
SYMBOLGEN: Macro variable OFFICE resolves to Sydney
181 title "&office Employees";
182 run;
93
After debugging, issue the following statement to turn off the SYMBOLGEN option:
options nosymbolgen;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-44 Chapter 2 Macro Variables
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.4 User- Defined Macro Variables 2-45
Exercises
Level 1
5. Defining and Using Macro Variables for Character Substitution
a. Open the m102e05 program shown below into the Editor window. Submit the program
and examine the output that it creates.
proc print data=orion.customer_dim;
var Customer_Name Customer_Gender Customer_Age;
where Customer_Group contains 'Gold';
title 'Gold Customers';
run;
b. Precede the program with a %LET statement to assign the value Gold to type. Modify the program
so that the two occurrences of Gold are replaced by references to the macro variable type. Submit
the program. It produces the same output as before.
c. Include the appropriate system option to display resolved values of macro variables in the SAS log.
Resubmit the program and examine the log.
d. Modify the value of type to Internet. Resubmit the program and examine the log.
e. Turn off the system option from part c above.
Level 2
6. Defining and Using Macro Variables for Numeric Substitution
a. Open the m102e06 program shown below into the Editor window. Edit the program to display only
the Gold-level customers between the ages of 30 to 45.
Customer ages range from 19 to 73.
%let type=Gold;
proc print data=orion.customer_dim;
var Customer_Name Customer_Gender Customer_Age;
where Customer_Group contains "&type";
title "&type Customers";
run;
SAS Output
Gold Customers between 30 and 45
Customer_ Customer_
Obs Customer_Name Gender Age
3 Cornelia Krahl F 33
11 Oliver S. Füßling M 43
32 James Klisurich M 38
35 Viola Folsom F 38
40 Kyndal Hooks F 43
57 Rita Lotz F 43
75 Angel Borwick F 38
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-46 Chapter 2 Macro Variables
b. Modify the program so that the values 30 and 45 are replaced by references to the macro variables
age1 and age2, respectively.
c. Include the appropriate system option to display resolved values of macro variables in the SAS log.
Resubmit the program and examine the log.
d. Modify the values of age1 and age2. Resubmit the program and examine the log.
e. Turn off the system option from part c above.
7. Deleting Macro Variables
a. Open the program m102e07 program shown below into the Editor window. Submit the program
to create the macro variables.
%let pet1=Paisley;
%let pet2=Sitka;
b. Delete all user-defined macro variables.
c. Use the %PUT statement to verify that the macro variable deletion is successful.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.5 Delimiting Macro Variable References 2-47
Objectives
Code macro variable references with leading
or trailing text.
Code adjacent macro variable references.
98
Business Scenario
The production program below requires the user
to repetitively enter the desired year, month,
and analysis variable. Automate the program with
user-defined macro variables. year
analysis variable
99
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-48 Chapter 2 Macro Variables
Leading text
Adjacent macro variable references
Trailing text
Leading Text
Leading text is never a problem.
%let month=jan;
proc chart data=orion.y2010&month;
hbar week / sumvar=sale;
run;
proc plot data=orion.y2010&month;
plot sale*day;
run;
proc chart data=orion.y2010jan;
hbar week / sumvar=sale;
run;
proc plot data=orion.y2010jan;
plot sale*day;
run;
101
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.5 Delimiting Macro Variable References 2-49
102
Trailing Text
Trailing text can be a problem. Why?
Why is trailing text not a problem here?
%let year=2010;
%let month=jan;
%let var=sale;
proc chart data=orion.y&year&month;
hbar week / sumvar=&var;
run;
proc plot data=orion.y&year&month;
plot &var*day;
run;
proc chart data=orion.y2010jan;
hbar week / sumvar=sale;
run;
proc plot data=orion.y2010jan;
plot sale*day;
run;
103
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-50 Chapter 2 Macro Variables
Trailing Text
Trailing text is a problem if it changes the reference.
It is not a problem here because of the special character.
%let year=2010;
%let month=jan;
%let var=sale;
proc chart data=orion.y&year&month;
hbar week / sumvar=&var;
run;
proc plot data=orion.y&year&month;
plot &var*day;
run;
proc chart data=orion.y2010jan;
hbar week / sumvar=sale;
run;
proc plot data=orion.y2010jan;
plot sale*day;
run; special character
104
105
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.5 Delimiting Macro Variable References 2-51
106
108
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-52 Chapter 2 Macro Variables
110
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.5 Delimiting Macro Variable References 2-53
Corrected Program
Use another period.
delimiter text
112
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-54 Chapter 2 Macro Variables
Exercises
Level 1
8. Consecutive Macro Variable References
a. Open the m102e08 program shown below into the Editor window. Submit the program
and examine the output that it creates.
proc print data=orion.organization_dim;
where Employee_Hire_Date='01AUG2006'd;
id Employee_ID;
var Employee_Name Employee_Country Employee_Hire_Date;
title 'Personal Information for Employees Hired in AUG
2006';
run;
b. Precede the program with %LET statements to assign the value AUG to month and the value 2006
to year. Modify the program so that the two occurrences of AUG and 2006 are replaced by
references to the macro variables month and year, respectively. Submit the program. It produces
the same output as before.
c. Modify the value of month to JUL and year to 2003. Resubmit the program.
Level 2
9. Macro Variable References with Delimiters
a. Open the m102e09 program shown below into the Editor window. Submit the program
and examine the output that it creates.
proc print data=orion.organization_dim;
id Employee_ID;
var Employee_Name Employee_Country Employee_Gender;
title 'Listing of All Employees From
Orion.Organization_Dim';
run;
b. Modify the program so that all occurrences of Organization and Employee are replaced with macro
variable references called dsn and var, respectively. Submit the program and verify the output.
When substituting for the hardcoded Employees in the TITLE statement, be sure to keep
the ending s as part of the title text.
c. Modify the value of dsn to Customer and var to Customer. Resubmit the program.
Challenge
10. Macro Variable References with Multiple Delimiters
a. Open the m102e10 program shown below into the Editor window. This program analyzes
the orion.staff data to find the employee with the most seniority within a job title. Submit
the program and examine the output that it creates.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.5 Delimiting Macro Variable References 2-55
Emp_Hire_
Job_Title Employee_ID Date
Emp_Hire_
Job_Title Employee_ID Date
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-56 Chapter 2 Macro Variables
Objectives
Use macro language functions to manipulate text.
Use macro language functions to perform arithmetic
operations.
Use macro language functions to execute SAS
functions.
116
Business Scenario
The production program below requires manual entry
of the year and data set name. How do you eliminate
manual data entry?
hardcoded
data orders;
set orion.Orders;
where year(Order_Date)=2011;
Lag=Delivery_Date-Order_Date;
run;
117
117
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.6 Macro Functions 2-57
Task Requirements
Extract the necessary information from automatic macro
variables.
&SYSDATE9=23JAN2011
data orders;
set orion.Orders;
where year(Order_Date)=2011;
Lag=Delivery_Date-Order_Date;
run;
118
118
119
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-58 Chapter 2 Macro Variables
Macro Functions
Macro functions manipulate macro variables.
SAS function
substr(date,6)
Macro function
%substr(&sysdate9,6)
121
121
Macro Functions
Selected character string manipulation functions:
%UPCASE Translates letters from lowercase to uppercase.
%SUBSTR Extracts a substring from a character string.
%SCAN Extracts a word from a character string.
%INDEX Searches a character string for specified text.
122
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.6 Macro Functions 2-59
%SUBSTR Function
Use the %SUBSTR function to extract the year portion
of the &SYSDATE9 macro variable.
17 %put &=sysdate9;
SYSDATE9=20APR2011
18 %put YEAR=%substr(&sysdate9,6);
YEAR=2011
%SUBSTR(argument, position <,n>)
The values of position and n can also be the result of an arithmetic expression that yields
an integer. For example,
%substr(&var,%length(&var)-1)
returns the last two characters of the value of the macro variable var.
Macro Functions
Arguments to macro string manipulation functions can
be any text or macro triggers, or both, including:
124
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-60 Chapter 2 Macro Variables
%let x=%substr("ABCD",2,1);
125
%SCAN Function
To extract the data set name from the &SYSLAST macro
variable, use the %SCAN macro function.
SAS Log
26 %put &=syslast;
SYSLAST=WORK.ORDERS
27 %put DSN=%scan(&syslast,2,.);
DSN=ORDERS
%SCAN(argument, n <,delimiters>)
The following are default delimiters for the %SCAN function: blank . ( & ! $ * ) ; - / , %
It is not necessary to place argument and delimiters in quotation marks because they are always handled
as character strings by the %SCAN function.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.6 Macro Functions 2-61
m102d05a
128
Order N
Type Obs Minimum Maximum Mean
ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ
1 70 0.00 10.00 0.43
2 15 2.00 10.00 4.27
3 31 1.00 7.00 3.87
ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ m102d05b
129
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-62 Chapter 2 Macro Variables
Business Scenario
Additional macro functions are available to automate
the generation of SAS code.
%EVAL
%SYSFUNC
%STR
%NRSTR
130
130
%EVAL Function
The %EVAL function performs arithmetic and logical
operations.
28 %put x=2+2;
x=2+2
29 %put x=%eval(2+2);
x=4 %EVAL(expression)
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.6 Macro Functions 2-63
%EVAL Function
Example: Compute the first year of a range based
on the current date.
%let thisyr=%substr(&sysdate9,6);
%let lastyr=%eval(&thisyr-1);
proc means data=orion.order_fact maxdec=2 min max mean;
class order_type;
var total_retail_price;
where year(order_date) between &lastyr and &thisyr;
title1 "Orders for &lastyr and &thisyr";
title2 "(as of &sysdate9)";
run;
Orders for 2010 and 2011
(as of 31DEC2011)
Order N
Type Obs Minimum Maximum Mean
ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ
%SYSFUNC Function
The %SYSFUNC macro function executes SAS functions.
31 %put &=syslast;
SYSLAST=WORK.ORDERS
32 %put DSN=%sysfunc(propcase(&syslast));
DSN=Work.Orders
%SYSFUNC(SAS function(argument(s)) <,format>)
133
Most SAS functions can be used with %SYSFUNC. Exceptions include array processing (DIM, HBOUND,
LBOUND), variable information (VNAME, VLABEL, MISSING), macro interface (RESOLVE, SYMGET),
and data conversion functions (INPUT, PUT), as well as the IORCMSG, LAG, and DIF functions.
Because %SYSFUNC is a macro function, do not enclose character arguments in quotation marks as you
do with SAS functions. Use commas to separate all arguments in SAS functions within %SYSFUNC.
You cannot use argument lists preceded by the word OF.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-64 Chapter 2 Macro Variables
%SYSFUNC executes one SAS function at a time. If you want to execute multiple SAS functions
in a single macro statement or expression, use a separate %SYSFUNC for each SAS function, as shown
below.
%put %sysfunc(year(%sysfunc(today())));
%SYSFUNC Function
The automatic macro variables SYSDATE9 and SYSTIME
can be used in titles.
title1 "&sysdate9";
title2 "&systime";
07MAR2011
13:39
m102d07
134
%SYSFUNC Function
Example: Generate titles that contain the current date
and time, appropriately formatted.
title1 "%sysfunc(today(),weekdate.)";
title2 "%sysfunc(time(),timeAMPM8.)";
m102d07
135
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.6 Macro Functions 2-65
m102d08
136
%STR Function
Example: Store a SAS statement in a macro variable.
%let statement=%str(title "S&P 500";);
%STR(argument)
m102d08
138
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-66 Chapter 2 Macro Variables
%STR Function
The %STR function masks (removes the normal meaning of)
these special tokens:
139
139
%STR Function
The following are true for the %STR function:
masks tokens, so the macro processor does not
interpret them as macro-level syntax
enables macro triggers to work normally
preserves leading and trailing blanks in its argument
masks an unpaired quotation mark or parenthesis
in its argument when the quotation mark or
parenthesis is immediately preceded by a percent
sign (%)
140
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.6 Macro Functions 2-67
%STR Function
The %STR function enables macro triggers to work normally.
SAS Log
3 %let statement=%str(title "S&P 500";);
WARNING: Apparent symbolic reference P not resolved.
m102d08
141
%NRSTR Function
The %NRSTR function works the same as the %STR
function, except it also masks macro triggers.
m102d08
142
In addition to %STR and %NRSTR, several other macro quoting functions are available for specialized
purposes. For further information, see “Macro Quoting” under “Understanding and Using the Macro
Facility” under SAS Macro Language: Reference in Base SAS documentation.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-68 Chapter 2 Macro Variables
143
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.6 Macro Functions 2-69
Exercises
Level 1
11. Using the %SUBSTR and %SCAN Functions
a. Submit a %LET statement to assign the value Anthony Miller to a macro variable named fullname.
b. Extract the first initial and last name, putting them together into a new macro variable as
A. Miller. Use the %PUT statement to display the results.
12. Using the %SYSFUNC Function
Use the %PUT statement and the %SYSFUNC function to display the current date and time. Format
the date with the MMDDYYP10. format and the time with the TIMEAMPM. format.
Level 2
13. Using Macro Functions
a. Open the m102e13 program shown below into the Editor window. Submit the program
and examine the output that it creates. Verify the titles.
%let d=&sysdate9;
%let t=&systime;
proc print data=orion.product_dim;
where Product_Name contains "Jacket";
var Product_Name Product_ID Supplier_Name;
title1 "Product Names Containing 'Jacket'";
title2 "Report produced &t &d";
run;
b. Submit a %LET statement to assign the value R&D to a macro variable named product. Reference
the new macro variable in the WHERE statement and the TITLE1 statement. Submit the modified
program.
PROC PRINT Output
Product Names Containing 'R&D'
Report produced 14:06 17FEB2009
393 Top Men's R&D Ultimate Jacket 240300300070 Top Sports Inc
395 Top R&D Long Jacket 240300300090 Top Sports Inc
Challenge
14. Manipulating Macro Variables
a. Assign your birthdate to a macro variable.
b. Issue a %PUT statement that writes the day of the week that you were born.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-70 Chapter 2 Macro Variables
2.7 Solutions
Solutions to Exercises
1. Displaying Automatic Macro Variables
a. The _AUTOMATIC_ argument in the %PUT statement displays the values of all automatic macro
variables in the SAS log. Many of the values shown are dependent on the host system.
%put _automatic_;
b. The value of SYSLAST is _NULL_ unless a data set has been created. Then it is the name
of the last created data set. The value of SYSUSERID is dependent on the host system. The value
of SYSTIME and SYSDATE9 is the initialization time of your SAS session.
c. The values of SYSTIME and SYSDATE do not reflect the current time and date. Instead, they
reflect the initialization time of the SAS session. Therefore, the values are not always accurate.
2. Using Automatic Macro Variables
a. Using the SORT procedure, sort the data set orion.continent by Continent_Name.
proc sort data=orion.continent out=sorted;
by Continent_Name;
run;
b. The SYSLAST automatic macro variable contains the name of the most recently created data set.
proc print data=&syslast;
title "&syslast";
run;
c. Submit the program and examine the results.
SAS Output
WORK.SORTED
Continent_
Obs ID Continent_Name
1 94 Africa
2 95 Asia
3 96 Australia/Pacific
4 93 Europe
5 91 North America
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.7 Solutions 2-71
run;
4. Using SAS Date Constants
a. Open the program into the Editor window.
b. Modify the program so that it subsets the data to return only the employees hired between
January 1, 2007, and today. Use the automatic macro variable SYSDATE9 to return today’s date.
proc print data=orion.employee_payroll;
format Birth_Date Employee_Hire_Date date9.;
where Employee_Hire_Date between '01jan2007'd and
"&sysdate"d;
run;
5. Defining and Using Macro Variables for Character Substitution
a. Submit the program below.
proc print data=orion.customer_dim;
var Customer_Name Customer_Gender Customer_Age;
where Customer_Group contains "Gold";
title "Gold Customers";
run;
Customer_ Customer_
Obs Customer_Name Gender Age
2 Sandrina Stephano F 28
3 Cornelia Krahl F 33
7 Markus Sepke M 19
11 Oliver S. Füßling M 43
b. The macro variable type should contain the text string Gold without any surrounding quotation
marks. To resolve the macro variable in the WHERE and TITLE statements, change the single
quotation marks to double quotation marks. It produces the same output as before.
%let type=Gold;
proc print data=orion.customer_dim;
var Customer_Name Customer_Gender Customer_Age;
where Customer_Group contains "&type";
title "&type Customers";
run;
c. Turn on the SYMBOLGEN option.
options symbolgen;
%let type=Gold;
proc print data=orion.customer_dim;
var Customer_Name Customer_Gender Customer_Age;
where Customer_Group contains "&type";
title "&type Customers";
run;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-72 Chapter 2 Macro Variables
NOTE: There were 8 observations read from the data set ORION.CUSTOMER_DIM.
WHERE customer_group contains 'Internet';
NOTE: PROCEDURE PRINT used (Total process time):
real time 5.04 seconds
cpu time 0.01 seconds
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.7 Solutions 2-73
NOTE: There were 7 observations read from the data set ORION.CUSTOMER_DIM.
WHERE customer_group contains 'Gold' and (Customer_Age>=20 and Customer_Age<=30);
Your solution could be different. It depends on the macro variables created during
the current SAS session.
c. Use the %PUT statement to verify that the macro variable deletion is successful.
%put _user_;
8. Consecutive Macro Variable References
a. Open the program into the Editor window.
b. Modify the program so that the two occurrences of AUG and 2006 are replaced by references
to the macro variables month and year, respectively.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-74 Chapter 2 Macro Variables
%let month=AUG;
%let year=2006;
proc print data=orion.organization_dim;
where Employee_Hire_Date="01&month&year"d;
id Employee_ID;
var Employee_Name Employee_Country Employee_Hire_Date;
title "Personal Information for Employees Hired in "
"&month &year";
run;
c. Modify the value of month to JUL and year to 2003. Resubmit the program.
%let month=JUL;
%let year=2003;
proc print data=orion.organization_dim;
where Employee_Hire_Date="01&month&year"d;
id Employee_ID;
var Employee_Name Employee_Country Employee_Hire_Date;
title "Personal Information for Employees Hired in "
"&month &year";
run;
9. Macro Variable References with Delimiters
a. Open the program into the Editor window.
b. Modify the program so that all occurrences of Organization and Employee are replaced with macro
variable references called dsn and var, respectively. Submit the program and verify the output.
%let dsn=Organization;
%let var=Employee;
proc print data=orion.&dsn._dim;
id &var._ID;
var &var._Name &var._Country &var._Gender;
title "Listing of All &var.s From Orion.&dsn ._Dim";
run;
c. Modify the value of dsn to Customer and var to Customer. Resubmit the program
%let dsn=Customer;
%let var=Customer;
proc print data=orion.&dsn._dim;
id &var._ID;
var &var._Name &var._Country &var._Gender;
title "Listing of All &var.s From Orion.&dsn._Dim";
run;
10. Macro Variable References with Multiple Delimiters
a. Open the program into the Editor window.
b. Using a macro variable, modify the program to return the employees with the most or least amount
of seniority.
proc sort data=orion.staff out=staffhires;
by Job_Title Emp_Hire_Date;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.7 Solutions 2-75
run;
data &seniority.Hired;
set staffhires;
by Job_Title;
if &seniority..Job_Title;
run;
proc print data=&seniority.Hired;
id Job_Title;
var Employee_ID Emp_Hire_Date;
title "&seniority Employee Hired within Each Job Title";
run;
11. Using the %SUBSTR and %SCAN Functions
a. Submit a %LET statement to assign the value Anthony Miller to a macro variable named fullname.
%let fullname=Anthony Miller;
b. Extract the first initial and last name, putting them together into a new variable as A. Miller.
%let newname=%substr(&fullname,1,1). %scan(&fullname,2);
%put &newname;
Alternate Solution
%let initial=%substr(&fullname,1,1);
%let last=%scan(&fullname,2);
%let newname=&initial.. &last;
%put &newname;
12. Using the %SYSFUNC Function
Use the %PUT statement and the %SYSFUNC function to display the current date and time. Format
the date with the MMDDYYP10. format and the time with the TIMEAMPM. format.
%put Today is %sysfunc(today(), mmddyyp10.) and time is
%sysfunc(time(), timeampm.);
13. Using Macro Functions
a. Open the program into the Editor window.
b. The %NRSTR function is required to prevent macro variable resolution.
%let d=&sysdate9;
%let t=&systime;
%let product=%nrstr(R&D);
proc print data=orion.product_dim;
where Product_Name contains "&product";
var Product_Name Product_ID Supplier_Name;
title1 "Product Names Containing '&product'";
title2 "Report produced &t &d";
run;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-76 Chapter 2 Macro Variables
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.7 Solutions 2-77
11
21
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-78 Chapter 2 Macro Variables
m102d01
38
50
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.7 Solutions 2-79
%let x=15;
%let y=10;
%let z=&x-&y;
82
91
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-80 Chapter 2 Macro Variables
107
missing period
What is the problem this time?
The period after &LIB is interpreted as a delimiter,
so the period does not appear as text.
111
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.7 Solutions 2-81
120
%let x=%substr("ABCD",2,1);
126
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-82 Chapter 2 Macro Variables
m102d08
137
144
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
Chapter 3 Macro Definitions
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Defining and Calling a Macro 3-3
Objectives
Define the purpose of a macro definition.
Specify the steps for creating and storing a macro.
Identify the steps for calling a macro.
Investigate the program flow of a macro call.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-4 Chapter 3 Macro Definitions
Defining a Macro
This code defines the Time macro, which displays
the current time.
%macro time;
%put The current time is %sysfunc
(time(),timeampm.).;
%mend time;
%MACRO macro-name;
macro-text
%MEND <macro-name>;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Defining and Calling a Macro 3-5
Macro Compilation
To verify macro compilation, specify
the MCOMPILENOTE=ALL option.
OPTIONS MCOMPILENOTE=ALL|NONE;
options mcompilenote=all;
%macro time;
%put The current time is %sysfunc
(time(),timeampm.).;
%mend time;
SAS Log
1 options mcompilenote=all;
2 %macro time;
3 %put The current time is %sysfunc
4 (time(),timeampm.).;
5 %mend time;
NOTE: The macro TIME completed compilation without errors.
3 instructions 76 bytes.
8
The default value is MCOMPILENOTE=NONE. m103d01
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-6 Chapter 3 Macro Definitions
Calling a Macro
To call a macro, precede the macro name with
a percent sign (%).
%time
%macro-name
SAS Log
178 %time
The current time is 2:49:39 PM.
A macro call
can appear anywhere (similar to a macro variable
reference)
represents a macro trigger
is passed to the macro processor
is not a statement (no semicolon required)
m103d01
9 causes the macro to execute.
3.01 Poll
Does the macro call below require a semicolon?
%Time
Yes
No
10
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Defining and Calling a Macro 3-7
Macro Storage
To display a list of compiled macros in a SAS catalog,
use the CONTENTS statement in PROC CATALOG.
proc catalog cat=work.sasmacr;
contents;
title "My Temporary Macros";
quit;
m103d02
12
The following code copies macro source code saved with the SOURCE option to the SAS log:
%copy time / source;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-8 Chapter 3 Macro Definitions
m103d03
14
The macro processor searches the work.sasmacr catalog first, followed by the SASMSTORE=
catalog.
Business Scenario
To minimize typing, create the Calc macro below.
%macro calc;
proc means data=orion.order_fact;
run;
%mend calc;
m103d04a
15
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Defining and Calling a Macro 3-9
%calc
Input Stack
16
continued...
Pause Resume
Pauses while the word Resumes execution
scanner tokenizes of macro language
inserted text, and SAS statements, if any
code, if any, compiles
and executes
17
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-10 Chapter 3 Macro Definitions
SAS Log
OPTIONS MPRINT;
1300 options mprint;
1301 %calc
MPRINT(CALC): proc means data=orion.order_fact;
MPRINT(CALC): run;
Macro-generated code is treated as a series of tokens. The MPRINT option writes each statement
to a new line without indention.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Defining and Calling a Macro 3-11
Business Scenario
For greater flexibility, revise the Calc macro as shown below.
%macro calc;
proc means data=
%mend calc;
m103d04b
20
%macro calc;
proc means data=
%mend calc;
%calc
orion.order_fact;
run;
m103d04b
21
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-12 Chapter 3 Macro Definitions
m103d04b
22
%calc;
orion.order_fact;
run;
m103d04b
23
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Defining and Calling a Macro 3-13
Compiler
24 ...
Compiler
25 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-14 Chapter 3 Macro Definitions
Compiler
26 ...
Compiler
27 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Defining and Calling a Macro 3-15
Compiler
proc means data=;
28 ...
Compiler
proc means data=;
29 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-16 Chapter 3 Macro Definitions
1206 run;
NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE MEANS used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
m103d04b
30
Business Scenario
Revise the Calc macro again to enable easy and flexible
selection of the data set name and variable name(s).
%macro calc;
proc means data= ;
var ;
run;
%mend calc;
m103d04c
31
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Defining and Calling a Macro 3-17
m103d04c
32
Macro variable references within a macro definition resolve during macro execution,
not compilation.
Placing a semicolon after a macro call might insert an inappropriate semicolon into the resulting
program, leading to errors during compilation or execution.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-18 Chapter 3 Macro Definitions
34 ...
35 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Defining and Calling a Macro 3-19
36 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-20 Chapter 3 Macro Definitions
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Defining and Calling a Macro 3-21
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-22 Chapter 3 Macro Definitions
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Defining and Calling a Macro 3-23
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-24 Chapter 3 Macro Definitions
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Defining and Calling a Macro 3-25
Macro Execution
SAS Log
52 %let stats=min max;
53 %let vars=quantity;
54 %calc
NOTE: There were 617 observations read from the data set ORION.ORDER_FACT.
NOTE: PROCEDURE MEANS used (Total process time):
real time 0.03 seconds
cpu time 0.03 seconds
m103d04c
48
50 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-26 Chapter 3 Macro Definitions
51 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Defining and Calling a Macro 3-27
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-28 Chapter 3 Macro Definitions
Exercises
Level 1
Level 2
2. Storing a Macro
a. Open the m103e02 program shown below into the Editor window.
%macro tut;
king tut
%mend tut;
b. Submit the macro definition and check the SAS log.
c. In the SAS Explorer window, navigate to the sasmacr catalog within the work library to locate
the Tut macro. In SAS Enterprise Guide, use PROC CATALOG.
Challenge
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Defining and Calling a Macro 3-29
a. Define a macro that issues the current time of day with the TIMEAMPM. format. Name
the macro Currtime. Submit the macro definition.
b. Open the m103e03 program shown below into the Editor window. Add a TITLE2 statement.
Call the Currtime macro from the TITLE2 statement. Submit the program and examine
the output.
proc print data=orion.customer_dim(obs=10);
var Customer_Name Customer_Group;
title 'Customer List';
run;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-30 Chapter 3 Macro Definitions
Objectives
Define and call macros with parameters.
Describe the difference between positional parameters
and keyword parameters.
58
Review
Example: Notice macro variable references within
the Calc macro.
%macro calc;
proc means data=&dsn;
var &vars;
run;
%mend calc;
m103d04c
59
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.2 Macro Parameters 3-31
Business Scenario
Simplify the Calc macro so that it can be called with one
line of code instead of three.
%let dsn=orion.order_fact;
%let vars=quantity; three lines of code
%calc
m103d04c
61
Parameter Lists
A parameter list is a list of macro variables referenced
within the macro. There are three types of parameter lists:
positional
keyword
mixed
62
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-32 Chapter 3 Macro Definitions
Positional Parameters
A positional parameter list defines macro parameters
in a particular order. Parameter names are supplied
when the macro is defined.
%macro calc(dsn,vars);
proc means data=&dsn;
var &vars;
run;
%mend calc;
%MACRO macro-name(parameter-1, … parameter-n);
macro text
%MEND <macro-name>;
m103d05
63
Positional Parameters
Parameter values are supplied when the macro is called.
%macro calc(dsn,vars);
proc means data=&dsn;
var &vars;
run;
%mend calc;
%calc(orion.order_fact,quantity)
%macro-name(value-1, … value-n)
To assign a null value to one or more positional parameters, use commas as placeholders
for the omitted values.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.2 Macro Parameters 3-33
66
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-34 Chapter 3 Macro Definitions
Positional Parameters
Example: Define and call a macro with positional
parameters.
%macro count(opts, start, stop);
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(nocum,01jan2008,31dec2008)
%count(,01jul2008,31dec2008)
m103d06a
68
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.2 Macro Parameters 3-35
m103d06a
Use positional parameters to specify a range of dates and TABLE statement options for
the FREQ procedure.
%macro count(opts, start, stop);
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(nocum,01jan2008,31dec2008)
%count(,01jul2008,31dec2008)
51 %count(,01jul2008,31dec2008)
MPRINT(COUNT): proc freq data=orion.orders;
MPRINT(COUNT): where order_date between "01jul2008"d and "31dec2008"d;
MPRINT(COUNT): table order_type / ;
MPRINT(COUNT): title1 "Orders from 01jul2008 to 31dec2008";
MPRINT(COUNT): run;
NOTE: There were 40 observations read from the data set ORION.ORDERS.
WHERE (order_date>='01JUL2008'D and order_date<='31DEC2008'D);
NOTE: PROCEDURE FREQ used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-36 Chapter 3 Macro Definitions
Business Scenario
For additional convenience, assign default values
to macro parameters.
Positional
X
parameters
Keyword
parameters
70
Keyword Parameters
Keyword parameters are assigned a default value after
an equal sign (=).
%macro count(opts=,start=01jan08,stop=31dec08);
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;
%MACRO macro-name(keyword=value, …, keyword=value);
macro text
%MEND <macro-name>;
m103d06b
71
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.2 Macro Parameters 3-37
Keyword Parameters
Call a macro with keyword parameters.
%macro count(opts=,start=01jan08,stop=31dec08);
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=01jul08,opts=nocum nopercent)
%count()
%macro-name(k eyword=value, …, keyword=value)
Keyword parameters can appear in any order and can be
omitted from the call without placeholders. If omitted from
the call, a keyword parameter receives its default value.
m103d06b
72
Specifying %macro-name without the parentheses might not execute the macro immediately.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-38 Chapter 3 Macro Definitions
m103d06b
Alter the previous macro by using keyword parameters. Issue various calls to the macro.
%macro count(opts=,start=01jan08,stop=31dec08);
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=01jul08,opts=nocum nopercent)
%count()
Partial SAS Log
64 %count(opts=nocum)
MPRINT(COUNT): proc freq data=orion.orders;
MPRINT(COUNT): where order_date between "01jan08"d and "31dec08"d;
MPRINT(COUNT): table order_type / nocum;
MPRINT(COUNT): title1 "Orders from 01jan08 to 31dec08";
MPRINT(COUNT): run;
NOTE: There were 87 observations read from the data set ORION.ORDERS.
WHERE (order_date>='01JAN2008'D and order_date<='31DEC2008'D);
NOTE: PROCEDURE FREQ used (Total process time):
real time 0.03 seconds
cpu time 0.03 seconds
65 %count(stop=01jul08,opts=nocum nopercent)
MPRINT(COUNT): proc freq data=orion.orders;
MPRINT(COUNT): where order_date between "01jan08"d and "01jul08"d;
MPRINT(COUNT): table order_type / nocum nopercent;
MPRINT(COUNT): title1 "Orders from 01jan08 to 01jul08";
MPRINT(COUNT): run;
NOTE: There were 47 observations read from the data set ORION.ORDERS.
WHERE (order_date>='01JAN2008'D and order_date<='01JUL2008'D);
NOTE: PROCEDURE FREQ used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
66 %count()
MPRINT(COUNT): proc freq data=orion.orders;
MPRINT(COUNT): where order_date between "01jan08"d and "31dec08"d;
MPRINT(COUNT): table order_type / ;
MPRINT(COUNT): title1 "Orders from 01jan08 to 31dec08";
MPRINT(COUNT): run;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.2 Macro Parameters 3-39
NOTE: There were 87 observations read from the data set ORION.ORDERS.
WHERE (order_date>='01JAN2008'D and order_date<='31DEC2008'D);
NOTE: PROCEDURE FREQ used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-40 Chapter 3 Macro Definitions
%dog()
74
Business Scenario
A parameter list can contain a mix of positional
and keyword parameters.
76
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.2 Macro Parameters 3-41
m103d06c
77
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-42 Chapter 3 Macro Definitions
m103d06c
Alter the previous macro by using a mixed parameter list. Issue various calls to the macro.
%macro count(opts,start=01jan08,stop=31dec08);
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(nocum)
%count(stop=30jun08,start=01apr08)
%count(nocum nopercent,stop=30jun08)
%count()
77 %count(stop=30jun08,start=01apr08)
MPRINT(COUNT): proc freq data=orion.orders;
MPRINT(COUNT): where order_date between "01apr08"d and "30jun08"d;
MPRINT(COUNT): table order_type / ;
MPRINT(COUNT): title1 "Orders from 01apr08 to 30jun08";
MPRINT(COUNT): run;
NOTE: There were 28 observations read from the data set ORION.ORDERS.
WHERE (order_date>='01APR2008'D and order_date<='30JUN2008'D);
NOTE: PROCEDURE FREQ used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.2 Macro Parameters 3-43
78 %count(nocum nopercent,stop=30jun08)
MPRINT(COUNT): proc freq data=orion.orders;
MPRINT(COUNT): where order_date between "01jan08"d and "30jun08"d;
MPRINT(COUNT): table order_type / nocum nopercent;
MPRINT(COUNT): title1 "Orders from 01jan08 to 30jun08";
MPRINT(COUNT): run;
NOTE: There were 47 observations read from the data set ORION.ORDERS.
WHERE (order_date>='01JAN2008'D and order_date<='30JUN2008'D);
NOTE: PROCEDURE FREQ used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
79 %count()
MPRINT(COUNT): proc freq data=orion.orders;
MPRINT(COUNT): where order_date between "01jan08"d and "31dec08"d;
MPRINT(COUNT): table order_type / ;
MPRINT(COUNT): title1 "Orders from 01jan08 to 31dec08";
MPRINT(COUNT): run;
NOTE: There were 87 observations read from the data set ORION.ORDERS.
WHERE (order_date>='01JAN2008'D and order_date<='31DEC2008'D);
NOTE: PROCEDURE FREQ used (Total process time):
real time 0.03 seconds
cpu time 0.03 seconds
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-44 Chapter 3 Macro Definitions
Exercises
Level 1
Level 2
a. Open the m103e05 program shown below into the Editor window.
options nolabel;
title 'Order Stats';
proc means data=orion.order_fact maxdec=2 mean;
var total_retail_price;
class order_type;
run;
title;
b. Create a macro with keyword parameters that generalize the code so that the following attributes
are controlled by macro variables. Choose default values for all parameters so that the code
executes correctly.
Statistics: any combination of N, NMISS, MIN, MEAN, MAX, RANGE, or a null value
Decimal places: 0, 1, 2, 3, or 4
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.2 Macro Parameters 3-45
Challenge
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-46 Chapter 3 Macro Definitions
3.3 Solutions
Solutions to Exercises
1. Defining and Calling a Macro
a. Open the program into the Editor window.
b. Convert the program into a macro named Customers. Set the MCOMPILENOTE= option
and add %MACRO and %MEND statements to create a macro definition.
options mcompilenote=all;
%macro customers;
proc print data=orion.customer_dim;
var Customer_Name Customer_Gender Customer_Age;
where Customer_Group contains "&type";
title "&type Customers";
run;
%mend customers;
SAS Log
1 options mcompilenote=all;
2 %macro customers;
3 proc print data=orion.customer_dim;
4 var Customer_Name Customer_Gender Customer_Age;
5 where Customer_Group contains "&type";
6 title "&type Customers";
7 run;
8 %mend customers;
NOTE: The macro CUSTOMERS completed compilation without errors.
3 instructions 188 bytes.
c. Submit a %LET statement to assign the value Gold to the macro variable type. Call the macro
by preceding its name with a percent sign.
%let type=Gold;
%customers
SAS Log
10 %let type=Gold;
11 %customers
NOTE: There were 21 observations read from the data set ORION.CUSTOMER_DIM.
WHERE customer_group contains 'Gold';
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.67 seconds
cpu time 0.18 seconds
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.3 Solutions 3-47
options mprint;
%customers
SAS Log
12 options mprint;
13 %customers
MPRINT(CUSTOMERS): proc print data=orion.customer_dim;
MPRINT(CUSTOMERS): var Customer_Name Customer_Gender Customer_Age;
MPRINT(CUSTOMERS): where Customer_Group contains "Internet";
MPRINT(CUSTOMERS): title "Internet Customers";
MPRINT(CUSTOMERS): run;
NOTE: There were 8 observations read from the data set ORION.CUSTOMER_DIM.
WHERE customer_group contains 'Internet';
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
2. Storing a Macro
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-48 Chapter 3 Macro Definitions
options mcompilenote=all;
%macro customers(type);
proc print data=orion.customer_dim;
var Customer_Name Customer_Gender Customer_Age;
where Customer_Group contains "&type";
title "&type Customers";
run;
%mend customers;
c. To execute the macro, use a percent sign followed by the name of the macro. To assign a value
to a positional parameter, supply the desired value within parentheses following the macro name.
options mprint;
%customers(Gold)
SAS Log
178 %customers(Gold)
MPRINT(CUSTOMERS): proc print data=orion.customer_dim;
MPRINT(CUSTOMERS): var Customer_Name Customer_Gender Customer_Age;
MPRINT(CUSTOMERS): where Customer_Group contains "Gold";
MPRINT(CUSTOMERS): title "Gold Customers";
MPRINT(CUSTOMERS): run;
NOTE: There were 21 observations read from the data set ORION.CUSTOMER_DIM.
WHERE customer_group contains 'Gold';
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.14 seconds
cpu time 0.00 seconds
Customer_ Customer_
Obs Customer_Name Gender Age
2 Sandrina Stephano F 28
3 Cornelia Krahl F 33
7 Markus Sepke M 19
11 Oliver S. Füßling M 43
17 Cynthia Martinez F 48
21 Alphone Greenwald M 23
24 Dianne Patchin F 28
25 Annmarie Leveille F 23
26 Gert-Gunter Mendler M 73
31 Carsten Maestrini M 63
32 James Klisurich M 38
35 Viola Folsom F 38
40 Kyndal Hooks F 43
46 Ramesh Trentholme M 58
48 Avni Umran M 28
53 Sanelisiwe Collier F 19
57 Rita Lotz F 43
58 Bill Cuddy M 21
62 Susan Krasowski F 48
64 Avinoam Tuvia M 23
75 Angel Borwick F 38
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.3 Solutions 3-49
d. The macro definition does not need to be resubmitted with each macro call. The macro call does
not end with a semicolon.
%customers(Catalog)
SAS Log
179 %customers(Catalog)
MPRINT(CUSTOMERS): proc print data=orion.customer_dim;
MPRINT(CUSTOMERS): var Customer_Name Customer_Gender Customer_Age;
MPRINT(CUSTOMERS): where Customer_Group contains "Catalog";
MPRINT(CUSTOMERS): title "Catalog Customers";
MPRINT(CUSTOMERS): run;
NOTE: There were 8 observations read from the data set ORION.CUSTOMER_DIM.
WHERE customer_group contains 'Catalog';
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
Customer_ Customer_
Obs Customer_Name Gender Age
8 Ulrich Heyde M 68
13 Tulio Devereaux M 58
14 Robyn Klem F 48
15 Cynthia Mccluney F 38
16 Candy Kinsey F 73
20 Phenix Hill M 43
59 Avinoam Zweig M 48
67 Lauren Marx F 38
e. When you define keyword parameters, an equal sign (=) must follow the name of each parameter.
A default value for each parameter can be specified following the equal sign.
%macro customers(type=Club);
proc print data=orion.customer_dim;
var Customer_Name Customer_Gender Customer_Age;
where Customer_Group contains "&type";
title "&type Customers";
run;
%mend customers;
f. To assign a value to a keyword parameter, specify the name of the parameter followed by an equal
sign (=), followed by the desired value.
%customers(type=Internet)
SAS Log
180 %customers(type=Internet)
MPRINT(CUSTOMERS): proc print data=orion.customer_dim;
MPRINT(CUSTOMERS): var Customer_Name Customer_Gender Customer_Age;
MPRINT(CUSTOMERS): where Customer_Group contains "Internet";
MPRINT(CUSTOMERS): title "Internet Customers";
MPRINT(CUSTOMERS): run;
NOTE: There were 8 observations read from the data set ORION.CUSTOMER_DIM.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-50 Chapter 3 Macro Definitions
Customer_ Customer_
Obs Customer_Name Gender Age
8 Ulrich Heyde M 68
13 Tulio Devereaux M 58
14 Robyn Klem F 48
15 Cynthia Mccluney F 38
16 Candy Kinsey F 73
20 Phenix Hill M 43
59 Avinoam Zweig M 48
67 Lauren Marx F 38
g. To request that all default parameter values be used, follow the macro call with empty
parentheses.
%customers()
SAS Log
189 %customers()
MPRINT(CUSTOMERS): proc print data=orion.customer_dim;
MPRINT(CUSTOMERS): var Customer_Name Customer_Gender Customer_Age;
MPRINT(CUSTOMERS): where Customer_Group contains "Club";
MPRINT(CUSTOMERS): title "Club Customers";
MPRINT(CUSTOMERS): run;
NOTE: There were 69 observations read from the data set ORION.CUSTOMER_DIM.
WHERE customer_group contains 'Club';
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
(var=total_retail_price,class=order_type,stats=mean,decimals=2
);
options nolabel;
title 'Order Stats';
proc means data=orion.order_fact maxdec=&decimals &stats;
var &var;
class &class;
run;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.3 Solutions 3-51
title;
%mend orderstats;
c. Execute the macro using the default parameter values.
%orderstats()
SAS Log
85 %orderstats()
MPRINT(ORDERSTATS): options nolabel;
MPRINT(ORDERSTATS): title 'Order Stats';
MPRINT(ORDERSTATS): proc means data=orion.order_fact maxdec=2 mean;
MPRINT(ORDERSTATS): var total_retail_price;
MPRINT(ORDERSTATS): class order_type;
MPRINT(ORDERSTATS): run;
MPRINT(ORDERSTATS): title;
d. Call the macro again, but override all default parameter values.
%orderstats(var=costprice_per_unit, class=quantity, stats=min mean max, decimals=0)
SAS Log
86 %orderstats(var=costprice_per_unit, class=quantity, stats=min mean max, decimals=0)
MPRINT(ORDERSTATS): options nolabel;
MPRINT(ORDERSTATS): title 'Order Stats';
MPRINT(ORDERSTATS): proc means data=orion.order_fact maxdec=0 min mean max;
MPRINT(ORDERSTATS): var costprice_per_unit;
MPRINT(ORDERSTATS): class quantity;
MPRINT(ORDERSTATS): run;
MPRINT(ORDERSTATS): title;
e. Call the macro again, but override only the default parameter values for statistics and decimal
places.
SAS Log
87 %orderstats(stats=min mean max, decimals=0)
MPRINT(ORDERSTATS): options nolabel;
MPRINT(ORDERSTATS): title 'Order Stats';
MPRINT(ORDERSTATS): proc means data=orion.order_fact maxdec=0 min mean max;
MPRINT(ORDERSTATS): var total_retail_price;
MPRINT(ORDERSTATS): class order_type;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-52 Chapter 3 Macro Definitions
MPRINT(ORDERSTATS): run;
MPRINT(ORDERSTATS): title;
a. Open the program into the Editor window. Submit the program to compile the macro.
b. The %STR function is required to prevent a special character such as a comma from
being misinterpreted as a parameter delimiter on the macro call.
options mprint;
%specialchars(%str(Abbott, Ray))
SAS Log
63 %specialchars(%str(Abbott, Ray))
MPRINT(SPECIALCHARS): proc print data=orion.employee_addresses;
MPRINT(SPECIALCHARS): where Employee_Name="Abbott, Ray";
MPRINT(SPECIALCHARS): var Employee_ID Street_Number Street_Name City State Postal_Code;
MPRINT(SPECIALCHARS): title "Data for Abbott, Ray";
MPRINT(SPECIALCHARS): run;
NOTE: There were 1 observations read from the data set ORION.EMPLOYEE_ADDRESSES.
WHERE Employee_Name='Abbott, Ray';
NOTE: PROCEDURE PRINT used (Total process time):
real time 2.51 seconds
cpu time 0.00 seconds
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.3 Solutions 3-53
%Time
Yes
No
11
67
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-54 Chapter 3 Macro Definitions
%dog
75
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
Chapter 4 DATA Step and SQL
Interfaces
Exercises............................................................................................................. 4-36
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.1 Creating Macro Variables in the DATA Step 4-3
Objectives
Create macro variables during DATA step execution.
Describe the difference between the SYMPUTX
routine and the %LET statement.
Business Scenario
Automate production of the report below, with a footnote
that indicates whether there are any Internet orders.
Orders for 2-2011
1 05FEB2011 1 1 $117.60
2 07FEB2011 1 2 $656.60
3 07FEB2011 1 2 $129.00
4 09FEB2011 1 2 $36.20
5 16FEB2011 1 1 $29.40
6 28FEB2011 1 5 $192.00
No Internet Orders
Many applications require macro variables to store values based on data, programming logic,
or expressions.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-4 Chapter 4 DATA Step and SQL Interfaces
data orders;
keep order_date order_type quantity total_retail_price;
set orion.order_fact end=final;
where year(order_date)=&year and month(order_date)=&month;
if order_type=3 then Number+1;
if final then do;
put Number=;
if Number=0 then do;
%let foot=No Internet Orders;
end;
else do;
%let foot=Some Internet Orders;
end;
end;
run;
1 05FEB2011 1 1 $117.60
2 07FEB2011 1 2 $656.60
3 07FEB2011 1 2 $129.00
4 09FEB2011 1 2 $36.20
5 16FEB2011 1 1 $29.40
6 28FEB2011 1 5 $192.00
m104d01a
6
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.1 Creating Macro Variables in the DATA Step 4-5
7 ...
Symbol Table
month 2
year 2011
8 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-6 Chapter 4 DATA Step and SQL Interfaces
data orders;
keep order_date order_type quantity total_retail_price;
set orion.order_fact end=final;
where year(order_date)=2011 and month(order_date)=2;
if order_type=3 then Number+1;
if final then do; Symbol Table
put Number=;
month
month 22
if Number=0 then do;
%let foot=No Internet Orders; year
year
2011
2011
end; foot No Internet Orders
else do; foot No Internet Orders
%let foot=Some Internet Orders;
end;
end;
run;
9 ...
data orders;
keep order_date order_type quantity total_retail_price;
set orion.order_fact end=final;
where year(order_date)=2011 and month(order_date)=2;
if order_type=3 then Number+1;
if final then do; Symbol Table
put Number=;
month 22
if Number=0 then do; month
year 2011
year 2011
end; foot No Internet Orders
else do; foot No Internet Orders
%let foot=Some Internet Orders;
end;
end;
run;
10 ...
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.1 Creating Macro Variables in the DATA Step 4-7
data orders;
keep order_date order_type quantity total_retail_price;
set orion.order_fact end=final;
where year(order_date)=2011 and month(order_date)=2;
if order_type=3 then Number+1;
if final then do; Symbol Table
put Number=;
month 2
if Number=0 then do;
year 2011
end; foot Some Internet Orders
else do;
%let foot=Some Internet Orders;
end;
end;
run;
11 ...
%LET statements execute at word-scanning time. SAS statements are sent to the compiler.
data orders;
keep order_date order_type quantity total_retail_price;
set orion.order_fact end=final;
where year(order_date)=2011 and month(order_date)=2;
if order_type=3 then Number+1;
if final then do; Symbol Table
put Number=;
month 2
if Number=0 then do;
year 2011
end; Nothing in this DATA foot Some Internet Orders
else do; step affects the value
end; of FOOT.
end;
run;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-8 Chapter 4 DATA Step and SQL Interfaces
SYMPUTX Routine
The SYMPUTX routine assigns to a macro variable any
value available to the DATA step during execution time.
It can create macro variables with the following:
static values
dynamic (data dependent) values
dynamic (data dependent) names
Symbol Table
The SYMPUTX routine was introduced in SAS®9. In prior versions of SAS, the SYMPUT routine was
available.
data orders;
keep order_date order_type quantity total_retail_price;
set orion.order_fact end=final;
where year(order_date)=&year and month(order_date)=&month;
if order_type=3 then Number+1;
if final then do;
put Number=; CALL SYMPUTX(macro-variable, value);
if Number=0 then do;
call symputx('foot', 'No Internet Orders');
end;
else do;
call symputx('foot', 'Some Internet Orders');
end;
end;
run; fixed m acro fixed m acro no m acro
variable nam e variable value triggers
m104d01b
14
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.1 Creating Macro Variables in the DATA Step 4-9
1 05FEB2011 1 1 $117.60
2 07FEB2011 1 2 $656.60
3 07FEB2011 1 2 $129.00
4 09FEB2011 1 2 $36.20
5 16FEB2011 1 1 $29.40
6 28FEB2011 1 5 $192.00
No Internet Orders
m104d01b
15
Macro variables created by the SYMPUTX routine are available following DATA step execution
and can be referenced after a step boundary.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-10 Chapter 4 DATA Step and SQL Interfaces
SYMPUTX Routine
m104d01b
Conditionally assign a text value to a macro variable foot based on DATA step values. Reference this
macro variable later in the program.
%let month=2;
%let year=2011;
data orders;
keep order_date order_type quantity total_retail_price;
set orion.order_fact end=final;
where year(order_date)=&year and month(order_date)=&month;
if order_type=3 then Number+1;
if final then do;
put Number=;
if Number=0 then do;
call symputx('foot', 'No Internet Orders');
end;
else do;
call symputx('foot', 'Some Internet Orders');
end;
end;
run;
1 05FEB2011 1 1 $117.60
2 07FEB2011 1 2 $656.60
3 07FEB2011 1 2 $129.00
4 09FEB2011 1 2 $36.20
5 16FEB2011 1 1 $29.40
6 28FEB2011 1 5 $192.00
No Internet Orders
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.1 Creating Macro Variables in the DATA Step 4-11
data _null_;
call symputx('foot','No Internet orders');
%let foot=Some Internet orders;
run;
17
Business Scenario
Enhance the footnote on the previous report to include
the total number of Internet orders.
Orders for 1-2011
1 02JAN2011 3 2 $195.60
2 03JAN2011 1 6 $160.80
3 04JAN2011 1 2 $306.20
4 06JAN2011 3 3 $37.80
5 13JAN2011 1 2 $362.60
6 23JAN2011 1 1 $72.60
7 24JAN2011 1 2 $258.20
8 24JAN2011 1 2 $81.20
9 24JAN2011 1 3 $358.20
10 25JAN2011 3 1 $102.40
11 25JAN2011 3 1 $113.20
12 28JAN2011 3 2 $174.40
13 29JAN2011 2 1 $37.40
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-12 Chapter 4 DATA Step and SQL Interfaces
SYMPUTX Routine
Copy the value of a DATA step variable into a macro variable.
%let month=1;
%let year=2011;
data orders;
keep order_date order_type quantity total_retail_price;
set orion.order_fact end=final;
where year(order_date)=&year and month(order_date)=&month;
if order_type=3 then Number+1;
if final then call symputx('num', Number);
run;
The SYMPUT routine, which remains available, has syntax and functionality that is similar to that
of the SYMPUTX routine. The SYMPUT routine does not trim leading and trailing blanks automatically
from either argument. Therefore, it is often necessary to use TRIM and LEFT functions within the
SYMPUT routine. When assigning numeric values to macro variables, the SYMPUT routine writes
numeric-to-character conversion notes to the log.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.1 Creating Macro Variables in the DATA Step 4-13
SYMPUTX Routine
m104d01c
%let month=1;
%let year=2011;
data orders;
keep order_date order_type quantity total_retail_price;
set orion.order_fact end=final;
where year(order_date)=&year and month(order_date)=&month;
if order_type=3 then Number+1;
if final then call symputx('num', Number);
run;
1 02JAN2011 3 2 $195.60
2 03JAN2011 1 6 $160.80
3 04JAN2011 1 2 $306.20
4 06JAN2011 3 3 $37.80
5 13JAN2011 1 2 $362.60
6 23JAN2011 1 1 $72.60
7 24JAN2011 1 2 $258.20
8 24JAN2011 1 2 $81.20
9 24JAN2011 1 3 $358.20
10 25JAN2011 3 1 $102.40
11 25JAN2011 3 1 $113.20
12 28JAN2011 3 2 $174.40
13 29JAN2011 2 1 $37.40
5 Internet Orders
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-14 Chapter 4 DATA Step and SQL Interfaces
Business Scenario
Further enhance the footnotes by adding the average
Internet order amount and last Internet order date.
Orders for 1-2011
1 02JAN2011 3 2 $195.60
2 03JAN2011 1 6 $160.80
3 04JAN2011 1 2 $306.20
4 06JAN2011 3 3 $37.80
5 13JAN2011 1 2 $362.60
6 23JAN2011 1 1 $72.60
7 24JAN2011 1 2 $258.20
8 24JAN2011 1 2 $81.20
9 24JAN2011 1 3 $358.20
10 25JAN2011 3 1 $102.40
11 25JAN2011 3 1 $113.20
12 28JAN2011 3 2 $174.40
13 29JAN2011 2 1 $37.40
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.1 Creating Macro Variables in the DATA Step 4-15
SYMPUTX Routine
m104d01d
%let month=1;
%let year=2011;
data orders;
keep order_date order_type quantity total_retail_price;
set orion.order_fact end=final;
where year(order_date)=&year and month(order_date)=&month;
if order_type=3 then do;
Number+1;
Amount+total_retail_price;
Date=order_date;
retain date;
end;
if final then do;
if number=0 then do;
call symputx('dat', 'N/A');
call symputx('avg', 'N/A');
end;
else do;
call symputx('dat', put(date,mmddyy10.));
call symputx('avg', put(amount/number,dollar8.));
end;
end;
run;
proc print data=orders;
title "Orders for &month-&year";
footnote1 "Average Internet Order: &avg";
footnote2 "Last Internet Order: &dat";
run;
The PUT function returns a character string by writing a value with a specified format.
You can use the PUT function to do the following:
format the result of a numeric expression
perform explicit numeric-to-character conversion
PUT(source, format)
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-16 Chapter 4 DATA Step and SQL Interfaces
format is any SAS format or user-defined format. It determines the width of the resulting string
and whether the string is right-aligned or left-aligned. The type for format must match the type
for source.
PROC PRINT Output
Orders for 1-2007
1 02JAN2011 3 2 $195.60
2 03JAN2011 1 6 $160.80
3 04JAN2011 1 2 $306.20
4 06JAN2011 3 3 $37.80
5 13JAN2011 1 2 $362.60
6 23JAN2011 1 1 $72.60
7 24JAN2011 1 2 $258.20
8 24JAN2011 1 2 $81.20
9 24JAN2011 1 3 $358.20
10 25JAN2011 3 1 $102.40
11 25JAN2011 3 1 $113.20
12 28JAN2011 3 2 $174.40
13 29JAN2011 2 1 $37.40
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.1 Creating Macro Variables in the DATA Step 4-17
24
Business Scenario
Based on user-selected time periods, dynamically compute
statistics for automatic inclusion within the graph below.
27 m104d02
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-18 Chapter 4 DATA Step and SQL Interfaces
28 m104d02
The PUTN function returns a character string by writing a value with a numeric format.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.1 Creating Macro Variables in the DATA Step 4-19
m104d02
%let start=01Jan2011;
%let stop=31Dec2011;
data _null_;
set stats;
call symputx('orders',count);
call symputx('average',avg);
run;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-20 Chapter 4 DATA Step and SQL Interfaces
Exercises
Level 1
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.1 Creating Macro Variables in the DATA Step 4-21
Level 2
Challenge
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-22 Chapter 4 DATA Step and SQL Interfaces
run;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.2 Indirect References to Macro Variables 4-23
Objectives
Reference macro variables indirectly.
Create a series of macro variables using
the SYMPUTX routine.
33
Business Scenario
Create an order history for a given customer. Report
titles should display customer name and number.
34
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-24 Chapter 4 DATA Step and SQL Interfaces
m104d03a
35
m104d03b
36
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.2 Indirect References to Macro Variables 4-25
Birth_
Obs Customer_ID Customer_Name Country Gender Date
37
data _null_;
set orion.customer;
where customer_ID=&custID; same
call symputx('name', Customer_Name); WHERE
run;
statement
proc print data=orion.order_fact;
where customer_ID=&custID;
var order_date order_type quantity total_retail_price;
title1 "Customer Number: &custID";
title2 "Customer Name: &name";
run;
m104d03c
38
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-26 Chapter 4 DATA Step and SQL Interfaces
%let custID=9;
data _null_;
set orion.customer;
where customer_ID=&custID;
call symputx('name', Customer_Name);
run;
proc print data=orion.order_fact;
where customer_ID=&custID;
var order_date order_type quantity total_retail_price;
title1 "Customer Number: &custID";
title2 "Customer Name: &name";
run;
m104d03c
39
41
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.2 Indirect References to Macro Variables 4-27
42
Symbol Table
Variable Value
NAME4 James Kvarniq
NAME5 Sandrina Stephano
NAME9 Cornelia Krahl
.
.
.
43
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-28 Chapter 4 DATA Step and SQL Interfaces
m104d03d
44
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.2 Indirect References to Macro Variables 4-29
%let custID=9;
proc print data=orion.order_fact;
where customer_ID=&custID;
var order_date order_type quantity total_retail_price;
title1 "Customer Number: &custID";
title2 "Customer Name: &name9";
run;
m104d03e
46
%let custID=9;
proc print data=orion.order_fact;
where customer_ID=&custID;
var order_date order_type quantity total_retail_price;
title1 "Customer Number: &custID";
title2 "Customer Name: &name9";
run;
m104a02
47
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-30 Chapter 4 DATA Step and SQL Interfaces
Symbol Table
Variable Value
CUSTID 9
NAME4 James Kvarniq
NAME5 Sandrina Stephano
NAME9
.
Cornelia
.
Krahl
.
. .
.
49
50
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.2 Indirect References to Macro Variables 4-31
m104d03f
51
52
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-32 Chapter 4 DATA Step and SQL Interfaces
Scan sequence:
&&name&custID &name9 Cornelia Krahl
53
54
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.2 Indirect References to Macro Variables 4-33
Is this successful?
m104a03
55
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-34 Chapter 4 DATA Step and SQL Interfaces
m104d04
data _null_;
set orion.customer;
call symputx('name'||left(Customer_ID), customer_Name);
run;
%let custID=9;
proc print data=orion.order_fact;
where customer_ID=&custID;
var order_date order_type quantity total_retail_price;
title1 "Customer Number: &custID";
title2 "Customer Name: &&name&custID";
run;
Partial SAS Log
451 %let custID=9;
452 proc print data=orion.order_fact;
453 where customer_ID=&custID;
SYMBOLGEN: Macro variable CUSTID resolves to 9
454 var order_date order_type quantity total_retail_price;
SYMBOLGEN: Macro variable CUSTID resolves to 9
455 title1 "Customer Number: &custID";
SYMBOLGEN: && resolves to &.
SYMBOLGEN: Macro variable CUSTID resolves to 9
SYMBOLGEN: Macro variable NAME9 resolves to Cornelia Krahl
456 title2 "Customer Name: &&name&custID";
457 run;
NOTE: There were 6 observations read from the data set ORION.ORDER_FACT.
WHERE customer_ID=9;
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.01 seconds
cpu time 0.00 seconds
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.2 Indirect References to Macro Variables 4-35
SYMGET Function
SYMGET
63
SYMGET Function
The SYMGET function retrieves a macro variable’s
value during DATA step execution.
Symbol Table
Program Data Vector
DATA Step SYMGET
Variables
64
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-36 Chapter 4 DATA Step and SQL Interfaces
Exercises
Level 1
%memberlist()
b. The orion.customer_type data set contains the variable Customer_Type_ID, which uniquely
identifies the customer membership level and activity level. Add a DATA step to create a series
of macro variables named typexxxx, where xxxx is the value of Customer_Type_ID. The value
of each type macro variable should be the value of Customer_Type. Place the DATA step before
the macro definition.
Listing of orion.customer_type
c. Modify the TITLE statement so that it displays the appropriate customer type. Use an indirect
macro variable reference to one of the type variables based on the current value of ID. Submit the
modified program.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.2 Indirect References to Macro Variables 4-37
1 James Kvarniq 4 M
10 Tonie Asmussen 18 M
19 Alvan Goheen 34 M
11 Oliver S. Füßling 19 M
21 Alphone Greenwald 39 M
25 Annmarie Leveille 49 F
26 Gert-Gunter Mendler 50 M
Level 2
%put _user_;
%macro memberlist(custtype);
proc print data=orion.customer_dim;
var Customer_Name Customer_ID Customer_Age_Group;
where Customer_Type="&custtype";
title "A List of &custtype";
run;
%mend memberlist;
b. Create a macro variable named num with the value 2010. Call the Memberlist macro. Pass the
appropriate parameter to the Memberlist macro, such that custtype resolves to Orion Club Gold
members low activity on the macro call.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-38 Chapter 4 DATA Step and SQL Interfaces
Customer_
Obs Customer_Name Customer_ID Age_Group
Challenge
b. Open the m104e06 program shown below into the Editor window.
%let code=AU;
proc print data=Orion.Employee_Addresses;
var Employee_Name City;
where Country="&code";
title "A List of xxxxx Employees";
run;
c. Use indirect macro variable referencing to replace the xxxxx with the appropriate country name.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.3 Creating Macro Variables in SQL 4-39
Objectives
Create macro variables during PROC SQL execution.
Store several values in one macro variable using
the SQL procedure.
67
Business Scenario
Create a macro variable that contains the total price
of all 2011 Internet orders.
TOTAL= $6,731
68
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-40 Chapter 4 DATA Step and SQL Interfaces
INTO Clause
The INTO clause creates macro variables from query
results.
Symbol Table
INTO clause
Query Results
69
INTO Clause
This INTO clause creates a single macro variable
named total.
proc sql noprint;
select sum(total_retail_price) format=dollar8.
into :total
from orion.order_fact
where year(order_date)=2011 and order_type=3;
quit;
SELECT col1, col2, ...
%put &=total; INTO :mvar1, :mvar2,...
FROM table-expression
Partial SAS Log WHERE where-expression
ORDER BY col1, col2, . . . ;
TOTAL= $6,731
A %LET statement can be used to trim leading and trailing blanks created by the INTO clause:
%let macrovariable=¯ovariable;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.3 Creating Macro Variables in SQL 4-41
INTO Clause
The INTO clause can create multiple macro variables.
m104d05b
71
INTO Clause
SQL Result
Top 2011 Sales
Total_Retail_
Price Order_Date
Macro variables ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ Macro variables
$1,937.20 06/20/2011
price1 date1
price2 $1,066.40 11/01/2011 date2
price3 $760.80 12/12/2011 date3
Partial SAS Log
1529 %put &price1 &date1, &price2 &date2, &price3 &date3;
$1,937.20 06/20/2011, $1,066.40 11/01/2011, $760.80 12/12/2011
m104d05b
72
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-42 Chapter 4 DATA Step and SQL Interfaces
INTO Clause
Example: Create a macro variable with a list of all
customer countries. Delimit the country
codes with a comma and a space.
proc sql noprint;
select distinct country
into :countries separated by ', '
from orion.customer;
quit;
INTO : macro-variable SEPARATED BY 'delimiters'
%put &=Countries;
data _null_;
set allcountries end=eof;
length countries $ 50;
retain countries;
countries=catx(', ', countries, country);
if eof then call symputx('countries', countries);
run;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.3 Creating Macro Variables in SQL 4-43
74
SQL Procedure
Example: Display user-defined macro variables in a report.
AVERAGE 157.49094595
AVG $125
COUNTRIES AU, CA, DE, IL, TR, US, ZA
CUSTID 9
DAT 01/28/2011
DATE1 06/20/2011
DATE2 11/01/2011
DATE3 12/12/2011
MONTH 1
NAME Cornelia Krahl
ORDERS 148
...
m104d05d
76
The dictionary.macros table is one of several PROC SQL read-only DICTIONARY tables that
store SAS metadata. For additional information, see “Accessing SAS System Information Using
DICTIONARY Tables” under “Programming with the SQL Procedure” in the SQL Procedure
User’s Guide.
An alternative to the SQL query above is the two-step program below that uses sashelp.vmacro in place
of dictionary.macros.
proc sort data=sashelp.vmacro
(keep=name value scope
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-44 Chapter 4 DATA Step and SQL Interfaces
where=(scope='GLOBAL'))
out=mymacrovariables(keep=name value)
sortseq=linguistic(numeric_collation=on);
by name;
run;
SQL Procedure
Example: Create a utility macro to display user-defined
macro variables in a report.
%macro putALL;
proc sql flow;
select name, value
from dictionary.macros
where scope='GLOBAL'
order by name;
quit;
%mend putALL;
m104d05d
77
INTO Clause
Example: Create a macro variable with a list of all
user-defined macro variable names. Delimit
the names with spaces.
proc sql noprint;
select name into: vars separated by ' '
from dictionary.macros
where scope='GLOBAL';
quit;
78
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.3 Creating Macro Variables in SQL 4-45
INTO Clause
Example: Create a utility macro that deletes all
user-defined macro variables.
%macro deleteALL;
%symdel &vars;
%mend deleteALL;
%deleteALL
m104d05e
79
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-46 Chapter 4 DATA Step and SQL Interf aces
Exercises
Level 1
data _null_;
set stats;
call symputx('Quant',put(Avg_Quant,4.2));
call symputx('Price',put(Avg_Price,dollar7.2));
run;
Total_
Order_ Retail_
Order_ID Date Quantity Price
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.3 Creating Macro Variables in SQL 4-47
N = 13
c. Delete the macro variables quant and price from the symbol table.
d. Replace the PROC MEANS step and the DATA step with a PROC SQL step.
e. Resubmit the PROC PRINT step and verify that the output is the same.
Level 2
8. Creating a List of Values in a Macro Variable Using SQL
a. Open the m104e08 program into the Editor window. Create a macro variable named top3 with
the customer ID numbers of the top three customers by Total_Retail_Price. Separate the ID
numbers with a comma and a blank. Use the OUTOBS= option.
proc sql;
select customer_id, sum(Total_Retail_Price) as total
from orion.order_fact
group by Customer_ID
order by total descending;
quit;
Challenge
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-48 Chapter 4 DATA Step and SQL Interfaces
You need two queries, one to return the number of rows that the query returns and the
other to create CTYPE1 through CTYPExx.
b. Open the program m104e09 to display only the macro variables that begin with CTYPE.
proc sql;
select name, value
from dictionary.macros
where name like "CTYPE%";
quit;
PROC SQL Output
Macro Variable beginning with CTYPE
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.4 Solutions 4-49
4.4 Solutions
Solutions to Exercises
1. Creating Macro Variables with the SYMPUTX Routine
a. Open the program into the Editor window.
b. Add a %LET statement before the DATA step to create the macro variable job with the value
Audit. Replace hardcoded values of Audit with references to the macro variable job. Resubmit
the program. It should produce the same output as before.
c. Change the value of job to Analyst. Resubmit the program and examine the new results.
d. Modify the DATA step to create the macro variable avg to store the average salary. Reference
the macro variable avg in a FOOTNOTE statement. Format the average salary with a dollar sign,
comma, and no decimal places.
%let job=Analyst;
data staff;
keep employee_ID job_title salary gender;
set orion.staff end=last;
where job_title contains "&job";
total+salary;
count+1;
if last then call symputx('avg',
put(total/count,dollar9.));
run;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-50 Chapter 4 DATA Step and SQL Interfaces
run;
3. Creating Macro Variables with the SYMPUTX Routine
a. Open the program into the Editor window.
b. Using the customer_sum data set, create a single macro variable, top3, that contains
the customer IDs of the top three customers by revenue.
data _null_;
set customer_sum(obs=3) end=last;
length top3 $50;
retain top3;
top3=catx(' ',top3, Customer_ID);
/* Alternative Solution for the CATX Function */
/* top3=trim(top3)||' '||left(Customer_ID); */
if last then call symputx('top3', top3);
run;
c. Using the orion.customer_dim data set, print a listing of the top three customers.
proc print data=orion.customer_dim noobs;
where Customer_ID in (&top3);
var Customer_ID Customer_Name Customer_Type;
title 'Top 3 Customers';
run;
4. Creating a Series of Macro Variables with the SYMPUTX Routine
a. Open the program into the Editor window.
b. Concatenating the character value type with the value of the Customer_Type_ID variable
specifies the name of each macro variable. Because the Customer_Type_ID variable is numeric,
the LEFT function is required to remove the leading blanks introduced by the automatic numeric -
to-character conversion that occurs as part of the SYMPUTX routine. The %PUT statement
displays the names and values of all user-created macro variables.
c. Because each macro variable that contains the customer type has a common root at the start
of its name (type) and a suffix that corresponds to the value of the ID macro variable, two
ampersands are used in front of the complete reference.
data _null_;
set orion.customer_type;
call symputx('type'||left(Customer_Type_ID),
Customer_Type);
*Alternative solution using the CATS function;
*call symputx(cats('type',Customer_Type_ID),
Customer_Type);
run;
%put _user_;
%macro memberlist(id=1020);
title "A List of &&type&id";
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.4 Solutions 4-51
%memberlist()
SAS Log
39 %put _user_;
GLOBAL TYPE1010 Orion Club members inactive
GLOBAL TYPE1020 Orion Club members low activity
GLOBAL TYPE2010 Orion Club Gold members low activity
GLOBAL TYPE1030 Orion Club members medium activity
GLOBAL TYPE2020 Orion Club Gold members medium activity
GLOBAL TYPE3010 Internet/Catalog Customers
GLOBAL TYPE1040 Orion Club members high activity
GLOBAL TYPE2030 Orion Club Gold members high activity
40 options symbolgen;
41 %let id=1020;
42 proc print data=orion.customer;
43 var Customer_Name Customer_ID Gender;
44 where Customer_Type_ID=&id;
SYMBOLGEN: Macro variable ID resolves to 1020
SYMBOLGEN: && resolves to &.
SYMBOLGEN: Macro variable ID resolves to 1020
SYMBOLGEN: Macro variable TYPE1020 resolves to Orion Club members low activity
45 title "A List of &&type&id";
46 run;
NOTE: There were 17 observations read from the data set ORION.CUSTOMER.
WHERE Customer_Type_ID=1020;
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.17 seconds
cpu time 0.00 seconds
%memberlist(id=2030)
NOTE: There were 10 observations read from the data set ORION.CUSTOMER.
WHERE Customer_Type_ID=2030;
NOTE: PROCEDURE PRINT used (Total process time):
real time 1.43 seconds
cpu time 0.00 seconds
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-52 Chapter 4 DATA Step and SQL Interfaces
b. Create a macro variable named num with the value of 2010. Execute the macro so that the value
of custtype resolves to Orion Club members low activity in the macro call.
%let num=2010;
%memberlist(&&type&num)
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.4 Solutions 4-53
d. Replace the PROC MEANS step and the DATA step with a PROC SQL step.
proc sql noprint;
select mean(Quantity) format=4.2,
mean(Total_Retail_Price) format=dollar7.2
into :quant, :price
from orion.order_fact
where order_date between "&start"d and "&stop"d;
quit;
e. Resubmit the PROC PRINT step and verify that the output is the same.
8. Creating a List of Values in a Macro Variable Using SQL
a. Open the m104e08 program into the Editor window and modify the SQL procedure to create
a macro variable named top3 that contains the customer ID numbers of the top three customers
by Total_Retail_Price in the orion.order_fact data set. Separate each of the values with
a comma and a blank. Use the OUTOBS= option to limit the number of output rows.
proc sql noprint outobs=3;
select customer_id, sum(Total_Retail_Price) as total
into :top3 separated by ', '
from orion.order_fact
group by Customer_ID
order by total descending;
b. Submit the program and review the results, which are shown in part b of the exercise.
9. Creating Multiple Macro Variables Using SQL
a. The first query creates the numobs macro variable that stores how many records are returned
by the query. This is the same as the number of macro variables in each series.
A special form of the INTO clause is useful for creating a series of macro variables from multiple
rows of an SQL query.
proc sql noprint;
select count(*) into :numobs
from orion.customer_type;
%let numobs=&numobs;
select Customer_Type_ID into :ctype1-:ctype&numobs
from orion.customer_type;
quit;
b. Submit the program and review the results, which are shown in part b of the exercise.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-54 Chapter 4 DATA Step and SQL Interfaces
data _null_;
call symputx('foot','No Internet orders');
%let foot=Some Internet orders;
run;
25
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.4 Solutions 4-55
m104a02
48
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-56 Chapter 4 DATA Step and SQL Interfaces
Is this successful?
No. It generates the following warning:
WARNING: Apparent symbolic reference NAME not resolved.
m104a03
56
75
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
Chapter 5 Macro Programs
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.1 Conditional Processing 5-3
Objectives
Conditionally process SAS code within a macro
program.
Monitor macro execution.
Insert entire steps, entire statements, and partial
statements into a SAS program.
Business Scenario
A daily sales report is generated every night. Every
Friday, a weekly report is generated. Determine the best
method to automate these reports.
Every Night
PROC PRINT
Every Friday
PROC MEANS
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-4 Chapter 5 Macro Programs
Conditional Processing
Solutions
Three methods:
Method 1 Create multiple macros, including a driver macro.
Method 2 Create a single macro with %DO and %END statements.
Method 3 Create a single macro with %INCLUDE statements.
2?
1? 3?
6
6
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.1 Conditional Processing 5-5
%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
7 continued...
%macro reports;
%daily
%if &sysday=Friday %then %weekly;
%mend reports;
%IF expression %THEN action;
%ELSE action;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-6 Chapter 5 Macro Programs
Macro Expressions
%IF expression
Macro SAS
Expressions Expressions
Arithmetic operators
Logical operators
(do not precede AND or OR with %)
Comparison operators
(symbols and mnemonics)
Case sensitivity
Special WHERE operators
Quotation marks
Ranges such as 1<=x<=10
IN operator
9 IN operator: parentheses required
Conditional Processing
%IF ... %THEN action;
%ELSE action;
10
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.1 Conditional Processing 5-7
12
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-8 Chapter 5 Macro Programs
%macro reports;
%include "&path\daily.sas";
%if &sysday=Friday %then %do;
%include "&path\weekly.sas";
%end;
%mend reports;
The %INCLUDE statement
retrieves SAS source code from an external file and places
it on the input stack
is a global SAS statement, not a macro language statement.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.1 Conditional Processing 5-9
Business Scenario
Generate frequency reports for all order types
or a specific order type.
01Jan2011
To
31Dec2011
orion.order_fact
16
m105d02
17
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-10 Chapter 5 Macro Programs
NOTE: There were 148 observations read from the data set ORION.ORDER_FACT.
WHERE (order_date>='01JAN2011'D and order_date<='31DEC2011'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>='01JAN2011'D and order_date<='31DEC2011'D) and
(order_type=3);
NOTE: PROCEDURE FREQ used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
SAME-AND is a WHERE statement operator that supplements an existing WHERE statement without
respecifying the original WHERE statement.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.1 Conditional Processing 5-11
20 m105d03
%UPCASE(argument)
Because macro comparisons are case sensitive, %UPCASE can eliminate case sensitivity when
a macro program checks a parameter value.
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
21 m105d03
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-12 Chapter 5 Macro Programs
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
22 m105d03
Idea Exchange
What is the difference between %IF-%THEN
and IF-THEN?
23
23
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.1 Conditional Processing 5-13
Business Scenario
Create a macro that conditionally generates a one-way
frequency report or a two-way frequency report.
tables customer_gender;
orion.customer_dim
tables customer_age_group*customer_gender;
25
25
%macro counts(rows);
title 'Customer Counts by Gender';
proc freq data=orion.customer_dim;
tables
%if &rows ne %then &rows *;
customer_gender;
run;
%mend counts;
%counts()
%counts(customer_age_group)
m105d04
26
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-14 Chapter 5 Macro Programs
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(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
m105d04
27
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.1 Conditional Processing 5-15
Exercises
Level 1
Level 2
2. Debugging a Macro
a. Open the m105e02 program shown below into the Editor window.
%macro day;
%if &sysday=SATURDAY
%then %put Yes;
%else %put Sorry;
%mend day;
%day
b. Change SATURDAY to today’s value and submit the program.
c. Did the log say Yes? If not, take the following steps, in sequence, until it does.
1) Activate the MLOGIC option, resubmit the program, check the log, and change the day
as necessary.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-16 Chapter 5 Macro Programs
2) Activate the SYMBOLGEN option, resubmit the program, check the log, and change the day
as necessary.
Challenge
3. Debugging a Macro
a. Open the m105e03 program shown below into the Editor window.
%macro where(state);
%if &state=OR
%then %put Oregon;
%else %put Wherever;
%mend where;
%where(CA)
b. Submit the program. Examine the log and correct the error.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.2 Parameter Validation 5-17
Objectives
Perform parameter validation with the OR operator.
Perform parameter validation with the IN operator.
Perform data-driven parameter validation.
31
Business Scenario
Validate a parameter against a list of valid COUNTRY
values. Explore three possible methods.
AU
CA
DE ? DE
IL
TR
US
ZA
32
32
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-18 Chapter 5 Macro Programs
Parameter Validation
Method 1 Use OR operators for parameter validation.
%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 ERROR: No customers from &place..;
%mend customers;
%customers(de)
%customers(aa)
m105d05a
33
Parameter Validation
SAS Log
955 %customers(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(aa)
ERROR: No customers from AA.
m105d05a
34
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.2 Parameter Validation 5-19
if Country='FR'
or Country='CA'
or Country='DE'
or Country='ZA' then do;
35
Parameter Validation
Method 2 Use the IN operator for parameter validation.
m105d05b
37
When using NOT with the IN operator, NOT must precede the IN expression. Parentheses
are required, as shown below.
%if not(&macvar in &valuelist) %then … ;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-20 Chapter 5 Macro Programs
m105d05b
38
Data-Driven Validation
Method 3 Use data-driven parameter validation.
%macro customers(place) / minoperator;
%let place=%upcase(&place);
proc sql noprint;
select distinct country into :list separated by ' '
from orion.customer;
quit;
%if &place in &list %then %do;
proc print data=orion.customer;
var customer_name customer_address country;
where upcase(country)="&place";
title "Customers from &place";
run;
%end;
%else %do;
%put ERROR: No customers from &place..;
%put ERROR- Valid countries are: &list..;
%end;
%mend customers;
40 m105d05c
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.2 Parameter Validation 5-21
Data-Driven Validation
SAS Log
1246 %customers(de)
NOTE: PROCEDURE SQL used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
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.00 seconds
cpu time 0.00 seconds
1247 %customers(aa)
NOTE: PROCEDURE SQL used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
m105d05c
41
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-22 Chapter 5 Macro Programs
Exercises
Level 1
d. Modify the macro to test whether TYPE is null. If so, do not execute PROC PRINT. Instead,
the macro should write this message to the SAS log:
ERROR: Missing TYPE.
ERROR: Valid values are INTERNET or GOLD.
The macro should first check for a null parameter value. If TYPE is not null, the macro should
convert TYPE to uppercase and test for valid values of GOLD or INTERNET.
e. Resubmit the macro definition with a null parameter value, valid values in uppercase, lowercase,
and mixed case, and an invalid value.
Level 2
5. Validating a Macro Parameter Using Data-Driven TechniquesOpen the m105e05 program shown
below into the Editor window and submit it.
%macro listing(custtype);
%if &custtype= %then %do;
proc print data=orion.customer noobs;
var Customer_ID Customer_Name Customer_Type_ID;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.2 Parameter Validation 5-23
%listing(1020)
%listing()
b. Modify the macro definition to validate CUSTTYPE against a data-driven list.
1) Use the SQL procedure to create the macro variable idlist that contains the unique values
of the variable Customer_Type_ID in the orion.customer_type data set.
2) If the CUSTTYPE parameter is not missing, validate it against idlist.
The macro IN operator cannot check for a null value. Check that a value is not null
before using the IN operator to check whether the value is valid.
3) If CUSTTYPE is in idlist, execute PROC PRINT. Otherwise, do not execute PROC PRINT.
Instead, the macro should write this message to the SAS log:
c. Resubmit the macro definition and call the macro with a null parameter value, a valid value,
and an invalid value.
Challenge
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-24 Chapter 5 Macro Programs
1) Create an additional macro variable named numerrors that accumulates the number
of parameter errors.
2) Execute PROC MEANS only if numerrors is zero.
c. The macro should write the following messages to the SAS log when parameters are invalid:
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.3 Iterative Pr ocessing 5-25
Objectives
Execute macro language statements iteratively.
Generate SAS code iteratively.
45
Business Scenario
Macro applications might require iterative processing.
%do;
…
%end;
46
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-26 Chapter 5 Macro Programs
SAS Log
639680 %put _user_;
GLOBAL COUNTRY1 Australia
GLOBAL COUNTRY2 Canada
GLOBAL COUNTRY3 Germany
GLOBAL COUNTRY4 Israel
GLOBAL COUNTRY5 Turkey
GLOBAL COUNTRY6 United States
GLOBAL COUNTRY7 South Africa
GLOBAL NUMROWS 7
m105d06
47
The PROC SQL step below creates the same series of macro variables. In SAS 9.3, you can use a hyphen
in the INTO clause to specify a range without an upper bound.
proc sql noprint;
select country_name into :country1-
from orion.country;
%let numrows=&sqlobs;
quit;
The automatic macro variable SQLOBS is populated with the number of rows processed
by the SELECT statement.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.3 Iterative Pr ocessing 5-27
Simple Loops
Example: Display a series of macro variables in the SAS log
by repeatedly executing %PUT within a macro loop.
%macro putloop;
%do i=1 %to &numrows;
%put Country&i is &&country&i;
%end;
%mend; %DO index-variable=start %TO stop <%BY increment>;
text
%END;
SAS Log
200 %putloop
Country1 is Australia
Country2 is Canada
Country3 is Germany
Country4 is Israel
Country5 is Turkey
Country6 is United States
Country7 is South Africa
m105d07
48
No code is sent to the compiler when the macro executes. The %PUT statements are executed
by the macro processor.
Simple Loops
%DO index-variable=start %TO stop <%BY increment>;
text
%END;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-28 Chapter 5 Macro Programs
50
Business Scenario
Import a series of text files into corresponding SAS data sets.
orders2007.dat year2007
orders2008.dat year2008
orders2009.dat year2009
52
52
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.3 Iterative Pr ocessing 5-29
%readraw(first=2008,last=2010)
m105d08
53
MLOGIC(READRAW): %DO loop index variable YEAR is now 2010; loop will iterate again.
MPRINT(READRAW): data year2010;
MPRINT(READRAW): infile "s:\workshop\orders2010.dat";
MPRINT(READRAW): input order_ID order_type order_date : date9.;
MPRINT(READRAW): run;
54 m105d08
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-30 Chapter 5 Macro Programs
55
m105d09a
56
Values of the selected variable must represent valid SAS names. The NOTNAME function
detects the position of invalid SAS name characters within a character string.
The statement below writes a macro’s local symbol table to the SAS log.
%put _local_;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.3 Iterative Pr ocessing 5-31
m105d09a
57
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-32 Chapter 5 Macro Programs
NOTE: There were 77 observations read from the data set ORION.CUSTOMER.
NOTE: The data set WORK.AU has 8 observations and 12 variables.
NOTE: The data set WORK.CA has 15 observations and 12 variables.
NOTE: The data set WORK.DE has 10 observations and 12 variables.
NOTE: The data set WORK.IL has 5 observations and 12 variables.
NOTE: The data set WORK.TR has 7 observations and 12 variables.
NOTE: The data set WORK.US has 28 observations and 12 variables.
NOTE: The data set WORK.ZA has 4 observations and 12 variables.
NOTE: DATA statement used (Total process time):
real time 0.10 seconds
cpu time 0.10 seconds
m105d09b
59
60
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.3 Iterative Pr ocessing 5-33
Business Scenario
Print every data set in a library.
%printlib(lib=orion)
sashelp.vstabvw
62
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-34 Chapter 5 Macro Programs
%printlib(lib=orion)
m105d11a
64
The statement below writes a macro’s local symbol table to the SAS log.
%put _local_;
m105d11a
65
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.3 Iterative Pr ocessing 5-35
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-36 Chapter 5 Macro Programs
Exercises
Level 1
1 Retail Sale
2 Catalog Sale
3 Internet Sale
Modify the following DATA step to create a series of macro variables named type1-typen, where
n is the number of observations in the orion.lookup_order_type data set. Each macro variable
should receive the value of the data set variable LABEL. Place the modified DATA step into the
macro definition.
data _null_;
set orion.lookup_order_type;
run;
c. Modify the macro to do the following:
create a macro variable endloop and populate it with the number of observations
in the orion.lookup_order_type data set
use the endloop macro variable as the stop value for the macro DO loop
use an indirect reference to typex in the TITLE statement
Level 2
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.3 Iterative Pr ocessing 5-37
%macro tops(obs=3);
proc means data=orion.order_fact sum nway noprint;
var Total_Retail_Price;
class Customer_ID;
output out=customer_freq sum=sum;
run;
data _null_;
set customer_freq(obs=&obs);
call symputx('top'||left(_n_), Customer_ID);
run;
%mend tops;
%tops()
%tops(obs=5)
b. Modify the macro to print a listing of the top x customers from the orion.customer_dim data set.
Display the variables Customer_ID, Customer_Name, and Customer_Type. Use a macro loop
to dynamically generate values for the WHERE statement based on the macro variables top1
through topx.
Challenge
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-38 Chapter 5 Macro Programs
%macro listall;
data _null_;
set orion.customer_type end=final;
call symputx('type'||left(_n_), Customer_Type);
if final then call symputx('n',_n_);
run;
%put _user_;
%mend listall;
%listall
b. Modify the Listall macro to call the Memberlist macro. The result of the macro call should
create a PROC PRINT step for each customer type. Use a macro loop and indirect references
to generate the appropriate macro calls.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.4 Global and Local Sy mbol Tables 5-39
Objectives
Explain the difference between global and local
symbol tables.
Describe how the macro processor decides which
symbol table to use.
Describe the concept of nested macros and the
hierarchy of symbol tables.
71
72
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-40 Chapter 5 Macro Programs
73
%GLOBAL Statement
General form of the %GLOBAL statement:
74
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.4 Global and Local Sy mbol Tables 5-41
75
76
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-42 Chapter 5 Macro Programs
77
78
The DATA step SYMPUT routine can also create local macro variables, but it does not remove
leading and trailing blanks from the macro variable's value.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.4 Global and Local Sy mbol Tables 5-43
%LOCAL Statement
General form of the %LOCAL statement:
79
%LOCAL Statement
Declare the index variable of a macro loop
as a local variable to prevent accidental contamination
of a like-named macro variable in the global table
or another local table.
%macro putloop;
%local i;
%do i=1 %to &numrows;
%put Country&i is &&country&i;
%end;
%mend putloop;
m105d13
80
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-44 Chapter 5 Macro Programs
81
&macvar
82
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.4 Global and Local Sy mbol Tables 5-45
%a(value=Today is Monday)
83
%macro outer;
%local x;
%let x=1;
%inner
%mend outer;
%macro inner;
%local y;
%let y=&x;
%mend inner;
85
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-46 Chapter 5 Macro Programs
%let x=0; X 0
%macro outer;
%local x;
%let x=1;
%inner
%mend outer;
%macro inner;
%local y;
%let y=&x;
%mend inner;
86
87
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.4 Global and Local Sy mbol Tables 5-47
89
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-48 Chapter 5 Macro Programs
90
Global Table
%macro outer; X 0
%local x;
%let x=1; Outer Local Table
%inner
%mend outer; X 1
%macro inner;
%local y;
%let y=&x;
%mend inner;
91
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.4 Global and Local Sy mbol Tables 5-49
Global Table
%macro outer; X 0
%local x;
%let x=1;
%inner
%mend outer;
%macro inner;
%local y;
%let y=&x;
%mend inner;
92
m105d14
93
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-50 Chapter 5 Macro Programs
%numobs(orion.order_fact)
%put ---> &num observations;
m105d14
94
SAS Log
1831 %numobs(orion.orders)
1832 %put ---> &num observations;
---> 490 observations
m105d14
96
The scope argument is recommended any time that the SYMPUTX routine is used within a macro
definition.
The STOP statement stops DATA step execution. The special variable NUMBER is populated
during compile time.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.4 Global and Local Sy mbol Tables 5-51
m105d14
97
m105d14
98
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-52 Chapter 5 Macro Programs
m105d14
99
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.4 Global and Local Sy mbol Tables 5-53
Exercises
Level 1
a. ______________________________________________________________________________
%let dog=Paisley;
%macro whereisit;
%put My dog is &dog;
%mend whereisit;
%whereisit
b. ______________________________________________________________________________
%macro whereisit;
%let dog=Paisley;
%put My dog is &dog;
%mend whereisit;
%whereisit
c. ______________________________________________________________________________
%macro whereisit(dog);
%put My dog is &dog;
%mend whereisit;
%whereisit(Paisley)
Level 2
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-54 Chapter 5 Macro Programs
%varscope
b. Modify the program so that all macro variables that are created in the DATA step are stored in the
local symbol table.
c. Modify the program by adding the following statement before the DATA step and removing the
scope specification in the SYMPUTX routine:
%local x;
In which symbol table are the macro variables stored?
____________________________________
d. Modify the program so that all macro variables that are created in the DATA step are stored in the
global symbol table.
Challenge
%macro sumreport;
%createmacvar
%do num=1 %to &endloop;
proc means data=orion.order_fact sum mean maxdec=2;
where Order_Type = #
var Total_Retail_Price CostPrice_Per_Unit;
title "Summary Report for &&type&num";
run;
%end;
%mend sumreport;
%sumreport
Submit the program. Review and describe the results.
___________________________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.4 Global and Local Sy mbol Tables 5-55
c. Correct the program so that the Sumreport macro executes correctly and does not create any
global macro variables. Verify that the title resolves properly. In addition, add an s to the end
of the type description in the title.
PROC MEANS Output
Summary Report for Retail Sales
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-56 Chapter 5 Macro Programs
5.5 Solutions
Solutions to Exercises
1. Conditionally Processing Complete Statements
a. Open the program into the Editor window.
b. Modify the macro to test the CUSTTYPE parameter. If the value is null, insert VAR and TITLE
statements into the PROC PRINT step. If the value is not null, insert WHERE, VAR, and TITLE
statements into the PROC PRINT step.
%macro listing(custtype);
proc print data=orion.customer noobs;
%if &custtype= %then %do;
var Customer_ID Customer_Name Customer_Type_ID;
title "All Customers";
%end;
%else %do;
where Customer_Type_ID=&custtype;
var Customer_ID Customer_Name;
title "Customer Type: &custtype";
%end;
run;
%mend listing;
c. Resubmit the macro definition using a null value and a valid value for CUSTTYPE.
Partial SAS Log
36 %listing()
MPRINT(LISTING): proc print data=orion.customer noobs;
MPRINT(LISTING): var Customer_ID Customer_Name Customer_Type_ID;
MPRINT(LISTING): title "All Customers";
MPRINT(LISTING): run;
NOTE: There were 77 observations read from the data set ORION.CUSTOMER.
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.23 seconds
cpu time 0.01 seconds
37 %listing(2010)
MPRINT(LISTING): proc print data= orion.customer noobs;
MPRINT(LISTING): where Customer_Type_ID=2010;
MPRINT(LISTING): var Customer_ID Customer_Name;
MPRINT(LISTING): title "Customer Type: 2010";
MPRINT(LISTING): run;
NOTE: There were 5 observations read from the data set ORION.CUSTOMER.
WHERE Customer_Type_ID=2010;
NOTE: PROCEDURE PRINT used (Total process time):
real time 1.13 seconds
cpu time 0.01 seconds
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.5 Solutions 5-57
2. Debugging a Macro
a. Open the program into the Editor window.
b. Change SATURDAY to today’s value and submit the program.
c. Change today’s value to the day that you launched SAS. Enter the day in mixed case, such
as Tuesday.
3. Debugging a Macro
a. Open the program into the Editor window.
b. The %STR function is required to interpret OR as plain text instead of a logical operator.
%macro where(state);
%if &state=%str(OR)
%then %put Oregon;
%else %put Wherever;
%mend where;
4. Validating a Macro Parameter
a. Open the program into the Editor window and submit it.
b. Use %IF to validate the TYPE parameter. The MINOPERATOR option in the %MACRO
statement activates the IN operator.
%macro custtype(type)/minoperator;
%let type=%upcase(&type);
%if &type in GOLD INTERNET %then %do;
proc print data=orion.customer_dim;
var Customer_Group Customer_Name Customer_Gender
Customer_Age;
where upcase(Customer_Group) contains "&type";
title "&type Customers";
run;
%end;
%else %do;
%put ERROR: Invalid TYPE: &type..;
%put ERROR: Valid TYPE values are INTERNET or GOLD.;
%end;
%mend custtype;
c. Resubmit the macro definition and call the macro using valid and invalid parameter values.
Partial SAS Log
248 %custtype(internet)
NOTE: There were 8 observations read from the data set ORION.CUSTOMER_DIM.
WHERE UPCASE(Customer_Group) contains 'INTERNET';
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
249 %custtype(silver)
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-58 Chapter 5 Macro Programs
d. Modify the macro to test whether TYPE is null. If so, do not execute PROC PRINT. Instead,
the macro should write messages to the SAS log.
%macro custtype(type)/minoperator;
%if &type= %then %do;
%put ERROR: Missing TYPE.;
%put ERROR: Valid TYPE values are INTERNET or GOLD.;
%end;
%else %do;
%let type=%upcase(&type);
%if &type in GOLD INTERNET %then %do;
proc print data=orion.customer_dim;
var Customer_Group Customer_Name Customer_Gender
Customer_Age;
where upcase(Customer_Group) contains "&type";
title "&type Customers";
run;
%end;
%else %do;
%put ERROR: Invalid TYPE: &type..;
%put ERROR: Valid TYPE values are INTERNET or GOLD.;
%end;
%end;
%mend custtype;
e. Resubmit the macro definition with a null parameter value, a valid value, and an invalid value.
Partial SAS Log
272 %custtype()
ERROR: Missing TYPE.
ERROR: Valid TYPE values are INTERNET or GOLD.
273 %custtype(internet)
NOTE: There were 8 observations read from the data set ORION.CUSTOMER_DIM.
WHERE UPCASE(Customer_Group) contains 'INTERNET';
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
274 %custtype(silver)
ERROR: Invalid TYPE: SILVER.
ERROR: Valid TYPE values are INTERNET or GOLD.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.5 Solutions 5-59
3) If CUSTTYPE is in IDLIST, execute PROC PRINT. Otherwise, do not execute PROC PRINT.
Instead, the macro should write this message to the SAS log:
Partial SAS Log
ERROR: Invalid CUSTTYPE.
Valid CUSTTYPEs: 1010 1020 1030 1040 2010 2020 2030 3010.
NOTE: There were 77 observations read from the data set ORION.CUSTOMER.
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
412 %listing(1020)
MPRINT(LISTING): proc sql noprint;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-60 Chapter 5 Macro Programs
MPRINT(LISTING): select distinct Customer_Type_ID into :IDlist separated by ' ' from
orion.customer_type;
MPRINT(LISTING): quit;
NOTE: PROCEDURE SQL used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
413 %listing(9999)
MPRINT(LISTING): proc sql noprint;
MPRINT(LISTING): select distinct Customer_Type_ID into :IDlist separated by ' ' from
orion.customer_type;
MPRINT(LISTING): quit;
NOTE: PROCEDURE SQL used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
c. Create an additional macro variable named numerrors that accumulates the number
of parameter errors.
1) Execute PROC MEANS only if numerrors is zero.
2) The macro should write messages to the SAS log when parameters are invalid.
%macro salarystats(decimals=2,order=internal)/minoperator;
%let numerrors=0;
%if not (&decimals in 0 1 2 3 4) %then %do;
%let numerrors=%eval(&numerrors+1);
%put ERROR: Invalid DECIMALS parameter: &decimals..;
%put ERROR- Valid DECIMALS values are 0 to 4.;
%end;
%let order=%upcase(&order);
%if not (&order in INTERNAL FREQ) %then %do;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.5 Solutions 5-61
%let numerrors=%eval(&numerrors+1);
%put ERROR: Invalid ORDER parameter: &order..;
%put ERROR- Valid ORDER values are INTERNAL or FREQ.;
%end;
%if &numerrors=0 %then %do;
options nolabel;
title 'Salary Stats';
proc means data=orion.staff maxdec=&decimals
order=ℴ
where job_title contains 'Sales';
var salary;
class job_title;
run;
title;
%end;
%else %put ERROR: &numerrors errors. Code not submitted.;
%mend salarystats;
%salarystats()
%salarystats(decimals=5,order=fudge)
7. Using Macro Loops and Indirect References
a. Open the program into the Editor window.
b. Define a macro that generates a separate PROC MEANS step for each of the order types
in the orion.order_fact data set. The values of Order_Type are 1, 2, and 3.
%macro sumreport;
%do num=1 %to 3;
proc means data=orion.order_fact sum mean maxdec=2;
where Order_Type=#
var Total_Retail_Price CostPrice_Per_Unit;
title "Order Type: &num";
run;
%end;
%mend sumreport;
%sumreport
c. Insert the provided DATA step to create the series of macro variables.
d. Modify the macro to use the following:
the endloop macro variable as the stop value for the iterative DO loop
an indirect reference to typex in the TITLE statement
%macro sumreport;
data _null_;
set orion.lookup_order_type end=last;
call symputx('type'||left(_n_), label);
if last then call symputx('endloop', _n_);
run;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-62 Chapter 5 Macro Programs
%sumreport
8. Generating Data-Dependent Steps
a. Open the program into the Editor window.
b. Modify the macro to print a listing of the topx customers from the orion.customer_dim data set.
Display the variables Customer_ID, Customer_Name, and Customer_Type.
Use a macro loop to dynamically generate values for the WHERE statement based on the macro
variables top1 through topx.
%macro tops(obs=3);
proc means data=orion.order_fact sum nway noprint;
var Total_Retail_Price;
class Customer_ID;
output out=customer_freq sum=sum;
run;
data _null_;
set customer_freq(obs=&obs);
call symputx('top'||left(_n_), Customer_ID);
run;
%tops()
%tops(obs=5)
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.5 Solutions 5-63
b. Modify the Listall macro to call the Memberlist macro. The result of the macro call should
create a PROC PRINT step for each customer type. Use a macro loop and indirect references
to generate the appropriate macro calls.
%macro memberlist(custtype);
proc print data=Orion.Customer_dim;
var Customer_Name Customer_ID Customer_Age_Group;
where Customer_Type="&custtype";
title "A List of &custtype";
run;
%mend memberlist;
%macro listall;
data _null_;
set orion.customer_type end=final;
call symputx('type'||left(_n_), Customer_Type);
if final then call symputx('n',_n_);
run;
%do num=1 %to &n;
%memberlist(&&type&num)
%end;
%mend listall;
%listall
10. Understanding Symbol Tables
Without submitting the programs, identify in which symbol table the macro variable dog is located.
a. Because the %LET statement is outside the macro definition, the macro variable dog is stored
in the global symbol table.
%let dog=Paisley;
%macro whereisit;
%put My dog is &dog;
%mend whereisit;
%whereisit
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-64 Chapter 5 Macro Programs
b. Because the %LET statement is inside the macro definition, the macro variable dog is stored
in the local symbol table.
%macro whereisit;
%let dog=Paisley;
%put My dog is &dog;
%mend whereisit;
%whereisit
c. Because DOG is a macro parameter, it is stored in the local symbol table.
%macro whereisit(dog);
%put My dog is &dog;
%mend whereisit;
%whereisit(Paisley)
11. Controlling Macro Variable Storage
a. Open the program into the Editor window.
b. Specifying L as the third argument of the SYMPUTX routine stores the macro variable in the
local symbol table.
%macro varscope;
data _null_;
set orion.customer_type end=final;
call symputx('localtype'||left(_n_), Customer_Type,'L');
if final then call symputx('localn',_n_,'L');
run;
%put _user_;
%mend varscope;
%varscope
c. By adding the %LOCAL statement and removing the scope specification, the SYMPUTX routine
creates local macro variables.
2 %macro varscope;
3 %local x;
4 data _null_;
5 set orion.customer_type end=final;
6 call symputx('localtype'||left(_n_), Customer_Type);
7 if final then call symputx('localn',_n_);
8 run;
9 %put _user_;
10 %mend varscope;
11
12 %varscope
NOTE: Numeric values have been converted to character values at the places given by:
(Line):(Column).
1:94
NOTE: There were 8 observations read from the data set ORION.CUSTOMER_TYPE.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.5 Solutions 5-65
VARSCOPE LOCALN 8
VARSCOPE LOCALTYPE1 Orion Club members inactive
VARSCOPE LOCALTYPE2 Orion Club members low activity
VARSCOPE LOCALTYPE3 Orion Club members medium activity
VARSCOPE LOCALTYPE4 Orion Club members high activity
VARSCOPE LOCALTYPE5 Orion Club Gold members low activity
VARSCOPE LOCALTYPE6 Orion Club Gold members medium activity
VARSCOPE LOCALTYPE7 Orion Club Gold members high activity
VARSCOPE LOCALTYPE8 Internet/Catalog Customers
VARSCOPE X
d. Specifying G as the third argument of the SYMPUTX routine stores the macro variables
in the global symbol table.
%macro varscope;
%local x;
data _null_;
set orion.customer_type end=final;
call symputx('localtype'||left(_n_), Customer_Type,'G');
if final then call symputx('localn',_n_,'G');
run;
%put _user_;
%mend varscope;
%varscope
12. Creating Multiple Symbol Tables
a. Open the cleanup program and submit the macro.
b. Open the m105e12 program into the Editor window.
c. Correct the program so that the Sumreport macro executes correctly and does not create any
global macro variables. Verify that the title resolves properly. In addition, add an s to the end
of the type description in the title.
The macro variables endloop and typex are stored in the local symbol table for the
Createmacvar macro and are not available to the Sumreport macro. Delete the scope argument
from the SYMPUTX routine and add the %LOCAL statement to the Sumreport macro to force
the macro variables into the local symbol table for the Sumreport macro.
%macro createmacvar;
data _null_;
set orion.lookup_order_type end=last;
call symputx('type'||left(start), label);
if last then call symputx('endloop', _n_);
run;
%mend createmacvar;
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-66 Chapter 5 Macro Programs
%macro sumreport;
%local type1 type2 type3 endloop num;
%createmacvar
%do num=1 %to &endloop;
proc means data=orion.order_fact sum mean maxdec=2;
where Order_Type = #
var Total_Retail_Price CostPrice_Per_Unit;
title "Summary Report for &&type&num..s";
run;
%end;
%mend sumreport;
%sumreport
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.5 Solutions 5-67
13
Idea Exchange
What is the difference between %IF-%THEN
and IF-THEN?
24
24
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-68 Chapter 5 Macro Programs
36
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.5 Solutions 5-69
51
&&VAL&COUNT &VAL7 ZA
61
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-70 Chapter 5 Macro Programs
%a(value=Today is Monday)
One. The parameter list in macro A causes a local
symbol table to be created. No local symbol table
is created when macro B is called because macro
84 B does not create local variables.
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
Chapter 6 Learning More
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
6.1 SAS Resources 6-3
Objectives
Identify areas of support that SAS offers.
Education
Comprehensive training to deliver greater value
to your organization
http://support.sas.com/training/
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
6-4 Chapter 6 Learning More
SAS Books
Convenient. Practical. Enlightening.
Valuable insight with solid results.
Available in a variety of formats
to best meet your needs:
hard-copy books
e-books
PDF
5 www.sas.com/store/books
Computer-based
certification exams –
typically 60-70 questions and
2-3 hours in length
Preparation materials and
practice exams available
Worldwide directory of
SAS Certified Professionals
http://support.sas.com/certify/
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
6.1 SAS Resources 6-5
Support
SAS provides a variety of self-help and assisted-help
resources.
http://support.sas.com/techsup/
User Groups
SAS supports many local, regional, international,
and special-interest SAS user groups.
http://support.sas.com/usergroups/
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
6-6 Chapter 6 Learning More
Objectives
Identify the next course that follows this course.
10
Next Steps
To learn advanced macro techniques, enroll in the following
course:
11
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
6.2 Beyond This Course 6-7
Next Steps
In addition, there are prerecorded short technical
discussions and demonstrations called e-lectures.
http://support.sas.com/training/
12
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
6-8 Chapter 6 Learning More
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
Chapter 7 Supplemental Materials
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
7.1 Program Flow 7-3
Program Flow
DATA Step Procedure Global Statement SQL
Compiler Parser Parser Compiler
Symbol Table
W ord Scanner Macro Processor
Macro Library
Input Stack
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
7-4 Chapter 7 Supplemental Materials
Copyright © 2016, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.