根据列表中的名称调整SAS宏

时间:2014-03-14 07:25:08

标签: sql macros sas

新来的。

我写了一对宏来搜索我们工作中的一个数据库。这是我如何使用它的例子:

%LET SVlist=%str(R_PAR_SV_2012_VER3 R_PAR_SV);
%LET ovlist=%str(R_PAR_OV_2012_VER3 R_PAR_OV);




%LET FILTER=
(DIAGNOS like 'S72%' or diagnos contains ' S72' or
DIAGNOS like 'I21%' or diagnos contains ' I21'
);

%LET OVSELECT=PNR,
          PNRQ, 
          INDATUM, 
          OP, 
          DIAGNOS, 
          HDIA,
          alder,
          SJUKHUS;
%LET sVSELECT=&OVSELECT,UTDATUM,OPD1;

%macro ovsql(ovlist);
proc sql noprint;
%let n=%sysfunc(countw(&ovlist));
    %do i=1 %to &n;
        %let val = %scan(&ovlist,&i);


        create table work.&val as

            select &ovselect,
'SV' as souce
from r_par.&val
            where pnrq='0';


    %end;
quit;
%mend;

%macro svsql(svlist);
proc sql noprint;
%let n=%sysfunc(countw(&svlist));
    %do i=1 %to &n;
        %let val = %scan(&svlist,&i);


        create table work.&val as

            select &svselect,
'SV' as souce
from r_par.&val
            where pnrq='0';


    %end;
quit;
%mend;

%ovsql(&ovlist);
%svsql(&SVlist);

以上工作正常:

正如您所看到的,我实际上有两个宏来处理2种略有不同类型的数据集。为此,我使用两个列表:

我想知道的是,是否有办法整合宏,以便您可以调整程序来运行" OV-macro"当列表中的集合包含名称中的字母OV和列表中的集合包含字母SV时的SV。可以这样做吗?

这是我自己的尝试,我尝试了一些变体,但未能使它工作,以供参考。

options mprint;
%macro PSQL(list);
proc sql ;
%let n=%sysfunc(countw(&list));
    %do i=1 %to &n;
        %let val = %scan(&list,&i);
         %let g= 
%substr(&val,7,2);
         ;
        %put(&g);

         %if &g=:SV %then %do; 

        create table work._&val as

            select &svselect,
'SV' as souce
from r_par.&val
            where pnrq='0';
            %end;
            %else %if  &g=:OV %then %do ;
                    create table work._&val as

            select &ovselect,
'OV' as souce
from r_par.&val
            where pnrq='0';
    %end;
    %end;
quit;
%mend;

%PSQL(R_PAR_SV_2012_VER3 R_PAR_OV_2012_VER3);

我真的很喜欢任何帮助。对于sas宏语言,我有点新手。提前致谢

1 个答案:

答案 0 :(得分:0)

我会用不同的方式写出来。拥有两个%if块并不能真正为你买到这么多;它仍然保留了两位代码,其余的代码并不是很有趣或难以维护两次。

您可以在一段代码中写下这个:

create table work._&val as
        select &&shortval.select, "&shortval." as source
          from r_par.&val
          where pnrq='0';

现在添加一些东西来定义& shortval为SV或OV,你现在根本不需要%。我认为你为此目的使用& g,如果这是为了它的目的,将它重命名为shortval(因为g是一个宏变量的坏名称)并与

一起使用

此外,关于上述代码结构的一些一般性评论:

通常,以这种方式进行宏解析比其他方法更难以实现相同的结果。尽管可以这样做,但与数据驱动的宏调用相比,它更容易工作,更容易出错,并且难以维护。

而不是让宏接受包含多次迭代的单个参数'值得数据,将宏写为单个迭代宏,并以编程方式多次调用它。 IE,有一个数据集,每个数据集包含一行,变量" Type":

R_PAR_SV_2012_VER3
R_PAR_OV_2012_VER3

然后做:

proc sql;
 select cats('%PSQL(',type,')') into :psqllist separated by ' '
        from have;
quit;

&psqllist.;

这使您可以更轻松地控制通话。它还允许您通过轻松包含几个宏变量来更轻松地实现上述部分。

这意味着,如果我写了上面的宏,我就这样做:

%macro psql(shortval=,val=);
  create table work._&val as
            select &&shortval.select, "&shortval." as source
              from r_par.&val
              where pnrq='0';
%mend psql;

proc sql;
 select cats('%PSQL(val=',type,',shortval=',substr(type,7,2),')') into :psqllist separated by ' '
        from have;
quit;
&psqllist.;

现在您有大约十行易于维护的代码加上一个小数据集,您甚至可以从Excel工作表或其他数据源中提取(取决于此值列表应该来自何处)。