LWMC1V2 001
LWMC1V2 001
Essentials
Course Notes
SAS® Macro Language 1: Essentials Course Notes was developed by Stacey Syphus, Mark Jordan,
and Kathy Passarella . Additional contributions were made by Brittany Coleman, Bruce Dawless,
Davetta Dunlap, Brian Gayle, Gina Repole, and Theresa Stemler. Instructional design, editing, and
production support was provided by the Learning Design and Development team.
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 © 2019 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 E71585, course code LWMC1V2/MC1V2, prepared date 11Dec2019. LWMC1V2_001
ISBN 978-1-64295-754-9
For Your Information iii
Table of Contents
Practice.............................................................................................................. 3-21
Demonstration: Creating Macro Variables with a PROC SQL Query ................ 3-28
Practice.............................................................................................................. 3-32
3.3 Using the DATA Step to Create Macro Variables .................................................... 3-34
Demonstration: Creating Macro Variables with the DATA Step ......................... 3-48
Practice.............................................................................................................. 3-52
Practice.............................................................................................................. 3-63
Practice.............................................................................................................. 4-20
Practice.............................................................................................................. 4-42
Practice.............................................................................................................. 4-61
Practice.............................................................................................................. 4-82
Practice.............................................................................................................. 5-25
Practice.............................................................................................................. 5-44
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 SAS books (including e-books) that relate to the topics
covered in this course notes, visit https://www.sas.com/sas/books.html or
call 1-800-727-0025. US customers receive free shipping to US
addresses.
Lesson 1 Introduction
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1.1 Why SAS Macro? 1-3
Macro Programming
SAS Macro
Facility TEXT
3
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
4
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
CarsProgram.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1-4 Lesson 1 Introduction
Easily replace
title "Trucks by Origin"; repetitive values.
proc freq data=sashelp.cars;
where Type="Truck";
table Origin;
run; Truck
title "Average Highway MPG for Trucks";
proc means data=sashelp.cars mean maxdec=1; SUV
where Type="Truck";
var MPG_Highway;
class Origin;
run; Sports
5
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
CarsProgram.sas
Conditional Processing
data mpg;
set sashelp.cars;
AvgMPG=mean(MPG_Highway, MPG_City);
run; Submit or modify
Did the step run without code based on a
warnings or errors? condition.
NO
YES
Write a custom error
Print the table.
message to the log.
6
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
CarsProgram.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1.1 Why SAS Macro? 1-5
Repetitive Processing
title "4-Cylinder Cars";
proc print data=sashelp.cars;
where Cylinders=4;
run; Generate repetitive
SAS code.
title "6-Cylinder Cars";
proc print data=sashelp.cars;
where Cylinders=6;
run;
Data-Driven Applications
data hybrid sedan sports suv truck wagon;
set sashelp.cars;
select(Type);
when("Hybrid") output hybrid;
when("Sedan") output sedan;
when("Sports") output sports;
when("SUV") output suv;
when("Truck") output truck;
when("Wagon") output wagon;
otherwise;
end; Build programs
run; dynamically based on
data values.
8
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
CarsProgram.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1-6 Lesson 1 Introduction
CarsMacro.sas
9
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
To view an example of a program that uses the SAS macro language to address the challenges
presented in the previous slides, open CarsMacro.sas in the demos folder of the course files.
CarsMacro.sas
10
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1.1 Why SAS Macro? 1-7
Use macro-level
Start with a Generalize Create a macro Validate
programming Add data-driven
validated SAS with macro definition with parameters and
for complex features
program variables parameters document
processing
11
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Discussion
How do you envision the SAS macro
language helping you in your work?
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1-8 Lesson 1 Introduction
14
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
15
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1.2 Setting Up for This Course 1-9
16
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
17
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1-10 Lesson 1 Introduction
case_study
data
demos
practices
18
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
case_study
data
demos
m104p01.sas
practices Macro 1, Lesson 4, practice 1
19
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1.2 Setting Up for This Course 1-11
course activities
files
autocall
case_study
cre8data.sas data
demos
practices
20
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
21
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1-12 Lesson 1 Introduction
1.02 Activity
1. Open the libname.sas program in the course files folder and run it.
2. Navigate to the SASHELP library and open the CARS table. Browse
the columns and values in the table. This table is used in many
of the sample programs.
3. Navigate to the MC1 library and open the STORM_FINAL table.
This table includes one row per storm recorded from 1980 to 2017.
This table is used in many of the demos.
4. Open and browse the CUSTOMERS table in the MC1 library. This table
is used in many of the practices.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1.3 Solutions 1-13
1.3 Solutions
Solutions to Activities and Questions
Confirm that
these 13 SAS
tables were
created.
22
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
1-14 Lesson 1 Introduction
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
Lesson 2 SAS® Macro Facility
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.1 Program Flow 2-3
Compile Execute
SAS program
3
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
SAS Macro
SAS macro Language
language generate SAS program code
Macro
Facility
Text SAS program
4
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-4 Lesson 2 SAS® Macro Facility
Macro Macro
code Processor
5
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Input Stack
title "Trucks with Horsepower > 250";
proc print data=sashelp.cars;
var Make Model MSRP Horsepower;
where Type="Truck" and Horsepower>250;
SAS program run;
6
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m102d01.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.1 Program Flow 2-5
Token Types
Input Stack
title "Trucks with Horsepower > 250";
proc print data=sashelp.cars;
var Make Model MSRP Horsepower;
where Type="Truck" and Horsepower>250;
run;
A program is
separated into name number
components called
tokens. There are
four types of
tokens. special literal
7
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Name Tokens
Input Stack
title "Trucks with Horsepower > 250";
proc print data=sashelp.cars;
var Make Model MSRP Horsepower;
where Type="Truck" and Horsepower>250;
run;
• maximum of 32 characters
name • must begin with a letter or
underscore
• can include only letters,
digits, and underscores
8
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Formats and informats (COMMA11.2, $5.) are considered name tokens. The period and dollar sign
are treated as part of the name token.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-6 Lesson 2 SAS® Macro Facility
Number Tokens
Input Stack
title "Trucks with Horsepower > 250";
proc print data=sashelp.cars;
var Make Model MSRP Horsepower;
where Type="Truck" and Horsepower>250;
run;
Literal Tokens
Input Stack
title "Trucks with Horsepower > 250";
proc print data=sashelp.cars;
var Make Model MSRP Horsepower;
where Type="Truck" and Horsepower>250;
run;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.1 Program Flow 2-7
Special Tokens
Input Stack
title "Trucks with Horsepower > 250";
proc print data=sashelp.cars;
var Make Model MSRP Horsepower;
where Type="Truck" and Horsepower>250;
run;
Token Delimiters
Input Stack
title "Trucks with Horsepower > 250";
proc print data=sashelp.cars;
var Make Model MSRP Horsepower;
where Type="Truck" and Horsepower>250;
run;
12
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-8 Lesson 2 SAS® Macro Facility
2.01 Activity
How many tokens are in each statement?
13
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
15
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.1 Program Flow 2-9
Tokenization
title
Compiler
16
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Tokenization
title "Trucks with Horsepower > 250"
Compiler
17
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
When a literal token is enclosed in double quotation marks, the word scanner examines
the individual tokens within the string before passing the text on to the compiler. If a literal token
is enclosed in single quotations marks, the word scanner does not tokenize the string.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-10 Lesson 2 SAS® Macro Facility
Tokenization
title "Trucks with Horsepower > 250";
Compiler
Execute
special ;
18
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Tokenization
Compiler
name proc
name print
Word name data
Scanner special =
name sashelp
special .
cars;
Input var Make Model MSRP Horsepower;
where Type="Truck" and Horsepower>250;
Stack run;
19
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.1 Program Flow 2-11
Tokenization
proc print data=sashelp.cars;
Compiler
name var
name Make
Word name Model
Scanner name MSRP
name Horsepower
special ;
20
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Tokenization
proc print data=sashelp.cars;
var Make Model MSRP Horsepower;
Compiler where Type="Truck" and Horsepower>250; Execute
run;
Input
Stack
21
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-12 Lesson 2 SAS® Macro Facility
Discussion
Why do you think unbalanced
quotation marks cause problems
when they are submitted in a
SAS program?
Macro Triggers
23
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.1 Program Flow 2-13
Macro Triggers
24
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Compiler
25
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-14 Lesson 2 SAS® Macro Facility
Compiler
Macro Processor
Word
Scanner
special %
name put
26
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Macro Processor
Word log
Scanner NOTE: This is a great program!
Input
Stack
27
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.1 Program Flow 2-15
Processing Overview
Execute
Code Processing
Code Generation
Word Macro Macro
Scanner Processor Catalogs
%put NOTE: This is a great program!
title "Trucks with Horsepower > 250";
proc print data=sashelp.cars;
var Make Model MSRP Horsepower; Input Symbol
where Type="Truck" and
run;
Horsepower>250; Stack Tables
Tokenization Macro Facility
28
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
2.02 Activity
1. Name the possible stages involved in the SAS program flow.
2. What are the four types of tokens recognized by the word scanner?
29
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-16 Lesson 2 SAS® Macro Facility
Use macro-level
Start with a Generalize Create a macro Validate
programming Add Data Driven
validated SAS with macro definition with parameters and
for complex Features
program variables parameters document
processing
Using macro
variables is an
effective way to make
your programs more
flexible.
33
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Macro Variables
SUV 200
34
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m102d01.SAS
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.2 Creating and Using Macro Variables 2-17
Macro Variables
Macro variables
each have a name
and value that are
stored in a memory- Global Symbol Table
based symbol table. Name Value
35
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
36
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
If the %LET statement includes macro triggers for either name or value, the macro references are
processed before the macro variable name and value are assigned.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-18 Lesson 2 SAS® Macro Facility
37
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
38
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.2 Creating and Using Macro Variables 2-19
40
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-20 Lesson 2 SAS® Macro Facility
41
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Mathematical expressions
are not evaluated.
42
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.2 Creating and Using Macro Variables 2-21
43
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
2.03 Activity
What would be stored as the value of Mylib?
44
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-22 Lesson 2 SAS® Macro Facility
46
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.2 Creating and Using Macro Variables 2-23
48
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
49
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m102d01.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-24 Lesson 2 SAS® Macro Facility
Compiler
Macro Processor
Word
Scanner
Compiler
Macro Processor
Word
Scanner
special %
name let
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.2 Creating and Using Macro Variables 2-25
Macro Processor
Word
Scanner
Macro Processor
Word
Scanner "
literal start
special &
name type
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-26 Lesson 2 SAS® Macro Facility
Macro Processor
Word
Scanner "
literal start
Macro Processor
Word
Scanner "
literal start
name Truck
literal end "
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.2 Creating and Using Macro Variables 2-27
Macro Processor
Word
Scanner
special &
name hp
Macro Processor
Word
Scanner
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-28 Lesson 2 SAS® Macro Facility
Macro Processor
Word
Scanner
number 250
special ;
Word
Scanner
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.2 Creating and Using Macro Variables 2-29
60
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m102d01.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-30 Lesson 2 SAS® Macro Facility
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.2 Creating and Using Macro Variables 2-31
2.04 Activity
Open m102a04.sas from the activities folder and perform the following tasks:
1. Notice that the program includes two TITLE statements, each referencing
a macro variable.
2. At the top of the program, turn on the SYMBOLGEN option.
At the bottom of the program, turn off SYMBOLGEN.
options symbolgen; options nosymbolgen;
3. Run the program and review the log and results. What is printed as the
second title?
4. In the TITLE2 statement, change the single quotation marks to double
quotation marks and run the program again. How do the results
and the log differ?
64
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Macro triggers in
Macro triggers in
single quotation
double quotation
marks are treated as
marks are sent to the
regular text and are
macro processor.
not resolved.
66
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-32 Lesson 2 SAS® Macro Facility
...
%let type=Truck;
title "&types with Horsepower > &hp";
...
What happens if a
macro variable
reference is
concatenated with
trailing text?
desired results
67
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
...
%let type=Truck;
title "&types with Horsepower > &hp";
...
Global Symbol Table
Name Value
TYPES is not found. TYPE Truck
HP 250
74 %let type=Truck;
75 %let hp=250;
WARNING: Apparent symbolic reference TYPES not resolved.
SYMBOLGEN: Macro variable HP resolves to 250
76 title "&types with Horsepower > &hp";
68
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.2 Creating and Using Macro Variables 2-33
...
%let type=Truck;
title "&type.s with Horsepower > &hp";
...
Use a period to delimit the macro
variable name from the text.
69
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
2.05 Activity
Open m102a05.sas from the activities folder and perform the following tasks:
1. Modify the TITLE statement reference to &type by adding a period before
the 's'.
2. Replace the hardcoded text sashelp in the FOOTNOTE and PROC
statements with a reference to the Lib macro variable (&lib).
footnote "Data Source: &lib.CARS";
proc print data=&lib.cars;
3. Run the program and examine the log and the error statements.
Why did the program fail to run?
70
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-34 Lesson 2 SAS® Macro Facility
72
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
74 %put _user_;
%PUT is a simple
...
GLOBAL CLIENTMACHINE L12345 way to view macro
GLOBAL HP 250 variable names and
GLOBAL LIB sashelp values in the log.
GLOBAL PATH s:/workshop
GLOBAL SYSUSERNAME John Smith
GLOBAL TYPE Truck
GLOBAL _CLIENTAPP 'SAS Studio'
GLOBAL _CLIENTAPPVERSION 3.8
...
73
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.2 Creating and Using Macro Variables 2-35
73 %put &=type;
TYPE=Truck
74
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
2.06 Activity
1. Open a new program and submit a %PUT statement to list all
user-defined macro variables.
2. Find the Path macro variable in the log. Path was created with
a %LET statement in the libname.sas program, and it stores the
location of the course files. Submit the following statements to
view the value of Path. How are the messages in the log different?
75
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-36 Lesson 2 SAS® Macro Facility
Several useful
73 %put _automatic_;
...
automatic macro
AUTOMATIC SYSDATE 01NOV19 variables are defined
AUTOMATIC SYSDATE9 01NOV2019 when you start a SAS
AUTOMATIC SYSDAY Friday
session.
AUTOMATIC SYSENCODING wlatin1
AUTOMATIC SYSUSERID msmith
AUTOMATIC SYSVER 9.4
...
77
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Automatic macro variables are available throughout the SAS session. Values can be updated by
SAS and, in some cases, can be assigned values by the user.
2.07 Activity
Open m102a07.sas from the activities folder and perform the following tasks:
1. Review the program and notice that the DATA step creates a table named
Avg_MPG. Highlight the DATA step and %PUT statement, and run the
selected code. Review the log to see all automatic macro variables stored
in the global symbol table.
2. Identify the macro variables that store the date and the last table created.
3. Use macro variable references in the TITLE2 and FOOTNOTE statements
to insert the table name and date into the program.
title2 "Data Source: <table>";
footnote "Created on <date>";
78
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.2 Creating and Using Macro Variables 2-37
81
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m102d01.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-38 Lesson 2 SAS® Macro Facility
82
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.2 Creating and Using Macro Variables 2-39
Practice
Level 1
Level 2
a. Open m102p02.sas from the practices folder. Submit the program and review the results.
Verify that the report contains 17 rows.
b. Create macro variables Lib, Dsn, and Var and assign the values mc1, newhires, and
Employee respectively. Modify the program so that every occurrence of mc1, newhires,
and Employee are replaced by references to the corresponding macro variable. Submit
the program.
Note: Be sure to include the ‘s’ in Employees as part of the title text.
• What is the report title?
• How many rows are in the report?
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-40 Lesson 2 SAS® Macro Facility
2.3 Solutions
Solutions to Practices
1. Defining and Using Macro Variables for Substitution
/* Part b. */
%let Country=US;
title "&Country Customers Ages 18 to 24";
proc print data=mc1.customers;
var Name Age Type;
where Country = "&Country"
and Age between 18 and 24;
run;
title;
/* Part c. */
%let Country=FR;
title "&Country Customers Ages 18 to 24";
proc print data=mc1.customers;
var Name Age Type;
where Country = "&Country"
and Age between 18 and 24;
run;
title;
/* Part d. */
%let Country=AU;
%let age1=25;
%let age2=34;
title "&Country Customers Ages &age1 to &age2";
proc print data=mc1.customers;
var Name Age Type;
where Country = "&Country"
and Age between &age1 and &age2;
run;
title;
What is the report title? AU Customers Ages 25 to 34
How many observations were read? 10
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.3 Solutions 2-41
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-42 Lesson 2 SAS® Macro Facility
14
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.3 Solutions 2-43
45
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-44 Lesson 2 SAS® Macro Facility
The period between &lib and cars was interpreted as a macro delimiter,
so the table name incorrectly resolved to SASHELPCARS.
71
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
76
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
The default colors for notes, errors, and warnings might be different in your environment.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2.3 Solutions 2-45
79
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
2-46 Lesson 2 SAS® Macro Facility
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
Lesson 3 Storing and Processing
Text
3.1 Macro Functions ..................................................................................................................... 3-3
Demonstration: Macro Functions ......................................................................................... 3-19
Practice ................................................................................................................................. 3-21
3.3 Using the DATA Step to Create Macro Variables ............................................................... 3-34
Demonstration: Creating Macro Variables with the DATA Step ........................................... 3-48
Practice ................................................................................................................................. 3-52
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Macro Functions 3-3
SAS Functions
data cars_subset;
set sashelp.cars; SAS functions
where upcase(DriveTrain)="FRONT";
run; manipulate data
values during the
Sashelp.cars (partial) execution phase.
Make Model DriveTrain
Acura MDX ... All
Acura TSX 4dr ... Front
Acura RSX Type S 2dr ... Front
3
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
data cars_subset;
set sashelp.cars;
where upcase(DriveTrain)="FRONT";
run;
4
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-4 Lesson 3 Storing and Processing Text
%let dt=front;
data cars_subset;
set sashelp.cars; UPCASE
where upcase(DriveTrain)="&dt";
run;
PROPCASE
title "&dt Wheel Drive Cars";
footnote "Listing from CARS_SUBSET Table";
proc print data=&syslast; Can functions
run; manipulate
program text?
5
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m103d01.sas
6
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Macro Functions 3-5
Compiler
Macro Processor
Word
Scanner
7
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Macro Processor
Word
literal start "
Scanner special %
name upcase
...
8
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-6 Lesson 3 Storing and Processing Text
Macro Processor
Word
literal start "
Scanner
9
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Macro Processor
Word
literal start "
Scanner
10
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Macro Functions 3-7
Macro Processor
Word
literal start "
Scanner name FRONT
literal end "
special ;
11
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Input
Stack
12
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-8 Lesson 3 Storing and Processing Text
13
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
resulting statement
where upcase(DriveTrain)=upcase("front");
14
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Macro Functions 3-9
resulting statement
The %UPCASE function
where upcase(DriveTrain)="FRONT"; converts front to FRONT once
in the macro processor before
the statement is compiled.
15
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
3.01 Activity
Open m103a01.sas from the activities folder and perform the following
tasks:
1. Examine the TITLE statement. What text will appear as the title? Run
the program and view the results.
2. Add % before the UPCASE function in the TITLE statement. Run the
program. What text appears as the title?
16
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m103a01.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-10 Lesson 3 Storing and Processing Text
18
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Macro Functions 3-11
21
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-12 Lesson 3 Storing and Processing Text
%let dt=front;
...
22
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m103d01.sas
3.02 Activity
Open m103a02.sas from the activities folder and perform the following tasks:
1. Run the program and examine the output and the log. SAS does not have
a %PROPCASE macro function, so it does not successfully resolve and the
title is incorrect.
2. Modify the TITLE statement to use the %SYSFUNC macro function in
combination with the PROPCASE function.
title "%sysfunc(propcase(&dt)) Wheel Drive Cars";
23
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Macro Functions 3-13
%let season=2019;
%let nextseason=&season+1; How can I ask the
macro processor to
evaluate arithmetic
Global Symbol Table expressions?
Name Value
SEASON 2019
NEXTSEASON 2019+1
25
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
%let season=2019;
%let nextseason=%sysevalf(&season+1);
Use the
%SYSEVALF
macro function!
Global Symbol Table
Name Value
evaluates an arithmetic
SEASON 2019 or logical expression
NEXTSEASON 2020 and returns a text value
26
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
%SYSEVALF performs precise numeric calculations. %EVAL is a legacy macro function that performs
simple integer arithmetic.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-14 Lesson 3 Storing and Processing Text
%SYSEVALF(expression<,conversion-type>)
Expression Value
%sysevalf(10/3.5) 2.85714285714285
%sysevalf(10/3.5,ceil) 3
%sysevalf(10/3.5,floor) 2
%sysevalf(10/3.5,integer) 2
%sysevalf(1.2<3,boolean) 1
27
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Macro Functions 3-15
%let clear=title;footnote;;
%put &=clear;
73 %let clear=title;footnote;;
74 %put &=clear;
CLEAR=title
30
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
31
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-16 Lesson 3 Storing and Processing Text
32
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
33
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Macro Functions 3-17
34
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
3.03 Activity
Open m103a03.sas from the activities folder and perform the following tasks:
1. The intent of the %SCAN function is to return the city from the Location
macro variable using only the comma as a delimiter. Run the program and
examine the log. Why does the program fail?
2. Use %STR to mask the comma in the appropriate places so that the value
of the City macro variable is Buenos Aires.
35
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-18 Lesson 3 Storing and Processing Text
76 %put &=dept;
DEPT=RDenmark
Global Symbol Table
Name Value
D Denmark
DEPT R&D
38
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
%let dept=%nrstr(R&D);
Global Symbol Table
Name Value
The & is treated as D Denmark
regular text rather DEPT R&D
than a macro trigger.
39
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Several macro functions have an alternative “Q” function that manipulates text and returns a result
that masks special characters and mnemonic operators:
• %QUPCASE
• %QSCAN
• %QSUBSTR
• %QSYSFUNC
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Macro Functions 3-19
Macro Functions
Scenario
This demonstration illustrates using macro statements and macro functions to create and populate
macro variables.
Files
• m103d02.sas
• mc1.storm_final
Syntax
%SYSEVALF(argument)
%SYSFUNC(function(argument(s))<,format>)
%STR(argument)
Notes
• Macro functions can be used to manipulate the text in a SAS program.
• The %SYSFUNC macro function enables the macro processor to execute most DATA step
functions. The first argument is a DATA step function, and the optional second argument is a format
to display the value returned by the first argument.
Demo
1. Open m103d02.sas from the demos folder and review the program.
a. Two macro variables, Year and WindM (miles per hour), are created and assigned values.
b. The values of these macro variables are used in the TITLE and WHERE statements.
c. Two automatic macro variables, Sysdate9 and Systime, are used in the FOOTNOTE
statement to print the day and time the SAS session began.
d. Run the program and confirm that six rows are printed. Verify that the macro variable values
are substituted in the title and footnote.
%let year=2015;
%let windm=150;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-20 Lesson 3 Storing and Processing Text
2. Modify the TITLE2 statement to include the WindM value converted to kilometers per hour. This
value can be calculated by multiplying the value of the WindM macro variable by 1.61. The
%SYSEVALF macro function must be used to perform the calculation and insert the resulting
value as text. Run the program and confirm that six rows are returned and that the title is correct.
title2 "Winds Exceeding &windm M/H or %sysevalf(&windm*1.61) KM/H";
3. Notice that the date and time in the footnote represent when the SAS session started rather than
the current date and time. Modify the FOOTNOTE statement to use %SYSFUNC in combination
with the TODAY() and TIME() functions to insert the date and time at which the program executes.
Use the second argument in %SYSFUNC to apply an appropriate format. Run the program and
confirm that the date and time in the footnote are current.
footnote "Report Created on %sysfunc(today(), date9.) at
%sysfunc(time(), timeampm.)";
4. The FOOTNOTE statement can be stored in a macro variable so that it can be easily reused in
other parts of the program. Use a %LET statement to assign the full FOOTNOTE statement to a
macro variable named dtfoot. Surround the FOOTNOTE statement with the %STR function to
mask special characters but still resolve macro triggers.
%let dtfoot=%str(footnote "Report Created on
%sysfunc(today(),date9.) at %sysfunc(time(),timeampm.)";);
5. Replace the previous FOOTNOTE statement with the &dtfoot macro variable reference. Run the
program and confirm the footnote is correct.
Note: A semicolon is not needed after &dtfoot because it is included as part of the macro
variable value. It might cause the color coding in your editor to appear as if there is a
syntax error in the PROC PRINT step.
%let year=2015;
%let windM=150;
%let dtfoot=%str(footnote "Report Created on %sysfunc(today(),
date9.) at %sysfunc(time(), timeampm.)";);
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.1 Macro Functions 3-21
Practice
Level 1
1. Using the %UPCASE and %SCAN Functions
a. Open m103p01.sas from the practices folder. Add a %LET statement to convert the value of
FullName to uppercase and assign the result to FullName. Write a single %PUT statement to
display FullName in a sentence using both its current form and proper case, as shown below.
Submit the program and view the log to verify the results.
Note: Use %SYSFUNC to execute the PROPCASE function.
ANTHONY MILLER in proper case is Anthony Miller.
c. Add a %SYMDEL statement to delete FullName, First, and Last from the global symbol
table. Use a %PUT statement to write the values of all user-defined macro variables to the
log. Submit the two statements and verify that that FullName, First, and Last are no longer
listed.
Level 2
2. Using Macro Quoting Functions
a. Open m103p02.sas from the practices folder and review the code. Submit the program and
review the results. Note that the footnote includes the date and time that the SAS session
started.
b. Create a macro variable named Product and assign the value R&D. Reference Product in
the TITLE and WHERE statements, replacing Jacket. Modify the FOOTNOTE statement to
display the current date and time, using the DATE9 and TIMEAMPM9 formats respectively.
Submit the program and verify that the title is Product Names Containing 'R&D' and that the
current date and time are displayed in the footnote.
• How many rows are in the report?
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-22 Lesson 3 Storing and Processing Text
Challenge
3. Using Macro Functions to Perform Calculations
a. Assign your birthdate to a macro variable named Birthdate in the form DDMONYYYY (for
example, 01Jan1990). Use %SYSEVALF to calculate your age by subtracting your birthdate
from today’s date and dividing the difference by 365.25. Write the result to the log.
For example, if your birthday is January 1, 1990, and today is April 3, 2019, the results would
appear as shown below. Hint: Reference Birthdate as a SAS date constant ("&birthdate"d).
Note: The value of age depends on the current date.
My age is 29.2183436002737
b. Use the second argument to %SYSEVALF to return just the integer portion of your age and
write the results to the log.
For example, if your birthday is January 1, 1990, and today is April 3, 2019, the results would
appear as shown below.
My age is 29
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.2 Using SQL to Create Macro Variables 3-23
%LET
statement %LET is an easy
way to create a
macro variable and
%let type=Sedan; assign a value.
44
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
45
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-24 Lesson 3 Storing and Processing Text
46
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
47
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.2 Using SQL to Create Macro Variables 3-25
49
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m103d03.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-26 Lesson 3 Storing and Processing Text
50
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m103d03.sas
When capturing multiple rows of values into a series of macro variables, unwanted blanks
are automatically trimmed before the values are stored. Use of the TRIMMED modifier is not
necessary and will generate an error.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.2 Using SQL to Create Macro Variables 3-27
52
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m103d03.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-28 Lesson 3 Storing and Processing Text
Scenario
This demonstration uses the INTO clause in PROC SQL to write SQL query results into macro
variables.
Files
• m103d04.sas
• mc1.storm_damage
• mc1.storm_type_codes
Syntax
Notes
• PROC SQL can be used to load data values from table columns or values calculated in a query into
one or more macro variables.
• The INTO clause assigns values produced by PROC SQL to macro variables.
Demo
1. Open m103d04.sas from the demos folder. In Section 1 of the program, note that the PROC SQL
step calculates the mean of the Cost column and writes the result to a macro variable named
Avgcost. The %PUT statements write the values of the Avgcost and Sqlobs macro variables to
the log.
proc sql;
select mean(cost)
into :avgcost
from mc1.storm_damage;
quit;
%put &=avgcost;
%put &=sqlobs;
2. Highlight the code in Section 1 and submit the selected program. Note that the SQL query
produces a report that shows the mean of Cost from the storm_damage table, which is
formatted using scientific notation. View the log to confirm that the value is also stored in the
macro variable Avgcost. The value of the Sqlobs macro variable is 1 because one row was
returned by the query.
79 %put &=avgcost;
AVGCOST=2.238E10
80 %put &=sqlobs;
SQLOBS=1
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.2 Using SQL to Create Macro Variables 3-29
3. Modify the query to suppress the report and format the result.
a. Add the NOPRINT option to the PROC SQL statement.
b. Add the FORMAT=DOLLAR20. column modifier to format the mean of Cost.
proc sql noprint;
select mean(cost) format=dollar20.
into :avgcost
...
c. Highlight the code in Section 1, submit the selected program, and review the log and results.
Note that a report is no longer produced and that the value stored in the macro variable
Avgcost is formatted with a dollar sign and commas. There are leading spaces in the macro
variable’s value.
80 %put &=avgcost;
AVGCOST= $22,381,578,947
d. Add the TRIMMED modifier after the Avgcost variable name in the INTO clause. Submit the
modified code and review the log. Note that the value of Avgcost no longer contains the
leading spaces.
proc sql noprint;
select mean(cost) format=dollar20.
into :avgcost trimmed
...
79 %put &=avgcost;
AVGCOST=$22,381,578,947
80 %put &=sqlobs;
SQLOBS=1
%put &=avgcost;
%put &=medcost;
%put &=sqlobs;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-30 Lesson 3 Storing and Processing Text
d. Highlight the PROC SQL step and %PUT statements, and submit the selected code. Confirm
in the log that the macro variable values are all formatted with leading spaces trimmed.
81 %put &=avgcost;
AVGCOST=$22,381,578,947
82 %put &=medcost;
MEDCOST=$8,600,000,000
83 %put &=sqlobs;
SQLOBS=1
5. Examine the SQL query in Section 2. The query selects all columns from the
mc1.storm_type_codes table. Highlight the code in Section 2 and submit the selected program.
Notice that the report displays five values for Type and StormType.
proc sql;
select *
from mc1.storm_type_codes;
quit;
6. Modify the query to suppress the printed report and load each value of StormType into a
numbered series of macro variables starting with Type1. Uncomment the %PUT statements to
write the values of the macro variables to the log.
Note: You do not need to specify the name of final macro variable in the range.
proc sql noprint;
select StormType
into :type1-
from mc1.storm_type_codes;
quit;
8. Modify the query to load all values of StormType into a single macro variable named TypeList.
Separate each value with a comma and a space. Write the value of TypeList in the log.
proc sql noprint;
select StormType
into :typelist separated by ", "
from mc1.storm_type_codes;
quit;
%put &=typelist;
%put &=sqlobs;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.2 Using SQL to Create Macro Variables 3-31
9. Highlight the code in Section 2 and submit the selected program. Note in the log that all five
values of StormType are stored in TYPELIST as a comma-delimited list.
79 %put &=typelist;
TYPELIST=Disturbance, Extratropical, Not Reported, Subtropical, Tropical
80 %put &=sqlobs;
SQLOBS=5
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-32 Lesson 3 Storing and Processing Text
Practice
Level 1
4. Using PROC SQL to Generate Macro Variables for Use in a Report Title
a. Open m103p04.sas from the practices folder. Review the code and submit the %LET
statements and the PROC SQL step. Verify that Qty (the mean for Quantity) is 1.43 and
Price (the mean for Total_Retail_Price) is 137.72.
b. In the TITLE2 statement, replace xxx with the mean for Quantity (1.43), and replace yyy with
the mean for Total_Retail_Price (137.72). Submit the TITLE statements and the PROC
PRINT step, and review the log and results.
• How many rows were read from the input table?
c. In the PROC SQL step, add an INTO clause to assign the mean for Quantity to a macro
variable named Qty, and the mean for Total_Retail_Price to a macro variable named Price.
In the TITLE2 statement, replace the hardcoded mean values with references to Qty and
Price.
Submit the entire program and review the log and results. Verify that the title displayed
correctly.
• How many rows were read from the input table?
• Why is the average price displayed with a leading dollar sign in the title?
d. Modify the %LET statements to assign 01Feb2019 to start and 28Feb2019 to stop. Submit
the program again.
• How many rows were read from the input table?
• What are the resolved values of qty and price in TITLE2?
Level 2
5. Using PROC SQL to Generate Macro Variables for Use in Subsequent Steps
a. Open m103p05.sas from the practices folder. Review and submit the code in part a. Verify
that the reported average wind speed is 79.
b. Review the code in part b. Replace every occurrence of XX with the average wind speed from
step a. Submit the code in part b and review the results.
• How many rows are in the table?
• Which bar has the highest frequency?
c. Modify the PROC SQL step.
• Suppress the PROC SQL output.
• Store the calculated value in a macro variable named AvgWind with no leading spaces.
• Add another SELECT statement to select the BasinName value from
mc1.storm_basin_codes where Basin is equal to the basincode macro variable. Write
the value to a macro variable named BasinName.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.2 Using SQL to Create Macro Variables 3-33
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-34 Lesson 3 Storing and Processing Text
DATA step
57
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Scenario
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.3 Using the DATA Step to Create Macro Variables 3-35
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-36 Lesson 3 Storing and Processing Text
3.04 Activity
Open m103a04.sas from the activities folder and perform the following tasks:
1. Run the program with Acura as the value of Make. First, examine the
output data and confirm that the value of HybridFlag is missing for the
last row because there are no hybrid cars. Second, confirm that the
footnote for the report is correct.
2. Modify the %LET statement to assign Honda as the value of the Make
macro variable. Run the program and view the output data. Confirm that
the value of HybridFlag is 1 for the last row.
3. Examine the report. Is the footnote correct?
62
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.3 Using the DATA Step to Create Macro Variables 3-37
end;
else do;
Input %let foot=&make Does Not Have a Hybrid Car;
end;
Stack end;
run;
65
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-38 Lesson 3 Storing and Processing Text
66
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
67
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.3 Using the DATA Step to Create Macro Variables 3-39
68
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-40 Lesson 3 Storing and Processing Text
Compilation
70
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
71
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.3 Using the DATA Step to Create Macro Variables 3-41
72
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Note: We discuss and demonstrate the uses of an optional third argument, <scope>,
in a subsequent lesson.
73
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-42 Lesson 3 Storing and Processing Text
74
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m103d05.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.3 Using the DATA Step to Create Macro Variables 3-43
76
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m103d05.sas
77
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m103d05.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-44 Lesson 3 Storing and Processing Text
data _null_;
call symputx('foot', 'No Hybrid Cars');
%let foot=Some Hybrid Cars;
run;
78
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
The DATA _NULL_ statement enables you to read the input table and execute DATA step code
without creating an output table.
Scenario
80
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.3 Using the DATA Step to Create Macro Variables 3-45
%let make=Honda;
data &make;
set sashelp.cars end=lastrow;
where upcase(Make)="%upcase(&make)";
if Type="Hybrid" then HybridCount+1;
if lastrow=1 then do;
call symputx("hybridnum", HybridCount);
end;
run;
fixed macro DATA step
variable name variable
81
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m103d05.sas
82
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m103d05.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-46 Lesson 3 Storing and Processing Text
84
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m103d05.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.3 Using the DATA Step to Create Macro Variables 3-47
3.06 Activity
Open m103a06.sas from the activities folder and perform the following tasks:
1. Highlight the %LET statement and PROC MEANS step and run the
selection. Examine the output data.
2. Complete the CALL SYMPUTX statement to create a macro variable
named AvgMSRP and load the value of the Mean column from the
CarsStat table.
3. Run the completed program. What is the value of the second title?
85
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-48 Lesson 3 Storing and Processing Text
Scenario
This demonstration uses the SYMPUTX CALL routine in the DATA step to create and populate macro
variables.
Files
• m103d06.sas
• mc1.storm_damage
• mc1.storm_type_codes
Syntax
Notes
• CALL SYMPUTX can be used to create macro variables and assign values during DATA step
execution.
• SYMPUTX automatically trims leading and trailing spaces from values assigned to macro variables.
Demo
1. Open m103d06.sas from the demos folder. In Section 1, the PROC MEANS step calculates the
mean and median for Cost from mc1.storm_damage and stores the results in an output table
named sumdata. Highlight the PROC MEANS step, run the selected code, and examine the
output table.
proc means data=mc1.storm_damage noprint;
var Cost;
output out=work.sumdata mean= median= /autoname;
run;
2. In the DATA _NULL_ step, add CALL SYMPUTX statements to create macro variables named
AvgCost and MedCost, and assign the values from the variables cost_mean and cost_median.
Highlight the code in Section 1, submit the selection, and examine the log. Notice that leading
blanks are automatically trimmed. However, the values are not formatted.
...
data _null_;
set sumdata;
call symputx("avgcost", cost_mean);
call symputx("medcost", cost_median);
run;
%put &=avgcost &=medcost;
AVGCOST=22381578947.3684 MEDCOST=8600000000
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.3 Using the DATA Step to Create Macro Variables 3-49
3. Modify the program to use the PUT function to write numeric values with the DOLLAR20. format.
Highlight the code in Section 1, submit the selection, and review the log. The macro variable
values are now formatted.
...
call symputx("avgcost", put(cost_mean, dollar20.));
call symputx("medcost", put(cost_median, dollar20.));
...
AVGCOST=$22,381,578,947 MEDCOST=$8,600,000,000
4. Find Section 2 in the program. Highlight the PROC PRINT step and run the selected code to view
the mc1.storm_type_codes table.
5. Notice that the DATA _NULL_ step creates a macro variable named Type and assigns the value
from the StormType column. Highlight the DATA step and %PUT statement, and run the selected
code. The log shows that the value of Type is Tropical, which is the last value from the
StormType column.
81 %put &=type;
TYPE=Tropical
6. Create a numbered series of macro variables starting with Type1 that will store each of the values
of the StormType column. Modify the first argument in the CALL SYMPUTX routine to
concatenate the prefix Type with the value of _N_. Delete the previous %PUT statement and
uncomment the %PUT statement that will display the Typen macro variables and values.
proc print data=mc1.storm_type_codes;
run;
data _null_;
set mc1.storm_type_codes;
call symputx(cats("type", _n_), StormType);
run;
8. Recall that in the mc1.storm_type_codes table, the Type column contains a two-letter code that
uniquely identifies the StormType values. Type values are valid as macro variable names. Modify
the DATA step to create a series of macro variables with the value of Type as the name and the
value of StormType as the macro variable value. Delete the previous %PUT statement and
uncomment the %PUT statement that will write the values of the macro variables DS, ET, NR,
SS, and TS to the log.
data _null_;
set mc1.storm_type_codes;
call symputx(Type, StormType);
run;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-50 Lesson 3 Storing and Processing Text
9. Submit the modified program and review the log. Note that the DATA step read five observations
and created a series of macro variables named DS, ET, NR, SS, and TS.
DS=Disturbance ET=Extratropical NR=Not Reported SS=Subtropical TS=Tropical
10. The Sqlobs macro variable is not populated when creating macro variables with the DATA step.
Modify the DATA step to record the number of macro variables produced.
a. Add the END=LAST option to the SET statement.
b. Add IF-THEN logic to execute CALL SYMPUTX to write the value of _N_ to a macro variable
named Dsobs when the last row of the table is being processed.
c. Add Dsobs to the %PUT statement.
data _null_;
set mc1.Storm_Type_Codes end=last;
call symputx(Type,StormType);
if last then call symputx('dsobs',_n_);
run;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.3 Using the DATA Step to Create Macro Variables 3-51
• can create a series of macro • can summarize data and load values
variables with both names and into a macro variable in one step
values based on columns • can load a delimited list into a
• can manipulate either the macro macro variable
variable names or values • can create a numbered series of
macro variables storing the distinct
values of a column
89
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-52 Lesson 3 Storing and Processing Text
Practice
Level 1
6. Creating Macro Variables with the SYMPUTX Routine
a. Open m103p06.sas from the practices folder. Review and submit the program. Verify that
the report title is New Staff: Administration Department and that the sum of Salary is
$221,618.
b. Add a %LET statement to assign the value Administration to a new macro variable named
dept, and replace every occurrence of Administration with a reference to dept. Submit the
modified program and verify that the title and report are the same as in part a.
c. Change the value of dept to Sales and submit the program. Verify that the report title is New
Staff: Sales Department.
• What is the sum of Salary?
d. Modify the DATA step to create a macro variable named avg to store the average salary on
the last iteration. Hint: Use the PUT function and the DOLLAR9. format when assigning the
value to avg.
Add a FOOTNOTE statement before the PROC PRINT step to display the value of avg as
shown below. Submit the program and review the results.
Average Salary: $xx,xxx
• What text is displayed in the footnote?
Level 2
7. Using a DATA _NULL_ Step to Create a Series of Macro Variables
a. Open m103p07.sas from the practices folder and review the program. The sashelp.vmacro
data source is a dynamic view that contains the name and value of all macro variables in the
current SAS session. Run the program and view the report.
b. Insert a DATA _NULL_ step before the PROC PRINT step to create a series of macro
variables using the values stored in the mc1.Storm_Ocean_Codes table. Use the values in
Ocean to name the macro variables. Use the values in OceanName as the macro variable
values.
c. Modify the PROC PRINT step to display only macro variables that are one character. Submit
the entire program and verify that five macro variables were created.
• What is the value of the macro variable, S?
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.4 Indirect References to Macro Variables 3-53
Scenario
%let cat=3;
%put NOTE: Category &cat storms >= 111 MPH;
mc1.storm_cat
Category MinWind How can I automatically
1 74 substitute the wind speed
2 96 into the program based
3 111 on the category value?
4 130
5 157
93
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
proc sql noprint; Either the DATA step or PROC SQL can
select MinWind create a series of macro variables that store
into :wind1-
minimum wind speeds for each category.
from mc1.storm_cat;
quit;
Global Symbol Table
OR Name Value
WIND1 74
data _null_; WIND2 96
set mc1.storm_cat;
WIND3 111
call symputx(cats("wind",_n_), MinWind);
run; WIND4 130
WIND5 157
94
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m103d07.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-54 Lesson 3 Storing and Processing Text
95
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
96
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.4 Indirect References to Macro Variables 3-55
97
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
98
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-56 Lesson 3 Storing and Processing Text
99
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
3.07 Activity
Open m103a07.sas from the activities folder and perform the following tasks:
1. Notice that the wind values have been replaced with &wind&cat. Run
the program and review the log.
2. Change &wind&cat to &&wind&cat. Run the program and review the
log. Does the program run successfully?
100
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.4 Indirect References to Macro Variables 3-57
102
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
103
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-58 Lesson 3 Storing and Processing Text
104
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.4 Indirect References to Macro Variables 3-59
The values of the column named in the first argument must be unique and valid macro variable
names.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-60 Lesson 3 Storing and Processing Text
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.4 Indirect References to Macro Variables 3-61
Scenario
This demonstration uses a series of macro variables as lookup tables with indirect referencing.
Files
• m103d08.sas
• mc1.storm_final
• mc1.storm_cat
• mc1.storm_basin_codes
Syntax
&&prefix&varname
&&&varname
Notes
• Use indirect referencing to look up values stored in a series of macro variables.
• Two ampersands (&&) resolve to one ampersand (&).
• A single ampersand followed by a name token is resolved.
• The macro processor then rescans the text until no more references can be resolved.
Demo
1. Open program m103d08.sas from the demos folder. Review the program:
a. The %LET statements create macro variables Year, Cat, and Basin.
%let year=2016;
%let cat=2;
%let basin=SI;
b. The PROC SQL step creates a numbered series of macro variables, Wind1 through Wind5,
with values assigned from the MinWind column in the mc1.storm_cat table. For example,
the minimum wind speed for a Category 2 storm is captured in the Wind2 macro variable.
proc sql noprint;
select MinWind
into :wind1-
from mc1.storm_cat;
quit;
c. The DATA step creates a series of macro variables with names derived from the Basin
column and values assigned from the BasinName column. For example, the macro variable
SI has a value of South Indian.
data _null_;
set mc1.storm_basin_codes;
call symputx(Basin, BasinName);
run;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-62 Lesson 3 Storing and Processing Text
d. The TITLE statement and PROC PRINT step include direct macro variable references,
&basin, &year, and &cat.
e. The WHERE statement includes an indirect macro variable reference, &&wind&cat, which
resolves to Wind1, Wind2, and so on, up to Wind5, depending on the value of &cat.
title1 "&basin &year Category &cat+ Storms";
proc print data=mc1.storm_final noobs;
where Basin="&basin" and
MaxWindMPH>=&&wind&cat and
Season=&year;
run;
2. Submit the program and review the output and log. Confirm that three storms are returned and
the title includes the Basin, Year, and Cat macro variable values.
3. Replace &basin in the TITLE statement with &&&basin. If the value of the macro variable Basin
is SI, then &&&basin first resolves to &SI, which then resolves to South Indian. Run the program
and confirm that the title includes South Indian.
4. Change the value of Year to 2014, Cat to 3, and Basin to NA. Submit the program and confirm
that two storms are returned and the title is updated.
5. Open the mc1.storm_cat table. Notice that the Damage column contains a descriptive label for
each value of Category.
6. In the program, modify the SQL query to select an additional column, Damage, and load values
into a range of macro variables, Damage1 through Damage5.
proc sql noprint;
select MinWind, Damage
into :wind1-, :damage1-
from mc1.storm_cat;
quit;
7. Add a FOOTNOTE statement before the PROC PRINT step that includes the selected storm
category and the corresponding damage description. Run the program and observe the results.
footnote "Category &cat storms typically cause &&damage&cat";
8. The resolved value of &&damage&cat has the first letter capitalized. Use the %LOWCASE
function to change the case of the returned text string in the TITLE statement. Run the program
and confirm that the footnote is correct.
footnote "Category &cat storms typically cause
%lowcase(&&damage&cat)";
9. Change the values of Year to 2015, Cat to 2, and Basin to WP. Confirm that the report, title, and
footnote are all updated.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.4 Indirect References to Macro Variables 3-63
Practice
Level 1
8. Using Indirect References to Macro Variables
a. Open m103p08.sas from the practices folder. Submit the code and review the results.
Level 2
9. Using Indirect References to Macro Variables
a. Open m103p09.sas from the practices folder and review the code. Submit the program and
review the results. Verify that the report is titled Customers Residing in LU and that there are
three rows in the report.
b. At the top of the program, insert a DATA _NULL_ step to create a series of macro variables
from the mc1.country_codes table. Use the value in the CountryCode column as the macro
variable name, and use the value of the corresponding CountryName column as the macro
variable's value. Submit the DATA _NULL_ step to create the macro variables.
c. Modify the TITLE statement to include the country name based on the value of the code
macro variable. Verify that the title is Customers Residing in Luxembourg.
d. Modify the %LET statement to assign a value of ZA to the macro variable, code. Submit the
program and review the results.
• How many customers are from ZA, and what is the country name?
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-64 Lesson 3 Storing and Processing Text
3.5 Solutions
Solutions to Practices
Section 3.1
1. Using the %UPCASE and %SCAN Functions
/* Part a. */
%let fullname=AnTHoNY MilLeR;
%put &fullname;
%let fullname=%upcase(&fullname);
%put &fullname in proper case is
%sysfunc(propcase(&fullname)).;
/* Part b. */
%let first=%sysfunc(propcase(%scan(&fullname,1)));
%let last=%sysfunc(propcase(%scan(&fullname,-1)));
%put &=fullname &=first &=last;
/* Part c. */
%symdel fullname first last;
%put _user_;
2. Using Macro Quoting Functions
%let product=%nrstr(R&D);
title "Product Names Containing '&product'";
footnote "Report Produced %sysfunc(date(), date9.)
%sysfunc(time(),timeampm9.)";
proc print data=mc1.products;
where Product_Name contains "&product";
var Product_Name Product_ID Supplier_Name;
run;
title;
footnote;
How many rows are in the report? Eight rows
3. Using Macro Functions to Perform Calculations
/* Part a. */
%let birthdate=01Jan1990;
%put My age is %sysevalf((%sysfunc(today())-
"&birthdate"d)/365.25);
/* Part b. */
%put My age is %sysevalf((%sysfunc(today())-
"&birthdate"d)/365.25, int);
Section 3.2
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.5 Solutions 3-65
4. Using PROC SQL to Generate Macro Variables for Use in a Report Title
/* Part b. */
%let start=01Jan2019;
%let stop=31Jan2019;
proc sql noprint;
select mean(Quantity) format=4.2 as qty,
mean(Total_Retail_Price) format=dollar7.2 as price
from mc1.orders
where Order_Date between "&start"d and "&stop"d;
quit;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-66 Lesson 3 Storing and Processing Text
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.5 Solutions 3-67
/* Part e. */
%let year=2015;
%let basincode=EP;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-68 Lesson 3 Storing and Processing Text
select BasinName
into :basinname
from mc1.storm_basin_codes
where basin="&basincode";
quit;
Section 3.3
6. Creating Macro Variables with the SYMPUTX Routine
/* Part b. */
%let dept=Administration;
data staff;
keep Employee_ID Department Job_Title Salary;
set mc1.newhires;
where Department="&dept";
run;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.5 Solutions 3-69
run;
Section 3.4
8. Using Indirect References to Macro Variables
/* Parts c. and d. */
proc sql noprint;
select Order_Type
into :type1-
from mc1.order_type_codes;
quit;
%put &=type1 &=type2 &=type3;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-70 Lesson 3 Storing and Processing Text
/* Part e. */
%let code=1;
title "High Profit Products for &&type&code Orders";
proc sql number;
select Product_ID format=z12.,
Sum(Total_Retail_Price) format=dollar10.2 as GrossSales,
Sum(Total_Retail_Price-CostPrice_Per_Unit)
format=dollar10.2 as Profit
from mc1.orders
where Order_Type=&code
group by Product_ID
having profit /grosssales > .95
order by Profit desc;
quit;
title;
/* Part f. */
%let code=3;
title "High Profit Products for &&type&code Orders";
proc sql number;
select Product_ID format=z12.,
Sum(Total_Retail_Price) format=dollar10.2 as GrossSales,
Sum(Total_Retail_Price-CostPrice_Per_Unit)
format=dollar10.2 as Profit
from mc1.orders
where Order_Type=&code
group by Product_ID
having profit /grosssales > .95
order by Profit desc;
quit;
title;
What is the report title? High Profit Products for Internet Orders
9. Using Indirect References to Macro Variables
/* Part b. */
data _null_;
set mc1.country_codes;
call symputx(CountryCode,CountryName);
run;
/* Part c. */
%let code=LU;
title "Customers Residing in &&&code";
proc print data=mc1.customers;
id ID;
var Name Age_Group;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.5 Solutions 3-71
where Country="&code";
run;
title;
/* Part d. */
%let code=ZA;
title "Customers Residing in &&&code";
proc print data=mc1.customers;
id ID;
var Name Age_Group;
where Country="&code";
run;
title;
How many customers are from ZA, and what is the country name? There are seven customers
from South Africa.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-72 Lesson 3 Storing and Processing Text
2. Add % before the UPCASE function in the TITLE statement. Run the
program. What text appears as the title?
%let text=class list;
title "%upcase(&text)";
proc print data=sashelp.class;
run;
17
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m103a01.sas
24
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.5 Solutions 3-73
36
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
37
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-74 Lesson 3 Storing and Processing Text
63
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
data _null_;
call symputx('foot', 'No Hybrid Cars’);
%let foot=Some Hybrid Cars;
run;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3.5 Solutions 3-75
continued...
3.06 Activity – Correct Answer
What is the value of the second title?
data _null_;
set CarsStat;
call symputx("avgmsrp",Mean);
run; Which DATA step
function can convert
title "&make Cars"; a number to a
title2 "Average MSRP: &avgmsrp";
proc print data=sashelp.cars noobs; formatted character
where Make="&make"; string?
run;
title;
86
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
87
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
3-76 Lesson 3 Storing and Processing Text
101
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
Lesson 4 Working with Macro
Programs
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.1 Defining and Calling a Macro 4-3
Use macro-level
Start with a Generalize Create a macro Validate
programming Add Data Driven
validated SAS with macro definition with parameters and
for complex Features
program variables parameters document
processing
3
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Use macro-level
Start with a Generalize Create a macro Validate
programming Add Data Driven
validated SAS with macro definition with parameters and
for complex Features
program variables parameters document
processing
4
Copy ri ght © S AS Insti tute Inc . Al l ri ghts reserved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-4 Lesson 4 Working with Macro Programs
Use macro-level
Start with a Generalize Create a macro Validate
programming Add Data Driven
validated SAS with macro definition with parameters and
for complex Features
program variables parameters document
processing
%let dsn=sashelp.cars;
%let obs=5;
proc print data=&dsn(obs=&obs);
run;
5
Copy ri ght © S AS Insti tute Inc . Al l ri ghts reserved.
Use macro-level
Start with a Generalize Create a macro Validate
programming Add Data Driven
validated SAS with macro definition with parameters and
for complex Features
program variables parameters document
processing
6
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.1 Defining and Calling a Macro 4-5
Macro Definitions
7
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m104d01.sas
Macro names must start with a letter or an underscore, and remaining characters can be letters,
numbers, or underscores.
Macro Definitions
8
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-6 Lesson 4 Working with Macro Programs
Macro Definitions
PROC CATALOG
proc catalog catalog=work.sasmacr; can be used to list
contents;
the contents of a
run;
catalog.
9
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m104d01.sas
continued...
4.01 Activity
Open m104a01.sas from the activities folder and perform the following tasks:
1. Notice that there is a missing semicolon after the PROC PRINT statement.
Run the program and confirm that an error is generated in the log. Do not
correct the error.
2. Modify the code to create a macro program named PrintTable. Run the
program and notice that there are no notes, warnings, or errors in the log.
%macro printtable;
proc print data=&dsn(obs=&obs)
run;
%mend printtable;
10
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.1 Defining and Calling a Macro 4-7
4.01 Activity
3. Add the following OPTIONS statements at the start of the program to
set the MCOMPILENOTE=ALL option.
options mcompilenote=all;
4. Submit the program. The log includes a note indicating that the
PrintTable macro compiled without errors.
5. Why does the macro program compile successfully even though there is
a syntax error in the PROC PRINT step?
11
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Macro Definitions
%macro printtable;
proc print data=&dsn(obs=&obs);
run;
%mend printtable;
options mcompilenote=none;
NOTE: The macro PRINTTABLE completed
compilation without errors.
13
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-8 Lesson 4 Working with Macro Programs
Calling a Macro
A macro call
%macro-name
executes the code
stored in the macro
definition.
%let dsn=sashelp.cars;
%let obs=5;
%printtable
Do not include a
semicolon after
the macro call.
14
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Calling a Macro
Compiler
Macro Processor
%printtable
work.sasmacr
Input
Name Stored Code
Stack
proc print data=&dsn(obs=&obs);
PRINTTABLE run;
15
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.1 Defining and Calling a Macro 4-9
Calling a Macro
%printtable
Compiler
Macro Processor
work.sasmacr
Input
Name Stored Code
Stack
proc print data=&dsn(obs=&obs);
PRINTTABLE run;
16
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Calling a Macro
%printtable
Compiler
Macro Processor
work.sasmacr
Input
Name Stored Code
Stack
proc print data=&dsn(obs=&obs);
PRINTTABLE run;
17
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-10 Lesson 4 Working with Macro Programs
Calling a Macro
Compiler
Macro Processor
18
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Calling a Macro
&dsn
The program is
Compiler
tokenized and macro
references are resolved.
Macro Processor
name proc
name print Global Symbol Table
Word name data
Name Value
Scanner special =
special & DSN sashelp.cars
name dsn OBS 5
(obs=&obs);
run; work.sasmacr
Input
Name Stored Code
Stack
proc print data=&dsn(obs=&obs);
PRINTTABLE run;
19
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.1 Defining and Calling a Macro 4-11
Calling a Macro
proc print data=sashelp.cars(obs=5);
run;
Compiler
Execute
Word
Scanner
Input
Stack
20
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
4.02 Activity
Open m104a02.sas from the activities folder and perform the following tasks:
1. Run the program and verify in the log that the %PrintTable macro
compiled successfully.
2. Add a line of code at the bottom of the program to call the %PrintTable
macro.
%printtable
3. Highlight the macro call and run the selected code. Based on only what
you see in the log, can you tell where in the SAS program the error
occurred?
21
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-12 Lesson 4 Working with Macro Programs
Troubleshooting a Macro
options mprint;
%printtable OPTIONS MPRINT;
options nomprint;
84 %printtable
MPRINT(PRINTTABLE): proc print data=sashelp.clas(obs=5);
ERROR: File SASHELP.CLAS.DATA does not exist.
MPRINT(PRINTTABLE): run;
The displayed
code has all macro
triggers already
name of the SAS code
resolved.
macro generating generated by
the code the macro
23
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Macro Parameters
%let dsn=sashelp.cars;
%let obs=5;
%printtable
24
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m104d01.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.1 Defining and Calling a Macro 4-13
Macro Parameters
Create a macro
definition with
parameters
%printtable(sashelp.cars,5)
25
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m104d01.sas
%macro-name(value-1, … value-n)
In a macro definition,
%macro printtable(dsn,obs); positional parameter names
are provided in an ordered list.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-14 Lesson 4 Working with Macro Programs
Scenario
We have a SAS program that produces a report about storms in the 2016 season in the North
Atlantic basin with maximum winds greater than 80 MPH. We want to be able to produce the same
report for other seasons, basins, and wind speeds.
Files
• m104d02.sas
Syntax
%macro-name(parameter1,…parameterN)
Notes
• Macro definitions can be created to accept parameters.
• Macro parameters are resolved as macro variables during macro execution.
• Parameters are named in a comma-separated list in parentheses in the %MACRO statement.
• When the macro is called, parameter values are supplied in parentheses as a comma-delimited
list.
• Because these parameters are positional, parameter values must be supplied in the proper order.
Demo
1. Open m104d02.sas from the demos folder. This program produces a bar chart to examine the
frequency of StormType by Basin. It includes storms in the NA basin (North Atlantic) during the
2016 season with maximum wind speed greater than 80 MPH. Run the program and confirm the
results.
2. Add %LET statements to create macro variables named Basin, Season, and MaxWind,
and assign values of NA, 2016, and 80 respectively. Replace hardcoded values in the SAS
program with the appropriate macro variable references. Run the program and verify that it
reproduces the original report with no errors or warnings in the log.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.1 Defining and Calling a Macro 4-15
%let Basin=NA;
%let Season=2016;
%let MaxWind=80;
4. Modify the program to create a macro named StormChart. Replace the three %LET statements
with positional parameters for Basin, Season, and MaxWind. Add an OPTIONS statement to
change the MCOMPILENOTE= option to ALL. Run the program and verify that the macro
compiled without error.
options mcompilenote=all;
%macro stormchart(Basin, Season, MaxWind);
title1 "Storm Frequency by Type";
title2 "&Basin Basin, &Season Season, Max Wind > &MaxWind MPH";
...
title;
%mend stormchart;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-16 Lesson 4 Working with Macro Programs
5. Call the %StormChart macro with parameter values EP for Basin, 2015 for Season, and 125
for MaxWind. Turn on the MPRINT option to view the submitted macro code in the log and turn
off the MPRINT option after the macro executes. Highlight the statements and run the selected
code. Review the results to verify that the results match the previous report. Confirm in the log
that the executed code is printed.
options mprint;
%stormchart(EP,2015,125)
options nomprint;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.1 Defining and Calling a Macro 4-17
%macro printtable(dsn=sashelp.cars,obs=5);
29
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-18 Lesson 4 Working with Macro Programs
%macro-name(name=value, …, name=value)
30
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
4.03 Activity
Open m104a03.sas from the activities folder and perform the following tasks:
1. Modify the %MACRO statement to use keyword parameters. Assign
default values of NA to Basin, 2016 to Season, and 20 to MaxWind. Run
the program and verify that the macro compiles successfully.
%macro stormchart(basin=NA, season=2016, maxwind=20);
3. Call the %StormChart macro with Season as 2015 and Basin as EP. View
the log. Is the table subset by MaxWind, even though it is not included as
a parameter in the macro call? 31
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.1 Defining and Calling a Macro 4-19
It is possible to mix
positional and keyword
%stormchart(WP) parameters in a list, but
positional parameters
%stormchart(NA, Season=2015) must always come first.
33
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
%stormchart(NA, Season=2015)
34
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-20 Lesson 4 Working with Macro Programs
Practice
Level 1
1. Defining and Using a Macro with Parameters
a. Open m104p01.sas from the practices folder. Review and submit the program. Verify that it
generates a report for Gold customers that contains 680 rows.
b. Convert the code to a macro named Customers that accepts a positional parameter named
Type. Submit the macro definition and review the log to verify that the macro compiled
successfully.
• Call the %Customers macro with the parameter value Gold. Verify that the title is Gold
Customers and that there are 680 rows in the report.
• Call %Customers again with the parameter value High Activity. No rows were selected
due to a case difference.
c. Modify the macro to convert the value of the parameter Type to uppercase and modify the
WHERE clause to make the string comparison case insensitive. Submit the macro definition
and verify that it compiled correctly.
• Call the macro with the parameter value High Activity. Verify that the title is HIGH
ACTIVITY Customers and that the report contains 461 rows.
d. Change the positional parameter to a keyword parameter with a default value of inactive.
• Call %Customers with the value high activity for the keyword parameter. Verify that the
title is HIGH ACTIVITY Customers and that the report contains 461 rows.
• Call %Customers without passing a parameter value. Verify that title is INACTIVE
Customers. How many rows are in the report?
Level 2
2. Using a Macro to Generate PROC MEANS Code
a. Open m104p02.sas from the practices folder. Submit the program and review the results.
Verify that the mean value of Total_Retail_Price for orders submitted by customer 51 is
314.74.
b. Convert the code to a macro named Orderstats that accepts the keyword parameters listed
below. Set default values for all parameters so that the code reproduces the original report
when called without parameter values. Modify the PROC MEANS code to reference the
parameters.
• var for the VAR statement variable list
• class for the CLASS statement variable list
• stats for the statistics to be calculated
• decimals for the MAXDEC= value
c. Call the %Orderstats macro without passing parameter values. Verify that the mean value of
Total_Retail_Price for Customer 51 is the same as in part a.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.1 Defining and Calling a Macro 4-21
d. Call the macro again, with the parameter values listed below.
• var=CostPrice_Per_Unit
• decimals=0
• stats=mean median
• class=order_type
What is the median value for Order_type 3?
Challenge
3. Using Parameters That Contain Special Characters
a. Open m104p03.sas from the practices folder. Review and submit the program. The macro
completes compilation without errors, but six warning messages are displayed because the
parameter contains a special character. Macro quoting functions are needed to eliminate the
unresolved references.
b. Modify the macro call to protect the parameter value at compile time and call the macro
again. Verify that four warning messages are displayed in the log.
c. You protected the special character during compilation, but during execution, the resolved
value of prodline contains an unprotected special character. The Q macro quoting functions
mask special characters in the result and return quoted text. The function names begin with
%Q (for example, %QSCAN).
Modify the macro definition to use Q functions where needed to eliminate all warning
messages from the log. Submit the modified code and verify that there are no error or
warning messages in the log.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-22 Lesson 4 Working with Macro Programs
Every macro
variable has a scope.
Global or local scope
impacts where the
macro variable is stored
and how long it exists.
global local
38
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
39
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.2 Macro Variable Scope 4-23
40
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
%GLOBAL var1 var2…; • creates macro variables in the global symbol table
• does not assign or modify values
• is valid anywhere in a program
If the variable already exists, its value is unchanged.
41
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
To create a read-only macro variable, specify the READONLY option in the %GLOBAL statement.
The READONLY option both creates a new macro variable in the global symbol table and assigns a
value. Variables created with the READONLY option cannot be modified or deleted for the duration
of the SAS session. When the READONLY option is used, you can list only one macro variable in
the %GLOBAL statement.
%global / readonly var=5;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-24 Lesson 4 Working with Macro Programs
42
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
• created when
- a macro with parameters is called
- a local macro variable is created
• deleted when the macro stops execution
43
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.2 Macro Variable Scope 4-25
44
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
%LOCAL var1 var2 …; • creates macro variables in the local symbol table
• does not assign or modify values
• is valid only inside a macro definition
If the variable already exists, its value is unchanged.
45
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-26 Lesson 4 Working with Macro Programs
global local
46
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Is X in GLOBAL
symbol table? Yes Set GLOBAL X to 1
No
Create X in LOCAL
table, set value to 1
47
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.2 Macro Variable Scope 4-27
48
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
49
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-28 Lesson 4 Working with Macro Programs
4.04 Activity
Open m104a04.sas from the activities folder and perform the following
tasks:
1. Notice that the %LET statement outside the %Test macro program sets
the value of X to OutsideMacro. Then the %LET statement inside the
%Test macro program sets the value of X to InsideMacro.
2. Submit the program and examine the log. What is the value of X before,
during, and after macro execution?
50
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
52
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.2 Macro Variable Scope 4-29
%test
What happens if X
is explicitly defined
as global scope?
53
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
4.05 Question
When the %Test macro executes, will it have a local symbol table?
Yes
No
%macro test;
%global x;
%let x=InsideMacro;
%mend test;
%test
54
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-30 Lesson 4 Working with Macro Programs
%test
This %LET statement
explicitly creates or updates
X in the global symbol table.
56
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
57
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.2 Macro Variable Scope 4-31
58
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
59
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-32 Lesson 4 Working with Macro Programs
%test
The local symbol table is
deleted when the macro
ends execution.
60
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
61
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.2 Macro Variable Scope 4-33
4.06 Activity
Open m104a06.sas from the activities folder and perform the following
tasks:
1. Review the program. Notice that the %Test macro includes a parameter
named X. X is assigned different values before and during the macro
call.
2. Submit the program and examine the log to view the value of X before,
during, and after macro execution.
3. What is the scope of the X parameter in the %Test macro?
4. Add a %GLOBAL statement before the %PUT statement in the %Test
macro definition to explicitly declare X as global scope. Does the
program run successfully?
62
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
global local
65
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-34 Lesson 4 Working with Macro Programs
No
66
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
67
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.2 Macro Variable Scope 4-35
68
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
69
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-36 Lesson 4 Working with Macro Programs
70
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
71
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.2 Macro Variable Scope 4-37
72
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
73
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-38 Lesson 4 Working with Macro Programs
74
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
75
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.2 Macro Variable Scope 4-39
76
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
77
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-40 Lesson 4 Working with Macro Programs
78
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.2 Macro Variable Scope 4-41
OUTER X 2
...
GLOBAL X 1
80
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
GLOBAL X 1
81
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-42 Lesson 4 Working with Macro Programs
Practice
Level 1
Without submitting the programs, identify in which symbol table the macro variable Zip is
located. Assume that each example is submitted in its own SAS session.
a.
%let Zip=27513;
%macro whereis;
%let state=%sysfunc(zipnamel(&Zip));
%put The Zip Code &Zip is in &state;
%mend whereis;
%whereis
b.
%macro whereis;
%let Zip=10312;
%let state=%sysfunc(zipnamel(&Zip));
%put The Zip Code &Zip is in &state;
%mend whereis;
%whereis
c.
%macro whereis(Zip);
%let state=%sysfunc(zipnamel(&Zip));
%put The Zip Code &Zip is in &state;
%mend whereis;
%whereis(91219)
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.2 Macro Variable Scope 4-43
Level 2
Challenge
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-44 Lesson 4 Working with Macro Programs
85
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
86
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m104d03.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.3 Conditional Processing 4-45
Macro conditional
statements can be
used either inside or
outside a macro
definition.
87
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-46 Lesson 4 Working with Macro Programs
89
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
You must be running SAS 9.4M5 or later to use %IF outside of a macro definition.
Note: You cannot use the macro IN operator as part of an %IF statement outside of a macro
definition.
90
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m104d03.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.3 Conditional Processing 4-47
91
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
92
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-48 Lesson 4 Working with Macro Programs
93
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m104d03.sas
94
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m104d03.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.3 Conditional Processing 4-49
4.07 Activity
Open m104a07.sas from the activities folder and perform the following tasks:
1. Notice that there is a missing semicolon after the DATA statement, which
causes a syntax error. If there is a syntax error in the first DATA step, then
the %PUT statement should execute and write a custom error message to
the log, and the remaining PROC steps should not execute.
2. Run the program and look at the log. Notice that although there was an
error in the DATA step, SAS still attempted to execute PROC PRINT and
PROC SGPLOT.
3. Identify the syntax error in the macro %IF statement. Fix the error and run
the program again to confirm that the %PUT statement is executed.
95
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
miles per
USA
hour
Origin
Asia or kilometers
Europe per liter
We want to calculate
fuel efficiency
differently depending
on the value of Origin.
97
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-50 Lesson 4 Working with Macro Programs
if &loc is null
Nested
conditional steps
else if &loc is must be included
USA inside a macro
definition.
else if &loc is
Asia or Europe
%mend avgfuel;
99
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.3 Conditional Processing 4-51
%macro avgfuel(loc);
%if &loc= %then %do;
%put ERROR: Provide a value for Origin.;
%put ERROR- Valid values: Asia, Europe, USA;
%end;
...
100
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m104a08.sas
%macro avgfuel(loc);
%if &loc= %then %do;
%put ERROR: Provide a value for Origin.;
%put ERROR- Valid values: Asia, Europe, USA;
%return;
%end;
...
proc print data=fuel_&loc;
run;
101
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m104a08.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-52 Lesson 4 Working with Macro Programs
102
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m104a08.sas
103
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m104a08.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.3 Conditional Processing 4-53
4.08 Activity
Open m104a08.sas from the activities folder and perform the following
tasks:
1. Review the program and notice that different DATA steps run,
depending on the value of the loc parameter. The %avgfuel macro call
at the end of the program assigns Europe to the loc parameter.
2. Run the program and view the log. Notice the MPRINT messages
displaying the final program that was compiled and executed.
3. Call the %avgfuel macro with usa as the parameter value. View the log.
Which DATA step was compiled and executed?
104
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Macro Logic
OPTIONS MLOGIC|NOMLOGIC; MLOGIC prints detailed
messages in the log regarding
73 options mprint mlogic; the flow of the macro logic.
74 %avgfuel(usa)
MLOGIC(AVGFUEL): Beginning execution.
MLOGIC(AVGFUEL): Parameter LOC has value usa
MLOGIC(AVGFUEL): %IF condition &loc=USA is FALSE
MPRINT(AVGFUEL): data fuel_usa;
MPRINT(AVGFUEL): set sashelp.cars;
MPRINT(AVGFUEL): where Origin="usa";
MPRINT(AVGFUEL): AvgKmL=mean(MPG_City, MPG_Highway)*.425;
MPRINT(AVGFUEL): keep Make Model Type AvgKmL;
MPRINT(AVGFUEL): run;
106
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-54 Lesson 4 Working with Macro Programs
%IF Expressions
%IF Expressions
How can I explicitly
specify if &loc is
either Asia or
Europe? AND or OR can be used
to build compound
expressions.
108
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.3 Conditional Processing 4-55
%IF Expression
A null value cannot be provided in the list of values after the macro IN operator. Null values must be
processed first with a separate %IF condition.
To enable the macro IN operator in open code, you must submit the following OPTIONS statement.
It is recommended that you disable the macro IN operator after it is used.
options minoperator;
%if &sysday in Saturday Sunday %then %do;
%put It is the weekend;
%end;
options nominoperator;
If you do not include the MINOPERATOR option, you likely will see a similar error message:
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric
operand is required. The condition was: &loc in Asia Europe
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-56 Lesson 4 Working with Macro Programs
%IF Expressions
How can I specify if
&loc is any value
other than Asia or Use parentheses to
Europe? isolate the IN
expression.
111
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.3 Conditional Processing 4-57
112
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m104d04.sas
113
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m104d04.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-58 Lesson 4 Working with Macro Programs
Conditional Processing
Scenario
In this demonstration, we use macro conditional processing to select which program steps are
generated, select which individual statements within a SAS program step are executed, and
conditionally modify portions of a SAS statement.
Files
• m104d05.sas
Syntax
Notes
• Conditional processing can be used to selectively generate entire program steps, individual
program statements, or portions of a program statement.
Demo
1. Open m104d05.sas from the demos folder. This program creates the %StormChart macro
definition and accepts three parameters (Basin, Season, and MaxWind). When executed, the
macro produces a bar chart. Run the program to compile the macro and call %StormChart with
parameter values NA, 2016, and 80. Review the results and log to confirm that the macro runs
successfully.
2. Modify the macro to provide a storm category rather than maximum wind speed as an input
parameter. Use macro conditional processing to assign the appropriate value to a macro variable
named MaxWind based on the value of Cat.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.3 Conditional Processing 4-59
Note: Copy and paste the statements from the comment block at the bottom of the
program.
%macro stormchart(basin, season, cat);
%local maxwind;
%if &cat=5 %then %let maxwind=157;
%else %if &cat=4 %then %let maxwind=130;
%else %if &cat=3 %then %let maxwind=111;
%else %if &cat=2 %then %let maxwind=96;
%else %if &cat=1 %then %let maxwind=74;
d. Run the %StormChart macro definition and review the log to verify that it compiled properly.
e. Add the MLOGIC and MPRINT options to the OPTIONS statement to enable detailed
messages in the log. Highlight the statement and run the selection.
options mcompilenote=all mlogic mprint;
f. Call %StormChart for NA, 2016, and 3. Run the selected code, and then review the log and
output to verify that the chart includes four storms.
%stormchart(NA,2016,3)
g. Modify the %StormChart macro call to specify values for only the first two parameters.
Highlight the macro call and run the selected code. Note that several errors are in the log
because no value is provided for the Cat or MaxWind macro variables.
%stormchart(EP,2015)
3. Modify the %StormChart macro program so that if no value is provided for the Cat parameter,
all storms are included for the selected Basin and Season and the footnote is All Storms
Included.
a. Add %IF and %END statements around the FOOTNOTE statement so that it executes only if
the macro variable Cat value is assigned a value. Add %ELSE and %END statements to
submit an alternative FOOTNOTE statement that prints All Storms Included.
%if &cat ne %then %do;
footnote "Max Wind > &maxwind MPH";
%end;
%else %do;
footnote "All Storms Included";
%end;
b. Modify the WHERE statement in the PROC SGPLOT step so that the MaxWindMPH
criterion is specified only if the Cat parameter is specified.
where Basin="&basin" and Season=&season
%if &cat ne %then %do;
and MaxWindMPH>&maxwind
%end;
;
c. Submit the macro definition to recompile the macro.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-60 Lesson 4 Working with Macro Programs
d. Call the %StormChart macro for EP, 2015. Review the log and results. Verify that the report
includes 26 storms and that the titles and footnote are correct.
%stormchart(EP,2015)
e. Call the %StormChart macro for SI, 2014, 2. Review the log and results. Verify that the
report includes seven storms and that the titles and footnote are correct.
%stormchart(SI,2014,2)
4. Submit an OPTIONS statement to reinstate the NOMLOGIC and NOMPRINT options.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.3 Conditional Processing 4-61
Practice
Level 1
7. Using Macro Conditional Processing to Choose Which SAS Statements Are Generated
d. Submit the macro call again with a value of AU for the country parameter. How many
customers are included in the report?
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-62 Lesson 4 Working with Macro Programs
Level 2
Challenge
c. Call the %SalesSummary macro with a parameter value of 4. Confirm that the error
message is displayed.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.4 Iterative Processing 4-63
Use macro-level
Start with a Generalize Create a macro Validate
programming Add Data Driven
validated SAS with macro definition with parameters and
for complex Features
program variables parameters document
processing
118
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Use macro-level
Start with a Generalize Create a macro Validate
programming Add Data Driven
validated SAS with macro definition with parameters and
for complex Features
program variables parameters document
processing
%let num=3;
title "&num-Cylinder Cars";
proc print data=sashelp.cars noobs;
where Cylinders=#
var Make Model Type Origin
MSRP MPG_City MPG_Highway;
run;
119
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-64 Lesson 4 Working with Macro Programs
Use macro-level
Start with a Generalize Create a macro Validate
programming Add Data Driven
validated SAS with macro definition with parameters and
for complex Features
program variables parameters document
processing
%macro cylreport(num);
title "&num-Cylinder Cars";
proc print data=sashelp.cars noobs;
where Cylinders=#
var Make Model Type Origin
MSRP MPG_City MPG_Highway;
run;
%mend cylreport;
%cylreport(3)
120
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Use macro-level
Start with a Generalize Create a macro Validate
programming Add Data Driven
validated SAS with macro definition with parameters and
for complex Features
program variables parameters document
processing
%macro cylreport(num);
title "&num-Cylinder Cars"; How can I generate
proc print data=sashelp.cars noobs; the report for each
where Cylinders=# Cylinder value
var Make Model Type Origin between 3 and 12?
MSRP MPG_City MPG_Highway;
run;
%mend cylreport;
%cylreport(3)
121
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.4 Iterative Processing 4-65
122
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
123
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m104d06.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-66 Lesson 4 Working with Macro Programs
124
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
%macro allcylinders(start,stop);
%do num=&start %to &stop;
%cylreport(&num)
%end; Create a driver macro to call
%mend allcylinders; the %CylReport macro once for
each value, 3 through 6.
%allcylinders(3,6)
125
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m104d06.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.4 Iterative Processing 4-67
Scenario
In this demonstration, we use macro %DO iterative processing to produce the storm report for
a range of years.
Files
• m104d07.sas
Syntax
Notes
• Iterative processing can be used to generate repetitive program statements.
• A macro can call another macro for execution.
Demo
1. Open m104d07.sas from the demos folder. This program creates the %StormChart macro
definition, which accepts two parameters: Basin and Season. The macro generates a bar chart
representing the number of storms by storm type for the selected Basin and Season.
2. Run the macro definition and the macro call with Basin as NA and Season as 2015. Verify that
the bar chart is created and includes 12 storms.
3. Create a driver macro named StormChartRange that calls the %StormChart macro for a range
of years.
a. Start with a %MACRO statement that includes the parameters Basin, Start, and Stop.
b. Add a %DO loop with an index variable named Season that ranges from the Start macro
variable value to the Stop macro variable value. Inside the %DO loop, call the %StormChart
macro with the parameter values provided by Basin and Season.
c. Add a %MEND statement to complete the macro definition.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-68 Lesson 4 Working with Macro Programs
4. Test the %StormChartRange macro, generating reports for a range of seasons for different
basins.
a. Submit the following macro call and verify the results:
%stormchartrange(EP,2011,2013)
b. Submit the following macro call and verify the results:
%stormchartrange(NA,2010,2016)
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.4 Iterative Processing 4-69
4.09 Activity
Open m104a09.sas from the activities folder and perform the following tasks:
1. Run the program and examine the log. Identify and correct the syntax
error and rerun the program. Verify that the macro compiled successfully.
2. Call the %AllCylinders macro with a start value of 3 and stop value of 12.
%allcylinders(3,12)
3. Examine the reports and log. Why are there some values between
3 and 12 that did not produce reports?
127
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
130
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-70 Lesson 4 Working with Macro Programs
132
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m104d08.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.4 Iterative Processing 4-71
133
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m104d08.sas
134
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m104d08.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-72 Lesson 4 Working with Macro Programs
Scenario
In this demonstration, we use macro %DO iterative processing to produce the storm report for
a range of years.
Files
• m104d09.sas
Syntax
Notes
• Macro %DO loops can be used along with indirect macro variable references to execute code for
a list of values.
• Use PROC SQL to generate a numbered sequence of macro variables to store the unique values
within a column for processing in the %DO loop.
Demo
1. Open m104d09.sas from the demos folder. This program creates the %StormChart macro
definition, which accepts two parameters: Basin and Season. The macro generates a bar chart
representing the number of storms by storm type for the selected Basin and Season.
2. Run the macro definition and the macro call with Basin as NA and Season as 2015. Verify that
the bar chart is created and includes 12 storms.
3. Create a driver macro named AllBasins that executes the %StormChart macro for each
individual Basin value. Include a positional parameter named Year. Use %LOCAL to explicitly
define i as a local macro variable.
%macro allbasins(year);
%local i;
4. Add a PROC SQL step to select the Basin column from the mc1.storm_basin_codes table.
Load each value into a numbered series of macro variables starting with Basin1.
proc sql noprint;
select basin
into :basin1-
from mc1.storm_basin_codes;
quit;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.4 Iterative Processing 4-73
5. Use a %DO loop to create an index variable I that ranges from 1 to the value of &sqlobs. Inside
the loop, call the %StormChart macro. The Basin parameter uses an indirect reference of
&&Basin&i. The second parameter is the value of &year. Close the %DO loop and the macro
definition. Run the macro definition and confirm that it compiles successfully.
%do i=1 %to &sqlobs;
%stormchart(&&basin&i, &year)
%end;
%mend allbasins;
6. Call the %AllBasins macro with 2015 as the parameter value. Run the macro call and confirm
that six bar charts are produced.
%allbasins(2015)
7. View the log and carefully read the MLOGIC messages. Notice that in the first iteration of the
macro %DO loop when &I is 1, &&Basin&i first resolves to &Basin1, which then resolves to NA.
In the second iteration, &&Basin&i resolves to WP.
...
MLOGIC(ALLBASINS): %DO loop beginning; index variable I; start value is 1;
stop value is 6; by value is 1.
MLOGIC(STORMCHART): Beginning execution.
MLOGIC(STORMCHART): Parameter BASIN has value NA
MLOGIC(STORMCHART): Parameter SEASON has value 2015
...
MLOGIC(ALLBASINS): %DO loop index variable I is now 2; loop will iterate again.
MLOGIC(STORMCHART): Beginning execution.
MLOGIC(STORMCHART): Parameter BASIN has value WP
...
8. Call the %AllBasins macro again with 2009 as the parameter value. Confirm that six charts are
generated.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-74 Lesson 4 Working with Macro Programs
136
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.4 Iterative Processing 4-75
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-76 Lesson 4 Working with Macro Programs
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.4 Iterative Processing 4-77
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-78 Lesson 4 Working with Macro Programs
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.4 Iterative Processing 4-79
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-80 Lesson 4 Working with Macro Programs
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.4 Iterative Processing 4-81
4.10 Question
Complete the query to generate a macro variable named List that includes
a space-delimited list of the distinct values of Cylinders.
from sashelp.cars
where Cylinders ne .;
quit;
%put &=list;
%cyllist(&list)
150
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m104a10.sas
152
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-82 Lesson 4 Working with Macro Programs
Practice
Level 1
10. Using Iterative Processing and Indirect Referencing
a. Open m104p10.sas from the practices folder. Review and submit the program. Verify that it
generates a PROC MEANS report for Type 1 orders.
b. Convert the code to a macro named Orders that uses a %DO loop to generate a separate
PROC MEANS step for order types 1, 2, and 3. Add a call to the %Orders macro. Submit the
program and verify that it generates three PROC MEANS reports, one for each order type.
Confirm that the mean of Total_Retail_Price for type 2 orders is 162.43.
c. Modify the program.
• Insert a DATA _NULL_ step after the %MACRO statement to create a series of macro
variables, type1 to typen, where n is the number of order types found in the
mc1.order_type_codes table. For each macro variable name, concatenate the prefix
type with the value of order_type_code. Assign the corresponding value of Order_Type
to the macro variable.
• Create a macro variable named numTypes and assign it the number of type macro
variables created. Hint: Use the END= option in the SET statement.
• Use numTypes as the stop value for the loop.
• Use an indirect reference to include the order type in the title as shown below.
Order Type: Retail Store
Level 2
a. Open m104p11.sas from the practices folder. Review and submit the program. Verify that
the maximum wind speed for the 2015 season was 213 MPH.
b. Modify the %Storms macro to accept a space-separated list of years. Use a %DO %UNTIL
loop and the %SCAN macro function to generate a report for each year in the list. Submit the
macro definition and verify that it completed compilation without errors.
c. Call the %Storms macro to generate a report for the 2011 and 2014 seasons as shown
below.
%storms(2011 2014)
• What was the maximum wind speed in each year?
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.4 Iterative Processing 4-83
Challenge
b. Part b contains starter code for the %Printlib macro, which accepts a libref and the number
of rows as parameters. The PROC SQL step creates a series of macro variables that contain
the names of the tables in the specified library.
Complete the %Printlib macro by adding an iterative %DO loop that calls the %Print macro
repetitively to print the first numrows rows of every table in the specified library. If the
numrows parameter is not specified, the %Print macro should use the default value for its
keyword parameter.
c. Call %Printlib to list the first 10 rows of every table in the mc1 library.
• What is the name of table in the last PROC PRINT report?
• How many rows are in the last report?
d. Call %Printlib to list every table in the mc1 library. Do not specify a value for numrows.
• What is the name of table in the first PROC PRINT report?
• How many rows are displayed in each report?
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-84 Lesson 4 Working with Macro Programs
4.5 Solutions
Solutions to Practices
Section 4.1
%customers(Gold)
%customers(High Activity)
/* Part c. */
%macro customers(type);
%let type=%upcase(&type);
title "&type Customers";
proc sql number;
select Name, Age_Group, Type
from mc1.customers
where upcase(Type) contains "&type";
quit;
title;
%mend customers;
%customers(High Activity)
/* Part d. */
%macro customers(type=inactive);
%let type=%upcase(&type);
title "&type Customers";
proc sql number;
select Name, Age_Group, Type
from mc1.customers
where upcase(Type) contains "&type";
quit;
title;
%mend customers;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.5 Solutions 4-85
%customers(type=High Activity)
%customers()
How many rows are in the final report? The report contains 209 rows.
2. Using a Macro to Generate PROC MEANS Code
%macro orderstats(var=Total_Retail_Price, class=Customer_ID,
stats=mean, decimals=2);
options nolabel;
title 'Order Stats';
proc means data=mc1.orders maxdec=&decimals &stats;
var &var;
class &class;
run;
title;
options label;
%mend orderstats;
%orderstats()
%orderstats(var=CostPrice_Per_Unit, decimals=0,
stats=mean median, class=order_type)
What is the median value for internet (type 3) orders? The median is 26.
/* Part c. */
%macro prodlist(prodline);
%let prodline=%qupcase(&prodline);
title "Listing of %qsysfunc(propcase(&prodline, %str( &)))";
proc print data=mc1.products;
where upcase(Product_Line)="&prodline";
var Product_ID Product_name Product_Line;
run;
title;
%mend prodlist;
%prodlist(%nrstr(clothes&shoes))
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-86 Lesson 4 Working with Macro Programs
Section 4.2
%scope
In which symbol table were the macro variables created? Local symbol table
/* Part b. */
/* Section 2: Macro variables created with SQL INTO */
%macro scope;
proc sql noprint;
select damage into :stormtype1-
from mc1.storm_cat
order by category;
quit;
%scope
In which symbol table were the macro variables created? Local symbol table
/* Part c. */
/* Section 3: Macro variables created with CALL SYMPUTX */
%macro scope;
data _null_;
set mc1.storm_cat end=last;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.5 Solutions 4-87
call symputx(cat('stormtype',_n_),Damage);
if last=1 then
call symputx('num',_n_);
run;
%put _user_;
%mend scope;
%scope
/* Part d. */
/* Section 3: Macro variables created with CALL SYMPUTX */
%macro scope;
%local x;
data _null_;
set mc1.storm_cat end=last;
call symputx(cat('stormtype',_n_),Damage);
if last=1 then
call symputx('num',_n_);
run;
%put _user_;
%mend scope;
%scope
/* Part e. */
/* Section 3: Macro variables created with CALL SYMPUTX */
%macro scope;
data _null_;
set mc1.storm_cat end=last;
call symputx(cat('stormtype',_n_),Damage,"L");
if last=1 then
call symputx('num',_n_,"L");
run;
%put _user_;
%mend scope;
%scope
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-88 Lesson 4 Working with Macro Programs
%number_of_rows(mc1.customers)
%put mc1.customers has &numrows rows.;
%symdel numrows;
options notes;
Section 4.3
7. Using Macro Conditional Processing to Choose Which SAS Statements Are Generated
%macro customerlist(country);
proc print data=mc1.customers noobs;
%if &country= %then %do;
title "All Customers";
var ID Name Country Type Age_Group;
%end;
%else %do;
title "Customers from Country: &country";
where Country="&country";
var ID Name Type Age_Group;
%end;
run;
%mend customerlist;
%customerlist()
%customerlist(AU)
How many customers are included in the report? 90
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.5 Solutions 4-89
%else %do;
proc sql;
create table orion.profit as
select o.product_id, Product_Name, Product_Category,
(Total_Retail_Price-(CostPrice_per_Unit*Quantity))
as Profit format=dollar12.2
from mc1.orders as o inner join mc1.products as p
on o.product_id=p.product_id;
quit;
%else %do;
%if &ot=1 %then %let otdesc=Retail;
%else %if &ot=2 %then %let otdesc=Catalog;
%else %if &ot=3 %then %let otdesc=Internet;
%mend SalesSummary;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-90 Lesson 4 Working with Macro Programs
%SalesSummary(1)
%SalesSummary(2)
%SalesSummary(3)
%SalesSummary(4)
Section 4.4
%orders
/* Part c. */
%macro orders;
data _null_;
set mc1.order_type_codes end=last;
call symputx(cats("type",Order_type_code),Order_type);
if last=1 then call symputx("numTypes", _n_);
run;
%do i=1 %to &numTypes;
title "Order Type: &&type&i";
proc means data=mc1.orders sum mean maxdec=2;
where Order_Type=&i;
var Total_Retail_Price CostPrice_Per_Unit;
run;
%end;
%mend orders;
%orders
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.5 Solutions 4-91
/* Part c. */
%storms(2011 2014)
What was the maximum wind speed in each year?
The maximum wind speed was 155 MPH in 2011 and 161 MPH in 2014.
12. Using Iterative Processing in One Macro to Call Another Macro
/* Part b. */
%macro printlib(lib,numrows);
%let lib=%upcase(&lib);
proc sql noprint;
select memname
into :tbl1-
from dictionary.tables
where libname="&lib";
quit;
/* add the %DO loop here */
%do i=1 %to &sqlobs;
%if &numrows= %then
%print(lib=&lib,tbl=&&tbl&i);
%else
%print(lib=&lib,tbl=&&tbl&i,rows=&numrows);
%end;
%mend printlib;
/* Part c. */
%printlib(mc1,10)
/* Part d. */
%printlib(mc1)
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-92 Lesson 4 Working with Macro Programs
c. Call %Printlib to list the first 10 rows of every table in the mc1 library.
• What is the name of table in the last PROC PRINT report? mc1.storm_type_codes
• How many rows are in the last report? Five
d. Call %Printlib to list every table in the mc1 library. Do not specify a value for numrows.
• What is the name of table in the first PROC PRINT report? mc1.country_codes
• How many rows are displayed in each report? Three
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.5 Solutions 4-93
12
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
74 %printtable
ERROR: File SASHELP.CLAS.DATA does not exist.
NOTE: The SAS System stopped processing this
step because of errors.
The error is displayed
in the log, but the code
is not displayed.
22
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-94 Lesson 4 Working with Macro Programs
%stormchart(season=2015, basin=EP)
32
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
51
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.5 Solutions 4-95
55
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
80 %let X=OutsideMacro;
81 %put NOTE: &=X before TEST macro execution.;
NOTE: X=OutsideMacro before TEST macro execution.
...
83 /* Execute the test macro */ Macro parameters create
84 %test(InsideMacro) and update macro variables
NOTE: X=InsideMacro during TEST macro execution.
in the local symbol table.
85
86 /* Check the value to X after execution */
87 %put NOTE: &=X after TEST macro execution.;
NOTE: X=OutsideMacro after TEST macro execution.
63
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-96 Lesson 4 Working with Macro Programs
85 %test(InsideMacro)
ERROR: Attempt to %GLOBAL a name (X)
which exists in a local environment.
Parameters cannot
be global.
64
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
96
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4.5 Solutions 4-97
%avgfuel(usa)
The second DATA
74 %avgfuel(usa) step executes.
MPRINT(AVGFUEL): data fuel_usa;
MPRINT(AVGFUEL): set sashelp.cars;
MPRINT(AVGFUEL): where Origin="usa";
MPRINT(AVGFUEL): AvgKmL=mean(MPG_City, MPG_Highway)*.425;
MPRINT(AVGFUEL): keep Make Model Type AvgKmL;
MPRINT(AVGFUEL): run;
105
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
%macro allcylinders(start,stop);
%do num=&start %to &stop;
title "&num-Cylinder Cars";
proc print data=sashelp.cars noobs;
where Cylinders=#
var Make Model Type Origin
MSRP MPG_City MPG_Highway;
run;
%end;
title;
%mend allcylinders; 128
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
4-98 Lesson 4 Working with Macro Programs
%put &=list;
151
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
Lesson 5 Developing Macro
Applications
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.1 Storing Macros 5-3
3
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
PRINTTABLE
work.sasmacr (default)
%macro printtable(dsn=sashelp.cars,obs=5)
/des='Print a table. Parms: DSN= OBS=';
proc print data=&dsn(obs=&obs);
run;
%mend printtable;
4
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m105d01.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-4 Lesson 5 Developing Macro Applications
5.01 Activity
Open m105a01.sas from the activities folder and perform the following tasks:
1. This program creates a macro named PrintTable in the default
work.sasmacr catalog. PROC CATALOG lists the contents of work.sasmacr.
2. Run the program. The report includes all macros in work.sasmacr,
including PRINTTABLE and its description.
3. Uncomment the second CONTENTS statement. This statement creates a
table including the macros in work.sasmacr. The WHERE= data set option
is used to filter the results.
contents out=macrolist(where=(name like '%TABLE%'));
4. Run the program and examine the output table. How many macros
include TABLE in the name? 5
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Using Macros
7
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.1 Storing Macros 5-5
Autocall Macros
The autocall facility
makes it easy to reuse
and share macro
programs in any SAS
session!
Autocall Autocall
library facility
8
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
9
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-6 Lesson 5 Developing Macro Applications
NOTE: SASAUTOS=(
'C:\Program Files\SASHome\SASFoundation\9.4\core\sasmacro'
'C:\Program Files\SASHome\SASFoundation\9.4\access\sasmacro'
...
10
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
5.02 Activity
Open m105a02.sas from the activities folder and perform the following
tasks:
1. Highlight the PROC CATALOG step and run the selected code. Notice
in the report that the DATATYP macro is not listed.
2. Run the %LET and %PUT statements that call the %Datatyp macro.
View the log and confirm the macro runs successfully.
3. Highlight the PROC CATALOG step again and run the selected code.
Is DATATYP included in the report?
11
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.1 Storing Macros 5-7
Autocall Rules
%datatyp(123)
DATATYP in a
Yes Execute compiled %Datatyp macro.
macro catalog?
No
No
14
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
s:/workshop/autocall
15
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-8 Lesson 5 Developing Macro Applications
%macro printtable(dsn=sashelp.cars,obs=5)
/des='Print a table. Parms: DSN= OBS=';
proc print data=&dsn(obs=&obs);
run;
%mend printtable;
&path/autocall/printtable.sas
16
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m105d01.sas
17
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m105d01.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.1 Storing Macros 5-9
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-10 Lesson 5 Developing Macro Applications
Scenario
Build a helpful utility macro to delete all user-defined macro variables from the global symbol table.
Save the program in an autocall library and set up the autocall facility to make the macro available in
any SAS session.
Files
• m105d02.sas
Syntax
OPTIONS SASAUTOS=("my-path",SASAUTOS)
Notes
• An autocall library is a location with .sas programs that each contain a macro definition. The name
of the .sas file must match the name of the macro.
• The macro facility calls macros in the autocall library without having to open and submit the macro
definition
• Use the SASAUTOS= option to specify the locations of autocall libraries
Demo
1. Open the m105d02.sas program from the demos folder. In Section 1, notice that the DATA step
creates a series of macro variables. Macro variable names are derived from the CountryCode
column and values are assigned from the CountryName column.
data _null_;
set mc1.country_codes;
call symputx(CountryCode, CountryName);
run;
2. Information about macro variables and values is stored in a read-only SAS view known as a
DICTIONARY table. The SQL step in Section 1 creates a report that includes all columns from
the dictionary.macros table ordered by Scope and Name.
proc sql;
select *
from dictionary.macros
order by Scope, Name;
quit;
3. Highlight the code in Section 1 and run the selection. Examine the report and notice all the
automatic and global macro variables that are listed. The global CountryCode macro variables
are included in the report. There are also several global macro variables that start with SYS,
SQL, STUDIO, OLD, or an underscore. These macro variables are in the global symbol table.
However, they are defined by the SAS application.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.1 Storing Macros 5-11
4. In Section 2, notice that the SQL query includes a WHERE statement to subset the
dictionary.macro table to include macro variables with global scope and exclude selected
macro variables that are defined by SAS applications. Highlight the SQL step in Section 2 and
run the selected code. The resulting report should include the user-defined macro variables.
Note: The ESCAPE clause in the LIKE expression is used to treat the underscore as text rather
than a wildcard for a single character.
proc sql;
select *
from dictionary.macros
where Scope='GLOBAL' and
Name not like 'SYS%' and
Name not like 'SQL%' and
Name not like 'SASWORK%' and
Name not like 'GRAPH%' and
Name not like 'STUDIO%' and
Name not like 'OLD%' and
Name not like '^_%' escape '^' and
Name ne 'CLIENTMACHINE' and
Name ne 'USERDIR';
quit;
5. Modify the SQL step as follows. Then run the step and examine the value of the Vars macro
variable in the log.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-12 Lesson 5 Developing Macro Applications
6. Copy the code in Section 2 and paste it in a new program. Make the following modifications:
8. Open the libname.sas program. Add the following OPTIONS statement to indicate that autocall
macros should be read from the autocall folder in the course files and the SASAUTOS fileref.
Save the program and run it.
options sasautos=("&path/autocall", sasautos);
9. Return to the m105d02.sas program and submit the PROC CATALOG step in Section 3 to
delete the DeleteAll macro from the work.sasmacr catalog. This enables us to test whether the
autocall macro is accessible the next time that we call %DeleteAll.
proc catalog cat=work.sasmacr;
delete deleteall.macro;
run;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.1 Storing Macros 5-13
10. In Section 1, insert the %deleteall macro call between the DATA step and the PROC SQL step.
data _null_;
set mc1.country_codes;
call symputx(CountryCode, CountryName);
run;
%deleteall
proc sql;
...
11. Highlight the code in Section 1 and run the selection. View the report and the log to confirm that
the CountryCode macro variables are no longer in the global symbol table.
12. Set up your SAS environment to automatically include your personal AUTOCALL macro libraries.
a. SAS Studio
1) Copy the code in the libname.sas program.
2) Click the More application options button and select Edit Autoexec File.
3) Paste the program in the editor. Click Run to test the code and execute it for the current
SAS session. Click Save to make the changes permanent:
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-14 Lesson 5 Developing Macro Applications
continued...
5.03 Activity
1. Open m105a03.sas from the activities folder. Run the PROC CATALOG
step and confirm that PROPCASE does not exist in work.sasmacr.
2. Create a new program and enter the following code. The %Propcase
macro applies the PROPCASE function to the text parameter. Do not run
the program, but save it as propcase.sas in the autocall folder.
%macro propcase(text);
%sysfunc(propcase(&text))
%mend propcase;
19
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
5.03 Activity
3. Open the libname.sas program. Add an OPTIONS statement and the
SASAUTOS= option to include the autocall folder as an additional
autocall library. Run the program and save it.
options sasautos=("&path/autocall", sasautos);
20
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.1 Storing Macros 5-15
22
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
23
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. autocall/varexist.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-16 Lesson 5 Developing Macro Applications
24
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. autocall/vartype.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.2 Generating Data-Dependent Code 5-17
27
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Use macro-level
Start with a Generalize Create a macro Validate
programming Add Data Driven
validated SAS with macro definition with parameters and
for complex Features
program variables parameters document
processing
%splittable(mc1.customers, Country)
28
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-18 Lesson 5 Developing Macro Applications
29
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m105d03.sas
30
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m105d03.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.2 Generating Data-Dependent Code 5-19
%splittable(sashelp.cars,origin)
31
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m105d03.sas
%macro splittable(tab,col);
data Asia Europe USA;
set &tab;
select(&col);
How can we update when ("Asia") output Asia;
the DATA and WHEN when ("Europe") output Europe;
statements based on when ("USA") output USA;
the values of the col otherwise;
parameter? end;
run;
%mend splittable;
%splittable(sashelp.cars,origin)
32
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m105d03.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-20 Lesson 5 Developing Macro Applications
%splittable(sashelp.cars,origin)
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.2 Generating Data-Dependent Code 5-21
36
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-22 Lesson 5 Developing Macro Applications
5.04 Activity
Open m105a04.sas from the activities folder and perform the following
tasks:
1. Notice that the program includes two SELECT statements. Run the
program. The first report includes the distinct values of Origin. The
second report includes a separate WHEN statement for each value
of Origin.
2. Change the value of the Col macro variable to Type. Run the program
again and observe the two reports.
3. What syntax can be used to create macro variables that store the
distinct values as a delimited list?
37
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.2 Generating Data-Dependent Code 5-23
Scenario
Create a macro program that splits a table based on the distinct values of a selected column. The
resulting program generated by the macro is dependent on the data associated with the input
parameters.
Files
• m105d04.sas
Syntax
OPTIONS SASAUTOS=("my-path",SASAUTOS)
Demo
1. Open the m105d04.sas program from the demos folder. This program does the following:
a. creates the macro variables Tab and Col and assigns the values of mc1.storm_final and
Ocean
b. creates the macro variable TabList by reading the distinct values from &col into a space-
delimited list
c. creates the macro variable WhenList by first concatenating text to build a WHEN statement
for each distinct value of &col and then combining the text into a list separated by a
semicolon
d. reads the Name and Value columns from the dictionary.macros table to print the values of
the TabList and WhenList macro variables
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-24 Lesson 5 Developing Macro Applications
3. Modify the program to create a macro named SplitTable_SQL with the parameters Tab and Col.
Include only the first PROC SQL step that creates the TabList and WhenList macro variables.
Add the following DATA step that is built using TabList and WhenList:
%macro splittable_sql(tab,col);
proc sql noprint;
select distinct &col
into :tablist separated by " "
from &tab;
select distinct
cat('when ("', &col, '") output ', &col)
into :whenlist separated by ";"
from &tab;
quit;
data &tablist;
set &tab;
select(&col);
&whenlist;
otherwise;
end;
run;
%mend splittable_sql;
4. Call the %SplitTable_SQL macro with sashelp.cars and Type as the parameter values. Run
the program and verify that six tables are created for the distinct values of Type.
%splittable_sql(sashelp.cars, Type)
5. Call the %SplitTable_SQL macro again with mc1.storm_final and Basin as the parameter
values. Run the program and verify that six tables are created for the distinct values of Basin.
%splittable_sql(mc1.storm_final, Basin)
6. Save the program in the autocall folder as splittable_sql.sas.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.2 Generating Data-Dependent Code 5-25
Practice
Level 1
a. Open m105p01.sas from the practices folder. Review and submit the program. Confirm that
a report listing Gold high activity customers is produced.
b. Add a %MACRO statement to create a macro named GroupList with two parameters, Tab
for the input table and Col for the selected column. This macro generalizes the starter
program so that a PROC PRINT report is generated for each unique value of the specified
column.
c. Use a PROC SQL step to select the distinct uppercase values of the Col parameter. Load
the values into a numbered series of macro variables starting with Val1. Read the column
from the table specified by the Tab parameter.
d. Add a macro %DO loop to repeat the TITLE statement and PROC PRINT step once for each
Valn macro variable created.
Note: Use the Sqlobs macro variable created automatically by the PROC SQL step to
provide the stop value for the loop.
e. Use an indirect macro variable reference to replace GOLD HIGH ACTIVITY with Val1 for the
first %DO loop iteration, Val2 for the second iteration, and so on.
f. Close the %DO loop with %END and the macro definition with %MEND.
g. Call the %GroupList macro with mc1.customers and Type as the parameter values.
Confirm that a separate PROC PRINT step is executed for each distinct value of Type.
h. Call the %GroupList macro with sashelp.cars and DriveTrain as the parameter values.
• What is the value of DriveTrain for the first report generated?
Level 2
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-26 Lesson 5 Developing Macro Applications
b. Create a macro named BasinXLS that writes storms for each distinct value of Basin to a
different worksheet in an Excel workbook named BasinStorms.xlsx. Include the following
logic in the macro program:
• Use the automatic macro variable Syslibrc to verify whether the LIBNAME statement runs
successfully (SYSLIBRC=0). If it does not run successfully (SYSLIBRC≠0), write a custom
error message to the log and terminate macro execution.
• Create a numbered series of macro variables for each value of Basin and BasinName in
the mc1.storm_basin_codes table. Remove all spaces from the BasinName values
before assigning them to macro variables.
• Use a macro %DO loop to repeat the DATA step for each value of Basin.
c. Call the %BasinXLS macro and open the BasinStorms.xlsx file. Confirm that six
worksheets are included.
• What is the name of the first storm listed in the SouthIndian_Storms worksheet?
Challenge
b. Create a macro named ColumnReport with one parameter, Tab. Add the following logic to
the macro to create a histogram for all numeric columns in the selected table and a donut
chart for all the character columns:
• Convert the tab parameter value to uppercase.
• After the first SQL query, add another SQL step to create a series of numbered macro
variables that will store the column values for Name and Type.
• Use a %DO loop to execute either the SGPLOT or SGPIE step for each column in the
input table. If the column type is num, then run the SGPLOT step to create the histogram.
If the column type is char, then run the SGPIE step to create the donut chart.
• Add a title for each graph: Distribution of <columnname>.
c. Call the %ColumnReport macro with mc1.storm_final as the parameter value. Verify that
the appropriate charts are created for each column.
Note: Character columns with many unique values, such as Name, are grouped into a
category labeled Other.
Note: You can ignore warnings regarding the font.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.3 Validating Parameters and Documenting Macros 5-27
Use macro-level
Start with a Generalize Create a macro Validate
programming Add Data Driven
validated SAS with macro definition with parameters and
for complex Features
program variables parameters document
processing
Effective macro
programs include logic
to address potential
issues with parameter
resolution.
43
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
What could
possibly break
the %SplitTable
macro?
%splittable(sashelp.cars,Origin)
44
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-28 Lesson 5 Developing Macro Applications
5.05 Activity
Open m105a05.sas from the activities folder and perform the following
tasks:
1. Open sashelp.cars to view the table and columns.
2. In the program, select the SplitTable macro definition and submit the
selected code.
3. Highlight each %SplitTable macro call, one at a time, and submit it.
4. Which macro calls fail and why?
45
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
48
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.3 Validating Parameters and Documenting Macros 5-29
49
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. ...
Conditional processing
What macro tools
can we use to Macro variables
address these
issues?
Custom log messages
Autocall macros
50
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-30 Lesson 5 Developing Macro Applications
%macro splittable(tab,col);
51
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m105d05.sas
52
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m105d05.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.3 Validating Parameters and Documenting Macros 5-31
%macro splittable(tab,col);
...
/* Check if the column exists in the selected table */
%else %if %varexist(&tab,&col)=0 %then %do;
%put ERROR: Column &col does not exist in &tab..;
%put ERROR- Macro will stop executing.;
%return;
%end;
...
%VarExist is an autocall macro that
returns 1 if the column exists in the
table and 0 otherwise.
53
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m105d05.sas
%macro splittable(tab,col);
...
/* Check if the column exists in the selected table */
%else %if %varexist(&tab,&col)=0 %then %do;
%put ERROR: Column &col does not exist in &tab..;
%put ERROR- Macro will stop executing.;
%return;
%end; How could we enhance
...
the macro by listing
columns from the given
table in the log?
54
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m105d05.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-32 Lesson 5 Developing Macro Applications
We can retrieve
column names and
attributes from
dictionary.columns.
55
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m105d05.sas
5.06 Activity
Open m105a06.sas from the activities folder and perform the following
tasks:
1. Review the program and notice that the query is reading all columns
from the dictionary.columns table for sashelp.cars. Run the program
and observe the information available in the generated report.
2. Modify the query to create a macro variable named Varlist that
is a comma-delimited list of values in the Name column.
3. Add &Varlist after the colon in the %PUT statement. Run the program
and verify that the log lists the column names.
4. Modify the program to examine the columns in sashelp.class.
Run the program. How many columns are listed in the log?
56
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.3 Validating Parameters and Documenting Macros 5-33
59
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m105d05.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-34 Lesson 5 Developing Macro Applications
...
when (3) output CYLINDERS_3;
when (4) output CYLINDERS_4;
when (5) output CYLINDERS_5;
when (6) output CYLINDERS_6;
...
60
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m105d05.sas
61
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m105d05.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.3 Validating Parameters and Documenting Macros 5-35
62
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m105d05.sas
...
when ("Acura") output Acura;
when ("Land Rover") output LandRover;
when ("Mercedes-Benz") output MercedesBenz;
when ("Volvo") output Volvo;
...
63
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m105d05.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-36 Lesson 5 Developing Macro Applications
64
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m105d05.sas
Note: The $QUOTE format does not include trailing blanks inside the quotation marks.
65
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m105d05.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.3 Validating Parameters and Documenting Macros 5-37
66
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m105d05.sas
67
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved. m105d05.sas
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-38 Lesson 5 Developing Macro Applications
Validating Parameters
Scenario
Build parameter validation into the %SplitTable macro to account for possible issues with the
parameter or data values.
Files
• m105d05.sas
Notes
The following macro tools are used to build a complete macro application that includes logic to
validate parameter values and resolve potential issues when possible:
• macro functions
• conditional processing
• macro variable
• custom log messages
• dynamic data validation
• autocall macros
Demo
1. Open the m105d05.sas program from the demos folder. This program does the following:
a. A macro named SplitTable is created with the parameters Tab and Col.
b. Parameter values are converted to uppercase. If only a table name is provided for the Tab
parameters, then WORK. is added as a prefix to the table name.
c. A condition tests whether the table exists. If the table does not exist, an error message is
written to the log, and the macro ends execution.
d. A condition verifies that the column exists in the specified table. If the column does not exist,
an error message is written to the log with a list of valid columns, and the macro ends
execution.
e. Based on the column type, values are assigned to macro variables for each distinct data
value and table value to be created.
f. A DATA step is generated to split the tables based on the distinct values of the Col
parameter.
2. Highlight and submit the macro program, and verify that it compiles successfully.
3. Select the OPTIONS statement and the first macro call with mc1.storm_final and Ocean as the
parameter values. Run the selected code. Confirm that the program runs successfully and that
three tables are created.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.3 Validating Parameters and Documenting Macros 5-39
4. Run the second macro call with false and ID as the parameter values. False is not a valid table.
Confirm that an error message is written to the log indicating that the table does not exist.
73 %splittable(false, ID)
ERROR: WORK.FALSE does not exist.
Macro will stop executing.
5. Run the third macro call with sashelp.cars and Test as the parameter values. Test is not a
column in the sashelp.cars table. Confirm that an error message is written to the log indicating
that the column does not exist and a list of valid columns is provided.
ERROR: Column TEST does not exist in SASHELP.CARS.
Columns in SASHELP.CARS include Make, Model, Type, Origin,
DriveTrain, MSRP, Invoice, EngineSize, Cylinders,
Horsepower, MPG_City, MPG_Highway, Weight, Wheelbase,
Length.
Macro will stop executing.
6. Run the fourth macro call with sashelp.cars and Make as the parameter values. Make includes
values with invalid table names with spaces and hyphens. Confirm that the tables are created
successfully, including tables for MERCEDESBENZ and LANDROVER.
7. Run the fifth macro call with mc1.orders and Order_Type as the parameter values. Order_Type
is numeric. Confirm that three tables are created with Order_Type as the prefix for each table
name.
8. Submit the final OPTIONS statement to turn off the MPRINT option.
9. Save the program as splittable.sas in the autocall folder.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-40 Lesson 5 Developing Macro Applications
69
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Multiple OR conditions
must be used in this
statement because the
macro IN operator
does not permit null
values in the list.
70
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.3 Validating Parameters and Documenting Macros 5-41
%splittable(help)
156 %splittable(help)
************************************
* SplitTable Macro *
* Syntax: splittable(tab,col) *
* Parameters: *
* TAB: Table to split *
* COL: Column to use to create *
* separate tables *
************************************
71
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
5.07 Activity
Open m105a07.sas from the activities folder and perform the following
tasks:
1. Run the SplitTable macro definition and verify that it compiles without
error.
2. Call the %SplitTable macro with help as the parameter value. View the
log. What is causing error messages to appear in the comment?
3. Use a macro quoting function to prevent macro triggers from resolving
in the %PUT statements.
4. Run the program again and confirm that the macro documentation is
printed in the log.
72
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-42 Lesson 5 Developing Macro Applications
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.3 Validating Parameters and Documenting Macros 5-43
Case Study
77
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-44 Lesson 5 Developing Macro Applications
Practice
Level 1
a. Open m105p04.sas from the practices folder. Review and submit the program.
d. Resubmit the macro definition and call the macro using a valid and invalid parameter value.
e. Modify the macro to first test whether Type is null. If so, do not execute the TITLE statement
or PROC FREQ step. Instead, the macro should write this message to the log:
ERROR: Missing TYPE
ERROR: Valid TYPE values are HIGH, MEDIUM, LOW
f. Resubmit the macro definition and call the macro with a null parameter value, valid values in
uppercase and lowercase, and an invalid value.
• How many low-activity customers are Italian (IT)?
Level 2
a. Open m105p05.sas from the practices folder. Review and submit the program.
b. Use PROC SQL to create the macro variables MinSeason and MaxSeason that store the
minimum and maximum values of the Season column in the mc1.storm_final table. Add a
condition to verify that the Season parameter is between MinSeason and MaxSeason. If
the Season parameter is outside of the valid range, write this message to the log:
ERROR: Valid Seasons are between <minSeason> and <maxSeason>
c. If the Season parameter is valid, use PROC SQL to create a space-delimited list of valid
Basin codes from the mc1.storm_basin_codes table. Load the list into a macro variable.
d. If the Basin parameter is in the list of valid codes, execute the TITLE statements and the
PROC SGPLOT step.
Note: Be sure to use the MINOPERATOR option in the %MACRO statement to enable the
macro IN operator.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.3 Validating Parameters and Documenting Macros 5-45
e. If the Basin parameter is not in the list of valid codes, write this message to the log:
ERROR: AA is an invalid basin code. Basin codes include NA WP EP SP NI SI.
f. Test the macro with valid and invalid values for both Basin and Season.
• How many tropical storms were there in the EP basin in 2010?
Challenge
6. Validating a Macro Parameter with Data Values That Require Quoting Functions
%SUPERQ is a helpful macro function that retrieves the value of a macro variable from the
macro symbol table and quotes it immediately, preventing the macro processor from making any
attempt to resolve anything that might occur in the resolved value. If the value of a macro
variable could include macro triggers, operators, or special symbols, %SUPERQ is an effective
alternative to resolving the macro variable with &mac-var.
%SUPERQ(mac-var)
Note: The country codes IN (India) and LT (Lithuania) are possible parameter values,
which could be interpreted as the macro IN operator or the less than operator. In the
%IF statement, use the %SUPERQ function to ensure that the Ctry parameter value
is treated as text.
c. If the Ctry parameter is not null, verify that it is one of the distinct values from the Country
column in the mc1.customers table. If Ctry is a valid country code, generate the chart for
customers in that country.
Note: Use %SUPERQ to ensure that the Ctry parameter value and the list of country
codes are treated as text.
d. If the Ctry parameter is an invalid value, write this message to the log and substitute a list of
valid country codes:
ERROR: ZZ is an invalid country code
Valid country codes include <list of country codes>
e. Test the macro for parameter values null, AU, in, and zz.
• What is the last valid country code listed in the log message when the Ctry parameter
is zz?
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-46 Lesson 5 Developing Macro Applications
5.4 Solutions
Solutions to Practices
Section 5.2
%grouplist(mc1.customers, Type)
%grouplist(sashelp.cars, DriveTrain)
What is the value of DriveTrain for the first report generated? ALL
2. Exporting Data to Separate Worksheets in Microsoft Excel
%macro basinxls;
libname storm xlsx "&path/basinstorms.xlsx";
%if &syslibrc ne 0 %then %do;
%put ERROR: BasinStorms.xlsx was not successfully assigned.
Check the path and filename.;
%end;
%else %do;
proc sql noprint;
select Basin, compress(BasinName)
into :basin1-, :basinname1-
from mc1.storm_basin_codes;
quit;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.4 Solutions 5-47
%end;
%end;
libname storm clear;
%mend basinxls;
%basinxls
What is the name of the first storm listed in the SouthIndian_Storms worksheet? ALFRED
3. Analyzing all Columns from a Table
%macro columnreport(tab);
%let tab=%upcase(&tab);
%else %do;
proc sgpie data=&tab;
donut &&col&i;
run;
%end;
%end;
%mend columnreport;
%columnreport(mc1.storm_final)
%columnreport(sashelp.cars)
%columnreport(mc1.customers)
%columnreport(sashelp.heart)
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-48 Lesson 5 Developing Macro Applications
In the Distribution of Group chart, how many Orion Club Gold members are there? 680
Section 5.3
%custtype(HIGH)
%custtype(low)
%custtype(med)
%custtype()
%else %do;
proc sql noprint;
select Basin
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.4 Solutions 5-49
%stormchart(NA,2020)
%stormchart(EP,2010)
%stormchart(AA,2010)
How many tropical storms were there in the EP basin in 2010? Two
6. Validating a Macro Parameter with Data Values That Require Quoting Functions
%macro customerlist(ctry) / minoperator;
%if %superq(ctry)= %then %do;
title "All Customers";
proc sgplot data=mc1.customers noborder;
vbar Group / filltype=gradient stat=percent;
yaxis grid display=(noticks noline nolabel);
run;
%end;
%else %do;
%let ctry=%upcase(&ctry);
proc sql noprint;
select distinct Country
into :ctrylist separated by " "
from mc1.customers;
quit;
%if %superq(ctry) in %superq(ctrylist) %then %do;
title "Customers from &ctry";
proc sgplot data=mc1.customers noborder;
vbar Group / filltype=gradient stat=percent;
yaxis grid display=(noticks noline nolabel);
where Country="&ctry";
run;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-50 Lesson 5 Developing Macro Applications
%end;
%else %do;
%put ERROR: &ctry is an invalid country code;
%put ERROR- Valid country codes include &ctrylist;
%end;
%end;
%mend customerlist;
%customerlist()
%customerlist(AU)
%customerlist(in)
%customerlist(zz)
What is the last valid country code listed in the log message when the Ctry parameter is zz? ZA
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.4 Solutions 5-51
6
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
12
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-52 Lesson 5 Developing Macro Applications
13
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
21
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.4 Solutions 5-53
%let tab=sashelp.cars;
%let col=Type;
proc sql ;
select distinct &col
into :tablist separated by " "
from &tab;
select distinct
cat('when ("', &col, '") output ', &col)
into :whenlist separated by ";"
from &tab;
quit;
38
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
continued...
5.05 Activity – Correct Answer
Which macro calls fail and why?
46
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-54 Lesson 5 Developing Macro Applications
%splittable(sashelp.cars,Origin)
Origin and DriveTrain both
%splittable(sashelp.crs,Origin) work because the column
%splittable(sashelp.cars,Price) values are valid table
names.
%splittable(sashelp.cars,DriveTrain)
%splittable(sashelp.cars,Make)
%splittable(sashelp.cars,Cylinders)
47
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
options nolabel;
proc sql noprint;
select Name
into :varlist separated by ", "
from dictionary.columns
where libname="SASHELP" and
memname="CLASS";
quit;
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5.4 Solutions 5-55
169 %splittable(help)
************************************
* SplitTable Macro *
ERROR: WORK.TAB does not exist.
Macro will stop executing.
* Syntax: *
73
Copyr i ght © SAS I nsti tute I nc. Al l r i ghts reser ved.
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.
5-56 Lesson 5 Developing Macro Applications
Copyright © 2019, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED.