Since you never assign a new value to the macro variable eggs, it will stay at 6 (or whatever value you use in the macro call) throughout, and the result of the %SYSEVALF will always be 5.
I suggest to run your macro using this statement before calling the macro
options mprint mlogic;
Some basic rules on macro processing:
You are mixing DATA step logic with macro processing logic. Just use DATA step programming for your loop.
Are you looking for something like this?
%let eggs = 4;
data hatchery;
eggs = &eggs;
do until (Eggs < 1);
putlog "NOTE: " eggs=;
eggs = eggs - 1;
Larva +1;
output;
end;
run;
Since you never assign a new value to the macro variable eggs, it will stay at 6 (or whatever value you use in the macro call) throughout, and the result of the %SYSEVALF will always be 5.
Since the only place you are changing the value of EGGS is with data step code the value of EGGS will not change until after the data step start running. The data step will not start running until after it has been fully defined.
Once the macro %DO loop is finished running your data step is going to look like:
data crap.hatchery;
Larva +1;
call symputx("Eggs", 5);
call symputx("Larva", Larva);
Larva +1;
call symputx("Eggs", 5);
call symputx("Larva", Larva);
Larva +1;
call symputx("Eggs", 5);
call symputx("Larva", Larva);
run;
I do not see why you need any macro logic here at all.
%macro Hatchery (Eggs = 6);
data crap.hatchery;
do eggs=&eggs to 0 by -1;
Larva +1;
output;
end;
run;
%mend Hatchery;
Thank you @Tom for the detailed answer.
The main purpose was to understand the macro logic a bit better. Especially the macro variable definitions in a local environment using proc sql, call symputx and %let statement.
In this regard your answer was perfectly explaining why call symputx can not work under this setting.
Yet I was wondering, why does the same logic not apply to the %let statement? I tried following code which did the job:
%macro Hatchery (Eggs = 6);
data crap.hatchery;
%do index= 1 %to 3;
%put NOTE: &Eggs.;
Larva +1;
%let Eggs = %eval(&Eggs. - 1);
call symputx("Larva", Larva);
%end;
run;
%mend Hatchery;
%Hatchery
Is it because the %let statement is directly processed in the macro processor and the symbol table is immediately updated after each iteration? I guess in contrast to that I get similar results to call symputx with proc sql select into clause as you described. My guess is that Macro processor is not triggered by either call symputx nor select into (proc sql) which are instead resolved as you described only after compilation.
data crap.hatchery;
Larva +1;
call symputx("Eggs", 5);
call symputx("Larva", Larva);
Larva +1;
call symputx("Eggs", 5);
call symputx("Larva", Larva);
Larva +1;
call symputx("Eggs", 5);
call symputx("Larva", Larva);
run;
Thanks again, now I have only to find out how I can mark your answer as solution as well.
If you turn on SYMBOLGEN option (and perhaps MLOGIC) option you will see more messages in the log showing what the macro processor is doing. (I do not recommend turning those on except for debugging the macro code because your log will become unreadable.)
Just step through it yourself and see what it is doing.
data crap.hatchery;
%do index= 1 %to 3;
%put NOTE: &Eggs.;
Larva +1;
%let Eggs = %eval(&Eggs. - 1);
call symputx("Larva", Larva);
%end;
run;
It generates a DATA statement.
Then the %DO runs. So when INDEX=1 it:
Then it does the same thing two more times.
Finally it generates the RUN statement so the data step can start being compiled and run.
The resulting data step is kind of silly looking and does not seem to have any purpose.
data crap.hatchery;
Larva +1;
call symputx("Larva", Larva);
Larva +1;
call symputx("Larva", Larva);
Larva +1;
call symputx("Larva", Larva);
run;
So all it does is create a dataset with one observation and one variable named LARVA with a value of 3. It also sets the macro variable named LARVA to the digit 3.
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.