An Introduction to Macros Deb Cassidy

Similar documents
DSCI 325: Handout 15 Introduction to SAS Macro Programming Spring 2017

Debugging. Where to start? John Ladds, SAS Technology Center, Statistics Canada.

AN INTRODUCTION TO MACRO VARIABLES AND MACRO PROGRAMS Mike Zdeb, School of Public Health

Foundations and Fundamentals. SAS System Options: The True Heroes of Macro Debugging Kevin Russell and Russ Tyndall, SAS Institute Inc.

SAS Macro Programming for Beginners

Unlock SAS Code Automation with the Power of Macros

PLA YING WITH MACROS: TAKE THE WORK OUT OF LEARNING TO DO MACROS. Arthur L. Carpenter

Macros are a block of code that can be executed/called on demand

The Ins and Outs of %IF

A Time Saver for All: A SAS Toolbox Philip Jou, Baylor University, Waco, TX

This chapter is intended to take you through the basic steps of using the Visual Basic

The 'SKIP' Statement

Going Under the Hood: How Does the Macro Processor Really Work?

Macro Basics. Introduction. Defining and Using Macro Variables. Defining and Using Macros. Macro Parameters. Part 1. Chapter 1. Chapter 2.

A Tutorial on the SAS Macro Language

Sandra Hendren Health Data Institute

The %let is a Macro command, which sets a macro variable to the value specified.

Job Security: Using the SAS Macro Language to Full Advantage

SAS Macro. SAS Training Courses. Amadeus Software Ltd

Remembering the Past. Who Needs Documentation?

Base and Advance SAS

SharePoint 2010 Site Owner s Manual by Yvonne M. Harryman

Here are a couple of warnings to my students who may be here to get a copy of what happened on a day that you missed.

CMSC 201 Fall 2016 Lab 09 Advanced Debugging

Introduction to Programming

Customizing DAZ Studio

SAS Macro Language: Reference

CONQUERING THE DREADED MACRO ERROR

Demystifying Inherited Programs

ORB Education Quality Teaching Resources

Introduction to Programming Style

Control Structures. Code can be purely arithmetic assignments. At some point we will need some kind of control or decision making process to occur

SAS Macro Dynamics - From Simple Basics to Powerful Invocations Rick Andrews, Office of the Actuary, CMS, Baltimore, MD

title1 "Visits at &string1"; proc print data=hospitalvisits; where sitecode="&string1";

MOBILE MACROS GET UP TO SPEED SOMEWHERE NEW FAST Author: Patricia Hettinger, Data Analyst Consultant Oakbrook Terrace, IL

Chapter 1 Introduction

Advanced Macro Topics Steven First, Systems Seminar Consultants, Madison, WI

Using GSUBMIT command to customize the interface in SAS Xin Wang, Fountain Medical Technology Co., ltd, Nanjing, China

Intro. Scheme Basics. scm> 5 5. scm>

1.7 Limit of a Function

Excel Basics: Working with Spreadsheets

Guidelines for Coding of SAS Programs Thomas J. Winn, Jr. Texas State Auditor s Office

Program Validation: Logging the Log

Use That SAP to Write Your Code Sandra Minjoe, Genentech, Inc., South San Francisco, CA

Introduction. Getting Started with the Macro Facility CHAPTER 1

Why & How To Use SAS Macro Language: Easy Ways To Get More Value & Power from Your SAS Software Tools

Formal Methods of Software Design, Eric Hehner, segment 1 page 1 out of 5

Understanding Recursion

CSE 417 Dynamic Programming (pt 6) Parsing Algorithms

Part 1 Simple Arithmetic

SURVIVING THE SAS MACRO JUNGLE BY USING YOUR OWN PROGRAMMING TOOLKIT

Software Compare and Contrast

Difference Between Dates Case Study 2002 M. J. Clancy and M. C. Linn

CSCI 1100L: Topics in Computing Lab Lab 11: Programming with Scratch

SAS Macro Dynamics: from Simple Basics to Powerful Invocations Rick Andrews, Office of Research, Development, and Information, Baltimore, MD

Moving from FrameMaker to Blaze: Best Practices

Have examined process Creating program Have developed program Written in C Source code

Lecture 4 CSE July 1992

printf( Please enter another number: ); scanf( %d, &num2);

SAS Macro Programming Tips and Techniques

Lecture 19 CSE August You taught me Language, and my profit on t is I know how to curse. William Shakspere, The Tempest, I, ii.

This book is about using Visual Basic for Applications (VBA), which is a

Amacro is a sequence of commands or keystrokes that Word records

More About SAS Macros

(Python) Chapter 3: Repetition

Basic Macro Processing Prepared by Destiny Corporation

PRINCIPLES OF SOFTWARE BIM209DESIGN AND DEVELOPMENT 00. WELCOME TO OBJECTVILLE. Speaking the Language of OO

Reliable programming

Java/RealJ Troubleshooting Guide

Lesson 1A - First Java Program HELLO WORLD With DEBUGGING examples. By John B. Owen All rights reserved 2011, revised 2015

Getting Up to Speed with PROC REPORT Kimberly LeBouton, K.J.L. Computing, Rossmoor, CA

Trombone players produce different pitches partly by varying the length of a tube.

3 Nonlocal Exit. Quiz Program Revisited

Copyright. For more information, please read the Disclosures and Disclaimers section at the end of this ebook. First PDF Edition, February 2013


CS125 : Introduction to Computer Science. Lecture Notes #4 Type Checking, Input/Output, and Programming Style

The compiler is spewing error messages.

COSC 2P95. Introduction. Week 1. Brock University. Brock University (Week 1) Introduction 1 / 18

Lab 1: Silver Dollar Game 1 CSCI 2101B Fall 2018

Contents. Overview How SAS processes programs Compilation phase Execution phase Debugging a DATA step Testing your programs

Project 5 - The Meta-Circular Evaluator

Class 1: Homework. Intro to Computer Science CSCI-UA.0101 New York University Courant Institute of Mathematical Sciences Fall 2017

Paper CC16. William E Benjamin Jr, Owl Computer Consultancy LLC, Phoenix, AZ

Write for your audience

Appendix A Design. User-Friendly Web Pages

1 Pencil and Paper stuff

What s the base case?

Macro Bugs - How to Create, Avoid and Destroy Them Ian Whitlock, Kennett Square, PA

Classes, interfaces, & documentation. Review of basic building blocks

1: Introduction to Object (1)

When using computers, it should have a minimum number of easily identifiable states.

Notes From SUGI 24. Jack Hamilton. First Health West Sacramento, California. SUGI24OV.DOC 2:45 PM 29 April, 1999 Page 1 of 18

Spectroscopic Analysis: Peak Detector

Working the System: Our Best SAS Options Patrick Thornton, SRI International, Menlo Park, CA Iuliana Barbalau, Adecco, Pleasanton, CA

STAT:5400 Computing in Statistics. Other software packages. Microsoft Excel spreadsheet very convenient for entering data in flatfile

Part II Composition of Functions

Windows Script Host Fundamentals

SAS Windowing environment Tips and Tricks

Using ANNOTATE MACROS as Shortcuts

Template Versatility Using SAS Macro Language to Generate Dynamic RTF Reports Patrick Leon, MPH

Transcription:

Paper #HW03 An Introduction to Macros Deb Cassidy Abstract A search in the proceedings for SUGI 24-28 for the word "macro" had over 1,000 hits. Why are macros so popular? A quick glance through the papers showed many were titled in the form "A Macro to... ". These macros were developed to write complex code once and then use it over and over again with different datasets. Macros are also useful for writing code conditionally. For example, if your data meets Condition X, then run Part A of the program. Otherwise, run Part B of the program. Without macros, you'll need to submit a program, manually check the results and then submit the correct second program. However, macro code often looks like hieroglyphics to many people. Others have trouble understanding the difference between macro code and other SAS code. This hands-on workshop is intended to give you the basics of macros so you can figure out what &&&i&j really does and why %IF and IF are not the same. Why Use Macros? SAS-L is an electronic user group. As I was working on this paper, there was an intense discussion about whether macros were necessary. Of course, there were differing opinions. My opinion, macros are extremely useful but they are also easy to overuse or use in situations where they make the code more complex. The online help states: The macro facility is a tool for extending and customizing SAS and for reducing the amount of text you must enter to do common tasks. The macro facility enables you to assign a name to character strings or groups of SAS programming statements. From that point on, you can work with the names rather than with the text itself. When you use a macro facility name in a SAS program or from a command prompt, the macro facility generates SAS statements and commands as needed. The rest of SAS receives those statements and uses them in the same way it uses the ones you enter in the standard manner. The above statements from the online help contain an important factor in deciding to use a macro does it reduce the amount of text you must enter? You should also consider if there are other ways to do this such as BY-statement processing on procedures, using other procedures, using CALL EXECUTE or changing the structure of your data. The other use where I find a macro often beneficial is writing conditional code. The rest of this paper assumes you have considered the options and macros are the best option for accomplishing your task. A Simple Example The following is a very simple example to help you understand that macros are just text substitution - a key fact that many people either never knew or seem to forget. As we cover more complex examples, you ll see there are better ways to do this to have more robust code. Two things to remember are that &name refers to a macro variable and %name refers to a macro. Determine what you want for a title and replace This is my title in the following code. %let title=this is my title; data one; set sasuser.houses; 1

proc print data=one; title "Proc print -- &title"; proc tabulate data=one; class style bedrooms; tables style*bedrooms,n; title "My Tabulate results for -- &title - this run"; proc means max data=one; title '&title - Results of means'; Submit the above code and you ll get three pages of output. The titles will show up as Output Section proc print proc tabulate proc means Title Proc print -- This is my title My Tabulate results for -- This is my title - this run &title - Results of means For the first two procs, the text you specified appeared in the title. However, it didn t work for the last proc. What s the difference? Someone might say the difference was because the &title was at the beginning for the last title statement. While that was a difference, the macro variable could be anywhere in the title. You could even have &title ; and it would work. Look carefully and you ll see the first two titles use doublequotes and the last one does not. This is a key point to remember. Macro variables will not be resolved in single quotes. If you specify single quotes, the macro processor assumes you really want the string containing the ampersand symbol itself. A Simple Macro Let s make the above example to the next step. You have the following code that you submit quite often. You just change the data set name and the title. proc print data=put-my-data-set-name-here; title PROC PRINT put-my-title-here from put-my-data-set-name-here ; proc means data=put-my-data-set-name-here; title put-my-title-here Results of means for put-my-data-set-name-here ; The general form of a macro is: %macro macro_name(parameters); your code. %mend macro_name; The above code would be changed to: %macro print_means(mydsn=,title=); proc print data=&mydsn; title "Proc print -- &title from &mydsn"; proc means max data=&mydsn; title "&title - Results of means for &mydsn"; %mend print_means; 2

The parts that you change each time are all now identified as macro variables. Everything else will be the same every time you run the code. There are actually two ways to specify the parameters. The other way is simply %macro print_means(mydsn,title); The disadvantage to this method is that you must always list all the parameters in the correct order. While simple with only two parameters, most macros will be far more complex. The first method also lets you specify a default value for each parameter. I actually have a default of blank in the example. To run the macro, you write it in the form: %macro_name(parameters); Many new users get confused and try to use %macro macro_name(parameters); The %macro and %mend statements are used in creating the macro. When you need to use the macro, you simply use the macro name itself. The following shows some example code using the macro. %print_means(mydsn=sasuser.houses,title=this is some title); %print_means(mydsn=sasuser.jobs,title=this is a second test); data one; set sasuser.fitness; %print_means(title=this is another order,mydsn=sasuser.fitness); Notice than on the last macro call, I switched the order of the parameters. As noted above, this is an advantage to this style of passing parameters. The other advantage I noted is shown in the following example. I have set the default value of mydsn to be _last_. This is an automatic variable that SAS sets to the name of the last data set created. %macro print_means2(mydsn=_last_,title=); proc print data=&mydsn; title "Proc print -- &title from &mydsn"; proc means max data=&mydsn; title "&title - Results of means for &mydsn"; %mend print_means2; You can then use the following macro call: %print_means2(title=this is leaving mydsn out); Basic Debugging Before we move to more complex macros, let s learn a bit about debugging macros. Submit %print_means(title=the one without the default); Submitting the macro with the default for the data set name will give you errors. The log shows: 3

%print_means(title=the one without the default); NOTE: Line generated by the invoked macro "PRINT_MEANS". 1 proc print data=&mydsn; title "Proc print -- &title from &mydsn"; proc means max data=&mydsn; title "&title - - 22 1! Results of means for &mydsn"; ERROR: File WORK.NAME.DATA does not exist. NOTE: The SAS System stopped processing this step because of errors. NOTE: PROCEDURE PRINT used (Total process time): real time 0.00 seconds cpu time 0.00 seconds 22: LINE and COLUMN cannot be determined. NOTE 242-205: NOSPOOL is on. Rerunning with OPTION SPOOL may allow recovery of the LINE and COLUMN where the error has occurred. ERROR 22-322: Expecting a name. ERROR: File WORK.NAME.DATA does not exist. NOTE: The SAS System stopped processing this step because of errors. NOTE: PROCEDURE MEANS used (Total process time): real time 0.00 seconds cpu time 0.00 seconds ERROR 22-322: Expecting a name. Does the log look a bit confusing? Although some people will be able to figure out the problem, several options can help. Symbolgen will show you how the macro variable resolves. If you submit your code as Options symbolgen; %print_means(title=the one without the default); you ll see the following lines now appear in the log. SYMBOLGEN: Macro variable MYDSN resolves to SYMBOLGEN: Macro variable TITLE resolves to The one without the default You are told explicitly that the line in the log came from the SYMOLGEN option. You see that MYDSN resolves to nothing. It other cases people will discover the macro variable resolves but just not how it was expected to resolve. In this case, it was rather obvious that substituting nothing in the line proc print data= ; was a problem. Let s assume you had more complicated code and didn t catch that SAS was trying to use the line proc print data= ; Options MPRINT will give you the following in the log. 4

MPRINT(PRINT_MEANS): proc print data=; ERROR: File WORK.NAME.DATA does not exist. MPRINT(PRINT_MEANS): title "Proc print -- The one without the default from "; MPRINT(PRINT_MEANS): MPRINT write the SAS code for you based on how the variables resolved. MLOGIC is another option and it controls whether macro execution is traced for debugging. Lines such as the following will now appear in the log. MLOGIC(PRINT_MEANS): Beginning execution. MLOGIC(PRINT_MEANS): Parameter TITLE has value The one without the default MLOGIC(PRINT_MEANS): Parameter MYDSN has value Based on this example, you may wonder what the difference is between symbolgen and mlogic since you found out through both methods that MYDSN was blank. Actually, you didn t. MLOGIC told you the value passed to the parameter was nothing. SYMBOLGEN told you the value of the macro variable resolved to nothing. In more complex examples, MLOGIC provides lots more detail. Notice that the log gets longer with more options. You turn off the macro options with a NO before the option name as in: Options nosymbolgen nomprint nomlogic; Once you debug your macro, you should turn off the options. Many people like to include a parameter within each macro to make it easy to turn the options on and off as you do your testing. The following method for executing code conditionally can be used to do so. Executing Code Conditionally The following is a simple example showing how to execute code conditionally. You want to have proc means run if you specify means and proc print run if you specify print. Pretty simple example, isn t it? %macro condition_ex(condition); %if &condition="means" %then %do; proc means data=one; title Results of condition &condition ; %end; %else %if &condition="print" %then %do; proc print data=one; title Results of condition &condition ; %end; %mend condition_ex; %condition_ex(means); When you run it, you get the following in the log. 116 %macro condition_ex(condition); 117 118 %if &condition="means" %then %do; 5

119 proc means data=one; 120 title "Results of condition &condition"; 121 %end; 122 123 %else %if &condition="print" %then %do; 124 proc print data=one; 125 title "Results of condition &condition"; 126 %end; 127 128 129 %mend condition_ex; 130 131 %condition_ex(means); There are no error messages yet there is nothing in the output window. Let s look at the code. %IF- %THEN-%DO-%ELSE-%END are the macro equivalents of IF-THEN-DO-ELSE-END. The difference that many people don t understand is that the macro portion of the code is saying to process the non-macro code when the condition is met. %IF statements have nothing to do with your data. Likewise, IF statements only deal with your data and not the code that is being passed to SAS from the macro language. At first glance, you might think you misspelled the parameter. You might also think it had to do with the case. The code is case-sensitive and that is often the problem but in this case, everything was spelled correctly and everything used lower case. Let s turn on the option SYMBOLGEN to see if we can figure out why it didn t work. The following lines now appear in the log. SYMBOLGEN: Macro variable CONDITION resolves to means SYMBOLGEN: Macro variable CONDITION resolves to means Condition resolves correctly so that is not the problem. You try MPRINT and get nothing added to the code since MPRINT shows you the code being passed to SAS. So, for some reason there is no code being generated from the macro processor. Let s try MLOGIC. MLOGIC(CONDITION_EX): Beginning execution. MLOGIC(CONDITION_EX): Parameter CONDITION has value means MLOGIC(CONDITION_EX): %IF condition &condition="means" is FALSE MLOGIC(CONDITION_EX): %IF condition &condition="print" is FALSE MLOGIC(CONDITION_EX): Ending execution. Well, this makes it quite clear that both %IF conditions were not met. But why? Do your own substitution and you see the line is: %IF means= means %THEN %DO; Those little quotes have caused problems again. You know you need to change the code so it will resolve to one the following. But which one or will both work? %IF means = means %THEN %DO; or %IF means=means %THEN %DO; If you run the code both ways, you ll discover both work. Remember, the macro processor is dealing with text. However, many people have problems because they get parameter values confused with variable names. While means is not a good variable name so it is a bit more obvious, you need to be sure if you 6

are dealing with a variable name or simply a text string as a parameter. Even when you are dealing with variable names, it can be easy to get macro variables confused with your data set variables. A Looping Example This is another simple example to show another aspect of the macro language that confuses some people. Let s assume you have many flat files in the same format. Each is identified by a unique number ranging from 1 to the number of files you have. You want to read each one and create a data set with the same number. Let s assume this is what the code looks like before you turn it into a macro. data file1; infile c:\mypath\mydata1.txt ; input myfield; data file2; infile c:\mypath\mydata2.txt ; input myfield; data file3; infile c:\mypath\mydata3.xt ; input myfield; Everything is identical except the 1,2, and 3 used to identify the different files. You look in the manual and find a %DO-%END with looks like DO-END in regular code. You write the following. %macro readdata(howmany); %do i=1 %to &howmany; data file&i; infile c:\mypath\mydata&i.txt ; input myfield; %end; %mend readdata; %readdata(3) You look in your log and see, among other things, lines containing: ERROR: Physical file does not exist, c:\mypath\mydata1txt. ERROR: Physical file does not exist, c:\mypath\mydata2txt. ERROR: Physical file does not exist, c:\mypath\mydata3txt. Well, the looping worked fine but what happened to the period before txt in your file name? It is definitely there in the macro. The macro processor needs a way to know when the macro variable name ends and when the next piece of text begins. In the earlier examples, a blank, quote or semi-colon following the macro variable. These characters can not be part of a variable name so the macro processor knew the macro variable name had finished. But what happens if you want some other character that can be part of a variable name to immediately follow your macro variable? A period is used to end the macro variable name. Thus, what you really wrote was the text string c:\mypath\mydata followed by the macro variable &i. followed by the text string txt. If you really want to include a period following a macro variable, you need to use 2 periods. The line should have been written as: 7

infile c:\mypath\mydata&i..txt ; You can also do incremental values such as %do i=1 %to &howmany %by 2; However, unlike the data step, the following is not acceptable: %do i=1,5,10; Macro do loops are not as flexible as data step do loops. Should you need code such as the above example which does not work, there are ways to accomplish it but they more complex than the basics this paper covers. Summary Do you know everything to write great macros. NO!!! This workshop should be viewed as getting your feet wet in 6 inches of water. You aren t ready to go swimming in the macro ocean just yet. However, you need to be comfortable with the simple examples and understand how they work before tackling the more complex examples. Odds are that you will use the functionality shown in this paper in most of your macros. You ll also be using a lot of other functionality as well. There are many macro functions which you ll need to learn as well. If the material in this workshop covered everything you needed, then your code could be a good example of the situation where a macro isn t what you really need. Key points to remember: Macros process CHARACTER STRINGS &xxxx is a macro variable while %yyyy is a macro Macro variables are resolved within double-quotes but not single-quotes Symbolgen, mlogic and mprint are useful options for debugging macros Macro language is similar to Base SAS in many ways but there are differences Recommended References The online help provides additional details and examples for learning more about macros. The SAS Books By Users program has recently published the second edition of Art Carpenter s book Carpenter's Complete Guide to the SAS Macro Language. This book contains over 400 pages of material about macros. Previous SUGI and regional conference presentations also provide a wealth of information about macros. Lex Jansen has created a search engine for the online papers. The search engine can be accessed at www.lexjansen.com/sugi. A different search method for SUGI papers can be accessed at support.sas.com/sugi. SAS-L is an electronic newsgroup that is also useful for answering questions about your specific macro. There are several ways to access SAS-L. One if through http://www.listserv.uga.edu/archives/sas-l.html It is recommended that you search previous messages before posting a question since a similar question may already have been asked. Contact info Deb Cassidy Debc_sugstuff@usa.com 8