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);___180ERROR 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___180ERROR 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 separate their values using the comma as the delimiter.
In this macro quoting functions summary, you may look up what symbols they mask and the timing they apply (macro compilation vs macro execution).
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 helpful article. See you next time.