Est. 1982 Advanced

SAS Macro Language

A text-substitution macro and metaprogramming layer built into base SAS that generates SAS code dynamically before it is compiled and executed

Created by SAS Institute

Paradigm Macro / metaprogramming; procedural text-substitution preprocessor layered on the SAS language
Typing Typeless; every macro value is stored and manipulated as a text string
First Appeared 1982 (early macro facility in SAS 82); a complete macro language followed with Version 5 in 1986
Latest Version Shipped as part of base SAS 9.4 (Maintenance 9, 2025) and SAS Viya

The SAS Macro Language is a text-substitution and metaprogramming facility built into base SAS. It is not a separate product but a layer that sits above ordinary SAS code: rather than processing data directly, macro code writes SAS code, which the SAS system then compiles and executes. Where a DATA step manipulates rows and columns, the macro language manipulates the program text itself — substituting values, looping to generate repetitive statements, and conditionally including or excluding blocks of code. This makes it the primary tool SAS programmers reach for when they need to reduce duplication, parameterize routines, and build flexible, reusable, data-driven programs.

History & Origins

The macro facility grew out of the broader SAS system, which began as an academic statistical-computing project at North Carolina State University in the 1960s and was spun out as SAS Institute Inc. in 1976. As SAS programs grew larger and more repetitive, users needed a way to avoid writing the same code over and over with only small changes.

An early macro language was introduced in SAS 82 (around 1982), giving programmers their first ability to substitute text and generate code from within a SAS program. The facility matured substantially with SAS Version 5 in 1986, which shipped a complete macro language — the %MACRO/%MEND definition model, the %LET statement for creating macro variables, macro program-control statements, and the ampersand-and-percent syntax that SAS programmers still use today. Later releases extended its reach: Version 6.12 (released around 1997) added the %SYSFUNC function, which exposes nearly all DATA step functions to macro code and dramatically expanded what macros could compute at generation time.

Design Philosophy

The macro language is built on one deceptively simple idea: everything is text. A macro variable does not hold a number or a date in any typed sense — it holds a string. When SAS reads a program, a component called the macro processor runs first, resolving all macro references and triggering macro logic. Only the resulting plain SAS text is handed on to the SAS compiler. In other words, the macro language is a preprocessor: it operates at a phase before the “real” SAS program even exists.

This two-phase model is the source of both the macro language’s power and its notorious difficulty. Understanding when something resolves — at macro time versus at execution time — is the central skill (and the central trap) of macro programming. The payoff is that a programmer can capture a pattern once and let SAS mechanically generate the dozens or hundreds of nearly identical statements that pattern implies.

Key Features

FeatureWhat it provides
Macro variables (&name)Named text values, referenced with a leading ampersand, substituted into code wherever they appear
%LETCreates and assigns macro variables
%MACRO / %MENDDefines a reusable, optionally parameterized macro program
Macro program control%IF/%THEN/%ELSE, %DO/%END, and iterative %DO loops for generating code conditionally and repeatedly
%GLOBAL / %LOCALControl the scope (symbol table) in which macro variables live
Automatic macro variablesSystem-supplied values such as &SYSDATE, &SYSVER, and &SYSLAST
Macro functionsText functions like %SCAN, %SUBSTR, %UPCASE, and %SYSFUNC (which calls DATA step functions)
Autocall & stored compiled macrosFacilities for sharing macros across programs and storing pre-compiled macros for reuse
PROC SQL ... INTO :varA common bridge that reads values from data into macro variables, enabling data-driven generation

A useful mental rule from the SAS community captures the whole model: macro variables are usually preceded by &, while macro statements and functions are usually preceded by %.

A Taste of the Language

The example below defines a parameterized macro that prints a summary for a chosen variable, then calls it twice. The macro processor generates two ordinary PROC MEANS steps before SAS ever runs them:

1
2
3
4
5
6
7
8
9
%macro summarize(ds=, var=);
   proc means data=&ds mean sum maxdec=2;
      var &var;
      title "Summary of &var in &ds";
   run;
%mend summarize;

%summarize(ds=sashelp.class, var=height)
%summarize(ds=sashelp.class, var=weight)

