Automation 使用%include为不同站点自动化SAS程序

Automation 使用%include为不同站点自动化SAS程序,automation,sas,sas-macro,Automation,Sas,Sas Macro,我的问题是,我在多个站点上使用同一个程序进行报告。我必须分别为它们运行代码。我正在寻找自动化我的过程,调用代码,并在一次运行的所有网站。这是我尝试使用的代码,但它不起作用 data _null_; array sites {2} _temporary_ (SiteA SiteB); do k = 1 to dim(sites); %let site = sites(k); %include '...path\SitesWait.sas'; end; run; SiteWa

我的问题是,我在多个站点上使用同一个程序进行报告。我必须分别为它们运行代码。我正在寻找自动化我的过程,调用代码,并在一次运行的所有网站。这是我尝试使用的代码,但它不起作用

data _null_;
array sites {2} _temporary_ (SiteA SiteB);

do k = 1 to dim(sites);
    %let site = sites(k);

    %include '...path\SitesWait.sas';

end; run;
SiteWait中的代码可以独立工作。我定义了一个名为site的宏变量,它设置代码运行的站点

我一直得到的错误是“错误117-185:有1个未关闭的DO块。”


谢谢

,因此您希望基于先前的数据集包含不同的文件。我建议您创建该文件,而不是从数组中读取它,但要遵循您最初请求的精神:

%let basePath= c:\foo;

data _NULL_;
    array sites {2} $5. ('SiteA' , 'SiteB');

    do k = 1 to dim(sites);
        site = sites(k);
        call execute('%nrstr(%put &basePath.\'||site||';)');
    end;
run;
这就产生了

c:\foo\SiteA

c:\foo\SiteB

您可以轻松地将%put命令替换为
%include
,以实现您的愿望

编辑:我建议您尝试这样做:

data includes;
    format path $30. file $10.;
    input path $ file $;
    cards;
    c:\foo\ file1.sas
    c:\foo\ file2.sas
    c:\Bar\ file1.sas
    c:\Bar\ file2.sas
; run;

data _null_;
    set includes;
        call execute('%nrstr(%put '||strip(path)||''||strip(file)||';)');
run;

因此,您希望基于先前的数据集包含不同的文件。我建议您创建该文件,而不是从数组中读取它,但要遵循您最初请求的精神:

%let basePath= c:\foo;

data _NULL_;
    array sites {2} $5. ('SiteA' , 'SiteB');

    do k = 1 to dim(sites);
        site = sites(k);
        call execute('%nrstr(%put &basePath.\'||site||';)');
    end;
run;
这就产生了

c:\foo\SiteA

c:\foo\SiteB

您可以轻松地将%put命令替换为
%include
,以实现您的愿望

编辑:我建议您尝试这样做:

data includes;
    format path $30. file $10.;
    input path $ file $;
    cards;
    c:\foo\ file1.sas
    c:\foo\ file2.sas
    c:\Bar\ file1.sas
    c:\Bar\ file2.sas
; run;

data _null_;
    set includes;
        call execute('%nrstr(%put '||strip(path)||''||strip(file)||';)');
run;

你应该这样做:

main.sas

%macro ProcessList;
    %let list_of_site=SiteA|SiteB|SiteC;
    %let k=1;
    %do %while (%qscan(&list_of_site, &k,|) ne );
        %let site = %scan(&list_of_site, &k,|);
        %include 'H:\desktop\SAS\test_inc.sas';
        /*%put site=&site;*/
        %let k = %eval(&k + 1);
    %end;


%mend ProcessList;
%processList;


test_inc.sas

%put site=&site;
结果:

site=SiteA
site=SiteB
site=SiteC
使用宏函数,它很简单。您可以将%include替换为%put

您可以使用以下技术从数据集获取站点列表:

data test;
infile datalines dsd;
   input site : $200. ;
   datalines;
SiteA,
SiteB,
SiteC,
SiteD,
SiteE,
SiteF,
; 
run;

proc sql noprint;
   select quote(trim(site), "'") into : list_of_site separated by "|" from work.test;
quit;

关于

您应该这样做:

main.sas

%macro ProcessList;
    %let list_of_site=SiteA|SiteB|SiteC;
    %let k=1;
    %do %while (%qscan(&list_of_site, &k,|) ne );
        %let site = %scan(&list_of_site, &k,|);
        %include 'H:\desktop\SAS\test_inc.sas';
        /*%put site=&site;*/
        %let k = %eval(&k + 1);
    %end;


%mend ProcessList;
%processList;


test_inc.sas

%put site=&site;
结果:

site=SiteA
site=SiteB
site=SiteC
使用宏函数,它很简单。您可以将%include替换为%put

您可以使用以下技术从数据集获取站点列表:

data test;
infile datalines dsd;
   input site : $200. ;
   datalines;
SiteA,
SiteB,
SiteC,
SiteD,
SiteE,
SiteF,
; 
run;

proc sql noprint;
   select quote(trim(site), "'") into : list_of_site separated by "|" from work.test;
quit;

关于

如果站点不经常更改,并且如果没有太多,这可能是最简单的方法:

%let site=siteA;
%include '...path\SitesWait.sas';

%let site=siteB;
%include '...path\SitesWait.sas';

%let site=siteC;
%include '...path\SitesWait.sas';

不过要小心。您可能希望在SitesWait.sas顶部包含“重置”sas会话的代码。例如,清除计划使用的任何宏值,删除工作文件夹中的任何数据集等。否则,对
站点的第二次调用wait.sas
可能会受到上次运行的影响。

如果站点不经常更改,并且如果没有太多,这可能是最简单的方法:

%let site=siteA;
%include '...path\SitesWait.sas';

%let site=siteB;
%include '...path\SitesWait.sas';

%let site=siteC;
%include '...path\SitesWait.sas';

不过要小心。您可能希望在SitesWait.sas顶部包含“重置”sas会话的代码。例如,清除您计划使用的任何宏值,删除工作文件夹中的任何数据集等。否则,对
SitesWait.sas
的第二次调用可能会受到上一次运行的影响。

您不能在数据步骤中间包含另一个多步骤程序
%include
只是将文件中的行放入程序流,就好像这些行已键入程序一样。当SAS在包含的文件中看到第一个数据或PROC语句时,它将停止编译主程序中的数据步骤并运行它。这就是为什么DO循环没有看到END语句

您可以使用数据步骤生成设置参数并包含程序的代码

data _null_;
  length site $20 ;
  do site='SiteA','SiteB' ;
    call execute(cats('%nrstr(%let) site=',site,';'));
    call execute("%include '...path\SitesWait.sas';");
  end;
run;
您所创建的基本上是一个宏,带有一个名为SITE的参数。实际上,您可以使用%INCLUDE作为宏定义的主体。然后,您可以只编写所需的调用代码,而不是尝试处理一些值列表

%macro siteswait(site);
%include '...path\SitesWait.sas';
%mend;
%siteswait(SiteA)
%siteswait(SiteB)

不能在数据步骤中间包含另一个多步骤程序
%include
只是将文件中的行放入程序流,就好像这些行已键入程序一样。当SAS在包含的文件中看到第一个数据或PROC语句时,它将停止编译主程序中的数据步骤并运行它。这就是为什么DO循环没有看到END语句

您可以使用数据步骤生成设置参数并包含程序的代码

data _null_;
  length site $20 ;
  do site='SiteA','SiteB' ;
    call execute(cats('%nrstr(%let) site=',site,';'));
    call execute("%include '...path\SitesWait.sas';");
  end;
run;
您所创建的基本上是一个宏,带有一个名为SITE的参数。实际上,您可以使用%INCLUDE作为宏定义的主体。然后,您可以只编写所需的调用代码,而不是尝试处理一些值列表

%macro siteswait(site);
%include '...path\SitesWait.sas';
%mend;
%siteswait(SiteA)
%siteswait(SiteB)

那没有多大意义。我假设您必须传递一些参数,否则程序只会运行很多次。唯一要传递的参数是“site”,它将在程序SitesWait.sas中使用。创建一个宏并将Sites作为参数传递,但代码不会这样做。您需要一个宏并使用调用EXECUTE或DOSUBL。在CALL EXECUTE的文档中有一个完整的示例可以说明其用法。因此%INCLUDE文件中的代码只是数据步骤的中间部分?这没有多大意义。我假设您必须传递一些参数,否则程序只会运行很多次。唯一要传递的参数是“site”,它将在程序SitesWait.sas中使用。创建一个宏并将Sites作为参数传递,但代码不会这样做。您需要一个宏并使用调用EXECUTE或DOSUBL。在CALL EXECUTE的文档中有一个完整的示例可以说明其用法。那么%INCLUDE文件中的代码只是数据步骤的中间部分?