In the %IF statement, the values of WORD being tested are ambiguous — they could
also be interpreted as the numeric operators AND and OR. Therefore, SAS generates the
following error messages in the log:
ERROR: A character operand was found in the %EVAL function or %IF
condition where a numeric operand is required. The condition
was:word = and or &word = but or &word = or
ERROR: The macro will stop executing.
To fix this problem, use the quoting functions %BQUOTE and %STR, as in the
following corrected program:
%macro conjunct(word= );
%if %bquote(&word) = %str(and) or %bquote(&word) = but or
%bquote(&word) = %str(or) %then
%do %put *** &word is a conjunction. ***;
%else
%do %put *** &word is not a conjunction. ***;
%mend conjunct;
In the corrected program, the %BQUOTE function quotes the result of the macro
variable resolution (in case the user passes in a word containing an unmatched quotation
mark or some other odd value). The %STR function quotes the comparison values AND
and OR at compile time, so they are not ambiguous. You do not need to use %STR on
the value BUT, because it is not ambiguous (not part of the SAS or macro languages).
For more information, see Chapter 7, “Macro Quoting,” on page 81.
Debugging Techniques
Using System Options to Track Problems
The SAS system options MLOGIC, MLOGICNEST, MPRINT, MPRINTNEST, and
SYMBOLGEN can help you track the macro code and SAS code generated by your
macro. Messages generated by these options appear in the SAS log, prefixed by the
name of the option responsible for the message.
Note: Whenever you use the macro facility, use the following macro options: MACRO,
MERROR, and SERROR. SOURCE is a system option that is helpful when using
the macro facility. It is also helpful to use the SOURCE2 system option when using
the %INCLUDE.
Although the following sections discuss each system option separately, you can, of
course, combine them. However, each option can produce a significant amount of
output, and too much information can be as confusing as too little. So, use only those
options that you think you might need and turn them off when you complete the
debugging.
Tracing the Flow of Execution with MLOGIC
The MLOGIC system option traces the flow of execution of your macro, including the
resolution of parameters, the scope of variables (global or local), the conditions of macro
expressions being evaluated, the number of loop iterations, and the beginning and end of
each macro execution. Use the MLOGIC option when you think a bug lies in the
program logic (as opposed to simple syntax errors).
136 Chapter 10 Macro Facility Error Messages and Debugging
Note: MLOGIC can produce a lot of output, so use it only when necessary, and turn it
off when debugging is finished.
In the following example, the macro FIRST calls the macro SECOND to evaluate an
expression:
%macro second(param);
%let a = %eval(&param); &a
%mend second;
%macro first(exp);
%if (%second(&exp) ge 0) %then
%put **** result >= 0 ****;
%else
%put **** result < 0 ****;
%mend first;
options mlogic;
%first(1+2)
Submitting this example with option MLOGIC shows when each macro starts execution,
the values of passed parameters, and the result of the expression evaluation.
MLOGIC(FIRST): Beginning execution.
MLOGIC(FIRST): Parameter EXP has value 1+2
MLOGIC(SECOND): Beginning execution.
MLOGIC(SECOND): Parameter PARAM has value 1+2
MLOGIC(SECOND): %LET (variable name is A)
MLOGIC(SECOND): Ending execution.
MLOGIC(FIRST): %IF condition (%second(&exp) ge 0) is TRUE
MLOGIC(FIRST): %PUT **** result >= 0 ****
MLOGIC(FIRST): Ending execution.
Nesting Information Generated by MLOGICNEST
MLOGICNEST allows the macro nesting information to be written to the SAS log in the
MLOGIC output. The setting of MLOGICNEST does not imply the setting of MLOGIC.
You must set both MLOGIC and MLOGICNEST in order for output (with nesting
information) to be written to the SAS log.
For more information and an example, see “MLOGICNEST System Option” on page
373.
Examining the Generated SAS Statements with MPRINT
The MPRINT system option writes to the SAS log each SAS statement generated by a
macro. Use the MPRINT option when you suspect your bug lies in code that is generated
in a manner that you did not expect.
For example, the following program generates a simple DATA step:
%macro second(param);
%let a = %eval(&param); &a
%mend second;
%macro first(exp);
data _null_;
var=%second(&exp);
Debugging Techniques 137
put var=;
run;
%mend first;
options mprint;
%first(1+2)
When you submit these statements with option MPRINT, these lines are written to the
SAS log:
MPRINT(FIRST): DATA _NULL_;
MPRINT(FIRST): VAR=
MPRINT(SECOND): 3
MPRINT(FIRST): ;
MPRINT(FIRST): PUT VAR=;
MPRINT(FIRST): RUN;
VAR=3
The MPRINT option shows you the generated text and identifies the macro that
generated it.
Nesting Information Generated by MPRINTNEST
MPRINTNEST allows the macro nesting information to be written to the SAS log in the
MPRINT output. This value has no effect on the MPRINT output that is sent to an
external file. For more information, see “MFILE System Option” on page 368.
The setting of MPRINTNEST does not imply the setting of MPRINT. You must set both
MPRINT and MPRINTNEST in order for output (with the nesting information) to be
written to the SAS log.
For more information and an example, see “MPRINTNEST System Option” on page
377.
Storing MPRINT Output in an External File
You can store text that is generated by the macro facility during macro execution in an
external file. Printing the statements generated during macro execution to a file is useful
for debugging macros when you want to test generated text in a later SAS session.
To use this feature, set both the MFILE and MPRINT system options on. Also assign
MPRINT as the fileref for the file to contain the output generated by the macro facility:
options mprint mfile;
filename mprint 'external-file';
The external file created by the MPRINT system option remains open until the SAS
session terminates. The MPRINT text generated by the macro facility is written to the
log during the SAS session and to the external file when the session ends. The text
consists of program statements generated during macro execution with macro variable
references and macro expressions resolved. Only statements generated by the macro are
stored in the external file. Any program statements outside the macro are not written to
the external file. Each statement begins on a new line with one space separating words.
The text is stored in the external file without the MPRINT(macroname): prefix, which
is displayed in the log.
138 Chapter 10 Macro Facility Error Messages and Debugging
If MPRINT is not assigned as a fileref or if the file cannot be accessed, warnings are
written to the log and MFILE is turned off. To use the feature again, you must specify
MFILE again.
By default, the MPRINT and MFILE options are off.
The following example uses the MPRINT and MFILE options to store generated text in
the external file named TempOut:
options mprint mfile;
filename mprint 'TEMPOUT';
%macro temp;
data one;
%do i=1 %to 3;
x&i=&i;
%end;
run;
%mend temp;
%temp
The macro facility writes the following lines to the SAS log and creates the external file
named TempOut:
MPRINT(TEMP): DATA ONE;
NOTE: The macro generated output from MPRINT will also be written
to external file '/u/local/abcdef/TEMPOUT' while OPTIONS
MPRINT and MFILE are set.
MPRINT(TEMP): X1=1;
MPRINT(TEMP): X2=2;
MPRINT(TEMP): X3=3;
MPRINT(TEMP): RUN;
When the SAS session ends, the file TempOut contains:
DATA ONE;
X1=1;
X2=2;
X3=3;
RUN;
Note: Using MPRINT to write code to an external file is a debugging tool only. It
should not be used to create SAS code files for purposes other than debugging.
Examining Macro Variable Resolution with SYMBOLGEN
The SYMBOLGEN system option tells you what each macro variable resolves to by
writing messages to the SAS log. This option is especially useful in spotting quoting
problems, where the macro variable resolves to something other than what you intended
because of a special character.
For example, suppose you submit the following statements:
options symbolgen;
%let a1=dog;
%let b2=cat;
%let b=1;
%let c=2;
Debugging Techniques 139
%let d=a;
%let e=b;
%put **** &&&d&b ****;
%put **** &&&e&c ****;
The SYMBOLGEN option writes these lines to the SAS log:
SYMBOLGEN: && resolves to &.
SYMBOLGEN: Macro variable D resolves to a
SYMBOLGEN: Macro variable B resolves to 1
SYMBOLGEN: Macro variable A1 resolves to dog
**** dog ****
SYMBOLGEN: && resolves to &.
SYMBOLGEN: Macro variable E resolves to b
SYMBOLGEN: Macro variable C resolves to 2
SYMBOLGEN: Macro variable B2 resolves to cat
**** cat ****
Reading the log provided by the SYMBOLGEN option is easier than examining the
program statements to trace the indirect resolution. Notice that the SYMBOLGEN
option traces each step of the macro variable resolution by the macro processor. When
the resolution is complete, the %PUT statement writes the value to the SAS log.
When you use SYMBOLGEN to trace the values of macro variables that have been
masked with a macro quoting function, you might see an additional message about the
quoting being “stripped for printing.” For example, suppose you submit the following
statements, with SYMBOLGEN:
%let nickname = %str(My name%'s O%'Malley, but I%'m called Bruce);
%put *** &nickname ***;
The SAS log contains the following after these statements have executed:
SYMBOLGEN: Macro variable NICKNAME resolves to
My name's O'Malley, but I'm called Bruce
SYMBOLGEN: Some characters in the above value which were
subject to macro quoting have been
unquoted for printing.
*** My name's O'Malley, but I'm called Bruce ***
You can ignore the unquoting message.
Using the %PUT Statement to Track Problems
Along with using the SYMBOLGEN system option to write the values of macro
variables to the SAS log, you might find it useful to use the %PUT statement while
developing and debugging your macros. When the macro is finished, you can delete or
comment out the %PUT statements. The following table provides some occasions where
you might find the %PUT statement helpful in debugging, and an example of each:
Table 10.4 Example %PUT Statements That Are Useful When Debugging Macros
Situation Example
Show a macro variable's value
%PUT ****&=variable-name****;
140 Chapter 10 Macro Facility Error Messages and Debugging
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset