新来的。
我写了一对宏来搜索我们工作中的一个数据库。这是我如何使用它的例子:
%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宏语言,我有点新手。提前致谢
答案 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工作表或其他数据源中提取(取决于此值列表应该来自何处)。