@newboy1218 wrote:
Hi.. my following macro keeps on running and won't stop.. Can anyone spot any mistake there?
In my macro, I am first checking if the file lib.dataset_&dt2. exists or not. If it does then append the file name to a list. If not, then skip the date dt2, and move on to the next date and next file.
At the end, my macro variable &fileList1 should have all the existing files. For example,
%put &fileList1.;
(lib.dataset_20190501 lib.dataset_20190524 lib.dataset_20190602 lib.dataset_20190603 .....)
rsubmit;
%macro code(d1=, d2=);
%let start_date = &d1.;
%let end_date = &d2.;
%let dt1 = &start_date.;
%do %while (%sysevalf("&dt1."d <= "&end_date."d));
%let dt1 = %sysfunc(putn("&dt1."d, date9.));
%let dt2 = &dt1.;
%let dt2 = %sysfunc(putn("&dt1."d, yymmddn8.));
%if %sysfunc(exist(lib.dataset_&dt2.)) = 1 %then %do;
%let fileList1 = %str();
%let thefile1 = lib.dataset_&dt2.;
%let fileList1 = %str(&fileList1 &thefile1);
%let dt1 = %sysfunc(intnx(day, "&dt1."d, 1, s), date9.);
%end;
%end;
%put &fileList1.;
%mend;
endrsubmit;
rsubmit;
%code(d1 = '01MAY2019', d2 = '02JUL2019');
endrsubmit;
Macros and macro variables are just text. Yes, we have the %eval and %sysevalf functions, but this line "worries" me.
%do %while (%sysevalf("&dt1."d <= "&end_date."d));
Why make this more complicated than it needs to be? If it were me, I'd code it this way:
%macro get_dates(start,end);
data _null_;
length buffer $32767; %* adjust as required, but the max length does not really hurt performance ; ;
do date="&start"d to "&end"d;
buffer=catx(" ",buffer,put(date,yymmddn8.));
end;
call symputx("dates",buffer,"G");
run;
%mend;
%get_dates(01MAY2019,02JUL2019);
%put &=dates;
%* this is the block of code you need to repeat for each token in the list ;
%macro code;
%let dataset=lib.dataset_&word;
%put &=dataset;
%mend;
%loop(&dates);
* if you want to wrap this in one uber-macro: ;
%macro my_uber_macro(start,end);
%* create a list of dates ;
data _null_;
length buffer $32767; %* adjust as required, but the max length does not really hurt performance ; ;
do date="&start"d to "&end"d;
buffer=catx(" ",buffer,put(date,yymmddn8.));
end;
call symputx("dates",buffer,"G");
run;
%* run a block of code over those dates ;
%let i=1;
%let word=%scan(&dates,&i,%str( ));
%do %while (&word ne );
%* this is the bit of code you need to repeat for each token ;
%let dataset=lib.dataset_&word;
%put &=dataset;
%* end of the bit of code you need to repeat ;
%let i=%eval(&i+1);
%let word=%scan(&dates,&i,%str( ));
%end;
%mend;
%my_uber_macro(01MAY2019,02JUL2019);
See https://github.com/scottbass/SAS/blob/master/Macro/loop.sas
for the loop macro. Save it to your autocall macro library.
If you don't want to use that macro, then just use the concepts in that macro to parse each token in the &dates list, and call a child macro or block of code for each word in the list. Put the block of code you need to repeat in that child macro.
You'll have to use a different approach if your list of dates won't fit into a macro variable (64K). Well, actually, the 32K limit of the buffer variable in the data step. However, I rarely encounter this limit in my day-to-day work.
(if you did encounter that limit, see https://github.com/scottbass/SAS/blob/master/Macro/loop_control.sas)
... View more