Here &ds and &var are macro variables carrying the parameter values, and the two %summarize(...) calls cause the macro processor to emit two complete, slightly different PROC MEANS steps. A %do loop could just as easily generate one step per variable in a list.

Evolution

The macro language has evolved less in syntax than in reach. Its core constructs — %MACRO, %LET, macro variables, %IF/%DO — have been remarkably stable since Version 5 in 1986, which is precisely why decades-old macro code still runs on current SAS. What expanded over time was its connection to the rest of the system: %SYSFUNC (introduced with Version 6.12, around 1997) let macros tap the entire DATA step function library; autocall and stored-compiled-macro facilities made large shared macro libraries practical; and tight integration with PROC SQL made it straightforward to drive code generation directly from data. Through the SAS 9 platform (rollout around 2004), SAS 9.4 (2013), and the cloud-native SAS Viya (2016), the macro language has been carried forward essentially intact as a standard part of base SAS.

Current Relevance

Because the macro language is bundled with base SAS, it is wherever SAS is — and SAS remains entrenched in pharmaceuticals, banking, insurance, government, and other regulated industries. In those settings, macros are the everyday mechanism for standardization and reuse: a validated macro can be written once, reviewed, and then applied uniformly across hundreds of outputs, which is exactly the kind of repeatable, auditable process that regulated work demands. The macro facility continues to ship and be maintained in current releases, including SAS 9.4 Maintenance 9 (2025) and SAS Viya, ensuring that the enormous body of existing macro code keeps running on modern platforms.

Why It Matters

The SAS Macro Language is a clear, long-lived example of metaprogramming put to practical, industrial use. Long before “code that writes code” became a common talking point, working SAS programmers were using macros to compress repetitive analytics work, parameterize entire pipelines, and adapt programs to their data at run time. Its preprocessor model — resolve the macro text first, then compile and run the result — is conceptually simple yet powerful enough to underpin some of the most heavily validated, mission-critical reporting code in medicine and finance. For the analysts who maintain those systems, the macro language is not an optional add-on but the essential glue that makes large-scale, reusable SAS programming possible.

Timeline

1976
SAS Institute Inc. is incorporated in North Carolina, establishing the base SAS system that the macro facility would later extend
1982
SAS 82 introduces an early macro language, giving programmers a way to substitute text and generate code within SAS programs for the first time
1986
SAS Version 5 introduces a complete macro language alongside the full-screen Display Manager interface, establishing the %MACRO/%MEND, %LET, and macro-variable model still in use today
1990s
Version 6.12 adds the %SYSFUNC function (released around 1997), which exposes nearly all DATA step functions to the macro language and greatly expands what macro code can compute
1999
SAS 8 ships with the mature macro facility integrated into base SAS, used heavily to drive the new Output Delivery System and reusable reporting code
2004
The SAS 9 platform (rollout completed around 2004) continues to bundle the macro language as a core part of base SAS, including the autocall and stored compiled macro facilities
2013
SAS 9.4 is released, the long-lived modern foundation in which the macro language remains a standard component of base SAS
2016
SAS Viya launches, and the macro language continues to be supported so that legacy and new SAS code can run on the cloud-native platform
2025
SAS 9.4 Maintenance 9 (9.4M9) is released, continuing to ship and maintain the macro facility as part of base SAS

Notable Uses & Legacy

Clinical trials & regulatory submissions

Pharmaceutical statistical programmers use macros to build reusable, validated routines that generate the many standardized tables, listings, and figures required for FDA submissions, parameterizing one macro across dozens of similar outputs

Banking & risk reporting

Financial institutions use the macro language to template repetitive regulatory and risk reports, looping a single macro over portfolios, time periods, or business units to generate consistent code at scale

Production data pipelines

Enterprises wrap recurring extract-transform-load and reporting jobs in macros so that the same logic can be re-run with different dates, libraries, or parameters without editing the underlying program

Reusable code libraries (autocall)

Organizations build shared autocall macro libraries — collections of general-purpose macros automatically available to every program — to standardize common tasks across analytics teams

Dynamic, data-driven programming

Analysts use macros together with PROC SQL's INTO clause to read values out of data at run time and feed them back into generated code, producing programs whose structure adapts to the data itself

Language Influence

Influenced By

Running Today

Run examples using the official Docker image:

docker pull
Last updated: