SAS Macro Code Examples: Practical Guide with Real-World SAS Macros

Isabella Sep 08, 2026

SAS macro code examples are one of the fastest ways to move from repetitive programming to reusable, dynamic SAS programs. A macro lets you package a sequence of DATA steps, PROC steps, and macro statements behind a single name, so you can call it repeatedly with different parameters. Instead of copying and pasting code for every region, year, or dataset, you write the logic once and let the macro language generate the right code at execution time.

8 Ways to count the number of observations in a SAS dataset.
8 Ways to count the number of observations in a SAS dataset.

This guide walks through practical SAS macro code examples, from simple parameterized macros that run summary statistics to advanced patterns that build dynamic WHERE clauses and handle conditional logic. The goal is not to memorize syntax but to recognize the patterns that make macros useful in real SAS projects. Each example includes the core idea, a code pattern, and notes on when to use it.

the flow diagram for an application with different types of data and numbers, including two lines
the flow diagram for an application with different types of data and numbers, including two lines

Core SAS Macro Code Examples for Everyday Automation

Every SAS programmer eventually writes the same block of code more than once. You might run PROC MEANS for each numeric variable, export a report for each month, or create a dataset for every department. Macros solve that problem by turning repeated steps into a callable routine. The basic structure uses %MACRO to start the definition, %MEND to end it, and positional or keyword parameters to pass values into the routine.

SAS Loops – Understanding Leave and Continue
SAS Loops – Understanding Leave and Continue

Before looking at specific examples, remember that macro code is resolved before the underlying SAS code is compiled. That timing matters. Macro variables are replaced with their values, %IF statements choose which code to emit, and %DO loops repeat code generation. If you keep that mental model, examples such as parameterized PROC steps and dynamic dataset names become much easier to read.

Example 1: A Parameterized Macro for Summary Statistics

SAS User's Guides
SAS User's Guides

A simple summary macro is a good first SAS macro code example because it shows the relationship between parameters and macro variables. The macro below accepts a dataset and a variable, then runs PROC MEANS. The parameter values are referenced with an ampersand, and the macro is invoked with keyword arguments. Code: %macro summary(data=, var=); proc means data=&data. n mean std min max; var &var.; run; %mend summary; %summary(data=sashelp.cars, var=mpg_city);

This pattern becomes more valuable when you add defaults and validation. For example, you can set a default dataset or check whether the variable parameter is empty before running the procedure. A small validation step prevents confusing errors later. Code: %macro summary(data=sashelp.cars, var=mpg_city); %if %superq(var)= %then %do; %put ERROR: The var parameter is required.; %return; %end; proc means data=&data. n mean std min max; var &var.; run; %mend summary;

Example 2: Using Macro Loops to Generate Repetitive Code

a poster with the words advanced and an image of a computer screen
a poster with the words advanced and an image of a computer screen

Macro loops are ideal when you need to generate multiple DATA steps, PROC steps, or reports from a single call. The %DO %TO loop iterates from a start value to an end value. In the example below, the macro creates one dataset per year and stores it with a year-specific name. This avoids writing five nearly identical DATA steps by hand. Code: %macro yearly_reports(start=, end=); %do year=&start. %to &end.; data work.sales_&year.; set work.sales; where year=&year.; run; %end; %mend yearly_reports; %yearly_reports(start=2020, end=2024);

Loop examples often need dynamic names and arithmetic. You can use %EVAL for integer calculations, %SYSEVALF for floating-point math, and %SYSFUNC to call SAS functions inside the macro. If you need to iterate over a list instead of a numeric range, combine %SCAN with a counting loop. For instance, %LET count=%SYSFUNC(countw(&list.)); then loop from 1 to &count. and extract each item with %SCAN. That pattern is common for processing variable lists, file names, or table names.

Advanced SAS Macro Code Examples for Dynamic Programming

an info sheet describing different types of computers
an info sheet describing different types of computers

Once basic parameterization and looping feel comfortable, macros can handle more complex decisions. Advanced macro code often checks conditions, reads metadata, or builds statements based on data values. These techniques reduce manual edits in production jobs, but they also require careful quoting and debugging. A macro that works for one value may fail when a value contains a comma, parenthesis, or semicolon.

Two options are essential when developing advanced macros: OPTIONS MPRINT and OPTIONS MLOGIC. MPRINT shows the SAS code generated by the macro, while MLOGIC shows the logical path through %IF and %DO statements. SYMBOLGEN displays macro variable values as they resolve. Together, these options turn a black-box macro into a transparent process you can troubleshoot step by step.

Client Challenge
Client Challenge
an image of a table with the names and numbers for different types of data sources
an image of a table with the names and numbers for different types of data sources
what is idc in sap? info sheet with information about it and how to use it
what is idc in sap? info sheet with information about it and how to use it
SAS - Macros
SAS - Macros
SQL Basics Cheat Sheet for Beginners | Learn SQL Fast 💻
SQL Basics Cheat Sheet for Beginners | Learn SQL Fast 💻
a poster with the words, sol commands and data analist must know on it
a poster with the words, sol commands and data analist must know on it
Data - GROUPING SETS makes SQL summaries cleaner.  Instead of writing separate queries for:  product totals category subtotals grand total  you can return them together in one result set.  That’s the power of GROUPING SETS.  It helps when you need reports, dashboards, exports, or summary tables where different levels of aggregation are shown together.  One query. Multiple summary levels. Cleaner reporting.  Save this one for your SQL reporting toolkit.  #SQL #DataAnalytics #SQLServer #DataDrivenInsights #Database #Analytics #LearnSQL | Facebook
Data - GROUPING SETS makes SQL summaries cleaner. Instead of writing separate queries for: product totals category subtotals grand total you can return them together in one result set. That’s the power of GROUPING SETS. It helps when you need reports, dashboards, exports, or summary tables where different levels of aggregation are shown together. One query. Multiple summary levels. Cleaner reporting. Save this one for your SQL reporting toolkit. #SQL #DataAnalytics #SQLServer #DataDrivenInsights #Database #Analytics #LearnSQL | Facebook
the sap mm materials management sheet
the sap mm materials management sheet
an image of a diagram with many different words
an image of a diagram with many different words

Example 3: Conditional Logic with %IF %THEN %ELSE

Conditional logic lets a macro behave differently depending on the input. A common use case is checking whether a dataset exists before attempting to print or modify it. The %SYSFUNC function calls the EXIST function, which returns 1 if the dataset exists and 0 if it does not. The macro then chooses which block of code to emit. Code: %macro check_ds(ds=); %if %sysfunc(exist(&ds.)) %then %do; proc print data=&ds.(obs=10); run; %end; %else %do; %put WARNING: &ds. does not exist.; %end; %mend check_ds; %check_ds(ds=work.sales);

You can extend this pattern to compare string values, check library references, or branch on the operating system. For example, %IF %UPCASE(&type.)=SUM %THEN ... is useful when a parameter controls whether the macro calculates a sum or an average. Keep comparisons simple and normalize case with %UPCASE to avoid mismatches. When multiple statements belong to one branch, wrap them in %DO and %END. This keeps the generated code readable and prevents accidental execution of the wrong branch.

Example 4: Building Dynamic WHERE Clauses and Macro Quoting

Dynamic WHERE clauses are a powerful SAS macro code example because they let users pass a list of values without editing the program. The macro below accepts a dataset, a variable, and a comma-separated list of values. It loops through the list, builds a WHERE clause with OR conditions, and applies it in a DATA step. Code: %macro subset(dsn=, var=, values=); %let where_clause=; %let count=%sysfunc(countw(&values., %str(,))); %do i=1 %to &count.; %let val=%scan(&values., &i., %str(,)); %if &i.=1 %then %let where_clause=&var.="&val."; %else %let where_clause=&where_clause. or &var.="&val."; %end; data subset; set &dsn.; where &where_clause.; run; %mend subset; %subset(dsn=sashelp.cars, var=origin, values=Asia,Europe);

Macro quoting is what keeps this example from breaking. %STR protects commas and semicolons during macro compilation, while %BQUOTE and %SUPERQ handle values that may contain unmatched quotes or ampersands. If a value includes a parenthesis, such as AWD (All-Wheel Drive), quoting prevents the macro parser from treating it as syntax. For production macros, validate the generated clause with %PUT before running the final step, especially when the input list comes from an external file or user prompt.

As you practice these patterns, start small and add complexity only when the problem demands it. A clean parameterized macro is often better than a clever one that no one can maintain. Take one repetitive task from your current SAS workflow, turn it into a macro, and test it with edge cases such as missing values, empty lists, and unusual dataset names. That habit will build a personal library of SAS macro code examples you can trust, reuse, and share with your team.