简体   繁体   中英

SAS Macro with a do loop

I am trying to write a query where a new table is created with a selection of variables from a number of existing datasets all ending with YYYYMM(eg dataset_201610). Then I am trying to append this data to a master database. When I run it, it doesnt loop back to the other datasets. Any help?

%macro create_master_data_table;
*If the master table exists then delete it;
%if %sysfunc(exist(data_master)) %then %do;
    proc sql;
        drop table data_master;
    quit;
%end;

%let yyyymm = 201702;
%do %while (&yyyymm >= 201610);
    *Create a simple table with a month id and the fields we want;
    data thismonth;
    set Base.Accounts_&yyyymm;
    keep var1 var2 var3
    run;

    *Append the fields we want to the master table;
    proc append base=data_master    
    data=Base.Accounts_&yyyymm(keep=var1 var2 var3);
    run;

    %end;
 %mend create_master_data_table;
 %create_master_cre_table;

You need to increment or decrement your &yyyymm macro variable, otherwise it will loop forever. Additionally, the way your program is set up will loop forever if you increment, so you will need to decrement starting at the maximum date.

Because you are dealing with months/dates and always appending a dataset, you'll want to use a few additional checks to ensure no errors and have timely execution.

Modify your program as such:

%macro create_master_data_table(mindate=, maxdate=);
*If the master table exists then delete it;
%if %sysfunc(exist(data_master)) %then %do;
    proc sql;
        drop table data_master;
    quit;
%end;

/* Initialize variables */
%let i = 0;
%let startdate = %sysfunc(inputn(&maxdate., yymmn6.) );
%let nextdate = %sysfunc(intnx(month, &startdate., &i.) );

%do %while (&nextdate > %sysfunc(inputn(&mindate., yymmn6.) ) );

    /* Decrease date by 1 month relative to start date */
    %let nextdate = %sysfunc(intnx(month, &startdate., &i.) );

    /* Convert from SAS date to yyyymm */
    %let yyyymm = %sysfunc(putn(&nextdate, yymmn6.) );

    /* Only pull data if the table exists */
    %if(%sysfunc(exist(Base.Accounts_&yyyymm.) ) ) %then %do;

        *Create a simple table with a month id and the fields we want;
        data thismonth;
        set Base.Accounts_&yyyymm;
        keep var1 var2 var3
        run;

        *Append the fields we want to the master table;
        proc append base=data_master    
        data=Base.Accounts_&yyyymm(keep=var1 var2 var3);
        run;
    %end;
        %else %put WARNING: Missing data: &yyyymm.;

    %let i = %eval(&i. - 1);

%end;
%mend create_master_data_table;

%create_master_data_table(mindate=201610, maxdate=201702);

You can set these to default min/max values if you wish. Also note that we are assuming the input dates will be in yyyymm format; it will not work with other date formats without changing the program.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM