Solving Problems with Macro Functions
Some common causes of problems with macro functions include the following:
misspelling the function name
omitting the opening or closing parenthesis
omitting an argument or specifying an extra argument
If you encounter an error related to a macro function, you might also see other error
messages. The messages are generated by the invalid tokens left on the input stack by
the macro processor.
Consider the following example. The user wants to use the %SUBSTR function to
assign a portion of the value of the macro variable LINCOLN to the macro variable
SECONDWD. But a typographical error exists in the second %LET statement, where
%SUBSTR is misspelled as %SUBSRT:
%macro test;
%let lincoln=Four score and seven;
%let secondwd=%subsrt(&lincoln,6,5); /* ERROR */
%put *** &secondwd ***;
%mend test;
%test
When the erroneous program is submitted, the following appears in the SAS log:
WARNING: Apparent invocation of macro SUBSRT not resolved.
The error messages clearly point to the function name, which is misspelled.
Solving Unresolved Macro Problems
When a macro name is passed to the macro processor but the processor does not find a
matching macro definition, it generates the following message:
WARNING: Apparent invocation of macro
NAME not resolved.
This error could be caused by the following:
the misspelling of the name of a macro or a macro function
an error in a macro definition that caused the macro to be compiled as a dummy
macro
A dummy macro is a macro that the macro processor partially compiles but does not
store.
Note: You receive this warning only if the MERROR system option is on.
Solving the “Black Hole” Macro Problem
When the macro processor begins compiling a macro definition, it reads and compiles
tokens until it finds a matching %MEND statement. If you omit a %MEND statement or
cause it to be unrecognized by omitting a semicolon in the preceding statement, the
128 Chapter 10 Macro Facility Error Messages and Debugging
macro processor does not stop compiling tokens. Every line of code that you submit
becomes part of the macro.
Resubmitting the macro definition and adding the %MEND statement does not correct
the error. When you submit the corrected definition, the macro processor treats it as a
nested definition in the original macro definition. The macro processor must find a
matching %MEND statement to stop compilation.
Note: It is a good practice to use the %MEND statement with the macro name, so you
can easily match %MACRO and %MEND statements.
If you recognize that SAS is not processing submitted statements and you are not sure
how to recover, submit %MEND statements one at a time until the following message
appears in the SAS log:
ERROR: No matching %MACRO statement for this %MEND statement.
Then recall the original erroneous macro definition, correct the error in the %MEND
statement, and submit the definition for compilation.
There are other syntax errors that can create similar problems, such as unmatched
quotation marks and unclosed parentheses. Often, one of these syntax errors leads to
others. Consider the following example:
%macro rooms;
/* other macro statements& */
%put **** %str(John's office) ****; /* ERROR */
%mend rooms;
%rooms
When you submit these statements, the macro processor begins to compile the macro
definition ROOMS. However, the single quotation mark in the %PUT statement is not
marked by a percent sign. Therefore, during compilation the macro processor interprets
the single quotation mark as the beginning of a literal token. It does not recognize the
closing parenthesis, the semicolon at the end of the statement, or the %MEND statement
at the end of the macro definition.
To recover from this error, you must submit the following:
');
%mend;
If the above methods do not work, try submitting the following string:
*'; *"; *); */; %mend; run;
Continue submitting this string until the following message appears in the SAS log:
ERROR: No matching %MACRO statement for this %MEND statement.
Obviously, it is easier to catch these errors before they occur. You can avoid subtle
syntax errors by carefully checking your macros before submitting them for compilation.
For a syntax checklist, see “Developing Bug-free Macros” on page 123.
Note: Another cause of unexplained and unexpected macro behavior is using a reserved
word as the name of a macro variable or macro. For example, because SAS reserves
names starting with SYS, you should not create macros and macro variables with
names beginning with SYS. Most host environments have reserved words too. For
example, on PC-based platforms, the word CON is reserved for console input. For
Troubleshooting Your Macros 129
reserved SAS keywords, see Appendix 1, “ Reserved Words in the Macro Facility,”
on page 391. Check your SAS companion for host environment reserved words.
Resolving Timing Issues
Many macro errors occur because a macro variable resolves at a different time than
when the user intended or a macro statement executes at an unexpected time. A prime
example of the importance of timing is when you use CALL SYMPUT to write a DATA
step variable to a macro variable. You cannot use this macro variable in the same DATA
step where it is defined; only in subsequent steps (after the DATA step's RUN
statement).
The key to preventing timing errors is to understand how the macro processor works. In
simplest terms, the two major steps are compilation and execution. The compilation step
resolves all macro code to compiled code. Then the code is executed. Most timing errors
occur because of the following:
the user expects something to happen during compilation that does not actually occur
until execution
expects something to happen later but is actually executed right away
Here are two examples to help you understand why the timing of compilation and
execution can be important.
Example of a Macro Statement Executing Immediately
In the following program, the user intends to use the %LET statement and the SR_CIT
variable to indicate whether a data set contains any data for senior citizens:
data senior;
set census;
if age > 65 then
do;
%let sr_cit = yes; /* ERROR */
output;
end;
run;
However, the results differ from the user's expectations. The %LET statement is
executed immediately and the DATA step is being compiled--before the data set is read.
Therefore, the %LET statement executes regardless of the results of the IF condition.
Even if the data set contains no observations where AGE is greater than 65, SR_CIT is
always yes.
The solution is to set the macro variable's value by a means that is controlled by the IF
logic and does not execute unless the IF statement is true. In this case, the user should
use CALL SYMPUT, as in the following correct program:
%let sr_cit = no;
data senior;
set census;
if age > 65 then
do;
call symput ("sr_cit","yes");
output;
end;
run;
130 Chapter 10 Macro Facility Error Messages and Debugging
When this program is submitted, the value of SR_CIT is set to yesonly if an observation
is found with AGE greater than 65. Note that the variable was initialized to
no. It is
generally a good idea to initialize your macro variables.
Resolving Macro Resolution Problems Occurring during DATA Step
Compilation
In the previous example, you learned you had to use CALL SYMPUT to conditionally
assign a macro variable a value in a DATA step. So, you submit the following program:
%let sr_age = 0;
data senior;
set census;
if age > 65 then
do;
call symput("sr_age",age);
put "This data set contains data about a person";
put "who is &sr_age years old."; /* ERROR */
end;
run;
If AGE was 67, you would expect to see a log message like the following:
This data set contains data about a person
who is 67 years old.
However, no matter what AGE is, the following message is sent to the log:
This data set contains data about a person
who is 0 years old.
When the DATA step is being compiled, &SR_AGE is sent to the macro facility for
resolution, and the result is passed back before the DATA step executes. To achieve the
desired result, submit this corrected program instead:
%let sr_age = 0;
data senior;
set census;
if age > 65 then
do;
call symput("sr_age",age);
stop;
end;
run;
data _null_;
put "This data set contains data about a person";
put "who is &sr_age years old.";
run;
Note: Use double quotation marks in statements like PUT, because macro variables do
not resolve when enclosed in single quotation marks.
Here is another example of erroneously referring to a macro variable in the same step
that creates it:
data _null_;
retain total 0;
set mydata end=final;
total=total+price;
Troubleshooting Your Macros 131
call symput("macvar",put(total,dollar14.2));
if final then put "*** total=&macvar ***"; /* ERROR */
run;
When these statements are submitted, the following lines are written to the SAS log:
WARNING: Apparent symbolic reference MACVAR not resolved.
*** total=&macvar ***
As this DATA step is tokenized and compiled, the &causes the word scanner to trigger
the macro processor, which looks for a MACVAR entry in a symbol table. Because such
an entry does not exist, the macro processor generates the warning message. Because the
tokens remain on the input stack, they are transferred to the DATA step compiler. During
DATA step execution, the CALL SYMPUT statement creates the macro variable
MACVAR and assigns a value to it. However, the text
&macvarin the PUT statement
occurs because the text has already been processed while the macro was being compiled.
If you were to resubmit these statements, the macro would appear to work correctly, but
the value of MACVAR would reflect the value set during the previous execution of the
DATA step. This value can be misleading.
Remember that in general, the % and &trigger immediate execution or resolution during
the compilation stage of the rest of your SAS code.
For more examples and explanation of how CALL SYMPUT creates macro variables,
see “Special Cases of Scope with the CALL SYMPUT Routine” on page 65.
Solving Problems with the Autocall Facility
The autocall facility is an efficient way of storing and using production (debugged)
macros. When a call to an autocall macro produces an error, the cause is one of two
things:
an erroneous autocall library specification
an invalid autocall macro definition
If the error is the autocall library specification and the MERROR option is set, SAS can
generate any or all of the following warnings:
WARNING: No logical assign for filename
FILENAME.
WARNING: Source level autocall is not found or cannot be opened.
Autocall has been suspended and OPTION NOMAUTOSOURCE has
been set. To use the autocall facility again, set OPTION
MAUTOSOURCE.
WARNING: Apparent invocation of macro
MACRO-NAME not resolved.
If the error is in the autocall macro definition, SAS generates a message like the
following:
NOTE: Line generated by the invoked macro
"MACRO-NAME".
132 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