带有do循环的SAS宏

时间:2017-03-28 02:47:55

标签: database loops sas

我正在尝试编写一个查询,其中创建一个新表,其中包含来自许多以YYYYMM结尾的数据集中的变量(例如dataset_201610)。然后我试图将此数据附加到主数据库。当我运行它时,它不会循环回到其他数据集。有帮助吗?

%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;

1 个答案:

答案 0 :(得分:0)

您需要增加或减少&yyyymm宏变量,否则它将永远循环。此外,如果你增加你的程序设置方式将永远循环,所以你需要从最大日期开始递减。

由于您正在处理月份/日期并且始终附加数据集,因此您需要使用一些额外的检查来确保没有错误并及时执行。

修改你的程序:

%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);

如果您愿意,可以将它们设置为默认的最小/最大值。另请注意,我们假设输入日期为yyyymm格式;如果不更改程序,它将无法与其他日期格式一起使用。