0

Having some problems with Do Loop Concepts. I have a static date (can be any date for that matter) defined with -

%LET DATE = %SYSFUNC(TODAY());
%PUT &DATE;

I need to create a series of macro variables that hold values of that date (&DATE) incremented by 10 days, so I used a simple data step to achieve this -

DATA _NULL_;
CALL SYMPUT('DATE10',&DATE+10);
CALL SYMPUT('DATE20',&DATE+20);
CALL SYMPUT('DATE30',&DATE+30);
RUN;

This method is OK for increments of 10 up to 30 days after the initial value of &DATE. I am now tasked with extending the report to execute on dates that extend to 250 days (incremented by 10 days) from the value of &DATE. Assuming a DO LOOP would be the most efficient execution method, I am having trouble understanding how the loop would "create" a new macro var (ex. &Date150) within the loop. Assuming the syntax below is correct, I am not sure what the next/correct step would be :

DATA _NULL_;
DO I=10 TO 150 BY 10;
CALL SYMPUT('DATE10',&DATE);
END;
RUN;

How would I "increment" the actual name of the macro var (&DATE10,&Date20...&Date150) in the loop while executing the creation of a macro var based on 10 day increments?

SMW
  • 470
  • 1
  • 4
  • 19
  • Why do you need all of those macro variables? Why not just pass the list of values in a single macro variable. Much simpler. – Tom Dec 04 '15 at 22:04
  • There is a series of queries that executes summaries for each date condition, so I figured I would just macro the query calling out each date to create the summary values/subset tables for each date. To be totally honest, it was the best approach I had at the time. Your suggestion...I didn't know I could do that (creating a "list" of values in one &variable). Is that how the "select into:" works when I see people reference lists as the :into value? Maybe you could point me in the right direction for reference? Very open to improving my methods.... – SMW Dec 04 '15 at 22:47
  • Say you have three dates. So you make `dates=1 2 3`. Then if you want to produce a report by date for just those date you just do `proc report; where date in (&dates); by date; .... run;` In a more complex report you just add a `%do i=1 %to %sysfunc(countw(&dates)); %let date=%scan(&dates,&i); ... where date=&date; ... %end;` – Tom Dec 04 '15 at 23:21

3 Answers3

2

Use the I variable as part of your variable name, via a concatenation function, cats() is probably appropriate. Also, a personal preference, but I prefer Call SymputX as it removes any extra spaces.

DATA _NULL_;
DO I=10 TO 150 BY 10;
CALL SYMPUTX(cats('DATE', i), &DATE+i);
END;
RUN;
Reeza
  • 20,510
  • 4
  • 21
  • 38
  • CALL SYMPUTX(cats('DATE', i), &DATE+i); maybe? – Haikuo Bian Dec 04 '15 at 20:16
  • SYMBOLGEN: Macro variable DATE10 resolves to 20426 SYMBOLGEN: Macro variable DATE20 resolves to 20426 SYMBOLGEN: Macro variable DATE150 resolves to 20426, not sure if I explained correctly or if there is an implied step I need to include. – SMW Dec 04 '15 at 20:16
  • @Haikuo Bian - That worked! Not aware I could concatenate the "I" within the CAT function. Should probably +1 for Reeza and User667...since he referenced the same concept (or so I believe). – SMW Dec 04 '15 at 20:20
  • @HaikuoBian You're correct, I just copied the code above...which is correct in one section and not another :) – Reeza Dec 04 '15 at 20:49
1

Consider placing the values into a single macro variable. As long as the list is not longer than maximum length of a macro variable.

DATA _NULL_;
  length dates $32767 ;
  date=today();
  DO I=10 TO 150 BY 10;
    dates=catx(' ',dates,date+i);
  end;
  CALL SYMPUTx('dates',dates);
RUN;

Then in your reporting code you can either just use the list of dates.

proc report ;
  where date in (&dates);
 ...
run;

Or if you have macro you can use a %DO loop.

%do i=1 %to %sysfunc(countw(&dates));
  %let date=%scan(&dates,&i);
  proc report;
    where date=&date;
    ....
%end;
Tom
  • 47,574
  • 2
  • 16
  • 29
0

Easy enough - pass in a variable as the first argument to call symput that contains the name of the macro variable you want to create.

user667489
  • 9,501
  • 2
  • 24
  • 35