SAS macro parameters with commas

Have you ever tried to pass multiple values for a SAS macro parameter to a SAS macro or a SAS macro function?

How can SAS distinguish commas separating parameters or arguments from commas separating parts of the values?

This article describes the problems associated with the resolution and use of macro variables that contain commas and how to use the macro quoting functions to pass SAS macro parameters with commas.

SAS macro parameters with commas to macro functions

Let us say you want to extract the first word from a string of characters using the scan function.

%let name=John,Mathew;
%put %scan(&name,1);

ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: Mathew
ERROR: Argument 2 to macro function %SCAN is not a number.

You may also get the below error.

ERROR: Macro function %SCAN has too many arguments.

The %scan macro function sees and treats those make, model, type and origin as arguments since commas between them are interpreted as argument separators.

The Solution: 

To pass commas in a macro function you need to mask them after resolving a macro-variable. This can be done by using the %BQUOTE %NRQUOTE(), %BQUOTE(), %NRBQUOTE() and %SUPERQ() macro-function.

%put %scan(%quote(&name), 1);
%put %scan(%bquote(&name), 1);
%put %scan(%nrquote(&name), 1);

The syntax of the %SUPERQ() function is different from the rest of the macro quoting functions. The %SUPERQ() macro function takes as its argument either a macro variable name without an ampersand or a macro text expression that yields a macro variable name without an ampersand.

%put %scan(%superq(name), 1)

SAS macro parameters with commas in SAS macros

%let var = name, weight, age;
%macro print(dsname=, varlist=);
   proc sql;
      select &varlist
      from &dsname;
   quit;
%mend print;
/*Below macro call will result in an error*/
%print(dsname=SASHELP.CLASS, varlist=&var);
%print(dsname=SASHELP.CLASS, varlist=name,weight,age)
78 %print(dsname=SASHELP.CLASS, varlist=name, weight,
ERROR: All positional parameters must precede keyword parameters.
78 ! age);
___
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
ERROR: All positional parameters must precede keyword parameters.
79 %print(dsname=SASHELP.CLASS, varlist=&var);
NOTE: Line generated by the macro variable "VAR".
79 name, weight, age
___
180
ERROR 180-322: Statement is not valid or it is used out of proper order.

This happens because the comma is used as a separator for SAS function arguments and SAS macro parameters. In addition, resolved macro variables also separate their values using a comma as the delimiter.

In this macro quoting functions summary, you may look up what symbols they mask and their application timing (macro compilation vs macro execution).

This happens because the comma is used as a separator for SAS function arguments and SAS macro parameters while resolved macro variables also separate their values using the comma as the delimiter.

You may look up what symbols they mask and the timing they apply (macro compilation vs. macro execution) in this macro quoting functions summary.

The Solution:

%print(dsname=SASHELP.CLASS, varlist=%str(name,weight,age))
%print(dsname=SASHELP.CLASS, varlist=%nrstr(name, weight, age)) 
%print(dsname=SASHELP.CLASS, varlist=%quote(&var))
%print(dsname=SASHELP.CLASS, varlist=%bquote(&var))
%print(dsname=SASHELP.CLASS, varlist=%nrbquote(&var))
%print(dsname=SASHELP.CLASS, varlist=%superq(var))

Note: Using %STR or %NRSTR directly on the macro variable throws an error. %NRSTR, which stands for No Resolution STRING will prevent any ampersands and per cent signs from being interpreted.

/*Error*/
%print(dsname=SASHELP.CLASS, varlist=%str(&var))
%print(dsname=SASHELP.CLASS, varlist=%nrstr(&var))

To summarize, %NRSTR() prevents macro variable and macro resolution of any kind, whereas %STR() does allow macro variable and macro resolution.

Summary

To summarize, %NRSTR() prevents macro variable and macro resolution of any kind, whereas %STR() does allow macro variable and macro resolution.

%BQUOTE and %NRBQUOTE mask values during execution of a macro statement. These functions instruct the macro processor to resolve a macro expression as far as possible and mask the result, issuing any warning messages for macro variable references or macro invocations it cannot resolve.

The %BQUOTE and %NRBQUOTE functions operate during execution and are more flexible than %STR and %NRSTR, %BQUOTE and %NRBQOUTE are good choices for masking strings that contain macro variable references.

I hope you found this article useful. See you next time.

Every week we'll send you SAS tips and in-depth tutorials

JOIN OUR COMMUNITY OF SAS Programmers!

Subhro Kar is an Analyst with over five years of experience. As a programmer specializing in SAS (Statistical Analysis System), Subhro also offers tutorials and guides on how to approach the coding language. His website, 9to5sas, offers students and new programmers useful easy-to-grasp resources to help them understand the fundamentals of SAS. Through this website, he shares his passion for programming while giving back to up-and-coming programmers in the field. Subhro’s mission is to offer quality tips, tricks, and lessons that give SAS beginners the skills they need to succeed.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Share via
Copy link
Powered by Social Snap