Macro quoting made easy

Are there times when you need to pass special characters to a macro variable but cannot find the right technique to accomplish the task?  In this article I’ll discuss the different macro quoting functions and give a simple technique to help you determine which macro quoting function to use.

Why do we need macro quoting?  The SAS macro language is a character-based language. With macro, you can specify special characters as text.  Some of these special characters (for example, a semicolon or percent sign) are part of the SAS language instruction set, so we need a way for the macro processor to interpret a particular special character when it’s being used as text in the macro language.  Macro quoting functions tell the macro processor to treat these special characters as text rather than as part of the macro language.  Without macro quoting functions, you would have no way to mask the real meaning of these special characters or mnemonics.

This post will list some all-purpose functions, tell how to determine when to use each type, and show you how to unmask, or unquote special characters.

Two types of macro quoting functions

There are basically two types of macro quoting functions:  compile time and execution time.

Compile time functions:

% STR

% NRSTR

%STR and %NRSTR mask the same characters except %NRSTR also masks & and % signs.

Execution time functions:

%SUPERQ   (Reminder: do not use & with macro variable name)

%BQUOTE

There are other execution-time functions, but these are the only two you really need. %BQUOTE and %SUPERQ mask the same characters except %SUPERQ does not attempt to resolve a macro variable reference or a macro invocation that occurs in the value of the specified macro variable.  %SUPERQ masks everything without any further resolution which makes it the best execution-time quoting function to use.

How to determine which type to use

Many times the hardest part of macro quoting is knowing whether you need a compile time function or an execution time function.  A simple technique that will help you easily choose the right one is to follow this motto:

If you can see the problem, it is a compile issue; otherwise, it is execution time.

These examples illustrate when a compile time function is needed.  You can see the potential problem in each of the examples:

There are a few special cases when you have an unmatched quotation mark or an unmatched parenthesis. These unmatched characters must be preceded with a percent sign when assigning a value at compile time.  For example:

These examples illustrate when an execution time function is needed.  You cannot see the potential problem in each of the examples:

Unquoting special characters

Now that we have seen how to mask special characters, we also need a way to reverse the masking. This reversal is referred to as unquoting which means to restore the significance of symbols in an item that was previously masked by a macro quoting function.

Generally, once you use a macro quoting function on a value, the macro processor retains that masking on the value. There are three cases where the unquoting is done for you:

The %UNQUOTE function was used.

The item leaves the word scanner and is passed to the DATA step compiler, SAS Macro Facility, or other parts of the SAS System.

The value is returned from the %SCAN, %SUBSTR, or %UPCASE function.

There are two cases where you might need to use the %UNQUOTE function to restore the original significance to a masked item:

When you want to use a value with its restored meaning later in the same macro in which its value was previously masked by a macro quoting function.

In some cases, masking text with a macro quoting function changes the way the word scanner tokenizes it, producing SAS statements that look correct but the SAS compiler does not recognize. This is the most common need for %UNQUOTE.

The code generated by the macro may look correct, but an error is generated because the masking placed on the value from the %QSCAN (to be discussed later) is causing the string to be tokenized incorrectly.  This can be corrected by using the %UNQUOTE function.
%unquote(val&v) = &v/500;

Resolving macro variables within single quotes

Many times single quotes are required around a string where the string is made up of a macro variable.  Since macro triggers of percent and ampersand are seen as text within single quotes, a common request is how to resolve a macro variable within single quotes.  We can use %UNQUOTE along with %STR for this task:

An easy way to determine if a quoting function has been used on a macro variable is to use the following statement to print out the values:
%PUT _USER_;

Here is a screenshot of a resulting SAS log. Notice the unusual spaces and characters. These represent the masking done by a quoting function.  Quoting functions mark the beginning and ending of the string as well as any special character.

Other quoting functions

There are a few other functions that mask a result that may contain special characters.  These functions all begin with Q:  %QSYSFUNC, %QSCAN, %QSUBSTR and %QUPCASE. Here are a few examples:

I hope this blog post has been helpful. If you have other SAS macro questions you’d like me to cover in future blogs, please comment below.

Macro quoting made easy was published on SAS Users.