I'm having problems understanding how the Index variable (i) is applied/resolved inside a do loop. I have a very simple SQL macro-
*Note - The macro is called after a preceding proc sql noprint;
as well as the quit;
statement outside of the macro.
%macro psql(into,date);
select count(distinct task) into: &into
from source
where c_date between &start and &date;
%mend psql;
The macro is called via - %psql(count10,&date10);
*Note - Macro variables &date10-&date20
have all been previously defined. This works perfectly-the macro var &count10
is created, using the date value from &date10-&date20
for each line calling the %psql
macro with its respective parameters.
As always, I have been asked to extend this to many more dates, so listing the %psql
macro is going to be repetitive.
Assuming a do loop would be most efficient, I attempted the following in order to use the index(i) to create my variables, instead of many macro calls (each holding new macro parameters):
%macro doloop;
%do i=10 %to 20;
proc sql noprint;
select count(distinct task) into: count&i
from source
where c_date between &start and &date&i;
quit;
%end;
%mend doloop;
My attempt to use (I) in order to create the &count
macro variables and reference the &date
parameter does not seem to resolve WITH the actual macro vars being created/referenced, but the varaiable (I) itself seems to resolve correctly during iterations -
SYMBOLGEN: Macro variable I resolves to 10
SYMBOLGEN: Macro variable START resolves to 20429
SYMBOLGEN: Macro variable DATE resolves to 20435
SYMBOLGEN: Macro variable I resolves to 10
SYMBOLGEN: Macro variable I resolves to 11
SYMBOLGEN: Macro variable START resolves to 20429
SYMBOLGEN: Macro variable DATE resolves to 20435
SYMBOLGEN: Macro variable I resolves to 11
Does the issue involve my attempting to use (I) in order to "call" an existing macro var, and using (I) to create a macro variable at the same time? How can I reference (I) in order to create my &count variables (&count10-&count....) while using the already existing date variables(&date10-&date....) ?
I think you are talking about the differences between count&i
, &date&i
, and &&date&i
.
count&i
will resolve to COUNT10. And the way your SQL code is written this will be used as the name of the macro variable that receives the count.
&date&i
will depend on the value of the DATE
macro variable. If the macro variable DATE
has the value 20435
then your SQL code will be using the value 2043510
, which is in the year 7554, in your date comparison
&&date&i
will first reduce to &date10
and then further resolve to the value of the macro variable DATE10
. I think this is what you want to use in your SQL code.
Here is an example with SYMBOLGEN
turned on.
105 %let date10=SOME DATE VALUE;
106 %let date=ANOTHER DATE VALUE;
107 %let i=10;
108 options symbolgen;
109 %put count&i;
SYMBOLGEN: Macro variable I resolves to 10
count10
110 %put &date&i;
SYMBOLGEN: Macro variable DATE resolves to ANOTHER DATE VALUE
SYMBOLGEN: Macro variable I resolves to 10
ANOTHER DATE VALUE10
111 %put &&date&i;
SYMBOLGEN: && resolves to &.
SYMBOLGEN: Macro variable I resolves to 10
SYMBOLGEN: Macro variable DATE10 resolves to SOME DATE VALUE
SOME DATE VALUE