Macro functions - %SCAN, %INDEX, %LENGTH, and building variable lists
What are macro functions
SAS provides a set of built-in macro functions that operate on macro variable values as text
These functions are distinct from DATA step functions — they run in the macro processor before any SAS step executes
The three most commonly used text manipulation macro functions are `%scan`, `%index`, and `%length`
Together they allow you to extract words from a list, locate text within a string, and measure string length — all at the macro level
A very practical application is building and iterating over lists of variable names or dataset names inside a macro
%LENGTH - count characters in a macro variable value
`%length(text)` returns the number of characters in the text, including spaces
It is the simplest of the three functions and is often used to check whether a parameter was supplied or is empty
SAS Log
The first `%put` should show length 9 (the word `Marketing` has nine characters)
The second `%put` should show length 0 because `empty_var` has no value
Testing `%length` is a clean way to validate whether a required parameter was passed to a macro
SAS Log
The first call prints the NOTE confirming processing for Sales
The second call triggers the ERROR message and returns early without continuing
Using `%length` to guard against empty parameters makes macros more robust
%SCAN - extract words from a delimited string
`%scan(string, n, delimiters)` returns the nth word from `string` using the specified delimiters
If the delimiter argument is omitted, SAS uses a default set of delimiters that includes spaces and several punctuation characters
A space-separated list is the most common pattern for building variable or dataset lists in macros
If `n` is positive, SAS counts from the left; if negative, it counts from the right
If the requested word does not exist, `%scan` returns an empty string
SAS Log
The log should show `systolic`, `diastolic`, and `weight` for the first, second, and last positions respectively
The `%str( )` wraps a single space, so SAS recognises the space as the delimiter rather than ignoring it
Loop through a list using %SCAN and %DO %WHILE
A very common pattern is to combine `%scan` with a `%do %while` loop to process each word in a list
The loop increments a counter and uses `%scan` to pull the next word on each iteration
The loop exits when `%scan` returns an empty string, which happens after the last word is extracted
This pattern is the foundation for macros that need to repeat code for a list of variables or datasets
SAS Log
The macro runs PROC MEANS four times — once for each variable in the list
All working variables (`i` and `var`) are declared `%local`, so the global symbol table is unaffected
To extend the analysis to more variables, you only need to add names to the `varlist` parameter — no other code changes are required
Dataset View
%INDEX - locate text within a macro variable value
`%index(source, target)` searches for the first occurrence of `target` within `source` and returns its starting position as a number
Positions are counted from 1, so `%index` returns 1 if the target starts at the very beginning of the source
If the target is not found, `%index` returns 0
This is useful for checking whether a list already contains a particular value, or for conditional logic based on string content
SAS Log
The first `%put` returns a positive number (the starting character position of `diastolic` in the string)
The second `%put` returns 0 because `heart_rate` is not in the list
SAS Log
The first call adds `heart_rate` because it is absent and prints the updated list
The second call reports that `diastolic` is already present and does not duplicate it
Note that the `varlist` update inside the macro is local and does not persist after the macro ends — this example demonstrates the logic pattern rather than persistent list management
Building a dynamic variable list from a dataset
A powerful application of these macro functions is building a list of variable names dynamically from the structure of a dataset
PROC SQL with `into :macvar separated by` creates a macro variable containing all values from a column joined by a chosen delimiter
Once stored, the list can be iterated with `%scan` in the same way as a hard-coded list
SAS Log
PROC SQL queries the SAS data dictionary to retrieve the names of all numeric variables in the `vitals` dataset
The names are joined with spaces and stored in `num_vars`
The same `%summarise_vars` macro from earlier then processes every numeric variable without hard-coding any names
This pattern is widely used in clinical and production programming, where variable sets are determined by the data rather than fixed in advance
Key points to remember
`%length(text)` returns the character count of a macro value — use it to check whether a parameter was supplied before proceeding
`%scan(string, n, delimiter)` extracts the nth word from a string — use it with a counter variable and a `%do %while` loop to iterate over a list
`%index(source, target)` returns the starting position of target in source, or 0 if not found — use it to test membership in a list
Space-separated lists stored in macro variables are a lightweight, readable alternative to arrays for processing sets of names inside macros
Combining `%scan` with a `%do %while` loop and a position counter is the standard pattern for iterating over a macro-level list
Always declare working variables (`i`, `var`, `check`) as `%local` inside macros that use these functions