01 Macro Concepts
With macros you can make one small change in your program and have SAS responds to that change throughout the program. Macros allow you to write a piece of code once and use it over and over (in the same program or in different programs). Stored in an autocall library, they can be shared between programs and between programmers. You can use macros to make programs data driven and let SAS decide what to do based on actual data values.
SAS macro code consists of two basic parts: macros and macro variables. The names of macros are prefixed with a % and the names of macro variables are prefixed with a &. A macro variable has only a single value and does not belong to a data set.
Before you can use macros you need to turn on the MACRO system option. This option is usually turned on by default. You can check the log whether this option is on by the following statements:
PROC OPTIONS OPTION = MACRO; RUN;
macro-text is a set of SAS statements. Use %macro-name to invoke a defined macro. A semicolon is not required here, but adding one does no harm.
Example program (See the Tropical data in 02): * Macro to print 5 largest sales; %MACRO sample; PROC SORT DATA=flowersales; BY DESCENDING Quantity; PROC PRINT DATA=flowersales; FORMAT SaleDate WORDDATE18.; TITLE 'Five Largest Sales; %MEND sample; DATA flowersales; INFILE 'v:\Tropical.txt'; INPUT CustomerID $ @6 SaleDate MMDDYY10. @17 Variety $9. Quantity; RUN; * Invoke the macro; %sample RUN; Macro autocall libraries You can save macros in a central location, called an autocall library so you macros can be shared by programs and programmers. Basically you save your macros as files in a directory or as members of a partitioned data set (depending on your operating environment), and use the MAUTOSOURCE and SASAUTOS= system options to tell SAS where to look for macros. Then you can invoke a macro even though the original macro does not appear in your program. See the SAS Help and Documentation for more details. Back to Top 04 Adding Parameters to Macros Usually you don't want to repeat exactly the same statements. You may want the same report, for example, but for a different data set, or product. Parameters allow you to do this. Parameters are macro variables whose value you set when you invoke a macro. To add parameters to a macro, simply list the macro-variable names between parentheses in the %MACRO statement. %MACRO macro-name (parameter-1= ,parameter-2=, ... parameter-n=); macro-text %MEND macro-name; Example program (See the Tropical data in 02): *Macro with parameters; %MACRO select(customer=,sortvar=); PROC SORT DATA=flowersales OUT=salesout; BY &sortvar; WHERE CustomerID="&customer"; PROC PRINT DATA=salesout; FORMAT SaleDate WORDDATE18.; TITLE1 "Orders for Customer Number &customer"; TITLE2 "Sorted by &sortvar"; %MEND select; DATA flowersales; INFILE 'v:\Tropical.txt'; INPUT CustomerID $ @6 SaleDate MMDDYY10. @17 Variety $9. Quantity; RUN; %select (customer=356W, sortvar=Quantity) %select (customer=240W, sortvar=Variety) RUN; Back to Top 05 Writing Macros with Conditional Logic %IF condition %THEN action; %ELSE %IF condition %THEN action; %ELSE action; %IF condition %THEN %DO; SAS statements %END; Notice that these macro statements can be used only inside a macro. Also, you may use standard IF-THEN statements in your macros, but you will use them for different actions. %IF statements can contain actions that standard IF statements can't contain, such as complete DATA or PROC steps and even other macro statements. Every time you invoke SAS, the macro processor automatically creates some macro variables that you can use. For example, &SYSDATE the character value of the date that session began &SYSDAY the day of the week that session began For example, %IF &SYSDAY = Tuesday %THEN %LET country=Finland; %ELSE %LET country = Sweden; Example program (See the Tropical data in 02): %MACRO dailyreports; %IF &SYSDAY=Monday %THEN %DO; PROC PRINT DATA=flowersales; FORMAT SaleDate WORDDATE18.; TITLE 'Monday Report: Current Flower Sales'; %END; %ELSE %IF &SYSDAY= Tuesday %THEN %DO; PROC MEANS DATA=flowersales MEAN MIN MAX; CLASS Variety; VAR Quantity; TITLE 'Tuesday Report: Summary of Flower Sales'; %END; %MEND dailyreports; DATA flowersales; INFILE 'v:\Tropical.txt'; INPUT CustomerID $ @6 SaleDate MMDDYY10. @17 Variety $9. Quantity; RUN; %dailyreports RUN; 06 Writing Data-Driven Programs with CALL SYMPUT When you submit a SAS program containing macros if goes first to the macro processor which produces standard SAS code from the macro references. Then SAS compiles and executes your program. So SAS does not see any actual data values until execution. This is the tricky part when you want to use macros to make programs data driven and let SAS decide what to do based on actual data values. In this case you can use CALL SYMPUT. CALL SYMPUT takes a value from a DATA step and assigns it to a macro variable. You can then use this macro variable in later steps. To assign a value to a single macro variable, you use CALL SYMPUT with this general form: CAKK SYMPUT ("macro-variable-name",value); where macro-variable-name is the name of a macro variable, either new or old, and value is the value you want to assign to that macro variable. value can be the name of a variable whose value SAS will use, or it can be a constant value enclosed in quotation marks. For example, IF Age>=18 THEN CALL SYMPUT("status","*****1"); ELSE CALL SYMPUT("status","Minor"); These statements create macro variable named &STATUS and assign to it a value of either *****1 or Minor depending on the variable Age. Example program (See See the Tropical data in 02): Suppose the gardener wants to find the customer with the single largest order, and print all the orders for that customer. DATA flowersales; INFILE 'v:\Tropical.txt'; INPUT CustomerID $ @6 SaleDate MMDDYY10. @17 Variety $9. Quantity; PROC SORT DATA=flowersales; BY DESCENDING Quantity; DATA _NULL_; SET flowersales; IF _N_=1 THEN CALL SYMPUT ("selectedcustomer",CustomerID); ELSE STOP; PROC PRINT DATA=flowersales; WHERE CustomerID="&selectedcustomer"; FORMAT SaleDate WORDDATE18.; TITLE "Customer &selectedcustomer Had the Single Largest Order";
Ready to start your tutorial with us? That's great! Send us an email and we will get back to you as soon as possible!