Suppose you create an online
training system in which users can enter problems and questions that
another macro prints for you later. The user's response to a %WINDOW
statement is assigned to a local macro variable and then to a global
macro variable. Because the user is asking questions about macros,
he or she might enter all sorts of macro variable references and macro
calls as examples of problems, as well as unmatched, unmarked quotation
marks and parentheses. If you mask the response with %BQUOTE, you
have used a few %PUT statements to warn the user about responses that
cause problems. If you the %SUPERQ function, you need fewer instructions.
The macros ASK1 and ASK2 show how the macro code becomes simpler as
you change macro quoting functions.
The macro ASK1, below,
shows how the macro looks when you use the %BQUOTE function:
%window ask
#5 @5 'Describe the problem.'
#6 @5 'Do not use macro language keywords, macro calls,'
#7 @5 'or macro variable references.'
#9 @5 'Enter /// when you are finished.'
#11 @5 val 100 attr=underline;
%macro ask1;
%global myprob;
%local temp;
%do %until(%bquote(&val) eq %str(///));
%display ask;
%let temp=&temp %bquote(&val);
%end;
%let myprob=&temp
%mend ask1;
The macro ASK1 does
not include a warning about unmatched quotation marks and parentheses.
You can invoke the macro ASK1 and enter a problem:
%ask1
Try entering:
Why did my macro not run when I called it? (It had three
parameters, but I wasn't using any of them.)
It ran after I submitted the next statement.
///
Notice that both the
first and second lines of the response contain an unmatched, unmarked
quotation mark and parenthesis. %BQUOTE can handle these characters
during execution.
The macro ASK2, shown
here, modifies the macro ASK1 by using the %SUPERQ function. Now the
%WINDOW statement accepts macro language keywords and does not attempt
to resolve macro calls and macro variable references:
%window ask
#5 @5 'Describe the problem.'
#7 @5 'Enter /// when you are finished.'
#9 @5 val 100 attr=underline;
%macro ask2;
%global myprob;
%local temp;
%do %until(%superq(val) eq %str(///)); /* No ampersand */
%display ask;
%let temp=&temp %superq(val); /* No ampersand */
%end;
%let myprob=&temp
%mend ask2;
You can invoke the macro
ASK2 and enter a response:
%ask2
Try entering:
My macro ADDRESS starts with %MACRO ADDRESS(COMPANY,
CITY);. I called it with %ADDRESS(SMITH-JONES, INC., BOSTON),
but it said I had too many parameters. What happened?
///
The response contains
a macro language keyword, a macro invocation, and unmatched parentheses.