John,
Though the problems in the upper and lower code snippets are different, they are all based on the same timing issue - the maco processor processes at a different time than the data step. For example, let's start with a little demo code:
%let SCOPE=GLOBAL;
TITLE "&SCOPE macro variables before DATA _NULL_";
proc print data=sashelp.vmacro;
where SCOPE="&SCOPE";
run;
This produces a report:
OUTPUT window:
GLOBAL macro variables before DATA _NULL_
Obs scope name offset value
1 GLOBAL SCOPE 0 GLOBAL
Note that the macro variable yr does not yet exist. Now for your code:
data _null_;
call symput('yr', year(today() ) );
put "&yr.";
run;
When submitted the first time, the macro variable yr still does not exist so cannot be resolved before the DATA step is compiled. See the SAS log:
WARNING: Apparent symbolic reference YR not resolved.
10 run;
&yr.
Because the macro processor could not resolve the variable yr, the DATA step compiles with the value '&yr.' in the PUT statement.
Now, when the data step executed for the first time, it created and populated the macro variable yr. Run this code after the first DATA _NULL_ step to prove that this is true:
TITLE "&SCOPE macro variables after DATA _NULL_";
proc print data=sashelp.vmacro;
where SCOPE="&SCOPE";
run;
OUTPUT window:
Global macro variables before DATA _NULL_
Obs scope name offset value
1 GLOBAL SCOPE 0 GLOBAL
2 GLOBAL YR 0 2011
So the second time you run your DATA step, the variable yr already exists, and it will be resolved before the DATA step gets compiled. This will avoid the WARNING and replace the text &yr. in the PUT statement with 2011 as the data step compiles. This is why the second time you run the code, you get the expected results.
Hope this helps.
May the SAS be with you
🙂