I have macros in my code that are created and used in random order.
It's showing "reference not resolved" for "%put &pincuk", and syntax error for the "&pincuk". It works fine when I run the code twice. I'm guessing it happens when SAS is reaching the &pincuk before the macro is created. For example,
data x.fcastukcalc;
do day=&daycountuk + 1 to &daycountkorea
retain fcast &ukdmax;
fcast=(fcast * &pincuk) + fcast;
output;
end;
run;
/* then this, later on */
data _null_;
keep deathsuk inc1 inc2 pinc1 pinc2 pinc;
set x.uk;
inc1=deathsuk - lag1(deathsuk);
pinc1=(inc1 / lag1(deathsuk));
inc2=lag1 (deathsuk) - lag2(deathsuk);
pinc2=(inc2 / lag2(deathsuk));
pinc=(pinc1 + pinc2) / 2;
call symputx('pincuk', pinc);
run;
%put &pincUK;
If, on the first run through, x.uk
does not exist, or has zero rows, the call symputx('pincUK',pinc);
will never be reached. So, in a 'random' situation of code running, lets be more generous and say a developmental situation, your expectations may have been subverted by a misremembered operation or subtle change of state. Check your code for %SYMDEL
statements. During development of a large macro, you may be submitting parts of the interior of a macro and not have complete 'simulation' of the state expected to exist during an actual call of the macro.
Start a fresh SAS session and see if the problem with the code persists and can be reproduced more directly.
To be specific, your question is about macro symbols, often referred to as macro variables. Macros themselves are names for groups of SAS programming statements.
From help (good read)
When SAS compiles program text, two delimiters trigger macro processor activity:
&name
- refers to a macro variable. Replacing Text Strings Using Macro Variables explains how to create a macro variable. The form &name is called a macro variable reference.
%name
- refers to a macro. Generating SAS Code Using Macros explains how to create a macro. The form %name is called a macro call.
The text substitution produced by the macro processor is completed before the program text is compiled and executed. The macro facility uses statements and functions that resemble the statements and functions that you use in the DATA step. An important difference, however, is that macro language elements can enable only text substitution and are not present during program or command execution.
------ Edit (added) ------
Writing code with lots of abstractions (i.e. macro variables) requires a certain level of discipline and system design. A macro must be compiled before it can be called, however the macro variables (i.e. symbols) it resolves within do NOT need to exist at compilation time, only at macro invocation (call) time. For old fuddies the concept is like a mail merge boilerplate with too many fields.
Macro variables can be local (as a parameter in the macro definition, or explicitly stated in a %LOCAL
, or as an assignment to a previously undefined symbol. Reliance on GLOBAL macro variables should be reduced to a minimum or none, as should an over-reliance on variables to be expected to exist in the caller scope. Dependence on a variable being global should be explicitly stated with a %GLOBAL
in the macros source.
An assignment to a non-declared %LOCAL
can be a problem because the assignment could accidentally (unexpectedly) replace the value of a declared or existing variable in an outer (or calling) scope, and be the cause of it don't work right problems. Good discipline is to explicitly %LOCAL
all variables within a macro definition - the macro system does not have a strict mode (as found in other languages) that reports problematic macro variables.